From a77fd34b49d29413df9c5816541b742e1293dbaf Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 14 Sep 2015 09:16:15 -0700 Subject: [PATCH 001/375] Update values and keys to v1beta3 --- gcloud-java-datastore/pom.xml | 20 +++++ .../datastore/BaseDatastoreBatchWriter.java | 3 +- .../google/gcloud/datastore/BaseEntity.java | 12 ++- .../com/google/gcloud/datastore/BaseKey.java | 23 +++--- .../google/gcloud/datastore/BatchImpl.java | 4 +- .../google/gcloud/datastore/BlobValue.java | 8 +- .../google/gcloud/datastore/BooleanValue.java | 8 +- .../gcloud/datastore/DatastoreImpl.java | 15 ++-- .../com/google/gcloud/datastore/DateTime.java | 22 ++++-- .../gcloud/datastore/DateTimeValue.java | 15 ++-- .../google/gcloud/datastore/DoubleValue.java | 8 +- .../google/gcloud/datastore/EntityValue.java | 25 +++--- .../com/google/gcloud/datastore/GqlQuery.java | 7 +- .../gcloud/datastore/IncompleteKey.java | 21 ++--- .../java/com/google/gcloud/datastore/Key.java | 8 +- .../com/google/gcloud/datastore/KeyValue.java | 8 +- .../google/gcloud/datastore/ListValue.java | 27 +++---- .../google/gcloud/datastore/LongValue.java | 8 +- .../google/gcloud/datastore/NullValue.java | 6 +- .../google/gcloud/datastore/PathElement.java | 17 ++-- .../gcloud/datastore/ProjectionEntity.java | 4 +- .../com/google/gcloud/datastore/Query.java | 7 +- .../com/google/gcloud/datastore/RawValue.java | 30 +++---- .../google/gcloud/datastore/StringValue.java | 8 +- .../gcloud/datastore/StructuredQuery.java | 9 ++- .../gcloud/datastore/TransactionImpl.java | 4 +- .../com/google/gcloud/datastore/Value.java | 78 +++++++------------ .../google/gcloud/datastore/ValueBuilder.java | 8 +- .../gcloud/datastore/ValueMarshaller.java | 6 +- .../google/gcloud/datastore/package-info.java | 4 +- .../BaseDatastoreBatchWriterTest.java | 16 ++-- .../gcloud/datastore/BlobValueTest.java | 11 +-- .../gcloud/datastore/BooleanValueTest.java | 11 +-- .../gcloud/datastore/DatastoreTest.java | 15 ++-- .../gcloud/datastore/DateTimeValueTest.java | 11 +-- .../gcloud/datastore/DoubleValueTest.java | 11 +-- .../gcloud/datastore/EntityValueTest.java | 17 +--- .../google/gcloud/datastore/KeyValueTest.java | 11 +-- .../gcloud/datastore/ListValueTest.java | 15 +--- .../gcloud/datastore/LongValueTest.java | 11 +-- .../gcloud/datastore/NullValueTest.java | 12 +-- .../google/gcloud/datastore/RawValueTest.java | 16 ++-- .../gcloud/datastore/SerializationTest.java | 13 ++-- .../gcloud/datastore/StringValueTest.java | 12 +-- .../google/gcloud/datastore/ValueTest.java | 65 +++------------- 45 files changed, 294 insertions(+), 376 deletions(-) diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index 52b3f62232c4..8315836f67cd 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -13,12 +13,32 @@ gcloud-java-pom 0.0.8-SNAPSHOT + + + sonatype-snapshots + sonatype-snapshots + https://oss.sonatype.org/content/repositories/snapshots/ + + true + + + ${project.groupId} gcloud-java-core ${project.version} + + com.google.cloud.datastore + datastore-v1beta3-protos + 0.0.1-SNAPSHOT + + + com.google.cloud.datastore + datastore-v1beta3-proto-client + 0.0.1-SNAPSHOT + com.google.apis google-api-services-datastore-protobuf diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java index 7eaf5c535f26..8d0eec117bdf 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java @@ -214,7 +214,8 @@ protected DatastoreV1.Mutation.Builder toMutationPb() { mutationPb.addUpsert(entity.toPb()); } for (Key key : toDelete()) { - mutationPb.addDelete(key.toPb()); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //mutationPb.addDelete(key.toPb()); } return mutationPb; } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java index 3a79f3053a1e..665b4d8d24b9 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java @@ -93,11 +93,13 @@ private B self() { protected B fill(DatastoreV1.Entity entityPb) { Map> copiedProperties = Maps.newHashMap(); for (DatastoreV1.Property property : entityPb.getPropertyList()) { - copiedProperties.put(property.getName(), Value.fromPb(property.getValue())); + // TODO(ajaykannan): Uncomment when possible in datastore v1beta3 transition + //copiedProperties.put(property.getName(), Value.fromPb(property.getValue())); } properties(copiedProperties); if (entityPb.hasKey()) { - key((K) IncompleteKey.fromPb(entityPb.getKey())); + // TODO(ajaykannan): Uncomment when possible in datastore v1beta3 transition + //key((K) IncompleteKey.fromPb(entityPb.getKey())); } return self(); } @@ -389,11 +391,13 @@ protected final DatastoreV1.Entity toPb() { for (Map.Entry> entry : properties.entrySet()) { DatastoreV1.Property.Builder propertyPb = DatastoreV1.Property.newBuilder(); propertyPb.setName(entry.getKey()); - propertyPb.setValue(entry.getValue().toPb()); + // TODO(ajaykannan): Uncomment when possible in datastore v1beta3 transition + //propertyPb.setValue(entry.getValue().toPb()); entityPb.addProperty(propertyPb.build()); } if (key != null) { - entityPb.setKey(key.toPb()); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //entityPb.setKey(key.toPb()); } return entityPb.build(); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java index 865b95ed8518..fdc973c6c4cc 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java @@ -20,8 +20,8 @@ import static com.google.gcloud.datastore.Validator.validateKind; import static com.google.gcloud.datastore.Validator.validateNamespace; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.base.Preconditions; +import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import java.util.LinkedList; @@ -31,7 +31,7 @@ /** * Base class for keys. */ -abstract class BaseKey extends Serializable { +abstract class BaseKey extends Serializable { private static final long serialVersionUID = -4671243265877410635L; @@ -172,20 +172,21 @@ public boolean equals(Object obj) { } @Override - protected DatastoreV1.Key toPb() { - DatastoreV1.Key.Builder keyPb = DatastoreV1.Key.newBuilder(); - DatastoreV1.PartitionId.Builder partitionIdPb = DatastoreV1.PartitionId.newBuilder(); - if (projectId != null) { - partitionIdPb.setDatasetId(projectId); + protected com.google.datastore.v1beta3.Key toPb() { + com.google.datastore.v1beta3.Key.Builder keyPb = com.google.datastore.v1beta3.Key.newBuilder(); + com.google.datastore.v1beta3.PartitionId.Builder partitionIdPb = + com.google.datastore.v1beta3.PartitionId.newBuilder(); + if (!Strings.isNullOrEmpty(projectId)) { + partitionIdPb.setProjectId(projectId); } - if (namespace != null) { - partitionIdPb.setNamespace(namespace); + if (!Strings.isNullOrEmpty(namespace)) { + partitionIdPb.setNamespaceId(namespace); } - if (partitionIdPb.hasDatasetId() || partitionIdPb.hasNamespace()) { + if (!partitionIdPb.getProjectId().isEmpty() || !partitionIdPb.getNamespaceId().isEmpty()) { keyPb.setPartitionId(partitionIdPb.build()); } for (PathElement pathEntry : path) { - keyPb.addPathElement(pathEntry.toPb()); + keyPb.addPath(pathEntry.toPb()); } return keyPb.build(); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java index 8cb41304500b..95cdfbb10f01 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java @@ -43,7 +43,9 @@ public List generatedKeys() { return Lists.transform(response.getMutationResult().getInsertAutoIdKeyList(), new Function() { @Override public Key apply(DatastoreV1.Key keyPb) { - return Key.fromPb(keyPb); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //return Key.fromPb(keyPb); + return Key.builder(null).build(); // TODO(ajaykannan): remove this line when possible } }); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BlobValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BlobValue.java index fb61c0b9ad34..19d545e1790c 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BlobValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BlobValue.java @@ -16,9 +16,7 @@ package com.google.gcloud.datastore; -import static com.google.api.services.datastore.DatastoreV1.Value.BLOB_VALUE_FIELD_NUMBER; - -import com.google.api.services.datastore.DatastoreV1; +import static com.google.datastore.v1beta3.Value.BLOB_VALUE_FIELD_NUMBER; public final class BlobValue extends Value { @@ -40,12 +38,12 @@ public Builder newBuilder(Blob value) { } @Override - protected Blob getValue(DatastoreV1.Value from) { + protected Blob getValue(com.google.datastore.v1beta3.Value from) { return new Blob(from.getBlobValue()); } @Override - protected void setValue(BlobValue from, DatastoreV1.Value.Builder to) { + protected void setValue(BlobValue from, com.google.datastore.v1beta3.Value.Builder to) { to.setBlobValue(from.get().byteString()); } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BooleanValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BooleanValue.java index 2dd98a5013ac..3e1bdc14e822 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BooleanValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BooleanValue.java @@ -16,9 +16,7 @@ package com.google.gcloud.datastore; -import static com.google.api.services.datastore.DatastoreV1.Value.BOOLEAN_VALUE_FIELD_NUMBER; - -import com.google.api.services.datastore.DatastoreV1; +import static com.google.datastore.v1beta3.Value.BOOLEAN_VALUE_FIELD_NUMBER; public final class BooleanValue extends Value { @@ -40,12 +38,12 @@ public Builder newBuilder(Boolean value) { } @Override - protected Boolean getValue(DatastoreV1.Value from) { + protected Boolean getValue(com.google.datastore.v1beta3.Value from) { return from.getBooleanValue(); } @Override - protected void setValue(BooleanValue from, DatastoreV1.Value.Builder to) { + protected void setValue(BooleanValue from, com.google.datastore.v1beta3.Value.Builder to) { to.setBooleanValue(from.get()); } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java index 6f2454c62167..23d4f74a8da1 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java @@ -126,12 +126,14 @@ public List allocateId(IncompleteKey... keys) { } DatastoreV1.AllocateIdsRequest.Builder requestPb = DatastoreV1.AllocateIdsRequest.newBuilder(); for (IncompleteKey key : keys) { - requestPb.addKey(trimNameOrId(key).toPb()); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //requestPb.addKey(trimNameOrId(key).toPb()); } DatastoreV1.AllocateIdsResponse responsePb = allocateIds(requestPb.build()); ImmutableList.Builder keyList = ImmutableList.builder(); for (DatastoreV1.Key keyPb : responsePb.getKeyList()) { - keyList.add(Key.fromPb(keyPb)); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // keyList.add(Key.fromPb(keyPb)); } return keyList.build(); } @@ -193,7 +195,8 @@ public List add(FullEntity... entities) { if (completeEntity != null) { responseBuilder.add(completeEntity); } else { - responseBuilder.add(Entity.builder(Key.fromPb(allocatedKeys.next()), entity).build()); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //responseBuilder.add(Entity.builder(Key.fromPb(allocatedKeys.next()), entity).build()); } } return responseBuilder.build(); @@ -223,7 +226,8 @@ Iterator get(DatastoreV1.ReadOptions readOptionsPb, final Key... keys) { requestPb.setReadOptions(readOptionsPb); } for (Key k : Sets.newLinkedHashSet(Arrays.asList(keys))) { - requestPb.addKey(k.toPb()); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //requestPb.addKey(k.toPb()); } return new ResultsIterator(requestPb); } @@ -310,7 +314,8 @@ public void delete(Key... keys) { DatastoreV1.Mutation.Builder mutationPb = DatastoreV1.Mutation.newBuilder(); Set dedupKeys = new LinkedHashSet<>(Arrays.asList(keys)); for (Key key : dedupKeys) { - mutationPb.addDelete(key.toPb()); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //mutationPb.addDelete(key.toPb()); } commitMutation(mutationPb); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java index af5a17ef7ef3..0d5c99d2b3fd 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java @@ -18,8 +18,6 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.api.services.datastore.DatastoreV1; -import com.google.api.services.datastore.DatastoreV1.Value; import com.google.protobuf.InvalidProtocolBufferException; import org.joda.time.format.ISODateTimeFormat; @@ -34,7 +32,7 @@ * @see Google Cloud Datastore * Entities, Properties, and Keys */ -public final class DateTime extends Serializable +public final class DateTime extends Serializable implements Comparable { private static final long serialVersionUID = 7343324797621228378L; @@ -98,12 +96,24 @@ public static DateTime copyFrom(Calendar calendar) { } @Override - protected Value toPb() { - return DatastoreV1.Value.newBuilder().setIntegerValue(timestampMicroseconds).build(); + protected com.google.datastore.v1beta3.Value toPb() { + return com.google.datastore.v1beta3.Value.newBuilder() + .setTimestampValue(microsecondsToTimestampPb(timestampMicroseconds)).build(); } @Override protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { - return new DateTime(DatastoreV1.Value.parseFrom(bytesPb).getIntegerValue()); + return new DateTime(timestampPbToMicroseconds(com.google.datastore.v1beta3.Value + .parseFrom(bytesPb).getTimestampValue())); + } + + protected static long timestampPbToMicroseconds(com.google.protobuf.Timestamp timestampPb) { + return timestampPb.getSeconds() * 10^6 + timestampPb.getNanos() / 10^3; + } + + protected static com.google.protobuf.Timestamp microsecondsToTimestampPb(long microseconds) { + long seconds = microseconds / 10^6; + int nanos = (int) (microseconds % 10^6) * 10^3; + return com.google.protobuf.Timestamp.newBuilder().setSeconds(seconds).setNanos(nanos).build(); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTimeValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTimeValue.java index 7aec5c7d3c47..e9c42ffabf4c 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTimeValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTimeValue.java @@ -16,9 +16,7 @@ package com.google.gcloud.datastore; -import static com.google.api.services.datastore.DatastoreV1.Value.TIMESTAMP_MICROSECONDS_VALUE_FIELD_NUMBER; - -import com.google.api.services.datastore.DatastoreV1; +import static com.google.datastore.v1beta3.Value.TIMESTAMP_VALUE_FIELD_NUMBER; public final class DateTimeValue extends Value { @@ -31,7 +29,7 @@ public final class DateTimeValue extends Value { @Override public int getProtoFieldId() { - return TIMESTAMP_MICROSECONDS_VALUE_FIELD_NUMBER; + return TIMESTAMP_VALUE_FIELD_NUMBER; } @Override @@ -40,13 +38,14 @@ public Builder newBuilder(DateTime value) { } @Override - protected DateTime getValue(DatastoreV1.Value from) { - return new DateTime(from.getTimestampMicrosecondsValue()); + protected DateTime getValue(com.google.datastore.v1beta3.Value from) { + return new DateTime(DateTime.timestampPbToMicroseconds(from.getTimestampValue())); } @Override - protected void setValue(DateTimeValue from, DatastoreV1.Value.Builder to) { - to.setTimestampMicrosecondsValue(from.get().timestampMicroseconds()); + protected void setValue(DateTimeValue from, com.google.datastore.v1beta3.Value.Builder to) { + to.setTimestampValue(DateTime.microsecondsToTimestampPb(from.get() + .timestampMicroseconds())); } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DoubleValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DoubleValue.java index d12bbe317aef..cf543ad94b78 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DoubleValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DoubleValue.java @@ -16,7 +16,7 @@ package com.google.gcloud.datastore; -import static com.google.api.services.datastore.DatastoreV1.Value.DOUBLE_VALUE_FIELD_NUMBER; +import static com.google.datastore.v1beta3.Value.DOUBLE_VALUE_FIELD_NUMBER; import com.google.api.services.datastore.DatastoreV1; @@ -40,12 +40,12 @@ public Builder newBuilder(Double value) { } @Override - protected Double getValue(DatastoreV1.Value from) { + protected Double getValue(com.google.datastore.v1beta3.Value from) { return from.getDoubleValue(); } - + @Override - protected void setValue(DoubleValue from, DatastoreV1.Value.Builder to) { + protected void setValue(DoubleValue from, com.google.datastore.v1beta3.Value.Builder to) { to.setDoubleValue(from.get()); } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java index da32c8eb2462..3105f9fa0dd9 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java @@ -16,10 +16,7 @@ package com.google.gcloud.datastore; -import static com.google.api.services.datastore.DatastoreV1.Value.ENTITY_VALUE_FIELD_NUMBER; - -import com.google.api.services.datastore.DatastoreV1; -import com.google.common.base.Preconditions; +import static com.google.datastore.v1beta3.Value.ENTITY_VALUE_FIELD_NUMBER; public class EntityValue extends Value> { @@ -41,13 +38,16 @@ public Builder newBuilder(FullEntity value) { } @Override - protected FullEntity getValue(DatastoreV1.Value from) { - return FullEntity.fromPb(from.getEntityValue()); + protected FullEntity getValue(com.google.datastore.v1beta3.Value from) { + // TODO(ajaykannan): uncomment this line when possible in datastore v1beta3 transition + //return FullEntity.fromPb(from.getEntityValue()); + return null; // TODO(ajaykannan): remove this line when possible } @Override - protected void setValue(EntityValue from, DatastoreV1.Value.Builder to) { - to.setEntityValue(from.get().toPb()); + protected void setValue(EntityValue from, com.google.datastore.v1beta3.Value.Builder to) { + // TODO(ajaykannan): uncomment this line when possible in datastore v1beta3 transition + //to.setEntityValue(from.get().toPb()); } }; @@ -57,13 +57,6 @@ private Builder() { super(ValueType.ENTITY); } - @Override - public Builder indexed(boolean indexed) { - // see issue #25 - Preconditions.checkArgument(!indexed, "EntityValue can't be indexed"); - return super.indexed(indexed); - } - @Override public EntityValue build() { return new EntityValue(this); @@ -88,6 +81,6 @@ public static EntityValue of(FullEntity entity) { } public static Builder builder(FullEntity entity) { - return new Builder().set(entity).indexed(false); + return new Builder().set(entity); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java index e9bd8e12cfd8..ff659805a34d 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java @@ -135,7 +135,8 @@ protected DatastoreV1.GqlQueryArg toPb() { argPb.setCursor(cursor.byteString()); } if (value != null) { - argPb.setValue(value.toPb()); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //argPb.setValue(value.toPb()); } return argPb.build(); } @@ -150,7 +151,9 @@ static Binding fromPb(DatastoreV1.GqlQueryArg argPb) { if (argPb.hasCursor()) { return new Binding(name, new Cursor(argPb.getCursor())); } - return new Binding(name, Value.fromPb(argPb.getValue())); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //return new Binding(name, Value.fromPb(argPb.getValue())); + return new Binding(name, new Cursor(null)); // TODO(ajaykannan): remove this line when possible } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java index 6134eed2905b..0eabefe32643 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java @@ -16,7 +16,6 @@ package com.google.gcloud.datastore; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.protobuf.InvalidProtocolBufferException; @@ -55,25 +54,27 @@ public IncompleteKey build() { @Override protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { - return fromPb(DatastoreV1.Key.parseFrom(bytesPb)); + return fromPb(com.google.datastore.v1beta3.Key.parseFrom(bytesPb)); } - static IncompleteKey fromPb(DatastoreV1.Key keyPb) { + static IncompleteKey fromPb(com.google.datastore.v1beta3.Key keyPb) { String projectId = null; String namespace = null; if (keyPb.hasPartitionId()) { - DatastoreV1.PartitionId partitionIdPb = keyPb.getPartitionId(); - if (partitionIdPb.hasDatasetId()) { - projectId = partitionIdPb.getDatasetId(); + com.google.datastore.v1beta3.PartitionId partitionIdPb = keyPb.getPartitionId(); + projectId = partitionIdPb.getProjectId(); + if (projectId.isEmpty()) { + projectId = null; } - if (partitionIdPb.hasNamespace()) { - namespace = partitionIdPb.getNamespace(); + namespace = partitionIdPb.getNamespaceId(); + if (namespace.isEmpty()) { + namespace = null; } } - List pathElementsPb = keyPb.getPathElementList(); + List pathElementsPb = keyPb.getPathList(); Preconditions.checkArgument(!pathElementsPb.isEmpty(), "Path must not be empty"); ImmutableList.Builder pathBuilder = ImmutableList.builder(); - for (DatastoreV1.Key.PathElement pathElementPb : pathElementsPb) { + for (com.google.datastore.v1beta3.Key.PathElement pathElementPb : pathElementsPb) { pathBuilder.add(PathElement.fromPb(pathElementPb)); } ImmutableList path = pathBuilder.build(); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Key.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Key.java index c625c067f6c2..04dbdddf8e23 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Key.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Key.java @@ -18,7 +18,6 @@ import static java.nio.charset.StandardCharsets.UTF_8; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.protobuf.InvalidProtocolBufferException; @@ -153,7 +152,8 @@ public String toUrlSafe() { public static Key fromUrlSafe(String urlSafe) { try { String utf8Str = URLDecoder.decode(urlSafe, UTF_8.name()); - DatastoreV1.Key.Builder builder = DatastoreV1.Key.newBuilder(); + com.google.datastore.v1beta3.Key.Builder builder = + com.google.datastore.v1beta3.Key.newBuilder(); TextFormat.merge(utf8Str, builder); return fromPb(builder.build()); } catch (UnsupportedEncodingException e) { @@ -165,10 +165,10 @@ public static Key fromUrlSafe(String urlSafe) { @Override protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { - return fromPb(DatastoreV1.Key.parseFrom(bytesPb)); + return fromPb(com.google.datastore.v1beta3.Key.parseFrom(bytesPb)); } - static Key fromPb(DatastoreV1.Key keyPb) { + static Key fromPb(com.google.datastore.v1beta3.Key keyPb) { IncompleteKey key = IncompleteKey.fromPb(keyPb); Preconditions.checkState(key instanceof Key, "Key is not complete"); return (Key) key; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyValue.java index 252f48ebc92a..fc1823730d12 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyValue.java @@ -16,9 +16,7 @@ package com.google.gcloud.datastore; -import static com.google.api.services.datastore.DatastoreV1.Value.KEY_VALUE_FIELD_NUMBER; - -import com.google.api.services.datastore.DatastoreV1; +import static com.google.datastore.v1beta3.Value.KEY_VALUE_FIELD_NUMBER; public final class KeyValue extends Value { @@ -40,12 +38,12 @@ public Builder newBuilder(Key key) { } @Override - protected Key getValue(DatastoreV1.Value from) { + protected Key getValue(com.google.datastore.v1beta3.Value from) { return Key.fromPb(from.getKeyValue()); } @Override - protected void setValue(KeyValue from, DatastoreV1.Value.Builder to) { + protected void setValue(KeyValue from, com.google.datastore.v1beta3.Value.Builder to) { to.setKeyValue(from.get().toPb()); } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java index 41c7e82788b5..242a2956b682 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java @@ -16,9 +16,8 @@ package com.google.gcloud.datastore; -import static com.google.api.services.datastore.DatastoreV1.Value.LIST_VALUE_FIELD_NUMBER; +import static com.google.datastore.v1beta3.Value.ARRAY_VALUE_FIELD_NUMBER; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; @@ -36,7 +35,7 @@ public final class ListValue extends Value>> { @Override public int getProtoFieldId() { - return LIST_VALUE_FIELD_NUMBER; + return ARRAY_VALUE_FIELD_NUMBER; } @Override @@ -45,19 +44,23 @@ public Builder newBuilder(List> values) { } @Override - protected List> getValue(DatastoreV1.Value from) { - List> properties = new ArrayList<>(from.getListValueCount()); - for (DatastoreV1.Value valuePb : from.getListValueList()) { + protected List> getValue(com.google.datastore.v1beta3.Value from) { + List> properties = new ArrayList<>(from.getArrayValue().getValuesCount()); + for (com.google.datastore.v1beta3.Value valuePb : from.getArrayValue().getValuesList()) { properties.add(Value.fromPb(valuePb)); } return properties; } @Override - protected void setValue(ListValue from, DatastoreV1.Value.Builder to) { + protected void setValue(ListValue from, com.google.datastore.v1beta3.Value.Builder to) { + List propertiesPb = + new ArrayList(); for (Value property : from.get()) { - to.addListValue(property.toPb()); + propertiesPb.add(property.toPb()); } + to.setArrayValue(com.google.datastore.v1beta3.ArrayValue.newBuilder() + .addAllValues(propertiesPb)); } }; @@ -71,7 +74,7 @@ private Builder() { } public Builder addValue(Value value) { - // see datastore_v1.proto definition for list_value + // see datastore.proto definition for list_value Preconditions.checkArgument(value.type() != ValueType.LIST, "Cannot contain another list"); listBuilder.add(value); return this; @@ -85,12 +88,6 @@ public Builder addValue(Value first, Value... other) { return this; } - @Override - public Builder indexed(boolean indexed) { - // see issue #26 - throw DatastoreException.throwInvalidRequest("ListValue can't specify index"); - } - /** * Copy the list of values. * diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LongValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LongValue.java index 43d139e90249..18cdead6280a 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LongValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LongValue.java @@ -16,9 +16,7 @@ package com.google.gcloud.datastore; -import static com.google.api.services.datastore.DatastoreV1.Value.INTEGER_VALUE_FIELD_NUMBER; - -import com.google.api.services.datastore.DatastoreV1; +import static com.google.datastore.v1beta3.Value.INTEGER_VALUE_FIELD_NUMBER; public final class LongValue extends Value { @@ -40,12 +38,12 @@ public Builder newBuilder(Long value) { } @Override - protected Long getValue(DatastoreV1.Value from) { + protected Long getValue(com.google.datastore.v1beta3.Value from) { return from.getIntegerValue(); } @Override - protected void setValue(LongValue from, DatastoreV1.Value.Builder to) { + protected void setValue(LongValue from, com.google.datastore.v1beta3.Value.Builder to) { to.setIntegerValue(from.get()); } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/NullValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/NullValue.java index 58fed152ffd5..173ee3ef79f0 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/NullValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/NullValue.java @@ -18,8 +18,6 @@ import static com.google.common.base.Preconditions.checkArgument; -import com.google.api.services.datastore.DatastoreV1; - public final class NullValue extends Value { private static final long serialVersionUID = 8497300779013002270L; @@ -40,12 +38,12 @@ public int getProtoFieldId() { } @Override - protected Void getValue(DatastoreV1.Value from) { + protected Void getValue(com.google.datastore.v1beta3.Value from) { return null; } @Override - protected void setValue(NullValue from, DatastoreV1.Value.Builder to) { + protected void setValue(NullValue from, com.google.datastore.v1beta3.Value.Builder to) { // nothing to set } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/PathElement.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/PathElement.java index 186ed97adcde..c0196a6326fe 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/PathElement.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/PathElement.java @@ -19,7 +19,6 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.base.Strings; import com.google.protobuf.InvalidProtocolBufferException; @@ -28,7 +27,7 @@ /** * Represents a single element in a key's path. */ -public final class PathElement extends Serializable { +public final class PathElement extends Serializable { private static final long serialVersionUID = -7968078857690784595L; @@ -86,8 +85,8 @@ public boolean equals(Object obj) { } @Override - protected DatastoreV1.Key.PathElement toPb() { - DatastoreV1.Key.PathElement.Builder pathElementPb = DatastoreV1.Key.PathElement.newBuilder(); + protected com.google.datastore.v1beta3.Key.PathElement toPb() { + com.google.datastore.v1beta3.Key.PathElement.Builder pathElementPb = com.google.datastore.v1beta3.Key.PathElement.newBuilder(); pathElementPb.setKind(kind); if (id != null) { pathElementPb.setId(id); @@ -99,15 +98,17 @@ protected DatastoreV1.Key.PathElement toPb() { @Override protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { - return fromPb(DatastoreV1.Key.PathElement.parseFrom(bytesPb)); + return fromPb(com.google.datastore.v1beta3.Key.PathElement.parseFrom(bytesPb)); } - static PathElement fromPb(DatastoreV1.Key.PathElement pathElementPb) { + static PathElement fromPb(com.google.datastore.v1beta3.Key.PathElement pathElementPb) { String kind = pathElementPb.getKind(); - if (pathElementPb.hasId()) { + if (pathElementPb.getIdTypeCase() == + com.google.datastore.v1beta3.Key.PathElement.IdTypeCase.ID) { return of(kind, pathElementPb.getId()); } - if (pathElementPb.hasName()) { + if (pathElementPb.getIdTypeCase() == + com.google.datastore.v1beta3.Key.PathElement.IdTypeCase.NAME) { return of(kind, pathElementPb.getName()); } return of(kind); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntity.java index 1ba054b68161..46a528617a0c 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntity.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntity.java @@ -56,7 +56,7 @@ public ProjectionEntity build() { @Override public DateTime getDateTime(String name) { Value value = getValue(name); - if (value.hasMeaning() && value.meaning() == 18 && value instanceof LongValue) { + if (value.meaning() == 18 && value instanceof LongValue) { return new DateTime(getLong(name)); } return ((Value) value).get(); @@ -66,7 +66,7 @@ public DateTime getDateTime(String name) { @Override public Blob getBlob(String name) { Value value = getValue(name); - if (value.hasMeaning() && value.meaning() == 18 && value instanceof StringValue) { + if (value.meaning() == 18 && value instanceof StringValue) { return new Blob(ByteString.copyFromUtf8(getString(name))); } return ((Value) value).get(); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java index 343535d94628..fdd120ccbe85 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java @@ -66,7 +66,8 @@ public abstract static class ResultType implements java.io.Serializable { if (!entityPb.hasKey()) { return null; } - return Key.fromPb(entityPb.getKey()); + //TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //return Key.fromPb(entityPb.getKey()); } return ProjectionEntity.fromPb(entityPb); } @@ -88,7 +89,9 @@ public abstract static class ResultType implements java.io.Serializable { private static final long serialVersionUID = -8514289244104446252L; @Override protected Key convert(DatastoreV1.Entity entityPb) { - return Key.fromPb(entityPb.getKey()); + //TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //return Key.fromPb(entityPb.getKey()); + return Key.builder(null).build(); // TODO(ajaykannan): remove this line when possible } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java index 9d447cf4289b..d60f215cd5f2 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java @@ -16,19 +16,17 @@ package com.google.gcloud.datastore; -import com.google.api.services.datastore.DatastoreV1; - -public final class RawValue extends Value { +public final class RawValue extends Value { private static final long serialVersionUID = -3359604598651897941L; - static final BaseMarshaller MARSHALLER = - new BaseMarshaller() { + static final BaseMarshaller MARSHALLER = + new BaseMarshaller() { private static final long serialVersionUID = 5320642719486106244L; @Override - public Builder newBuilder(DatastoreV1.Value value) { + public Builder newBuilder(com.google.datastore.v1beta3.Value value) { return builder(value); } @@ -38,18 +36,18 @@ public int getProtoFieldId() { } @Override - protected DatastoreV1.Value getValue(DatastoreV1.Value from) { + protected com.google.datastore.v1beta3.Value getValue(com.google.datastore.v1beta3.Value from) { return from; } @Override - protected void setValue(RawValue from, DatastoreV1.Value.Builder to) { + protected void setValue(RawValue from, com.google.datastore.v1beta3.Value.Builder to) { to.mergeFrom(from.get()); } }; public static final class Builder - extends Value.BaseBuilder { + extends Value.BaseBuilder { private Builder() { super(ValueType.RAW_VALUE); @@ -65,7 +63,7 @@ private RawValue(Builder builder) { super(builder); } - RawValue(DatastoreV1.Value valuePb) { + RawValue(com.google.datastore.v1beta3.Value valuePb) { this(builder(valuePb)); } @@ -74,18 +72,14 @@ public Builder toBuilder() { return new Builder().mergeFrom(this); } - static RawValue of(DatastoreV1.Value valuePb) { + static RawValue of(com.google.datastore.v1beta3.Value valuePb) { return new RawValue(valuePb); } - static Builder builder(DatastoreV1.Value valuePb) { + static Builder builder(com.google.datastore.v1beta3.Value valuePb) { Builder builder = new Builder(); - if (valuePb.hasIndexed()) { - builder.indexed(valuePb.getIndexed()); - } - if (valuePb.hasMeaning()) { - builder.meaning(valuePb.getMeaning()); - } + builder.excludeFromIndexes(valuePb.getExcludeFromIndexes()); + builder.meaning(valuePb.getMeaning()); builder.set(valuePb); return builder; } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StringValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StringValue.java index 95a31e714876..4b2c8e123be7 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StringValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StringValue.java @@ -16,9 +16,7 @@ package com.google.gcloud.datastore; -import static com.google.api.services.datastore.DatastoreV1.Value.STRING_VALUE_FIELD_NUMBER; - -import com.google.api.services.datastore.DatastoreV1; +import static com.google.datastore.v1beta3.Value.STRING_VALUE_FIELD_NUMBER; public final class StringValue extends Value { @@ -40,12 +38,12 @@ public Builder newBuilder(String value) { } @Override - protected String getValue(DatastoreV1.Value from) { + protected String getValue(com.google.datastore.v1beta3.Value from) { return from.getStringValue(); } @Override - protected void setValue(StringValue from, DatastoreV1.Value.Builder to) { + protected void setValue(StringValue from, com.google.datastore.v1beta3.Value.Builder to) { to.setStringValue(from.get()); } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java index ce596307d6da..b034b15995a3 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java @@ -228,8 +228,10 @@ private PropertyFilter(String property, Operator operator, Value value) { public static PropertyFilter fromPb(DatastoreV1.PropertyFilter propertyFilterPb) { String property = propertyFilterPb.getProperty().getName(); Operator operator = Operator.fromPb(propertyFilterPb.getOperator()); - Value value = Value.fromPb(propertyFilterPb.getValue()); - return new PropertyFilter(property, operator, value); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //Value value = Value.fromPb(propertyFilterPb.getValue()); + //return new PropertyFilter(property, operator, value); + return new PropertyFilter(property, operator, null); // TODO(ajaykannan): remove this line when possible } @Override @@ -435,7 +437,8 @@ protected DatastoreV1.Filter toPb() { propertyFilterPb.getPropertyBuilder().setName(property); propertyFilterPb.setOperator(operator.toPb()); if (value != null) { - propertyFilterPb.setValue(value.toPb()); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //propertyFilterPb.setValue(value.toPb()); } return filterPb.build(); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java index ae677aa005d6..62978ce73be6 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java @@ -47,7 +47,9 @@ public List generatedKeys() { return Lists.transform(response.getMutationResult().getInsertAutoIdKeyList(), new Function() { @Override public Key apply(DatastoreV1.Key keyPb) { - return Key.fromPb(keyPb); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //return Key.fromPb(keyPb); + return Key.builder(null).build(); //: TODO(ajaykannan) remove this placeholder line } }); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java index c5fc63a960b1..94e1d7de545f 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java @@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.api.services.datastore.DatastoreV1; import com.google.protobuf.Descriptors.FieldDescriptor; import com.google.protobuf.InvalidProtocolBufferException; @@ -33,14 +32,14 @@ * * @param the type of the content for this value */ -public abstract class Value extends Serializable { +public abstract class Value extends Serializable { private static final long serialVersionUID = -1899638277588872742L; private final transient ValueType valueType; - private final transient Boolean indexed; - private final transient Integer meaning; + private final transient boolean excludeFromIndexes; + private final transient int meaning; private final transient V value; interface BuilderFactory, B extends ValueBuilder> @@ -55,34 +54,26 @@ abstract static class BaseMarshaller, B extends ValueBuild @SuppressWarnings("deprecation") @Override - public final B fromProto(DatastoreV1.Value proto) { + public final B fromProto(com.google.datastore.v1beta3.Value proto) { B builder = newBuilder(getValue(proto)); - if (proto.hasIndexed()) { - builder.indexed(proto.getIndexed()); - } - if (proto.hasMeaning()) { - builder.meaning(proto.getMeaning()); - } + builder.excludeFromIndexes(proto.getExcludeFromIndexes()); + builder.meaning(proto.getMeaning()); return builder; } @SuppressWarnings("deprecation") @Override - public final DatastoreV1.Value toProto(P value) { - DatastoreV1.Value.Builder builder = DatastoreV1.Value.newBuilder(); - if (value.hasIndexed()) { - builder.setIndexed(value.indexed()); - } - if (value.hasMeaning()) { - builder.setMeaning(value.meaning()); - } + public final com.google.datastore.v1beta3.Value toProto(P value) { + com.google.datastore.v1beta3.Value.Builder builder = com.google.datastore.v1beta3.Value.newBuilder(); + builder.setExcludeFromIndexes(value.excludeFromIndexes()); + builder.setMeaning(value.meaning()); setValue(value, builder); return builder.build(); } - protected abstract V getValue(DatastoreV1.Value from); + protected abstract V getValue(com.google.datastore.v1beta3.Value from); - protected abstract void setValue(P from, DatastoreV1.Value.Builder to); + protected abstract void setValue(P from, com.google.datastore.v1beta3.Value.Builder to); } @SuppressWarnings("deprecation") @@ -90,8 +81,8 @@ abstract static class BaseBuilder, B extends BaseBuilder { private final ValueType valueType; - private Boolean indexed; - private Integer meaning; + private boolean excludeFromIndexes; + private int meaning; private V value; BaseBuilder(ValueType valueType) { @@ -105,30 +96,30 @@ public ValueType getValueType() { @Override public B mergeFrom(P other) { - indexed = other.indexed(); + excludeFromIndexes = other.excludeFromIndexes(); meaning = other.meaning(); set(other.get()); return self(); } @Override - public Boolean getIndexed() { - return indexed; + public boolean getExcludeFromIndexes() { + return excludeFromIndexes; } @Override - public B indexed(boolean indexed) { - this.indexed = indexed; + public B excludeFromIndexes(boolean excludeFromIndexes) { + this.excludeFromIndexes = excludeFromIndexes; return self(); } @Override - public Integer getMeaning() { + public int getMeaning() { return meaning; } @Override - public B meaning(Integer meaning) { + public B meaning(int meaning) { this.meaning = meaning; return self(); } @@ -155,7 +146,7 @@ private B self() {

, B extends BaseBuilder> Value(ValueBuilder builder) { valueType = builder.getValueType(); - indexed = builder.getIndexed(); + excludeFromIndexes = builder.getExcludeFromIndexes(); meaning = builder.getMeaning(); value = builder.get(); } @@ -164,21 +155,12 @@ public final ValueType type() { return valueType; } - public final boolean hasIndexed() { - return indexed != null; - } - - public final Boolean indexed() { - return indexed; - } - - @Deprecated - public final boolean hasMeaning() { - return meaning != null; + public final boolean excludeFromIndexes() { + return excludeFromIndexes; } @Deprecated - public final Integer meaning() { + public final int meaning() { return meaning; } @@ -190,7 +172,7 @@ public final V get() { @Override public int hashCode() { - return Objects.hash(valueType, indexed, meaning, value); + return Objects.hash(valueType, excludeFromIndexes, meaning, value); } @Override @@ -204,18 +186,18 @@ public boolean equals(Object obj) { } Value other = (Value) obj; return Objects.equals(valueType, other.valueType) - && Objects.equals(indexed, other.indexed) + && Objects.equals(excludeFromIndexes, other.excludeFromIndexes) && Objects.equals(meaning, other.meaning) && Objects.equals(value, other.value); } @Override @SuppressWarnings("unchecked") - protected DatastoreV1.Value toPb() { + protected com.google.datastore.v1beta3.Value toPb() { return type().getMarshaller().toProto(this); } - static Value fromPb(DatastoreV1.Value proto) { + static Value fromPb(com.google.datastore.v1beta3.Value proto) { for (Entry entry : proto.getAllFields().entrySet()) { FieldDescriptor descriptor = entry.getKey(); if (descriptor.getName().endsWith("_value")) { @@ -232,6 +214,6 @@ static Value fromPb(DatastoreV1.Value proto) { @Override protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { - return fromPb(DatastoreV1.Value.parseFrom(bytesPb)); + return fromPb(com.google.datastore.v1beta3.Value.parseFrom(bytesPb)); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueBuilder.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueBuilder.java index f5b5d4c1319b..5094062e1ec8 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueBuilder.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueBuilder.java @@ -25,14 +25,14 @@ public interface ValueBuilder, B extends ValueBuilder, B extends ValueBuilder> extends java.io.Serializable { - B fromProto(DatastoreV1.Value proto); + B fromProto(com.google.datastore.v1beta3.Value proto); - DatastoreV1.Value toProto(P value); + com.google.datastore.v1beta3.Value toProto(P value); int getProtoFieldId(); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/package-info.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/package-info.java index 3b402820e663..f63be902c319 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/package-info.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/package-info.java @@ -27,7 +27,7 @@ * if (entity == null) { * entity = Entity.builder(key) * .set("name", "John Do") - * .set("age", LongValue.builder(100).indexed(false).build()) + * .set("age", LongValue.builder(100).excludeFromIndexes(true).build()) * .set("updated", false) * .build(); * datastore.put(entity); @@ -37,7 +37,7 @@ * String[] name = entity.getString("name").split(" "); * entity = Entity.builder(entity) * .set("name", name[0]) - * .set("last_name", StringValue.builder(name[1]).indexed(false).build()) + * .set("last_name", StringValue.builder(name[1]).excludeFromIndexes(true).build()) * .set("updated", true) * .remove("old_property") * .set("new_property", 1.1) diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java index ad8e0cee266a..28fea360ecf4 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java @@ -272,10 +272,11 @@ public void testPutWhenNotActive() throws Exception { @Test public void testDelete() throws Exception { + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addDelete(KEY1.toPb()) - .addDelete(KEY2.toPb()) - .addDelete(KEY3.toPb()) + //.addDelete(KEY1.toPb()) + //.addDelete(KEY2.toPb()) + //.addDelete(KEY3.toPb()) .build(); batchWriter.delete(KEY1, KEY2); batchWriter.delete(KEY3); @@ -284,9 +285,10 @@ public void testDelete() throws Exception { @Test public void testDeleteAfterAdd() throws Exception { + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() .addInsertAutoId(INCOMPLETE_ENTITY_1.toPb()) - .addDelete(KEY1.toPb()) + //.addDelete(KEY1.toPb()) .build(); batchWriter.add(ENTITY1); batchWriter.addWithDeferredIdAllocation(INCOMPLETE_ENTITY_1); @@ -296,8 +298,9 @@ public void testDeleteAfterAdd() throws Exception { @Test public void testDeleteAfterUpdate() throws Exception { + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addDelete(KEY1.toPb()) + //.addDelete(KEY1.toPb()) .build(); batchWriter.update(ENTITY1); batchWriter.delete(KEY1); @@ -306,8 +309,9 @@ public void testDeleteAfterUpdate() throws Exception { @Test public void testDeleteAfterPut() throws Exception { + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addDelete(KEY1.toPb()) + //.addDelete(KEY1.toPb()) .build(); batchWriter.put(ENTITY1); batchWriter.delete(KEY1); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BlobValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BlobValueTest.java index 40d0299d8fb3..2a4c0dc956e3 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BlobValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BlobValueTest.java @@ -37,19 +37,16 @@ public void testToBuilder() throws Exception { public void testOf() throws Exception { BlobValue value = BlobValue.of(CONTENT); assertEquals(CONTENT, value.get()); - assertFalse(value.hasIndexed()); - assertFalse(value.hasMeaning()); + assertFalse(value.excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { BlobValue.Builder builder = BlobValue.builder(CONTENT); - BlobValue value = builder.meaning(1).indexed(false).build(); + BlobValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertEquals(CONTENT, value.get()); - assertTrue(value.hasMeaning()); - assertEquals(Integer.valueOf(1), value.meaning()); - assertTrue(value.hasIndexed()); - assertFalse(value.indexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BooleanValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BooleanValueTest.java index 16bbe9cbf518..bff3d67c9465 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BooleanValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BooleanValueTest.java @@ -35,19 +35,16 @@ public void testToBuilder() throws Exception { public void testOf() throws Exception { BooleanValue value = BooleanValue.of(false); assertFalse(value.get()); - assertFalse(value.hasIndexed()); - assertFalse(value.hasMeaning()); + assertFalse(value.excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { BooleanValue.Builder builder = BooleanValue.builder(true); - BooleanValue value = builder.meaning(1).indexed(true).build(); + BooleanValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertTrue(value.get()); - assertTrue(value.hasMeaning()); - assertEquals(Integer.valueOf(1), value.meaning()); - assertTrue(value.hasIndexed()); - assertTrue(value.indexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index 156f9684f8ba..65872abb79e7 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -59,7 +59,8 @@ public class DatastoreTest { private static final String KIND3 = "kind3"; private static final NullValue NULL_VALUE = NullValue.of(); private static final StringValue STR_VALUE = StringValue.of("str"); - private static final BooleanValue BOOL_VALUE = BooleanValue.builder(false).indexed(false).build(); + private static final BooleanValue BOOL_VALUE = BooleanValue.builder(false) + .excludeFromIndexes(true).build(); private static final IncompleteKey INCOMPLETE_KEY1 = IncompleteKey.builder(PROJECT_ID, KIND1).build(); private static final IncompleteKey INCOMPLETE_KEY2 = @@ -636,17 +637,19 @@ public void testKeyFactory() { @Test public void testRetires() throws Exception { - DatastoreV1.LookupRequest requestPb = - DatastoreV1.LookupRequest.newBuilder().addKey(KEY1.toPb()).build(); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //DatastoreV1.LookupRequest requestPb = + // DatastoreV1.LookupRequest.newBuilder().addKey(KEY1.toPb()).build(); DatastoreV1.LookupResponse responsePb = DatastoreV1.LookupResponse.newBuilder() .addFound(EntityResult.newBuilder().setEntity(ENTITY1.toPb())).build(); DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) .andReturn(rpcMock); - EasyMock.expect(rpcMock.lookup(requestPb)) - .andThrow(new DatastoreRpc.DatastoreRpcException(Reason.UNAVAILABLE)) - .andReturn(responsePb); + // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //EasyMock.expect(rpcMock.lookup(requestPb)) + // .andThrow(new DatastoreRpc.DatastoreRpcException(Reason.UNAVAILABLE)) + // .andReturn(responsePb); EasyMock.replay(rpcFactoryMock, rpcMock); DatastoreOptions options = this.options.toBuilder() .retryParams(RetryParams.getDefaultInstance()) diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DateTimeValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DateTimeValueTest.java index d7fef2ca69b9..c90e8c88ba52 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DateTimeValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DateTimeValueTest.java @@ -37,19 +37,16 @@ public void testToBuilder() throws Exception { public void testOf() throws Exception { DateTimeValue value = DateTimeValue.of(CONTENT); assertEquals(CONTENT, value.get()); - assertFalse(value.hasIndexed()); - assertFalse(value.hasMeaning()); + assertFalse(value.excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { DateTimeValue.Builder builder = DateTimeValue.builder(CONTENT); - DateTimeValue value = builder.meaning(1).indexed(false).build(); + DateTimeValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertEquals(CONTENT, value.get()); - assertTrue(value.hasMeaning()); - assertEquals(Integer.valueOf(1), value.meaning()); - assertTrue(value.hasIndexed()); - assertFalse(value.indexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DoubleValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DoubleValueTest.java index fa39511a45de..24d9113ce873 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DoubleValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DoubleValueTest.java @@ -37,19 +37,16 @@ public void testToBuilder() throws Exception { public void testOf() throws Exception { DoubleValue value = DoubleValue.of(CONTENT); assertEquals(CONTENT, value.get()); - assertFalse(value.hasIndexed()); - assertFalse(value.hasMeaning()); + assertFalse(value.excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { DoubleValue.Builder builder = DoubleValue.builder(CONTENT); - DoubleValue value = builder.meaning(1).indexed(false).build(); + DoubleValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertEquals(CONTENT, value.get()); - assertTrue(value.hasMeaning()); - assertEquals(Integer.valueOf(1), value.meaning()); - assertTrue(value.hasIndexed()); - assertFalse(value.indexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/EntityValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/EntityValueTest.java index cd1f7af38067..e7df91ac0016 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/EntityValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/EntityValueTest.java @@ -38,25 +38,16 @@ public void testToBuilder() throws Exception { public void testOf() throws Exception { EntityValue value = EntityValue.of(CONTENT); assertEquals(CONTENT, value.get()); - assertTrue(value.hasIndexed()); - assertFalse(value.indexed()); - assertFalse(value.hasMeaning()); - } - - @Test(expected = IllegalArgumentException.class) - public void testIndexedNotAllowed() { - EntityValue.builder(CONTENT).indexed(true); + assertFalse(value.excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { EntityValue.Builder builder = EntityValue.builder(CONTENT); - EntityValue value = builder.meaning(1).indexed(false).build(); + EntityValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertEquals(CONTENT, value.get()); - assertTrue(value.hasMeaning()); - assertEquals(Integer.valueOf(1), value.meaning()); - assertTrue(value.hasIndexed()); - assertFalse(value.indexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyValueTest.java index 131a80462a62..b2e916983b8a 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyValueTest.java @@ -37,19 +37,16 @@ public void testToBuilder() throws Exception { public void testOf() throws Exception { KeyValue value = KeyValue.of(CONTENT); assertEquals(CONTENT, value.get()); - assertFalse(value.hasIndexed()); - assertFalse(value.hasMeaning()); + assertFalse(value.excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { KeyValue.Builder builder = KeyValue.builder(CONTENT); - KeyValue value = builder.meaning(1).indexed(false).build(); + KeyValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertEquals(CONTENT, value.get()); - assertTrue(value.hasMeaning()); - assertEquals(Integer.valueOf(1), value.meaning()); - assertTrue(value.hasIndexed()); - assertFalse(value.indexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java index 36e3571d49ac..23a9325f22de 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java @@ -41,24 +41,17 @@ public void testToBuilder() throws Exception { public void testOf() throws Exception { ListValue value = ListValue.of(CONTENT); assertEquals(CONTENT, value.get()); - assertFalse(value.hasIndexed()); - assertFalse(value.hasMeaning()); - } - - @Test(expected = DatastoreException.class) - public void testIndexedCannotBeSpecified() { - ListValue.builder().indexed(false); + assertFalse(value.excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { ListValue.Builder builder = ListValue.builder().set(CONTENT); - ListValue value = builder.meaning(1).build(); + ListValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertEquals(CONTENT, value.get()); - assertTrue(value.hasMeaning()); - assertEquals(Integer.valueOf(1), value.meaning()); - assertFalse(value.hasIndexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); builder = ListValue.builder(); for (Value v : CONTENT) { diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LongValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LongValueTest.java index c4c899785d68..717c1567bc45 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LongValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LongValueTest.java @@ -37,19 +37,16 @@ public void testToBuilder() throws Exception { public void testOf() throws Exception { LongValue value = LongValue.of(CONTENT); assertEquals(CONTENT, value.get()); - assertFalse(value.hasIndexed()); - assertFalse(value.hasMeaning()); + assertFalse(value.excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { LongValue.Builder builder = LongValue.builder(CONTENT); - LongValue value = builder.meaning(1).indexed(false).build(); + LongValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertEquals(CONTENT, value.get()); - assertTrue(value.hasMeaning()); - assertEquals(Integer.valueOf(1), value.meaning()); - assertTrue(value.hasIndexed()); - assertFalse(value.indexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/NullValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/NullValueTest.java index a42fdaf0229f..0856fced7992 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/NullValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/NullValueTest.java @@ -31,24 +31,20 @@ public void testToBuilder() throws Exception { assertEquals(value, value.toBuilder().build()); } - @SuppressWarnings("deprecation") @Test public void testOf() throws Exception { NullValue value = NullValue.of(); assertNull(value.get()); - assertFalse(value.hasIndexed()); - assertFalse(value.hasMeaning()); + assertFalse(value.excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { NullValue.Builder builder = NullValue.builder(); - NullValue value = builder.meaning(1).indexed(false).build(); + NullValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertNull(value.get()); - assertTrue(value.hasMeaning()); - assertEquals(Integer.valueOf(1), value.meaning()); - assertTrue(value.hasIndexed()); - assertFalse(value.indexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/RawValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/RawValueTest.java index 4d63bc89bacb..1ab1c36538de 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/RawValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/RawValueTest.java @@ -20,13 +20,11 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import com.google.api.services.datastore.DatastoreV1; - import org.junit.Test; public class RawValueTest { - private static final DatastoreV1.Value CONTENT = StringValue.of("hello").toPb(); + private static final com.google.datastore.v1beta3.Value CONTENT = StringValue.of("hello").toPb(); @Test public void testToBuilder() throws Exception { @@ -34,24 +32,20 @@ public void testToBuilder() throws Exception { assertEquals(value, value.toBuilder().build()); } - @SuppressWarnings("deprecation") @Test public void testOf() throws Exception { RawValue value = RawValue.of(CONTENT); assertEquals(CONTENT, value.get()); - assertFalse(value.hasIndexed()); - assertFalse(value.hasMeaning()); + assertFalse(value.excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { RawValue.Builder builder = RawValue.builder(CONTENT); - RawValue value = builder.meaning(1).indexed(false).build(); + RawValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertEquals(CONTENT, value.get()); - assertTrue(value.hasMeaning()); - assertEquals(Integer.valueOf(1), value.meaning()); - assertTrue(value.hasIndexed()); - assertFalse(value.indexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index 5f3bfc036fa2..9dfdd33c873d 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -20,7 +20,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.Multimap; import com.google.gcloud.AuthCredentials; @@ -82,27 +81,27 @@ public class SerializationTest { .addOrderBy(OrderBy.asc("p")) .build(); private static final KeyValue KEY_VALUE = KeyValue.of(KEY1); - private static final NullValue NULL_VALUE = NullValue.builder().indexed(true).build(); + private static final NullValue NULL_VALUE = NullValue.builder().excludeFromIndexes(true).build(); private static final StringValue STRING_VALUE = StringValue.of("hello"); private static final LongValue LONG_VALUE = LongValue.of(123); private static final DoubleValue DOUBLE_VALUE = DoubleValue.of(12.34); private static final BooleanValue BOOLEAN_VALUE = BooleanValue.of(true); private static final DateTimeValue DATE_AND_TIME_VALUE = DateTimeValue.of(DateTime.now()); private static final BlobValue BLOB_VALUE = BlobValue.of(BLOB1); - private static final RawValue RAW_VALUE = RawValue.of( - DatastoreV1.Value.newBuilder().setBlobKeyValue("blob-key").setMeaning(18).build()); + private static final RawValue RAW_VALUE = RawValue.of(com.google.datastore.v1beta3.Value + .newBuilder().setStringValue("blob-key").setMeaning(18).build()); private static final Entity ENTITY1 = Entity.builder(KEY1).build(); private static final Entity ENTITY2 = Entity.builder(KEY2).set("null", NullValue.of()).build(); private static final Entity ENTITY3 = Entity.builder(KEY2) .set("p1", StringValue.builder("hi1").meaning(10).build()) - .set("p2", StringValue.builder("hi2").meaning(11).indexed(false).build()) - .set("p3", LongValue.builder(100).indexed(false).meaning(100).build()) + .set("p2", StringValue.builder("hi2").meaning(11).excludeFromIndexes(true).build()) + .set("p3", LongValue.builder(100).excludeFromIndexes(true).meaning(100).build()) .set("blob", BLOB1) .build(); private static final FullEntity EMBEDDED_ENTITY = Entity.builder(INCOMPLETE_KEY1) .set("p1", STRING_VALUE) - .set("p2", LongValue.builder(100).indexed(false).meaning(100).build()) + .set("p2", LongValue.builder(100).excludeFromIndexes(true).meaning(100).build()) .build(); private static final EntityValue EMBEDDED_ENTITY_VALUE1 = EntityValue.of(ENTITY1); private static final EntityValue EMBEDDED_ENTITY_VALUE2 = EntityValue.of(ENTITY2); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/StringValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/StringValueTest.java index a2cacd6574aa..4f02568bf924 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/StringValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/StringValueTest.java @@ -32,24 +32,20 @@ public void testToBuilder() throws Exception { assertEquals(value, value.toBuilder().build()); } - @SuppressWarnings("deprecation") @Test public void testOf() throws Exception { StringValue value = StringValue.of(CONTENT); assertEquals(CONTENT, value.get()); - assertFalse(value.hasIndexed()); - assertFalse(value.hasMeaning()); + assertFalse(value.excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { StringValue.Builder builder = StringValue.builder(CONTENT); - StringValue value = builder.meaning(1).indexed(false).build(); + StringValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertEquals(CONTENT, value.get()); - assertTrue(value.hasMeaning()); - assertEquals(Integer.valueOf(1), value.meaning()); - assertTrue(value.hasIndexed()); - assertFalse(value.indexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java index 973a3c3c0da4..12908add4c8e 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java @@ -18,7 +18,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import com.google.common.collect.ImmutableList; @@ -116,67 +115,22 @@ public void testType() throws Exception { } @Test - public void testHasIndexed() throws Exception { + public void testExcludeFromIndexes() throws Exception { for (Map.Entry> entry : typeToValue.entrySet()) { - ValueType valueType = entry.getKey(); - Boolean indexed = entry.getValue().hasIndexed(); - switch (valueType) { - case ENTITY: - assertTrue(indexed); - break; - default: - assertFalse(indexed); - break; - } - } - - TestBuilder builder = new TestBuilder(); - assertFalse(builder.build().hasIndexed()); - assertTrue(builder.indexed(false).build().hasIndexed()); - assertTrue(builder.indexed(true).build().hasIndexed()); - } - - @Test - public void testIndexed() throws Exception { - for (Map.Entry> entry : typeToValue.entrySet()) { - ValueType valueType = entry.getKey(); - Boolean indexed = entry.getValue().indexed(); - switch (valueType) { - case ENTITY: - assertFalse(indexed); - break; - default: - assertNull(indexed); - break; - } - } - - TestBuilder builder = new TestBuilder(); - assertNull(builder.build().indexed()); - assertFalse(builder.indexed(false).build().indexed()); - assertTrue(builder.indexed(true).build().indexed()); - } - - @SuppressWarnings("deprecation") - @Test - public void testHasMeaning() throws Exception { - for (Value value: typeToValue.values()) { - assertFalse(value.hasMeaning()); + assertFalse(entry.getValue().excludeFromIndexes()); } TestBuilder builder = new TestBuilder(); - assertTrue(builder.meaning(10).build().hasMeaning()); + assertFalse(builder.build().excludeFromIndexes()); + assertTrue(builder.excludeFromIndexes(true).build().excludeFromIndexes()); + assertFalse(builder.excludeFromIndexes(false).build().excludeFromIndexes()); } @SuppressWarnings("deprecation") @Test public void testMeaning() throws Exception { - for (Value value: typeToValue.values()) { - assertNull(value.meaning()); - } - TestBuilder builder = new TestBuilder(); - assertEquals(Integer.valueOf(10), builder.meaning(10).build().meaning()); + assertEquals(10, builder.meaning(10).build().meaning()); } @Test @@ -197,12 +151,11 @@ public void testGet() throws Exception { public void testToBuilder() throws Exception { Set content = Collections.singleton("bla"); ValueBuilder builder = new TestBuilder(); - builder.meaning(1).set(content).indexed(true); + builder.meaning(1).set(content).excludeFromIndexes(true); Value value = builder.build(); builder = value.toBuilder(); - assertEquals(Integer.valueOf(1), value.meaning()); - assertTrue(value.hasIndexed()); - assertTrue(value.indexed()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); assertEquals(ValueType.LIST, value.type()); assertEquals(content, value.get()); assertEquals(value, builder.build()); From 9f40a5f4b9a8d60e02e5cf4b004bee290b231eba Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 14 Sep 2015 15:25:12 -0700 Subject: [PATCH 002/375] Default projectId and namespace are empty strings, NullValue and DateTime are fixed, along with other minor edits --- .../datastore/BaseDatastoreBatchWriter.java | 2 +- .../google/gcloud/datastore/BaseEntity.java | 8 ++--- .../com/google/gcloud/datastore/BaseKey.java | 17 ++++------- .../google/gcloud/datastore/BatchImpl.java | 4 +-- .../gcloud/datastore/DatastoreImpl.java | 10 +++---- .../com/google/gcloud/datastore/DateTime.java | 17 +++++------ .../google/gcloud/datastore/DoubleValue.java | 4 +-- .../google/gcloud/datastore/EntityValue.java | 6 ++-- .../com/google/gcloud/datastore/GqlQuery.java | 6 ++-- .../gcloud/datastore/IncompleteKey.java | 10 ++----- .../google/gcloud/datastore/KeyFactory.java | 3 +- .../google/gcloud/datastore/NullValue.java | 9 ++++-- .../google/gcloud/datastore/PathElement.java | 18 +++++------ .../com/google/gcloud/datastore/Query.java | 6 ++-- .../com/google/gcloud/datastore/RawValue.java | 3 +- .../gcloud/datastore/StructuredQuery.java | 6 ++-- .../gcloud/datastore/TransactionImpl.java | 4 +-- .../google/gcloud/datastore/Validator.java | 12 ++++---- .../com/google/gcloud/datastore/Value.java | 24 +++++---------- .../google/gcloud/datastore/ValueType.java | 4 +++ .../BaseDatastoreBatchWriterTest.java | 30 ++++++++++++------- .../google/gcloud/datastore/BaseKeyTest.java | 3 +- .../gcloud/datastore/DatastoreTest.java | 15 +++++----- .../gcloud/datastore/KeyFactoryTest.java | 8 ++--- .../gcloud/datastore/ListValueTest.java | 2 +- .../gcloud/datastore/SerializationTest.java | 19 +++++++----- 26 files changed, 125 insertions(+), 125 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java index 8d0eec117bdf..d94eafbb42f6 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java @@ -214,7 +214,7 @@ protected DatastoreV1.Mutation.Builder toMutationPb() { mutationPb.addUpsert(entity.toPb()); } for (Key key : toDelete()) { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //mutationPb.addDelete(key.toPb()); } return mutationPb; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java index 665b4d8d24b9..8608e4fcedc9 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java @@ -93,12 +93,12 @@ private B self() { protected B fill(DatastoreV1.Entity entityPb) { Map> copiedProperties = Maps.newHashMap(); for (DatastoreV1.Property property : entityPb.getPropertyList()) { - // TODO(ajaykannan): Uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //copiedProperties.put(property.getName(), Value.fromPb(property.getValue())); } properties(copiedProperties); if (entityPb.hasKey()) { - // TODO(ajaykannan): Uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //key((K) IncompleteKey.fromPb(entityPb.getKey())); } return self(); @@ -391,12 +391,12 @@ protected final DatastoreV1.Entity toPb() { for (Map.Entry> entry : properties.entrySet()) { DatastoreV1.Property.Builder propertyPb = DatastoreV1.Property.newBuilder(); propertyPb.setName(entry.getKey()); - // TODO(ajaykannan): Uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //propertyPb.setValue(entry.getValue().toPb()); entityPb.addProperty(propertyPb.build()); } if (key != null) { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //entityPb.setKey(key.toPb()); } return entityPb.build(); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java index fdc973c6c4cc..2e6264af9927 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java @@ -21,7 +21,6 @@ import static com.google.gcloud.datastore.Validator.validateNamespace; import com.google.common.base.Preconditions; -import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; import java.util.LinkedList; @@ -41,8 +40,8 @@ abstract class BaseKey extends Serializable { abstract static class Builder> { - String projectId; - String namespace; + String projectId = ""; + String namespace = ""; String kind; final List ancestors; @@ -176,15 +175,9 @@ protected com.google.datastore.v1beta3.Key toPb() { com.google.datastore.v1beta3.Key.Builder keyPb = com.google.datastore.v1beta3.Key.newBuilder(); com.google.datastore.v1beta3.PartitionId.Builder partitionIdPb = com.google.datastore.v1beta3.PartitionId.newBuilder(); - if (!Strings.isNullOrEmpty(projectId)) { - partitionIdPb.setProjectId(projectId); - } - if (!Strings.isNullOrEmpty(namespace)) { - partitionIdPb.setNamespaceId(namespace); - } - if (!partitionIdPb.getProjectId().isEmpty() || !partitionIdPb.getNamespaceId().isEmpty()) { - keyPb.setPartitionId(partitionIdPb.build()); - } + partitionIdPb.setProjectId(projectId); + partitionIdPb.setNamespaceId(namespace); + keyPb.setPartitionId(partitionIdPb.build()); for (PathElement pathEntry : path) { keyPb.addPath(pathEntry.toPb()); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java index 95cdfbb10f01..c86ae28b3344 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java @@ -43,9 +43,9 @@ public List generatedKeys() { return Lists.transform(response.getMutationResult().getInsertAutoIdKeyList(), new Function() { @Override public Key apply(DatastoreV1.Key keyPb) { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //return Key.fromPb(keyPb); - return Key.builder(null).build(); // TODO(ajaykannan): remove this line when possible + return Key.builder(null).build(); // TODO(ajaykannan): fix me! } }); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java index 23d4f74a8da1..c21c0c2a7087 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java @@ -126,13 +126,13 @@ public List allocateId(IncompleteKey... keys) { } DatastoreV1.AllocateIdsRequest.Builder requestPb = DatastoreV1.AllocateIdsRequest.newBuilder(); for (IncompleteKey key : keys) { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //requestPb.addKey(trimNameOrId(key).toPb()); } DatastoreV1.AllocateIdsResponse responsePb = allocateIds(requestPb.build()); ImmutableList.Builder keyList = ImmutableList.builder(); for (DatastoreV1.Key keyPb : responsePb.getKeyList()) { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! // keyList.add(Key.fromPb(keyPb)); } return keyList.build(); @@ -195,7 +195,7 @@ public List add(FullEntity... entities) { if (completeEntity != null) { responseBuilder.add(completeEntity); } else { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //responseBuilder.add(Entity.builder(Key.fromPb(allocatedKeys.next()), entity).build()); } } @@ -226,7 +226,7 @@ Iterator get(DatastoreV1.ReadOptions readOptionsPb, final Key... keys) { requestPb.setReadOptions(readOptionsPb); } for (Key k : Sets.newLinkedHashSet(Arrays.asList(keys))) { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //requestPb.addKey(k.toPb()); } return new ResultsIterator(requestPb); @@ -314,7 +314,7 @@ public void delete(Key... keys) { DatastoreV1.Mutation.Builder mutationPb = DatastoreV1.Mutation.newBuilder(); Set dedupKeys = new LinkedHashSet<>(Arrays.asList(keys)); for (Key key : dedupKeys) { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //mutationPb.addDelete(key.toPb()); } commitMutation(mutationPb); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java index 0d5c99d2b3fd..eca352f5ba0c 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java @@ -32,7 +32,7 @@ * @see Google Cloud Datastore * Entities, Properties, and Keys */ -public final class DateTime extends Serializable +public final class DateTime extends Serializable implements Comparable { private static final long serialVersionUID = 7343324797621228378L; @@ -96,24 +96,23 @@ public static DateTime copyFrom(Calendar calendar) { } @Override - protected com.google.datastore.v1beta3.Value toPb() { - return com.google.datastore.v1beta3.Value.newBuilder() - .setTimestampValue(microsecondsToTimestampPb(timestampMicroseconds)).build(); + protected com.google.protobuf.Timestamp toPb() { + return microsecondsToTimestampPb(timestampMicroseconds); } @Override protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { - return new DateTime(timestampPbToMicroseconds(com.google.datastore.v1beta3.Value - .parseFrom(bytesPb).getTimestampValue())); + return new DateTime(timestampPbToMicroseconds( + com.google.protobuf.Timestamp.parseFrom(bytesPb))); } protected static long timestampPbToMicroseconds(com.google.protobuf.Timestamp timestampPb) { - return timestampPb.getSeconds() * 10^6 + timestampPb.getNanos() / 10^3; + return timestampPb.getSeconds() * 1000000 + timestampPb.getNanos() / 1000; } protected static com.google.protobuf.Timestamp microsecondsToTimestampPb(long microseconds) { - long seconds = microseconds / 10^6; - int nanos = (int) (microseconds % 10^6) * 10^3; + long seconds = microseconds / 1000000; + int nanos = (int) (microseconds % 1000000) * 1000; return com.google.protobuf.Timestamp.newBuilder().setSeconds(seconds).setNanos(nanos).build(); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DoubleValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DoubleValue.java index cf543ad94b78..d7409d08fe63 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DoubleValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DoubleValue.java @@ -18,8 +18,6 @@ import static com.google.datastore.v1beta3.Value.DOUBLE_VALUE_FIELD_NUMBER; -import com.google.api.services.datastore.DatastoreV1; - public final class DoubleValue extends Value { private static final long serialVersionUID = -5096238337676649540L; @@ -43,7 +41,7 @@ public Builder newBuilder(Double value) { protected Double getValue(com.google.datastore.v1beta3.Value from) { return from.getDoubleValue(); } - + @Override protected void setValue(DoubleValue from, com.google.datastore.v1beta3.Value.Builder to) { to.setDoubleValue(from.get()); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java index 3105f9fa0dd9..16ca55aec4a6 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java @@ -39,14 +39,14 @@ public Builder newBuilder(FullEntity value) { @Override protected FullEntity getValue(com.google.datastore.v1beta3.Value from) { - // TODO(ajaykannan): uncomment this line when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //return FullEntity.fromPb(from.getEntityValue()); - return null; // TODO(ajaykannan): remove this line when possible + return null; // TODO(ajaykannan): fix me! } @Override protected void setValue(EntityValue from, com.google.datastore.v1beta3.Value.Builder to) { - // TODO(ajaykannan): uncomment this line when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //to.setEntityValue(from.get().toPb()); } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java index ff659805a34d..54110a89c3e0 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java @@ -135,7 +135,7 @@ protected DatastoreV1.GqlQueryArg toPb() { argPb.setCursor(cursor.byteString()); } if (value != null) { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //argPb.setValue(value.toPb()); } return argPb.build(); @@ -151,9 +151,9 @@ static Binding fromPb(DatastoreV1.GqlQueryArg argPb) { if (argPb.hasCursor()) { return new Binding(name, new Cursor(argPb.getCursor())); } - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //return new Binding(name, Value.fromPb(argPb.getValue())); - return new Binding(name, new Cursor(null)); // TODO(ajaykannan): remove this line when possible + return new Binding(name, new Cursor(null)); // TODO(ajaykannan): fix me! } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java index 0eabefe32643..367bdbafed71 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java @@ -58,18 +58,12 @@ protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { } static IncompleteKey fromPb(com.google.datastore.v1beta3.Key keyPb) { - String projectId = null; - String namespace = null; + String projectId = ""; + String namespace = ""; if (keyPb.hasPartitionId()) { com.google.datastore.v1beta3.PartitionId partitionIdPb = keyPb.getPartitionId(); projectId = partitionIdPb.getProjectId(); - if (projectId.isEmpty()) { - projectId = null; - } namespace = partitionIdPb.getNamespaceId(); - if (namespace.isEmpty()) { - namespace = null; - } } List pathElementsPb = keyPb.getPathList(); Preconditions.checkArgument(!pathElementsPb.isEmpty(), "Path must not be empty"); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java index 28f852ed5355..c5b9d77a8cd7 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java @@ -16,6 +16,7 @@ package com.google.gcloud.datastore; +import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; /** @@ -35,7 +36,7 @@ public KeyFactory(String projectId, String namespace) { super(projectId); namespace(namespace); this.pi = projectId; - this.ns = namespace; + this.ns = MoreObjects.firstNonNull(namespace, ""); } public IncompleteKey newKey() { diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/NullValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/NullValue.java index 173ee3ef79f0..ed314200b8bb 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/NullValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/NullValue.java @@ -18,6 +18,8 @@ import static com.google.common.base.Preconditions.checkArgument; +import static com.google.datastore.v1beta3.Value.NULL_VALUE_FIELD_NUMBER; + public final class NullValue extends Value { private static final long serialVersionUID = 8497300779013002270L; @@ -34,7 +36,7 @@ public Builder newBuilder(Void value) { @Override public int getProtoFieldId() { - return 0; + return NULL_VALUE_FIELD_NUMBER; } @Override @@ -44,11 +46,12 @@ protected Void getValue(com.google.datastore.v1beta3.Value from) { @Override protected void setValue(NullValue from, com.google.datastore.v1beta3.Value.Builder to) { - // nothing to set + to.setNullValue(com.google.protobuf.NullValue.NULL_VALUE); } }; - public static final class Builder extends Value.BaseBuilder { + public static final class Builder + extends Value.BaseBuilder { private Builder() { super(ValueType.NULL); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/PathElement.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/PathElement.java index c0196a6326fe..b0eb9fd83855 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/PathElement.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/PathElement.java @@ -86,7 +86,8 @@ public boolean equals(Object obj) { @Override protected com.google.datastore.v1beta3.Key.PathElement toPb() { - com.google.datastore.v1beta3.Key.PathElement.Builder pathElementPb = com.google.datastore.v1beta3.Key.PathElement.newBuilder(); + com.google.datastore.v1beta3.Key.PathElement.Builder pathElementPb = + com.google.datastore.v1beta3.Key.PathElement.newBuilder(); pathElementPb.setKind(kind); if (id != null) { pathElementPb.setId(id); @@ -103,15 +104,14 @@ protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { static PathElement fromPb(com.google.datastore.v1beta3.Key.PathElement pathElementPb) { String kind = pathElementPb.getKind(); - if (pathElementPb.getIdTypeCase() == - com.google.datastore.v1beta3.Key.PathElement.IdTypeCase.ID) { - return of(kind, pathElementPb.getId()); + switch (pathElementPb.getIdTypeCase()) { + case ID: + return of(kind, pathElementPb.getId()); + case NAME: + return of(kind, pathElementPb.getName()); + default: + return of(kind); } - if (pathElementPb.getIdTypeCase() == - com.google.datastore.v1beta3.Key.PathElement.IdTypeCase.NAME) { - return of(kind, pathElementPb.getName()); - } - return of(kind); } static PathElement of(String kind) { diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java index fdd120ccbe85..f3dd254ce9a3 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java @@ -66,7 +66,7 @@ public abstract static class ResultType implements java.io.Serializable { if (!entityPb.hasKey()) { return null; } - //TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //TODO(ajaykannan): fix me! //return Key.fromPb(entityPb.getKey()); } return ProjectionEntity.fromPb(entityPb); @@ -89,9 +89,9 @@ public abstract static class ResultType implements java.io.Serializable { private static final long serialVersionUID = -8514289244104446252L; @Override protected Key convert(DatastoreV1.Entity entityPb) { - //TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + //TODO(ajaykannan): fix me! //return Key.fromPb(entityPb.getKey()); - return Key.builder(null).build(); // TODO(ajaykannan): remove this line when possible + return Key.builder(null).build(); // TODO(ajaykannan): fix me! } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java index d60f215cd5f2..cd64bcdeff05 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java @@ -36,7 +36,8 @@ public int getProtoFieldId() { } @Override - protected com.google.datastore.v1beta3.Value getValue(com.google.datastore.v1beta3.Value from) { + protected com.google.datastore.v1beta3.Value getValue( + com.google.datastore.v1beta3.Value from) { return from; } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java index b034b15995a3..1dd35cb4f191 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java @@ -228,10 +228,10 @@ private PropertyFilter(String property, Operator operator, Value value) { public static PropertyFilter fromPb(DatastoreV1.PropertyFilter propertyFilterPb) { String property = propertyFilterPb.getProperty().getName(); Operator operator = Operator.fromPb(propertyFilterPb.getOperator()); - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //Value value = Value.fromPb(propertyFilterPb.getValue()); //return new PropertyFilter(property, operator, value); - return new PropertyFilter(property, operator, null); // TODO(ajaykannan): remove this line when possible + return new PropertyFilter(property, operator, null); // TODO(ajaykannan): fix me! } @Override @@ -437,7 +437,7 @@ protected DatastoreV1.Filter toPb() { propertyFilterPb.getPropertyBuilder().setName(property); propertyFilterPb.setOperator(operator.toPb()); if (value != null) { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //propertyFilterPb.setValue(value.toPb()); } return filterPb.build(); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java index 62978ce73be6..ae9d0e50f0d7 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java @@ -47,9 +47,9 @@ public List generatedKeys() { return Lists.transform(response.getMutationResult().getInsertAutoIdKeyList(), new Function() { @Override public Key apply(DatastoreV1.Key keyPb) { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition + // TODO(ajaykannan): fix me! //return Key.fromPb(keyPb); - return Key.builder(null).build(); //: TODO(ajaykannan) remove this placeholder line + return Key.builder(null).build(); // TODO(ajaykannan): fix me! } }); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Validator.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Validator.java index 09a3fa7defcc..791adec53101 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Validator.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Validator.java @@ -45,13 +45,13 @@ static String validateDatabase(String projectId) { } static String validateNamespace(String namespace) { - if (namespace != null) { - checkArgument(!namespace.isEmpty(), "namespace must not be an empty string"); - checkArgument(namespace.length() <= MAX_NAMESPACE_LENGTH, - "namespace must not contain more than 100 characters"); - checkArgument(NAMESPACE_PATTERN.matcher(namespace).matches(), - "namespace must the following pattern: " + NAMESPACE_PATTERN.pattern()); + if (Strings.isNullOrEmpty(namespace)) { + return ""; } + checkArgument(namespace.length() <= MAX_NAMESPACE_LENGTH, + "namespace must not contain more than 100 characters"); + checkArgument(NAMESPACE_PATTERN.matcher(namespace).matches(), + "namespace must the following pattern: " + NAMESPACE_PATTERN.pattern()); return namespace; } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java index 94e1d7de545f..9e4aae0fb6f5 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java @@ -18,10 +18,9 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.protobuf.Descriptors.FieldDescriptor; +import com.google.datastore.v1beta3.Value.ValueTypeCase; import com.google.protobuf.InvalidProtocolBufferException; -import java.util.Map.Entry; import java.util.Objects; /** @@ -64,7 +63,8 @@ public final B fromProto(com.google.datastore.v1beta3.Value proto) { @SuppressWarnings("deprecation") @Override public final com.google.datastore.v1beta3.Value toProto(P value) { - com.google.datastore.v1beta3.Value.Builder builder = com.google.datastore.v1beta3.Value.newBuilder(); + com.google.datastore.v1beta3.Value.Builder builder = + com.google.datastore.v1beta3.Value.newBuilder(); builder.setExcludeFromIndexes(value.excludeFromIndexes()); builder.setMeaning(value.meaning()); setValue(value, builder); @@ -160,7 +160,7 @@ public final boolean excludeFromIndexes() { } @Deprecated - public final int meaning() { + final int meaning() { return meaning; } @@ -198,18 +198,10 @@ protected com.google.datastore.v1beta3.Value toPb() { } static Value fromPb(com.google.datastore.v1beta3.Value proto) { - for (Entry entry : proto.getAllFields().entrySet()) { - FieldDescriptor descriptor = entry.getKey(); - if (descriptor.getName().endsWith("_value")) { - ValueType valueType = ValueType.getByDescriptorId(descriptor.getNumber()); - if (valueType == null) { - // unsupported type - return RawValue.MARSHALLER.fromProto(proto).build(); - } - return valueType.getMarshaller().fromProto(proto).build(); - } - } - return NullValue.MARSHALLER.fromProto(proto).build(); + ValueTypeCase descriptorId = proto.getValueTypeCase(); + ValueType valueType = ValueType.getByDescriptorId(descriptorId.getNumber()); + return valueType == null ? RawValue.MARSHALLER.fromProto(proto).build() + : valueType.getMarshaller().fromProto(proto).build(); } @Override diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java index b09583103a59..20c89a86e7a0 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java @@ -80,6 +80,10 @@ public enum ValueType { */ RAW_VALUE(RawValue.MARSHALLER); + /** + * TODO(ajaykannan): add GEO_POINT_VALUE + * Will represent a geolocation value in latitude/longitude + */ private static final ImmutableMap DESCRIPTOR_TO_TYPE_MAP; diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java index 28fea360ecf4..43df45d7a04e 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java @@ -80,6 +80,8 @@ public void tearDown() { batchWriter.finish(); } + // TODO(ajaykannan): fix me! + /* @Test public void testAdd() throws Exception { Entity entity2 = @@ -98,6 +100,7 @@ public void testAdd() throws Exception { assertEquals(Entity.builder(KEY3, INCOMPLETE_ENTITY_2).build(), entities.get(2)); assertEquals(entity2, entities.get(3)); } + */ @Test public void testAddAfterDelete() throws Exception { @@ -133,6 +136,8 @@ public void testAddWhenNotActive() throws Exception { batchWriter.add(ENTITY1); } + // TODO(ajaykannan): fix me! + /* @Test public void testAddWithDeferredAllocation() throws Exception { DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() @@ -195,6 +200,7 @@ public void testUpdateAfterPut() throws Exception { batchWriter.update(entity); assertEquals(pb, batchWriter.toMutationPb().build()); } + */ @Test(expected = DatastoreException.class) public void testUpdateAfterDelete() throws Exception { @@ -208,6 +214,8 @@ public void testUpdateWhenNotActive() throws Exception { batchWriter.update(ENTITY1); } + // TODO(ajaykannan): fix me! + /* @Test public void testPut() throws Exception { DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() @@ -263,20 +271,21 @@ public void testPutAfterDelete() throws Exception { batchWriter.put(entity); assertEquals(pb, batchWriter.toMutationPb().build()); } + */ @Test(expected = DatastoreException.class) public void testPutWhenNotActive() throws Exception { batchWriter.deactivate(); batchWriter.put(ENTITY1); } - + // TODO(ajaykannan): fix me! + /* @Test public void testDelete() throws Exception { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - //.addDelete(KEY1.toPb()) - //.addDelete(KEY2.toPb()) - //.addDelete(KEY3.toPb()) + .addDelete(KEY1.toPb()) + .addDelete(KEY2.toPb()) + .addDelete(KEY3.toPb()) .build(); batchWriter.delete(KEY1, KEY2); batchWriter.delete(KEY3); @@ -285,10 +294,9 @@ public void testDelete() throws Exception { @Test public void testDeleteAfterAdd() throws Exception { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() .addInsertAutoId(INCOMPLETE_ENTITY_1.toPb()) - //.addDelete(KEY1.toPb()) + .addDelete(KEY1.toPb()) .build(); batchWriter.add(ENTITY1); batchWriter.addWithDeferredIdAllocation(INCOMPLETE_ENTITY_1); @@ -296,11 +304,11 @@ public void testDeleteAfterAdd() throws Exception { assertEquals(pb, batchWriter.toMutationPb().build()); } + @Test public void testDeleteAfterUpdate() throws Exception { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - //.addDelete(KEY1.toPb()) + .addDelete(KEY1.toPb()) .build(); batchWriter.update(ENTITY1); batchWriter.delete(KEY1); @@ -309,14 +317,14 @@ public void testDeleteAfterUpdate() throws Exception { @Test public void testDeleteAfterPut() throws Exception { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - //.addDelete(KEY1.toPb()) + .addDelete(KEY1.toPb()) .build(); batchWriter.put(ENTITY1); batchWriter.delete(KEY1); assertEquals(pb, batchWriter.toMutationPb().build()); } + */ @Test(expected = DatastoreException.class) public void testDeleteWhenNotActive() throws Exception { diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java index e99e7a60fd0b..79576748bb58 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java @@ -78,7 +78,8 @@ public void testBadDatasetInSetter() throws Exception { public void testNamespace() throws Exception { Builder builder = new Builder("ds", "k"); BaseKey key = builder.build(); - assertNull(key.namespace()); + assertTrue(key.namespace() != null); + assertTrue(key.namespace().isEmpty()); key = builder.namespace("ns").build(); assertEquals("ns", key.namespace()); } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index 65872abb79e7..57342ed3e26d 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -14,6 +14,8 @@ * limitations under the License. */ +// TODO(ajaykannan): fix me! +/* package com.google.gcloud.datastore; import static org.junit.Assert.assertEquals; @@ -637,19 +639,17 @@ public void testKeyFactory() { @Test public void testRetires() throws Exception { - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition - //DatastoreV1.LookupRequest requestPb = - // DatastoreV1.LookupRequest.newBuilder().addKey(KEY1.toPb()).build(); + DatastoreV1.LookupRequest requestPb = + DatastoreV1.LookupRequest.newBuilder().addKey(KEY1.toPb()).build(); DatastoreV1.LookupResponse responsePb = DatastoreV1.LookupResponse.newBuilder() .addFound(EntityResult.newBuilder().setEntity(ENTITY1.toPb())).build(); DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) .andReturn(rpcMock); - // TODO(ajaykannan): uncomment when possible in datastore v1beta3 transition - //EasyMock.expect(rpcMock.lookup(requestPb)) - // .andThrow(new DatastoreRpc.DatastoreRpcException(Reason.UNAVAILABLE)) - // .andReturn(responsePb); + EasyMock.expect(rpcMock.lookup(requestPb)) + .andThrow(new DatastoreRpc.DatastoreRpcException(Reason.UNAVAILABLE)) + .andReturn(responsePb); EasyMock.replay(rpcFactoryMock, rpcMock); DatastoreOptions options = this.options.toBuilder() .retryParams(RetryParams.getDefaultInstance()) @@ -661,3 +661,4 @@ public void testRetires() throws Exception { EasyMock.verify(rpcFactoryMock, rpcMock); } } +*/ diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyFactoryTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyFactoryTest.java index 92851bd87efe..7acf8abbbf19 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyFactoryTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyFactoryTest.java @@ -55,7 +55,7 @@ public void testReset() { key = keyFactory.newKey(); assertEquals("k1", key.kind()); assertEquals(PROJECT_ID, key.projectId()); - assertNull(key.namespace()); + assertTrue(key.namespace().isEmpty()); assertTrue(key.ancestors().isEmpty()); keyFactory = new KeyFactory(PROJECT_ID, "ns1").kind("k"); @@ -75,9 +75,9 @@ public void testReset() { @Test public void testNewKey() throws Exception { Key key = keyFactory.newKey(1); - verifyKey(key, 1L, null); + verifyKey(key, 1L, ""); key = keyFactory.newKey("n"); - verifyKey(key, "n", null); + verifyKey(key, "n", ""); PathElement p1 = PathElement.of("k1", "n"); PathElement p2 = PathElement.of("k2", 10); key = keyFactory.namespace("ns").ancestors(p1, p2).newKey("k3"); @@ -87,7 +87,7 @@ public void testNewKey() throws Exception { @Test public void testNewIncompleteKey() throws Exception { IncompleteKey key = keyFactory.newKey(); - verifyIncompleteKey(key, null); + verifyIncompleteKey(key, ""); PathElement p1 = PathElement.of("k1", "n"); PathElement p2 = PathElement.of("k2", 10); key = keyFactory.namespace("ns").ancestors(p1, p2).newKey(); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java index 23a9325f22de..74b74facfe45 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java @@ -28,7 +28,7 @@ public class ListValueTest { - private static final List> CONTENT = ImmutableList.of(NullValue.of(), StringValue.of("foo")); + private static final List> CONTENT = ImmutableList.of(NullValue.of(), StringValue.of("foo")); @Test public void testToBuilder() throws Exception { diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index 9dfdd33c873d..624689cd420e 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -88,8 +88,11 @@ public class SerializationTest { private static final BooleanValue BOOLEAN_VALUE = BooleanValue.of(true); private static final DateTimeValue DATE_AND_TIME_VALUE = DateTimeValue.of(DateTime.now()); private static final BlobValue BLOB_VALUE = BlobValue.of(BLOB1); - private static final RawValue RAW_VALUE = RawValue.of(com.google.datastore.v1beta3.Value - .newBuilder().setStringValue("blob-key").setMeaning(18).build()); + private static final RawValue RAW_VALUE = + RawValue.of(com.google.datastore.v1beta3.Value.newBuilder() + .setGeoPointValue(com.google.type.LatLng.newBuilder() + .setLatitude(0.0).setLongitude(0.0).build()) + .setMeaning(18).build()); private static final Entity ENTITY1 = Entity.builder(KEY1).build(); private static final Entity ENTITY2 = Entity.builder(KEY2).set("null", NullValue.of()).build(); @@ -119,8 +122,9 @@ public class SerializationTest { .put(ValueType.NULL, NULL_VALUE) .put(ValueType.KEY, KEY_VALUE) .put(ValueType.STRING, STRING_VALUE) - .putAll(ValueType.ENTITY, EMBEDDED_ENTITY_VALUE1, EMBEDDED_ENTITY_VALUE2, - EMBEDDED_ENTITY_VALUE3) + // TODO(ajaykannan): fix me! + //.putAll(ValueType.ENTITY, EMBEDDED_ENTITY_VALUE1, EMBEDDED_ENTITY_VALUE2, + // EMBEDDED_ENTITY_VALUE3) .put(ValueType.LIST, LIST_VALUE) .put(ValueType.LONG, LONG_VALUE) .put(ValueType.DOUBLE, DOUBLE_VALUE) @@ -166,9 +170,10 @@ public void testValues() throws Exception { @Test public void testTypes() throws Exception { - Serializable[] types = { KEY1, KEY2, INCOMPLETE_KEY1, INCOMPLETE_KEY2, ENTITY1, ENTITY2, - ENTITY3, EMBEDDED_ENTITY, PROJECTION_ENTITY, DATE_TIME1, BLOB1, CURSOR1, GQL1, GQL2, - QUERY1, QUERY2, QUERY3}; + // TODO(ajaykannan): fix me! + Serializable[] types = { KEY1, KEY2, INCOMPLETE_KEY1, INCOMPLETE_KEY2, /*ENTITY1, ENTITY2, + ENTITY3, EMBEDDED_ENTITY, PROJECTION_ENTITY,*/ DATE_TIME1, BLOB1/*, CURSOR1, GQL1, GQL2, + QUERY1, QUERY2, QUERY3*/}; for (Serializable obj : types) { Object copy = serializeAndDeserialize(obj); assertEquals(obj, obj); From e0784699b1320f36b7df456666ea52e656f31d5b Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 22 Sep 2015 18:42:33 -0700 Subject: [PATCH 003/375] Updates to write-related code for datastore v1beta3 update --- .../datastore/BaseDatastoreBatchWriter.java | 34 ++-- .../google/gcloud/datastore/BaseEntity.java | 32 ++-- .../google/gcloud/datastore/BatchImpl.java | 54 +++--- .../google/gcloud/datastore/BatchOption.java | 58 ------ .../google/gcloud/datastore/Datastore.java | 7 +- .../gcloud/datastore/DatastoreHelper.java | 5 +- .../gcloud/datastore/DatastoreImpl.java | 165 ++++++++++-------- .../gcloud/datastore/DatastoreOptions.java | 26 +-- .../com/google/gcloud/datastore/Entity.java | 3 +- .../google/gcloud/datastore/EntityValue.java | 7 +- .../google/gcloud/datastore/FullEntity.java | 4 +- .../gcloud/datastore/ProjectionEntity.java | 3 +- .../com/google/gcloud/datastore/Query.java | 12 +- .../gcloud/datastore/QueryResultsImpl.java | 3 +- .../gcloud/datastore/TransactionImpl.java | 65 +++---- .../gcloud/datastore/TransactionOption.java | 114 ------------ .../com/google/gcloud/spi/DatastoreRpc.java | 31 ++-- .../gcloud/spi/DefaultDatastoreRpc.java | 94 +++++----- .../BaseDatastoreBatchWriterTest.java | 156 +++++++---------- .../google/gcloud/datastore/BaseKeyTest.java | 1 - .../datastore/DatastoreOptionsTest.java | 2 +- .../gcloud/datastore/DatastoreTest.java | 30 ++-- .../gcloud/datastore/KeyFactoryTest.java | 1 - .../gcloud/datastore/LocalGcdHelper.java | 12 +- 24 files changed, 349 insertions(+), 570 deletions(-) delete mode 100644 gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchOption.java delete mode 100644 gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionOption.java diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java index d94eafbb42f6..6d8ac86834de 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java @@ -16,11 +16,11 @@ package com.google.gcloud.datastore; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.base.Preconditions; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; +import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashMap; @@ -88,9 +88,7 @@ public final List add(FullEntity... entities) { for (FullEntity entity : entities) { IncompleteKey key = entity.key(); Preconditions.checkArgument(key != null, "Entity must have a key"); - if (key instanceof Key) { - addInternal((FullEntity) entity); - } else { + if (!(key instanceof Key)) { incompleteKeys.add(key); } } @@ -104,6 +102,7 @@ public final List add(FullEntity... entities) { List answer = Lists.newArrayListWithExpectedSize(entities.length); for (FullEntity entity : entities) { if (entity.key() instanceof Key) { + addInternal((FullEntity) entity); answer.add(Entity.convert((FullEntity) entity)); } else { Entity entityWithAllocatedId = Entity.builder(allocated.next(), entity).build(); @@ -185,6 +184,10 @@ protected Set toDelete() { return toDelete; } + protected int numAutoAllocatedIds() { + return toAddAutoId.size(); + } + protected void deactivate() { active = false; } @@ -199,25 +202,30 @@ protected DatastoreException newInvalidRequest(String msg, Object... params) { return DatastoreException.throwInvalidRequest(String.format(msg, params)); } - protected DatastoreV1.Mutation.Builder toMutationPb() { - DatastoreV1.Mutation.Builder mutationPb = DatastoreV1.Mutation.newBuilder(); + protected List toMutationPbList() { + List mutationsPb = + new ArrayList<>(); for (FullEntity entity : toAddAutoId()) { - mutationPb.addInsertAutoId(entity.toPb()); + mutationsPb.add( + com.google.datastore.v1beta3.Mutation.newBuilder().setInsert(entity.toPb()).build()); } for (FullEntity entity : toAdd().values()) { - mutationPb.addInsert(entity.toPb()); + mutationsPb.add( + com.google.datastore.v1beta3.Mutation.newBuilder().setInsert(entity.toPb()).build()); } for (FullEntity entity : toUpdate().values()) { - mutationPb.addUpdate(entity.toPb()); + mutationsPb.add( + com.google.datastore.v1beta3.Mutation.newBuilder().setUpdate(entity.toPb()).build()); } for (FullEntity entity : toPut().values()) { - mutationPb.addUpsert(entity.toPb()); + mutationsPb.add( + com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(entity.toPb()).build()); } for (Key key : toDelete()) { - // TODO(ajaykannan): fix me! - //mutationPb.addDelete(key.toPb()); + mutationsPb.add( + com.google.datastore.v1beta3.Mutation.newBuilder().setDelete(key.toPb()).build()); } - return mutationPb; + return mutationsPb; } protected abstract Datastore datastore(); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java index 8608e4fcedc9..97718e708e83 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java @@ -27,7 +27,6 @@ import static com.google.gcloud.datastore.NullValue.of; import static com.google.gcloud.datastore.StringValue.of; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.collect.ImmutableSortedMap; import com.google.common.collect.Maps; import com.google.protobuf.InvalidProtocolBufferException; @@ -48,7 +47,8 @@ * @see Google Cloud Datastore * Entities, Properties, and Keys */ -public abstract class BaseEntity extends Serializable { +public abstract class BaseEntity + extends Serializable { private static final long serialVersionUID = 8175618724683792766L; @@ -90,16 +90,15 @@ private B self() { } @SuppressWarnings("unchecked") - protected B fill(DatastoreV1.Entity entityPb) { + protected B fill(com.google.datastore.v1beta3.Entity entityPb) { Map> copiedProperties = Maps.newHashMap(); - for (DatastoreV1.Property property : entityPb.getPropertyList()) { - // TODO(ajaykannan): fix me! - //copiedProperties.put(property.getName(), Value.fromPb(property.getValue())); + for (Map.Entry entry : + entityPb.getProperties().entrySet()) { + copiedProperties.put(entry.getKey(), Value.fromPb(entry.getValue())); } properties(copiedProperties); if (entityPb.hasKey()) { - // TODO(ajaykannan): fix me! - //key((K) IncompleteKey.fromPb(entityPb.getKey())); + key((K) IncompleteKey.fromPb(entityPb.getKey())); } return self(); } @@ -379,25 +378,22 @@ ImmutableSortedMap> properties() { @Override protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { Builder builder = emptyBuilder(); - builder.fill(DatastoreV1.Entity.parseFrom(bytesPb)); + builder.fill(com.google.datastore.v1beta3.Entity.parseFrom(bytesPb)); return builder.build(); } protected abstract Builder emptyBuilder(); @Override - protected final DatastoreV1.Entity toPb() { - DatastoreV1.Entity.Builder entityPb = DatastoreV1.Entity.newBuilder(); + protected final com.google.datastore.v1beta3.Entity toPb() { + com.google.datastore.v1beta3.Entity.Builder entityPb = + com.google.datastore.v1beta3.Entity.newBuilder(); + Map propertiesPb = entityPb.getMutableProperties(); for (Map.Entry> entry : properties.entrySet()) { - DatastoreV1.Property.Builder propertyPb = DatastoreV1.Property.newBuilder(); - propertyPb.setName(entry.getKey()); - // TODO(ajaykannan): fix me! - //propertyPb.setValue(entry.getValue().toPb()); - entityPb.addProperty(propertyPb.build()); + propertiesPb.put(entry.getKey(), entry.getValue().toPb()); } if (key != null) { - // TODO(ajaykannan): fix me! - //entityPb.setKey(key.toPb()); + entityPb.setKey(key.toPb()); } return entityPb.build(); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java index c86ae28b3344..a9eab9e9c3f1 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java @@ -16,65 +16,53 @@ package com.google.gcloud.datastore; -import com.google.api.services.datastore.DatastoreV1; -import com.google.common.base.Function; -import com.google.common.collect.Lists; -import com.google.gcloud.datastore.BatchOption.ForceWrites; - +import java.util.Iterator; +import java.util.LinkedList; import java.util.List; -import java.util.Map; class BatchImpl extends BaseDatastoreBatchWriter implements Batch { private final DatastoreImpl datastore; - private final boolean force; static class ResponseImpl implements Batch.Response { - private final DatastoreV1.CommitResponse response; + private final com.google.datastore.v1beta3.CommitResponse response; + private final int numAutoAllocatedIds; - ResponseImpl(DatastoreV1.CommitResponse response) { + ResponseImpl(com.google.datastore.v1beta3.CommitResponse response, int numAutoAllocatedIds) { this.response = response; + this.numAutoAllocatedIds = numAutoAllocatedIds; } @Override public List generatedKeys() { - return Lists.transform(response.getMutationResult().getInsertAutoIdKeyList(), - new Function() { - @Override public Key apply(DatastoreV1.Key keyPb) { - // TODO(ajaykannan): fix me! - //return Key.fromPb(keyPb); - return Key.builder(null).build(); // TODO(ajaykannan): fix me! - } - }); + Iterator results = + response.getMutationResultsList().iterator(); + List generated = new LinkedList(); + for (int i = 0; i < numAutoAllocatedIds; i++) { + generated.add(Key.fromPb(results.next().getKey())); + } + return generated; } } - BatchImpl(DatastoreImpl datastore, BatchOption... options) { + BatchImpl(DatastoreImpl datastore) { super("batch"); this.datastore = datastore; - Map, BatchOption> optionsMap = BatchOption.asImmutableMap(options); - if (optionsMap.containsKey(ForceWrites.class)) { - force = ((ForceWrites) optionsMap.get(ForceWrites.class)).force(); - } else { - force = datastore.options().force(); - } } @Override public Batch.Response submit() { validateActive(); - DatastoreV1.Mutation.Builder mutationPb = toMutationPb(); - if (force) { - mutationPb.setForce(force); - } - DatastoreV1.CommitRequest.Builder requestPb = DatastoreV1.CommitRequest.newBuilder(); - requestPb.setMode(DatastoreV1.CommitRequest.Mode.NON_TRANSACTIONAL); - requestPb.setMutation(mutationPb); - DatastoreV1.CommitResponse responsePb = datastore.commit(requestPb.build()); + List mutationsPb = toMutationPbList(); + com.google.datastore.v1beta3.CommitRequest.Builder requestPb = + com.google.datastore.v1beta3.CommitRequest.newBuilder(); + requestPb.setMode(com.google.datastore.v1beta3.CommitRequest.Mode.NON_TRANSACTIONAL); + requestPb.addAllMutations(mutationsPb); + com.google.datastore.v1beta3.CommitResponse responsePb = datastore.commit(requestPb.build()); deactivate(); - return new ResponseImpl(responsePb); + return new ResponseImpl(responsePb, numAutoAllocatedIds()); } @Override diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchOption.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchOption.java deleted file mode 100644 index 362a74e96c79..000000000000 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchOption.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * 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.gcloud.datastore; - -import com.google.common.collect.ImmutableMap; - -import java.util.Map; - -public abstract class BatchOption implements java.io.Serializable { - - private static final long serialVersionUID = -3932758377282659839L; - - public static final class ForceWrites extends BatchOption { - - private static final long serialVersionUID = 2555054296046232799L; - - private final boolean force; - - public ForceWrites(boolean force) { - this.force = force; - } - - public boolean force() { - return force; - } - } - - BatchOption() { - // package protected - } - - public static ForceWrites forceWrites() { - return new ForceWrites(true); - } - - static Map, BatchOption> asImmutableMap(BatchOption... options) { - ImmutableMap.Builder, BatchOption> builder = - ImmutableMap.builder(); - for (BatchOption option : options) { - builder.put(option.getClass(), option); - } - return builder.build(); - } -} diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java index 870ed8d9474f..b49db1cacdfe 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java @@ -30,7 +30,7 @@ public interface Datastore extends Service, DatastoreReaderWri * * @throws DatastoreException upon failure */ - Transaction newTransaction(TransactionOption... options); + Transaction newTransaction(); /** @@ -54,15 +54,14 @@ interface TransactionCallable { * as a {@link DatastoreException} with the original exception as its root cause. * * @param callable the callback to call with a newly created transactional readerWriter - * @param options the options for the created transaction * @throws DatastoreException upon failure */ - T runInTransaction(TransactionCallable callable, TransactionOption... options); + T runInTransaction(TransactionCallable callable); /** * Returns a new Batch for processing multiple write operations in one request. */ - Batch newBatch(BatchOption... options); + Batch newBatch(); /** * Allocate a unique id for the given key. diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java index a74d06642740..5ea0f755d2f8 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java @@ -69,9 +69,8 @@ static List fetch(DatastoreReader reader, Key... keys) { return list; } - static T runInTransaction(Datastore datastore, - Datastore.TransactionCallable callable, TransactionOption... options) { - Transaction transaction = datastore.newTransaction(options); + static T runInTransaction(Datastore datastore, Datastore.TransactionCallable callable) { + Transaction transaction = datastore.newTransaction(); try { T value = callable.run(transaction); transaction.commit(); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java index c21c0c2a7087..262098e82f96 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java @@ -16,7 +16,6 @@ package com.google.gcloud.datastore; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.base.MoreObjects; import com.google.common.base.Preconditions; import com.google.common.collect.AbstractIterator; @@ -33,6 +32,7 @@ import com.google.protobuf.ByteString; import java.util.Arrays; +import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.LinkedHashMap; @@ -79,18 +79,18 @@ public RetryResult beforeEval(Exception exception) { } @Override - public Batch newBatch(BatchOption... options) { - return new BatchImpl(this, options); + public Batch newBatch() { + return new BatchImpl(this); } @Override - public Transaction newTransaction(TransactionOption... options) { - return new TransactionImpl(this, options); + public Transaction newTransaction() { + return new TransactionImpl(this); } @Override - public T runInTransaction(TransactionCallable callable, TransactionOption... options) { - return DatastoreHelper.runInTransaction(this, callable, options); + public T runInTransaction(TransactionCallable callable) { + return DatastoreHelper.runInTransaction(this, callable); } @Override @@ -98,14 +98,19 @@ public QueryResults run(Query query) { return run(null, query); } - QueryResults run(DatastoreV1.ReadOptions readOptionsPb, Query query) { - return new QueryResultsImpl<>(this, readOptionsPb, query); + QueryResults run(com.google.datastore.v1beta3.ReadOptions readOptionsPb, Query query) { + // TODO(ajaykannan): fix me! + //return new QueryResultsImpl<>(this, readOptionsPb, query); + return null; // TODO(ajaykannan): fix me! } - DatastoreV1.RunQueryResponse runQuery(final DatastoreV1.RunQueryRequest requestPb) { + com.google.datastore.v1beta3.RunQueryResponse runQuery( + final com.google.datastore.v1beta3.RunQueryRequest requestPb) { try { - return RetryHelper.runWithRetries(new Callable() { - @Override public DatastoreV1.RunQueryResponse call() throws DatastoreRpcException { + return RetryHelper.runWithRetries( + new Callable() { + @Override public com.google.datastore.v1beta3.RunQueryResponse call() + throws DatastoreRpcException { return datastoreRpc.runQuery(requestPb); } }, retryParams, EXCEPTION_HANDLER); @@ -124,24 +129,26 @@ public List allocateId(IncompleteKey... keys) { if (keys.length == 0) { return Collections.emptyList(); } - DatastoreV1.AllocateIdsRequest.Builder requestPb = DatastoreV1.AllocateIdsRequest.newBuilder(); + com.google.datastore.v1beta3.AllocateIdsRequest.Builder requestPb = + com.google.datastore.v1beta3.AllocateIdsRequest.newBuilder(); for (IncompleteKey key : keys) { - // TODO(ajaykannan): fix me! - //requestPb.addKey(trimNameOrId(key).toPb()); + requestPb.addKeys(trimNameOrId(key).toPb()); } - DatastoreV1.AllocateIdsResponse responsePb = allocateIds(requestPb.build()); + com.google.datastore.v1beta3.AllocateIdsResponse responsePb = allocateIds(requestPb.build()); ImmutableList.Builder keyList = ImmutableList.builder(); - for (DatastoreV1.Key keyPb : responsePb.getKeyList()) { - // TODO(ajaykannan): fix me! - // keyList.add(Key.fromPb(keyPb)); + for (com.google.datastore.v1beta3.Key keyPb : responsePb.getKeysList()) { + keyList.add(Key.fromPb(keyPb)); } return keyList.build(); } - DatastoreV1.AllocateIdsResponse allocateIds(final DatastoreV1.AllocateIdsRequest requestPb) { + com.google.datastore.v1beta3.AllocateIdsResponse allocateIds( + final com.google.datastore.v1beta3.AllocateIdsRequest requestPb) { try { - return RetryHelper.runWithRetries(new Callable() { - @Override public DatastoreV1.AllocateIdsResponse call() throws DatastoreRpcException { + return RetryHelper.runWithRetries( + new Callable() { + @Override public com.google.datastore.v1beta3.AllocateIdsResponse call() + throws DatastoreRpcException { return datastoreRpc.allocateIds(requestPb); } }, retryParams, EXCEPTION_HANDLER); @@ -168,7 +175,7 @@ public List add(FullEntity... entities) { if (entities.length == 0) { return Collections.emptyList(); } - DatastoreV1.Mutation.Builder mutationPb = DatastoreV1.Mutation.newBuilder(); + List mutationsPb = new ArrayList<>(); Map completeEntities = new LinkedHashMap<>(); for (FullEntity entity : entities) { Entity completeEntity = null; @@ -180,23 +187,26 @@ public List add(FullEntity... entities) { throw DatastoreException.throwInvalidRequest( "Duplicate entity with the key %s", entity.key()); } - mutationPb.addInsert(completeEntity.toPb()); + mutationsPb.add(com.google.datastore.v1beta3.Mutation.newBuilder() + .setInsert(completeEntity.toPb()).build()); } else { Preconditions.checkArgument(entity.hasKey(), "entity %s is missing a key", entity); - mutationPb.addInsertAutoId(entity.toPb()); + mutationsPb.add(com.google.datastore.v1beta3.Mutation.newBuilder() + .setInsert(entity.toPb()).build()); } } - DatastoreV1.CommitResponse commitResponse = commitMutation(mutationPb); - Iterator allocatedKeys = - commitResponse.getMutationResult().getInsertAutoIdKeyList().iterator(); + com.google.datastore.v1beta3.CommitResponse commitResponse = commitMutation(mutationsPb); + Iterator mutationResults = + commitResponse.getMutationResultsList().iterator(); ImmutableList.Builder responseBuilder = ImmutableList.builder(); for (FullEntity entity : entities) { Entity completeEntity = completeEntities.get(entity.key()); if (completeEntity != null) { responseBuilder.add(completeEntity); + mutationResults.next(); } else { - // TODO(ajaykannan): fix me! - //responseBuilder.add(Entity.builder(Key.fromPb(allocatedKeys.next()), entity).build()); + responseBuilder.add( + Entity.builder(Key.fromPb(mutationResults.next().getKey()), entity).build()); } } return responseBuilder.build(); @@ -217,37 +227,37 @@ public List fetch(Key... keys) { return DatastoreHelper.fetch(this, keys); } - Iterator get(DatastoreV1.ReadOptions readOptionsPb, final Key... keys) { + Iterator get(com.google.datastore.v1beta3.ReadOptions readOptionsPb, final Key... keys) { if (keys.length == 0) { return Collections.emptyIterator(); } - DatastoreV1.LookupRequest.Builder requestPb = DatastoreV1.LookupRequest.newBuilder(); + com.google.datastore.v1beta3.LookupRequest.Builder requestPb = + com.google.datastore.v1beta3.LookupRequest.newBuilder(); if (readOptionsPb != null) { requestPb.setReadOptions(readOptionsPb); } for (Key k : Sets.newLinkedHashSet(Arrays.asList(keys))) { - // TODO(ajaykannan): fix me! - //requestPb.addKey(k.toPb()); + requestPb.addKeys(k.toPb()); } return new ResultsIterator(requestPb); } final class ResultsIterator extends AbstractIterator { - private final DatastoreV1.LookupRequest.Builder requestPb; - Iterator iter; + private final com.google.datastore.v1beta3.LookupRequest.Builder requestPb; + Iterator iter; - ResultsIterator(DatastoreV1.LookupRequest.Builder requestPb) { + ResultsIterator(com.google.datastore.v1beta3.LookupRequest.Builder requestPb) { this.requestPb = requestPb; loadResults(); } private void loadResults() { - DatastoreV1.LookupResponse responsePb = lookup(requestPb.build()); + com.google.datastore.v1beta3.LookupResponse responsePb = lookup(requestPb.build()); iter = responsePb.getFoundList().iterator(); - requestPb.clearKey(); + requestPb.clearKeys(); if (responsePb.getDeferredCount() > 0) { - requestPb.addAllKey(responsePb.getDeferredList()); + requestPb.addAllKeys(responsePb.getDeferredList()); } } @@ -255,7 +265,7 @@ private void loadResults() { @Override protected Entity computeNext() { while (!iter.hasNext()) { - if (requestPb.getKeyCount() == 0) { + if (requestPb.getKeysCount() == 0) { return endOfData(); } loadResults(); @@ -264,10 +274,13 @@ protected Entity computeNext() { } } - DatastoreV1.LookupResponse lookup(final DatastoreV1.LookupRequest requestPb) { + com.google.datastore.v1beta3.LookupResponse lookup( + final com.google.datastore.v1beta3.LookupRequest requestPb) { try { - return RetryHelper.runWithRetries(new Callable() { - @Override public DatastoreV1.LookupResponse call() throws DatastoreRpcException { + return RetryHelper.runWithRetries( + new Callable() { + @Override public com.google.datastore.v1beta3.LookupResponse call() + throws DatastoreRpcException { return datastoreRpc.lookup(requestPb); } }, retryParams, EXCEPTION_HANDLER); @@ -280,15 +293,17 @@ DatastoreV1.LookupResponse lookup(final DatastoreV1.LookupRequest requestPb) { @Override public final void update(Entity... entities) { if (entities.length > 0) { - DatastoreV1.Mutation.Builder mutationPb = DatastoreV1.Mutation.newBuilder(); + List mutationsPb = + new ArrayList<>(); Map dedupEntities = new LinkedHashMap<>(); for (Entity entity : entities) { dedupEntities.put(entity.key(), entity); } for (Entity entity : dedupEntities.values()) { - mutationPb.addUpdate(entity.toPb()); + mutationsPb.add( + com.google.datastore.v1beta3.Mutation.newBuilder().setUpdate(entity.toPb()).build()); } - commitMutation(mutationPb); + commitMutation(mutationsPb); } } @@ -296,28 +311,30 @@ public final void update(Entity... entities) { @Override public final void put(Entity... entities) { if (entities.length > 0) { - DatastoreV1.Mutation.Builder mutationPb = DatastoreV1.Mutation.newBuilder(); + List mutationsPb = + new ArrayList<>(); Map dedupEntities = new LinkedHashMap<>(); for (Entity entity : entities) { dedupEntities.put(entity.key(), entity); } for (Entity e : dedupEntities.values()) { - mutationPb.addUpsert(e.toPb()); + mutationsPb.add( + com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(e.toPb()).build()); } - commitMutation(mutationPb); + commitMutation(mutationsPb); } } @Override public void delete(Key... keys) { if (keys.length > 0) { - DatastoreV1.Mutation.Builder mutationPb = DatastoreV1.Mutation.newBuilder(); + List mutationsPb = new ArrayList<>(); Set dedupKeys = new LinkedHashSet<>(Arrays.asList(keys)); for (Key key : dedupKeys) { - // TODO(ajaykannan): fix me! - //mutationPb.addDelete(key.toPb()); + mutationsPb.add( + com.google.datastore.v1beta3.Mutation.newBuilder().setDelete(key.toPb()).build()); } - commitMutation(mutationPb); + commitMutation(mutationsPb); } } @@ -326,20 +343,22 @@ public KeyFactory newKeyFactory() { return DatastoreHelper.newKeyFactory(options()); } - private DatastoreV1.CommitResponse commitMutation(DatastoreV1.Mutation.Builder mutationPb) { - if (options().force()) { - mutationPb.setForce(true); - } - DatastoreV1.CommitRequest.Builder requestPb = DatastoreV1.CommitRequest.newBuilder(); - requestPb.setMode(DatastoreV1.CommitRequest.Mode.NON_TRANSACTIONAL); - requestPb.setMutation(mutationPb); + private com.google.datastore.v1beta3.CommitResponse commitMutation( + List mutationsPb) { + com.google.datastore.v1beta3.CommitRequest.Builder requestPb = + com.google.datastore.v1beta3.CommitRequest.newBuilder(); + requestPb.setMode(com.google.datastore.v1beta3.CommitRequest.Mode.NON_TRANSACTIONAL); + requestPb.addAllMutations(mutationsPb); return commit(requestPb.build()); } - DatastoreV1.CommitResponse commit(final DatastoreV1.CommitRequest requestPb) { + com.google.datastore.v1beta3.CommitResponse commit( + final com.google.datastore.v1beta3.CommitRequest requestPb) { try { - return RetryHelper.runWithRetries(new Callable() { - @Override public DatastoreV1.CommitResponse call() throws DatastoreRpcException { + return RetryHelper.runWithRetries( + new Callable() { + @Override public com.google.datastore.v1beta3.CommitResponse call() + throws DatastoreRpcException { return datastoreRpc.commit(requestPb); } }, retryParams, EXCEPTION_HANDLER); @@ -348,16 +367,19 @@ DatastoreV1.CommitResponse commit(final DatastoreV1.CommitRequest requestPb) { } } - ByteString requestTransactionId(DatastoreV1.BeginTransactionRequest.Builder requestPb) { + ByteString requestTransactionId( + com.google.datastore.v1beta3.BeginTransactionRequest.Builder requestPb) { return beginTransaction(requestPb.build()).getTransaction(); } - DatastoreV1.BeginTransactionResponse beginTransaction( - final DatastoreV1.BeginTransactionRequest requestPb) { + com.google.datastore.v1beta3.BeginTransactionResponse beginTransaction( + final com.google.datastore.v1beta3.BeginTransactionRequest requestPb) { try { - return RetryHelper.runWithRetries(new Callable() { + return RetryHelper.runWithRetries( + new Callable() { @Override - public DatastoreV1.BeginTransactionResponse call() throws DatastoreRpcException { + public com.google.datastore.v1beta3.BeginTransactionResponse call() + throws DatastoreRpcException { return datastoreRpc.beginTransaction(requestPb); } }, retryParams, EXCEPTION_HANDLER); @@ -367,12 +389,13 @@ public DatastoreV1.BeginTransactionResponse call() throws DatastoreRpcException } void rollbackTransaction(ByteString transaction) { - DatastoreV1.RollbackRequest.Builder requestPb = DatastoreV1.RollbackRequest.newBuilder(); + com.google.datastore.v1beta3.RollbackRequest.Builder requestPb = + com.google.datastore.v1beta3.RollbackRequest.newBuilder(); requestPb.setTransaction(transaction); rollback(requestPb.build()); } - void rollback(final DatastoreV1.RollbackRequest requestPb) { + void rollback(final com.google.datastore.v1beta3.RollbackRequest requestPb) { try { RetryHelper.runWithRetries(new Callable() { @Override public Void call() throws DatastoreRpcException { diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java index 7b0dd3a2a606..23128a856761 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java @@ -18,9 +18,7 @@ import static com.google.gcloud.datastore.Validator.validateNamespace; -import com.google.api.services.datastore.DatastoreV1; -import com.google.api.services.datastore.DatastoreV1.EntityResult; -import com.google.api.services.datastore.DatastoreV1.LookupResponse; +import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.gcloud.ServiceOptions; @@ -102,21 +100,23 @@ private DatastoreOptions normalize() { Builder builder = toBuilder(); builder.normalizeDataset(false); // Replace provided project-id with full project-id (s~xxx, e~xxx,...) - DatastoreV1.LookupRequest.Builder requestPb = DatastoreV1.LookupRequest.newBuilder(); - DatastoreV1.Key key = DatastoreV1.Key.newBuilder() - .addPathElement(DatastoreV1.Key.PathElement.newBuilder().setKind("__foo__").setName("bar")) + com.google.datastore.v1beta3.LookupRequest.Builder requestPb = + com.google.datastore.v1beta3.LookupRequest.newBuilder(); + com.google.datastore.v1beta3.Key key = com.google.datastore.v1beta3.Key.newBuilder() + .addPath(com.google.datastore.v1beta3.Key.PathElement.newBuilder() + .setKind("__foo__").setName("bar")) .build(); - requestPb.addKey(key); + requestPb.addKeys(key); try { - LookupResponse responsePb = datastoreRpc().lookup(requestPb.build()); + com.google.datastore.v1beta3.LookupResponse responsePb = datastoreRpc().lookup(requestPb.build()); if (responsePb.getDeferredCount() > 0) { key = responsePb.getDeferred(0); } else { - Iterator combinedIter = + Iterator combinedIter = Iterables.concat(responsePb.getMissingList(), responsePb.getFoundList()).iterator(); key = combinedIter.next().getEntity().getKey(); } - builder.projectId(key.getPartitionId().getDatasetId()); + builder.projectId(key.getPartitionId().getProjectId()); return new DatastoreOptions(builder); } catch (DatastoreRpcException e) { throw DatastoreException.translateAndThrow(e); @@ -149,10 +149,10 @@ private static String defaultNamespace() { Class clazz = Class.forName("com.google.appengine.api.NamespaceManager"); Method method = clazz.getMethod("get"); String namespace = (String) method.invoke(null); - return namespace == null || namespace.isEmpty() ? null : namespace; + return MoreObjects.firstNonNull(namespace, ""); } catch (Exception ignore) { - // return null (Datastore default namespace) if could not automatically determine - return null; + // return empty string (Datastore default namespace) if could not automatically determine + return ""; } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Entity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Entity.java index dc1af5b8a2d9..d012eff14422 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Entity.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Entity.java @@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.base.Preconditions; /** @@ -93,7 +92,7 @@ public static Builder builder(Key key, FullEntity copyFrom) { return new Builder(key, copyFrom); } - static Entity fromPb(DatastoreV1.Entity entityPb) { + static Entity fromPb(com.google.datastore.v1beta3.Entity entityPb) { return new Builder().fill(entityPb).build(); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java index 16ca55aec4a6..4a327383afd4 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java @@ -39,15 +39,12 @@ public Builder newBuilder(FullEntity value) { @Override protected FullEntity getValue(com.google.datastore.v1beta3.Value from) { - // TODO(ajaykannan): fix me! - //return FullEntity.fromPb(from.getEntityValue()); - return null; // TODO(ajaykannan): fix me! + return FullEntity.fromPb(from.getEntityValue()); } @Override protected void setValue(EntityValue from, com.google.datastore.v1beta3.Value.Builder to) { - // TODO(ajaykannan): fix me! - //to.setEntityValue(from.get().toPb()); + to.setEntityValue(from.get().toPb()); } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/FullEntity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/FullEntity.java index bb08fca12e3c..b1534984aeb0 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/FullEntity.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/FullEntity.java @@ -16,8 +16,6 @@ package com.google.gcloud.datastore; -import com.google.api.services.datastore.DatastoreV1; - /** * A full entity is a {@link BaseEntity} that with a complete set of properties. */ @@ -70,7 +68,7 @@ public static Builder builder(FullEntity copyFro } - static FullEntity fromPb(DatastoreV1.Entity entityPb) { + static FullEntity fromPb(com.google.datastore.v1beta3.Entity entityPb) { return new Builder<>().fill(entityPb).build(); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntity.java index 46a528617a0c..f8af814245ab 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntity.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntity.java @@ -16,7 +16,6 @@ package com.google.gcloud.datastore; -import com.google.api.services.datastore.DatastoreV1; import com.google.protobuf.ByteString; /** @@ -72,7 +71,7 @@ public Blob getBlob(String name) { return ((Value) value).get(); } - static ProjectionEntity fromPb(DatastoreV1.Entity entityPb) { + static ProjectionEntity fromPb(com.google.datastore.v1beta3.Entity entityPb) { return new Builder().fill(entityPb).build(); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java index f3dd254ce9a3..7fae120dd402 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java @@ -69,7 +69,9 @@ public abstract static class ResultType implements java.io.Serializable { //TODO(ajaykannan): fix me! //return Key.fromPb(entityPb.getKey()); } - return ProjectionEntity.fromPb(entityPb); + // TODO(ajaykannan): fix me! + //return ProjectionEntity.fromPb(entityPb); + return ProjectionEntity.fromPb((com.google.datastore.v1beta3.Entity) null); // TODO(ajaykannan): fix me! } }; @@ -79,7 +81,9 @@ public abstract static class ResultType implements java.io.Serializable { private static final long serialVersionUID = 7712959777507168274L; @Override protected Entity convert(DatastoreV1.Entity entityPb) { - return Entity.fromPb(entityPb); + // TODO(ajaykannan): fix me! + //return Entity.fromPb(entityPb); + return Entity.fromPb((com.google.datastore.v1beta3.Entity) null); // TODO(ajaykannan): fix me! } }; @@ -102,7 +106,9 @@ public abstract static class ResultType implements java.io.Serializable { private static final long serialVersionUID = -7591409419690650246L; @Override protected ProjectionEntity convert(DatastoreV1.Entity entityPb) { - return ProjectionEntity.fromPb(entityPb); + // TODO(ajaykannan): fix me! + //return ProjectionEntity.fromPb(entityPb); + return ProjectionEntity.fromPb((com.google.datastore.v1beta3.Entity) null); // TODO(ajaykannan): fix me! } }; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java index cd3fe9dd776b..caf5d7f8a84f 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java @@ -63,7 +63,8 @@ private void sendRequest() { } requestPb.setPartitionId(partitionIdPb); query.populatePb(requestPb); - queryResultBatchPb = datastore.runQuery(requestPb.build()).getBatch(); + // TODO(ajaykannan): fix me! + //queryResultBatchPb = datastore.runQuery(requestPb.build()).getBatch(); lastBatch = queryResultBatchPb.getMoreResults() != MoreResultsType.NOT_FINISHED; entityResultPbIter = queryResultBatchPb.getEntityResultList().iterator(); // cursor = resultPb.getSkippedCursor(); // available in v1beta3, use startCursor if not skipped diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java index ae9d0e50f0d7..ff9ce5e50e9d 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java @@ -16,58 +16,45 @@ package com.google.gcloud.datastore; -import com.google.api.services.datastore.DatastoreV1; -import com.google.common.base.Function; -import com.google.common.collect.Lists; -import com.google.gcloud.datastore.TransactionOption.ForceWrites; -import com.google.gcloud.datastore.TransactionOption.IsolationLevel; import com.google.protobuf.ByteString; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; -import java.util.Map; final class TransactionImpl extends BaseDatastoreBatchWriter implements Transaction { private final DatastoreImpl datastore; private final ByteString transaction; - private final boolean force; private boolean rolledback; static class ResponseImpl implements Transaction.Response { - private final DatastoreV1.CommitResponse response; + private final com.google.datastore.v1beta3.CommitResponse response; + private final int numAutoAllocatedIds; - ResponseImpl(DatastoreV1.CommitResponse response) { + ResponseImpl(com.google.datastore.v1beta3.CommitResponse response, int numAutoAllocatedIds) { this.response = response; + this.numAutoAllocatedIds = numAutoAllocatedIds; } @Override public List generatedKeys() { - return Lists.transform(response.getMutationResult().getInsertAutoIdKeyList(), - new Function() { - @Override public Key apply(DatastoreV1.Key keyPb) { - // TODO(ajaykannan): fix me! - //return Key.fromPb(keyPb); - return Key.builder(null).build(); // TODO(ajaykannan): fix me! - } - }); + Iterator results = + response.getMutationResultsList().iterator(); + List generated = new LinkedList(); + for (int i = 0; i < numAutoAllocatedIds; i++) { + generated.add(Key.fromPb(results.next().getKey())); + } + return generated; } } - TransactionImpl(DatastoreImpl datastore, TransactionOption... options) { + TransactionImpl(DatastoreImpl datastore) { super("transaction"); this.datastore = datastore; - DatastoreV1.BeginTransactionRequest.Builder requestPb = - DatastoreV1.BeginTransactionRequest.newBuilder(); - Map, TransactionOption> optionsMap = - TransactionOption.asImmutableMap(options); - IsolationLevel isolationLevel = (IsolationLevel) optionsMap.get(IsolationLevel.class); - if (isolationLevel != null) { - requestPb.setIsolationLevel(isolationLevel.level().toPb()); - } - ForceWrites forceWrites = (ForceWrites) optionsMap.get(TransactionOption.ForceWrites.class); - force = forceWrites != null && forceWrites.force(); + com.google.datastore.v1beta3.BeginTransactionRequest.Builder requestPb = + com.google.datastore.v1beta3.BeginTransactionRequest.newBuilder(); transaction = datastore.requestTransactionId(requestPb); } @@ -79,7 +66,8 @@ public Entity get(Key key) { @Override public Iterator get(Key... keys) { validateActive(); - DatastoreV1.ReadOptions.Builder readOptionsPb = DatastoreV1.ReadOptions.newBuilder(); + com.google.datastore.v1beta3.ReadOptions.Builder readOptionsPb = + com.google.datastore.v1beta3.ReadOptions.newBuilder(); readOptionsPb.setTransaction(transaction); return datastore.get(readOptionsPb.build(), keys); } @@ -93,7 +81,8 @@ public List fetch(Key... keys) { @Override public QueryResults run(Query query) { validateActive(); - DatastoreV1.ReadOptions.Builder readOptionsPb = DatastoreV1.ReadOptions.newBuilder(); + com.google.datastore.v1beta3.ReadOptions.Builder readOptionsPb = + com.google.datastore.v1beta3.ReadOptions.newBuilder(); readOptionsPb.setTransaction(transaction); return datastore.run(readOptionsPb.build(), query); } @@ -101,17 +90,15 @@ public QueryResults run(Query query) { @Override public Transaction.Response commit() { validateActive(); - DatastoreV1.Mutation.Builder mutationPb = toMutationPb(); - if (force) { - mutationPb.setForce(force); - } - DatastoreV1.CommitRequest.Builder requestPb = DatastoreV1.CommitRequest.newBuilder(); - requestPb.setMode(DatastoreV1.CommitRequest.Mode.TRANSACTIONAL); + List mutationsPb = toMutationPbList(); + com.google.datastore.v1beta3.CommitRequest.Builder requestPb = + com.google.datastore.v1beta3.CommitRequest.newBuilder(); + requestPb.setMode(com.google.datastore.v1beta3.CommitRequest.Mode.TRANSACTIONAL); requestPb.setTransaction(transaction); - requestPb.setMutation(mutationPb); - DatastoreV1.CommitResponse responsePb = datastore.commit(requestPb.build()); + requestPb.addAllMutations(mutationsPb); + com.google.datastore.v1beta3.CommitResponse responsePb = datastore.commit(requestPb.build()); deactivate(); - return new ResponseImpl(responsePb); + return new ResponseImpl(responsePb, numAutoAllocatedIds()); } @Override diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionOption.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionOption.java deleted file mode 100644 index c1c8368213dc..000000000000 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionOption.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * 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.gcloud.datastore; - -import com.google.api.services.datastore.DatastoreV1; -import com.google.common.collect.ImmutableMap; - -import java.io.Serializable; -import java.util.Map; - - -public abstract class TransactionOption implements Serializable { - - private static final long serialVersionUID = -1862234444015690375L; - - public static final class ForceWrites extends TransactionOption { - - private static final long serialVersionUID = -6873967516988380886L; - - private final boolean force; - - public ForceWrites(boolean force) { - this.force = force; - } - - public boolean force() { - return force; - } - - @Override - BatchOption toBatchWriteOption() { - return new BatchOption.ForceWrites(force); - } - } - - public static final class IsolationLevel extends TransactionOption { - - private static final long serialVersionUID = -5592165378565409515L; - - private final Level level; - - public enum Level { - - SERIALIZABLE(DatastoreV1.BeginTransactionRequest.IsolationLevel.SERIALIZABLE), - SNAPSHOT(DatastoreV1.BeginTransactionRequest.IsolationLevel.SNAPSHOT); - - private final DatastoreV1.BeginTransactionRequest.IsolationLevel levelPb; - - Level(DatastoreV1.BeginTransactionRequest.IsolationLevel levelPb) { - this.levelPb = levelPb; - } - - DatastoreV1.BeginTransactionRequest.IsolationLevel toPb() { - return levelPb; - } - } - - public IsolationLevel(Level level) { - this.level = level; - } - - - public Level level() { - return level; - } - - @Override - BatchOption toBatchWriteOption() { - return null; - } - } - - TransactionOption() { - // package protected - } - - public static ForceWrites forceWrites() { - return new ForceWrites(true); - } - - public static IsolationLevel serializable() { - return new IsolationLevel(IsolationLevel.Level.SERIALIZABLE); - } - - public static IsolationLevel snapshot() { - return new IsolationLevel(IsolationLevel.Level.SNAPSHOT); - } - - static Map, TransactionOption> asImmutableMap( - TransactionOption... options) { - ImmutableMap.Builder, TransactionOption> builder = - ImmutableMap.builder(); - for (TransactionOption option : options) { - builder.put(option.getClass(), option); - } - return builder.build(); - } - - abstract BatchOption toBatchWriteOption(); -} diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DatastoreRpc.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DatastoreRpc.java index dffcc3f0e16f..329623a565f6 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DatastoreRpc.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DatastoreRpc.java @@ -15,19 +15,6 @@ */ package com.google.gcloud.spi; -import com.google.api.services.datastore.DatastoreV1.AllocateIdsRequest; -import com.google.api.services.datastore.DatastoreV1.AllocateIdsResponse; -import com.google.api.services.datastore.DatastoreV1.BeginTransactionRequest; -import com.google.api.services.datastore.DatastoreV1.BeginTransactionResponse; -import com.google.api.services.datastore.DatastoreV1.CommitRequest; -import com.google.api.services.datastore.DatastoreV1.CommitResponse; -import com.google.api.services.datastore.DatastoreV1.LookupRequest; -import com.google.api.services.datastore.DatastoreV1.LookupResponse; -import com.google.api.services.datastore.DatastoreV1.RollbackRequest; -import com.google.api.services.datastore.DatastoreV1.RollbackResponse; -import com.google.api.services.datastore.DatastoreV1.RunQueryRequest; -import com.google.api.services.datastore.DatastoreV1.RunQueryResponse; - /** * Provides access to the remote Datastore service. */ @@ -103,16 +90,22 @@ public boolean retryable() { } } - AllocateIdsResponse allocateIds(AllocateIdsRequest request) throws DatastoreRpcException; + com.google.datastore.v1beta3.AllocateIdsResponse allocateIds( + com.google.datastore.v1beta3.AllocateIdsRequest request) throws DatastoreRpcException; - BeginTransactionResponse beginTransaction(BeginTransactionRequest request) + com.google.datastore.v1beta3.BeginTransactionResponse beginTransaction( + com.google.datastore.v1beta3.BeginTransactionRequest request) throws DatastoreRpcException; - CommitResponse commit(CommitRequest request) throws DatastoreRpcException; + com.google.datastore.v1beta3.CommitResponse commit( + com.google.datastore.v1beta3.CommitRequest request) throws DatastoreRpcException; - LookupResponse lookup(LookupRequest request) throws DatastoreRpcException; + com.google.datastore.v1beta3.LookupResponse lookup( + com.google.datastore.v1beta3.LookupRequest request) throws DatastoreRpcException; - RollbackResponse rollback(RollbackRequest request) throws DatastoreRpcException; + com.google.datastore.v1beta3.RollbackResponse rollback( + com.google.datastore.v1beta3.RollbackRequest request) throws DatastoreRpcException; - RunQueryResponse runQuery(RunQueryRequest request) throws DatastoreRpcException; + com.google.datastore.v1beta3.RunQueryResponse runQuery( + com.google.datastore.v1beta3.RunQueryRequest request) throws DatastoreRpcException; } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java index 2f245260b325..1ae0b6eea22e 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java @@ -16,36 +16,16 @@ package com.google.gcloud.spi; -import com.google.api.services.datastore.DatastoreV1.AllocateIdsRequest; -import com.google.api.services.datastore.DatastoreV1.AllocateIdsResponse; -import com.google.api.services.datastore.DatastoreV1.BeginTransactionRequest; -import com.google.api.services.datastore.DatastoreV1.BeginTransactionResponse; -import com.google.api.services.datastore.DatastoreV1.CommitRequest; -import com.google.api.services.datastore.DatastoreV1.CommitResponse; -import com.google.api.services.datastore.DatastoreV1.LookupRequest; -import com.google.api.services.datastore.DatastoreV1.LookupResponse; -import com.google.api.services.datastore.DatastoreV1.RollbackRequest; -import com.google.api.services.datastore.DatastoreV1.RollbackResponse; -import com.google.api.services.datastore.DatastoreV1.RunQueryRequest; -import com.google.api.services.datastore.DatastoreV1.RunQueryResponse; -import com.google.api.services.datastore.client.Datastore; -import com.google.api.services.datastore.client.DatastoreException; -import com.google.api.services.datastore.client.DatastoreFactory; -import com.google.api.services.datastore.client.DatastoreOptions.Builder; import com.google.common.collect.ImmutableMap; import com.google.gcloud.datastore.DatastoreOptions; import com.google.gcloud.spi.DatastoreRpc.DatastoreRpcException.Reason; -import org.json.JSONException; -import org.json.JSONObject; -import org.json.JSONTokener; - import java.util.HashMap; import java.util.Map; public class DefaultDatastoreRpc implements DatastoreRpc { - private final Datastore client; + private final com.google.datastore.v1beta3.client.Datastore client; private static final ImmutableMap STR_TO_REASON; private static final ImmutableMap HTTP_STATUS_TO_REASON; @@ -62,26 +42,27 @@ public class DefaultDatastoreRpc implements DatastoreRpc { } public DefaultDatastoreRpc(DatastoreOptions options) { - client = DatastoreFactory.get().create( - new Builder() - .dataset(options.projectId()) - .host(options.host()) - .initializer(options.httpRequestInitializer()) - .build()); + if (options.host().contains("localhost")) { + client = com.google.datastore.v1beta3.client.DatastoreFactory.get().create( + new com.google.datastore.v1beta3.client.DatastoreOptions.Builder() + .projectId(options.projectId()) + .localHost(options.host()) + .initializer(options.httpRequestInitializer()) + .build()); + } else { + client = com.google.datastore.v1beta3.client.DatastoreFactory.get().create( + new com.google.datastore.v1beta3.client.DatastoreOptions.Builder() + .projectId(options.projectId()) + .initializer(options.httpRequestInitializer()) + .build()); + } } - private static DatastoreRpcException translate(DatastoreException exception) { - String message = exception.getMessage(); + private static DatastoreRpcException translate( + com.google.datastore.v1beta3.client.DatastoreException exception) { String reasonStr = ""; - if (message != null) { - try { - JSONObject json = new JSONObject(new JSONTokener(message)); - JSONObject error = json.getJSONObject("error").getJSONArray("errors").getJSONObject(0); - reasonStr = error.getString("reason"); - message = error.getString("message"); - } catch (JSONException ignore) { - // ignore - will be converted to unknown - } + if (exception.getCode() != null) { + reasonStr = exception.getCode().name(); } Reason reason = STR_TO_REASON.get(reasonStr); if (reason == null) { @@ -89,61 +70,68 @@ private static DatastoreRpcException translate(DatastoreException exception) { } return reason != null ? new DatastoreRpcException(reason) - : new DatastoreRpcException("Unknown", exception.getCode(), false, message); + : new DatastoreRpcException("Unknown", + exception.getCode().ordinal(), + false, + exception.getMessage()); } @Override - public AllocateIdsResponse allocateIds(AllocateIdsRequest request) - throws DatastoreRpcException { + public com.google.datastore.v1beta3.AllocateIdsResponse allocateIds( + com.google.datastore.v1beta3.AllocateIdsRequest request) throws DatastoreRpcException { try { return client.allocateIds(request); - } catch (DatastoreException ex) { + } catch (com.google.datastore.v1beta3.client.DatastoreException ex) { throw translate(ex); } } @Override - public BeginTransactionResponse beginTransaction(BeginTransactionRequest request) - throws DatastoreRpcException { + public com.google.datastore.v1beta3.BeginTransactionResponse beginTransaction( + com.google.datastore.v1beta3.BeginTransactionRequest request) throws DatastoreRpcException { try { return client.beginTransaction(request); - } catch (DatastoreException ex) { + } catch (com.google.datastore.v1beta3.client.DatastoreException ex) { throw translate(ex); } } @Override - public CommitResponse commit(CommitRequest request) throws DatastoreRpcException { + public com.google.datastore.v1beta3.CommitResponse commit( + com.google.datastore.v1beta3.CommitRequest request) throws DatastoreRpcException { try { return client.commit(request); - } catch (DatastoreException ex) { + } catch (com.google.datastore.v1beta3.client.DatastoreException ex) { throw translate(ex); } } @Override - public LookupResponse lookup(LookupRequest request) throws DatastoreRpcException { + public com.google.datastore.v1beta3.LookupResponse lookup( + com.google.datastore.v1beta3.LookupRequest request) throws DatastoreRpcException { try { return client.lookup(request); - } catch (DatastoreException ex) { + } catch (com.google.datastore.v1beta3.client.DatastoreException ex) { throw translate(ex); } } @Override - public RollbackResponse rollback(RollbackRequest request) throws DatastoreRpcException { + public com.google.datastore.v1beta3.RollbackResponse rollback( + com.google.datastore.v1beta3.RollbackRequest request) throws DatastoreRpcException { try { return client.rollback(request); - } catch (DatastoreException ex) { + } catch (com.google.datastore.v1beta3.client.DatastoreException ex) { throw translate(ex); } } @Override - public RunQueryResponse runQuery(RunQueryRequest request) throws DatastoreRpcException { + public com.google.datastore.v1beta3.RunQueryResponse runQuery( + com.google.datastore.v1beta3.RunQueryRequest request) throws DatastoreRpcException { try { return client.runQuery(request); - } catch (DatastoreException ex) { + } catch (com.google.datastore.v1beta3.client.DatastoreException ex) { throw translate(ex); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java index 43df45d7a04e..8996f4536931 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java @@ -21,7 +21,6 @@ import static org.easymock.EasyMock.verify; import static org.junit.Assert.assertEquals; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.collect.ImmutableList; import org.easymock.EasyMock; @@ -30,6 +29,7 @@ import org.junit.Test; import java.util.List; +import java.util.LinkedList; public class BaseDatastoreBatchWriterTest { @@ -80,36 +80,33 @@ public void tearDown() { batchWriter.finish(); } - // TODO(ajaykannan): fix me! - /* @Test public void testAdd() throws Exception { Entity entity2 = Entity.builder(ENTITY2).key(Key.builder(KEY1).name("name2").build()).build(); - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addInsert(ENTITY1.toPb()) - .addInsert(entity2.toPb()) - .addInsert(Entity.builder(KEY2, INCOMPLETE_ENTITY_1).build().toPb()) - .addInsert(Entity.builder(KEY3, INCOMPLETE_ENTITY_2).build().toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setInsert(ENTITY1.toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder() + .setInsert(Entity.builder(KEY2, INCOMPLETE_ENTITY_1).build().toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder() + .setInsert(Entity.builder(KEY3, INCOMPLETE_ENTITY_2).build().toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setInsert(entity2.toPb()).build()); List entities = batchWriter .add(ENTITY1, INCOMPLETE_ENTITY_1, INCOMPLETE_ENTITY_2, entity2); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); assertEquals(ENTITY1, entities.get(0)); assertEquals(Entity.builder(KEY2, INCOMPLETE_ENTITY_1).build(), entities.get(1)); assertEquals(Entity.builder(KEY3, INCOMPLETE_ENTITY_2).build(), entities.get(2)); assertEquals(entity2, entities.get(3)); } - */ @Test public void testAddAfterDelete() throws Exception { - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addUpsert(ENTITY1.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(ENTITY1.toPb()).build()); batchWriter.delete(KEY1); batchWriter.add(ENTITY1); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test(expected = DatastoreException.class) @@ -136,18 +133,17 @@ public void testAddWhenNotActive() throws Exception { batchWriter.add(ENTITY1); } - // TODO(ajaykannan): fix me! - /* @Test public void testAddWithDeferredAllocation() throws Exception { - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addInsert(ENTITY1.toPb()) - .addInsertAutoId(INCOMPLETE_ENTITY_1.toPb()) - .addInsertAutoId(INCOMPLETE_ENTITY_2.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder() + .setInsert(INCOMPLETE_ENTITY_1.toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder() + .setInsert(INCOMPLETE_ENTITY_2.toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setInsert(ENTITY1.toPb()).build()); batchWriter.addWithDeferredIdAllocation(ENTITY1, INCOMPLETE_ENTITY_1); batchWriter.addWithDeferredIdAllocation(INCOMPLETE_ENTITY_2); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test(expected = DatastoreException.class) @@ -158,49 +154,44 @@ public void testAddWithDeferredAllocationWhenNotActive() throws Exception { @Test public void testUpdate() throws Exception { - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addUpdate(ENTITY1.toPb()) - .addUpdate(ENTITY2.toPb()) - .addUpdate(ENTITY3.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpdate(ENTITY1.toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpdate(ENTITY2.toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpdate(ENTITY3.toPb()).build()); batchWriter.update(ENTITY1, ENTITY2); batchWriter.update(ENTITY3); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test public void testUpdateAfterUpdate() throws Exception { Entity entity = Entity.builder(ENTITY1).set("foo", "bar").build(); - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addUpdate(entity.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpdate(entity.toPb()).build()); batchWriter.update(ENTITY1); batchWriter.update(entity); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test public void testUpdateAfterAdd() throws Exception { Entity entity = Entity.builder(ENTITY1).set("foo", "bar").build(); - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addUpsert(entity.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(entity.toPb()).build()); batchWriter.add(ENTITY1); batchWriter.update(entity); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test public void testUpdateAfterPut() throws Exception { Entity entity = Entity.builder(ENTITY1).set("foo", "bar").build(); - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addUpsert(entity.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(entity.toPb()).build()); batchWriter.put(ENTITY1); batchWriter.update(entity); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } - */ @Test(expected = DatastoreException.class) public void testUpdateAfterDelete() throws Exception { @@ -214,117 +205,104 @@ public void testUpdateWhenNotActive() throws Exception { batchWriter.update(ENTITY1); } - // TODO(ajaykannan): fix me! - /* @Test public void testPut() throws Exception { - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addUpsert(ENTITY1.toPb()) - .addUpsert(ENTITY2.toPb()) - .addUpsert(ENTITY3.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(ENTITY1.toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(ENTITY2.toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(ENTITY3.toPb()).build()); batchWriter.put(ENTITY1, ENTITY2); batchWriter.put(ENTITY3); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test public void testPutAfterPut() throws Exception { Entity entity = Entity.builder(ENTITY1).set("foo", "bar").build(); - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addUpsert(entity.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(entity.toPb()).build()); batchWriter.put(ENTITY1); batchWriter.put(entity); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test public void testPutAfterAdd() throws Exception { Entity entity = Entity.builder(ENTITY1).set("foo", "bar").build(); - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addUpsert(entity.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(entity.toPb()).build()); batchWriter.add(ENTITY1); batchWriter.put(entity); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test public void testPutAfterUpdate() throws Exception { Entity entity = Entity.builder(ENTITY1).set("foo", "bar").build(); - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addUpsert(entity.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(entity.toPb()).build()); batchWriter.update(ENTITY1); batchWriter.put(entity); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test public void testPutAfterDelete() throws Exception { Entity entity = Entity.builder(ENTITY1).set("foo", "bar").build(); - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addUpsert(entity.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(entity.toPb()).build()); batchWriter.delete(KEY1); batchWriter.put(entity); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } - */ @Test(expected = DatastoreException.class) public void testPutWhenNotActive() throws Exception { batchWriter.deactivate(); batchWriter.put(ENTITY1); } - // TODO(ajaykannan): fix me! - /* + @Test public void testDelete() throws Exception { - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addDelete(KEY1.toPb()) - .addDelete(KEY2.toPb()) - .addDelete(KEY3.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setDelete(KEY1.toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setDelete(KEY2.toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setDelete(KEY3.toPb()).build()); batchWriter.delete(KEY1, KEY2); batchWriter.delete(KEY3); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test public void testDeleteAfterAdd() throws Exception { - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addInsertAutoId(INCOMPLETE_ENTITY_1.toPb()) - .addDelete(KEY1.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder() + .setInsert(INCOMPLETE_ENTITY_1.toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setDelete(KEY1.toPb()).build()); batchWriter.add(ENTITY1); batchWriter.addWithDeferredIdAllocation(INCOMPLETE_ENTITY_1); batchWriter.delete(KEY1); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test public void testDeleteAfterUpdate() throws Exception { - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addDelete(KEY1.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setDelete(KEY1.toPb()).build()); batchWriter.update(ENTITY1); batchWriter.delete(KEY1); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } @Test public void testDeleteAfterPut() throws Exception { - DatastoreV1.Mutation pb = DatastoreV1.Mutation.newBuilder() - .addDelete(KEY1.toPb()) - .build(); + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setDelete(KEY1.toPb()).build()); batchWriter.put(ENTITY1); batchWriter.delete(KEY1); - assertEquals(pb, batchWriter.toMutationPb().build()); + assertEquals(pbs, batchWriter.toMutationPbList()); } - */ @Test(expected = DatastoreException.class) public void testDeleteWhenNotActive() throws Exception { diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java index 79576748bb58..c8773243ed69 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java @@ -17,7 +17,6 @@ package com.google.gcloud.datastore; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import com.google.common.collect.ImmutableList; diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java index e7dc71c50ff6..97aeec3ee129 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java @@ -65,7 +65,7 @@ public void testHost() throws Exception { @Test public void testNamespace() throws Exception { - assertNull(options.build().namespace()); + assertTrue(options.build().namespace().isEmpty()); assertEquals("ns1", options.namespace("ns1").build().namespace()); } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index 57342ed3e26d..689d2a7b8b6b 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -14,8 +14,6 @@ * limitations under the License. */ -// TODO(ajaykannan): fix me! -/* package com.google.gcloud.datastore; import static org.junit.Assert.assertEquals; @@ -27,8 +25,6 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import com.google.api.services.datastore.DatastoreV1; -import com.google.api.services.datastore.DatastoreV1.EntityResult; import com.google.common.collect.Iterators; import com.google.gcloud.RetryParams; import com.google.gcloud.datastore.Query.ResultType; @@ -116,12 +112,12 @@ public static void beforeClass() throws IOException, InterruptedException { public void setUp() throws IOException, InterruptedException { options = DatastoreOptions.builder() .projectId(PROJECT_ID) - .host("http://localhost:" + LocalGcdHelper.PORT) + .host("localhost:" + LocalGcdHelper.PORT) .build(); datastore = DatastoreFactory.instance().get(options); - StructuredQuery query = Query.keyQueryBuilder().build(); - QueryResults result = datastore.run(query); - datastore.delete(Iterators.toArray(result, Key.class)); + //StructuredQuery query = Query.keyQueryBuilder().build(); + //QueryResults result = datastore.run(query); + //datastore.delete(Iterators.toArray(result, Key.class)); datastore.add(ENTITY1, ENTITY2); } @@ -192,7 +188,7 @@ public void testTransactionWithRead() { assertEquals(DatastoreException.Code.ABORTED, expected.code()); } } - + /* TODO(ajaykannan): fix me! @Test public void testTransactionWithQuery() { Query query = Query.entityQueryBuilder() @@ -220,7 +216,7 @@ public void testTransactionWithQuery() { assertEquals(DatastoreException.Code.ABORTED, expected.code()); } } - + */ @Test public void testNewTransactionRollback() { Transaction transaction = datastore.newTransaction(); @@ -335,7 +331,7 @@ public void testNewBatch() { assertNull(entities.get(4)); assertEquals(5, entities.size()); } - + /* TODO(ajaykannan): fix me! @Test public void testRunGqlQueryNoCasting() { Query query1 = Query.gqlQueryBuilder(ResultType.ENTITY, "select * from " + KIND1).build(); @@ -452,7 +448,7 @@ public void testRunStructuredQuery() { assertFalse(results4.hasNext()); // TODO(ozarov): construct a test to verify nextQuery/pagination } - + */ @Test public void testAllocateId() { KeyFactory keyFactory = datastore.newKeyFactory().kind(KIND1); @@ -570,7 +566,6 @@ public void testAddEntity() { assertNotNull(datastore.get(entities.get(2).key())); } - @Test public void testUpdate() { List keys = datastore.fetch(ENTITY1.key(), ENTITY3.key()); @@ -639,10 +634,10 @@ public void testKeyFactory() { @Test public void testRetires() throws Exception { - DatastoreV1.LookupRequest requestPb = - DatastoreV1.LookupRequest.newBuilder().addKey(KEY1.toPb()).build(); - DatastoreV1.LookupResponse responsePb = DatastoreV1.LookupResponse.newBuilder() - .addFound(EntityResult.newBuilder().setEntity(ENTITY1.toPb())).build(); + com.google.datastore.v1beta3.LookupRequest requestPb = + com.google.datastore.v1beta3.LookupRequest.newBuilder().addKeys(KEY1.toPb()).build(); + com.google.datastore.v1beta3.LookupResponse responsePb = com.google.datastore.v1beta3.LookupResponse.newBuilder() + .addFound(com.google.datastore.v1beta3.EntityResult.newBuilder().setEntity(ENTITY1.toPb())).build(); DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) @@ -661,4 +656,3 @@ public void testRetires() throws Exception { EasyMock.verify(rpcFactoryMock, rpcMock); } } -*/ diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyFactoryTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyFactoryTest.java index 7acf8abbbf19..dacb348c2172 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyFactoryTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyFactoryTest.java @@ -17,7 +17,6 @@ package com.google.gcloud.datastore; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import org.junit.Before; diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java index 2d7f5802f247..0625f2afb38d 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java @@ -61,9 +61,9 @@ public class LocalGcdHelper { public static final String DEFAULT_PROJECT_ID = "projectid1"; public static final int PORT = 8080; - private static final String GCD = "gcd-v1beta2-rev1-2.1.2b"; + private static final String GCD = "gcd-v1beta3-0.0.1"; private static final String GCD_FILENAME = GCD + ".zip"; - private static final String MD5_CHECKSUM = "d84384cdfa8658e1204f4f8be51300e8"; + private static final String MD5_CHECKSUM = "496b16f32473d0de0c7a974bd0ee1461"; private static final URL GCD_URL; static { @@ -159,13 +159,13 @@ public void start() throws IOException, InterruptedException { } } // cleanup any possible data for the same project - File datasetFolder = new File(gcdFolder, GCD + '/' + projectId); + File datasetFolder = new File(gcdFolder, "gcd/" + projectId); deleteRecurse(datasetFolder.toPath()); // create the datastore for the project ProcessBuilder processBuilder = new ProcessBuilder() .redirectError(ProcessBuilder.Redirect.INHERIT) - .directory(new File(gcdFolder, GCD)); + .directory(new File(gcdFolder, "gcd")); if (isWindows()) { processBuilder.command("cmd", "/C", "gcd.cmd", "create", "-p", projectId, projectId); processBuilder.redirectOutput(new File("NULL:")); @@ -179,7 +179,7 @@ public void start() throws IOException, InterruptedException { // start the datastore for the project processBuilder = new ProcessBuilder() - .directory(new File(gcdFolder, GCD)) + .directory(new File(gcdFolder, "gcd")) .redirectErrorStream(true); if (isWindows()) { processBuilder.command("cmd", "/C", "gcd.cmd", "start", "--testing", @@ -309,7 +309,7 @@ public static void main(String... args) throws IOException, InterruptedException public static boolean isActive(String projectId) { try { StringBuilder urlBuilder = new StringBuilder("http://localhost:").append(PORT); - urlBuilder.append("/datastore/v1beta2/datasets/").append(projectId).append("/lookup"); + urlBuilder.append("/datastore/v1beta3/datasets/").append(projectId).append(":lookup"); URL url = new URL(urlBuilder.toString()); try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), UTF_8))) { From 959d67d9f9f940b3db62b556076b2a90ba2fb263 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 25 Sep 2015 09:22:16 -0700 Subject: [PATCH 004/375] cleanup v1beta3 changes and fix LocalGcdHelper bugs --- .../datastore/BaseDatastoreBatchWriter.java | 4 --- .../google/gcloud/datastore/BatchImpl.java | 6 ++-- .../gcloud/datastore/DatastoreImpl.java | 17 +++++---- .../gcloud/datastore/DatastoreOptions.java | 3 +- .../gcloud/datastore/TransactionImpl.java | 6 ++-- .../gcloud/spi/DefaultDatastoreRpc.java | 36 ++++++++++++------- .../datastore/DatastoreOptionsTest.java | 1 - .../gcloud/datastore/LocalGcdHelper.java | 2 +- 8 files changed, 40 insertions(+), 35 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java index 6d8ac86834de..3aa0d38f45f1 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java @@ -184,10 +184,6 @@ protected Set toDelete() { return toDelete; } - protected int numAutoAllocatedIds() { - return toAddAutoId.size(); - } - protected void deactivate() { active = false; } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java index a9eab9e9c3f1..303e9703f4cc 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java @@ -16,8 +16,8 @@ package com.google.gcloud.datastore; +import java.util.ArrayList; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; @@ -39,7 +39,7 @@ static class ResponseImpl implements Batch.Response { public List generatedKeys() { Iterator results = response.getMutationResultsList().iterator(); - List generated = new LinkedList(); + List generated = new ArrayList<>(numAutoAllocatedIds); for (int i = 0; i < numAutoAllocatedIds; i++) { generated.add(Key.fromPb(results.next().getKey())); } @@ -62,7 +62,7 @@ public Batch.Response submit() { requestPb.addAllMutations(mutationsPb); com.google.datastore.v1beta3.CommitResponse responsePb = datastore.commit(requestPb.build()); deactivate(); - return new ResponseImpl(responsePb, numAutoAllocatedIds()); + return new ResponseImpl(responsePb, toAddAutoId().size()); } @Override diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java index 262098e82f96..f0238083b5fa 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java @@ -176,33 +176,32 @@ public List add(FullEntity... entities) { return Collections.emptyList(); } List mutationsPb = new ArrayList<>(); - Map completeEntities = new LinkedHashMap<>(); + Set completeEntities = new LinkedHashSet<>(); for (FullEntity entity : entities) { Entity completeEntity = null; if (entity.key() instanceof Key) { completeEntity = Entity.convert((FullEntity) entity); } if (completeEntity != null) { - if (completeEntities.put(completeEntity.key(), completeEntity) != null) { + if (completeEntities.contains(completeEntity)) { throw DatastoreException.throwInvalidRequest( "Duplicate entity with the key %s", entity.key()); } - mutationsPb.add(com.google.datastore.v1beta3.Mutation.newBuilder() - .setInsert(completeEntity.toPb()).build()); + completeEntities.add(completeEntity); } else { Preconditions.checkArgument(entity.hasKey(), "entity %s is missing a key", entity); - mutationsPb.add(com.google.datastore.v1beta3.Mutation.newBuilder() - .setInsert(entity.toPb()).build()); } + mutationsPb.add(com.google.datastore.v1beta3.Mutation.newBuilder() + .setInsert(entity.toPb()).build()); } com.google.datastore.v1beta3.CommitResponse commitResponse = commitMutation(mutationsPb); Iterator mutationResults = commitResponse.getMutationResultsList().iterator(); + Iterator completeEntitiesIt = completeEntities.iterator(); ImmutableList.Builder responseBuilder = ImmutableList.builder(); for (FullEntity entity : entities) { - Entity completeEntity = completeEntities.get(entity.key()); - if (completeEntity != null) { - responseBuilder.add(completeEntity); + if (completeEntities.contains(entity)) { + responseBuilder.add(completeEntitiesIt.next()); mutationResults.next(); } else { responseBuilder.add( diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java index 23128a856761..a354f7328959 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java @@ -108,7 +108,8 @@ private DatastoreOptions normalize() { .build(); requestPb.addKeys(key); try { - com.google.datastore.v1beta3.LookupResponse responsePb = datastoreRpc().lookup(requestPb.build()); + com.google.datastore.v1beta3.LookupResponse responsePb = + datastoreRpc().lookup(requestPb.build()); if (responsePb.getDeferredCount() > 0) { key = responsePb.getDeferred(0); } else { diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java index ff9ce5e50e9d..5a422927005a 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java @@ -18,8 +18,8 @@ import com.google.protobuf.ByteString; +import java.util.ArrayList; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; final class TransactionImpl extends BaseDatastoreBatchWriter implements Transaction { @@ -42,7 +42,7 @@ static class ResponseImpl implements Transaction.Response { public List generatedKeys() { Iterator results = response.getMutationResultsList().iterator(); - List generated = new LinkedList(); + List generated = new ArrayList<>(numAutoAllocatedIds); for (int i = 0; i < numAutoAllocatedIds; i++) { generated.add(Key.fromPb(results.next().getKey())); } @@ -98,7 +98,7 @@ public Transaction.Response commit() { requestPb.addAllMutations(mutationsPb); com.google.datastore.v1beta3.CommitResponse responsePb = datastore.commit(requestPb.build()); deactivate(); - return new ResponseImpl(responsePb, numAutoAllocatedIds()); + return new ResponseImpl(responsePb, toAddAutoId().size()); } @Override diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java index 1ae0b6eea22e..3c82e2a93cc4 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java @@ -20,6 +20,10 @@ import com.google.gcloud.datastore.DatastoreOptions; import com.google.gcloud.spi.DatastoreRpc.DatastoreRpcException.Reason; +import java.net.InetAddress; +import java.net.MalformedURLException; +import java.net.UnknownHostException; +import java.net.URL; import java.util.HashMap; import java.util.Map; @@ -42,20 +46,26 @@ public class DefaultDatastoreRpc implements DatastoreRpc { } public DefaultDatastoreRpc(DatastoreOptions options) { - if (options.host().contains("localhost")) { - client = com.google.datastore.v1beta3.client.DatastoreFactory.get().create( - new com.google.datastore.v1beta3.client.DatastoreOptions.Builder() - .projectId(options.projectId()) - .localHost(options.host()) - .initializer(options.httpRequestInitializer()) - .build()); - } else { - client = com.google.datastore.v1beta3.client.DatastoreFactory.get().create( - new com.google.datastore.v1beta3.client.DatastoreOptions.Builder() - .projectId(options.projectId()) - .initializer(options.httpRequestInitializer()) - .build()); + com.google.datastore.v1beta3.client.DatastoreOptions.Builder clientBuilder = + new com.google.datastore.v1beta3.client.DatastoreOptions.Builder() + .projectId(options.projectId()) + .initializer(options.httpRequestInitializer()); + if (options.host() != null) { + try { + String normalizedHost = options.host(); + if (!normalizedHost.startsWith("http")) { + normalizedHost = "http://" + normalizedHost; + } + InetAddress hostAddr = InetAddress.getByName(new URL(normalizedHost).getHost()); + if (hostAddr.isAnyLocalAddress() || hostAddr.isLoopbackAddress()) { + clientBuilder = clientBuilder.localHost(options.host()); + } + } catch (UnknownHostException | MalformedURLException e) { + // ignore + } } + client = com.google.datastore.v1beta3.client.DatastoreFactory.get() + .create(clientBuilder.build()); } private static DatastoreRpcException translate( diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java index 97aeec3ee129..63657902d737 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java @@ -18,7 +18,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java index 0625f2afb38d..1d692040c015 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java @@ -309,7 +309,7 @@ public static void main(String... args) throws IOException, InterruptedException public static boolean isActive(String projectId) { try { StringBuilder urlBuilder = new StringBuilder("http://localhost:").append(PORT); - urlBuilder.append("/datastore/v1beta3/datasets/").append(projectId).append(":lookup"); + urlBuilder.append("/datastore/v1beta3/projects/").append(projectId).append(":lookup"); URL url = new URL(urlBuilder.toString()); try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), UTF_8))) { From 9463c5592e230e7384960664119781e642a87c45 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Wed, 30 Sep 2015 18:33:27 -0700 Subject: [PATCH 005/375] Fix handling of host in DatastoreOptions.java --- .../gcloud/datastore/DatastoreImpl.java | 11 +++---- .../gcloud/datastore/DatastoreOptions.java | 26 +++++----------- .../gcloud/spi/DefaultDatastoreRpc.java | 31 +++++++++++++++---- .../datastore/DatastoreOptionsTest.java | 9 +----- .../gcloud/datastore/SerializationTest.java | 1 - 5 files changed, 38 insertions(+), 40 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java index f0238083b5fa..59804831872c 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java @@ -176,18 +176,17 @@ public List add(FullEntity... entities) { return Collections.emptyList(); } List mutationsPb = new ArrayList<>(); - Set completeEntities = new LinkedHashSet<>(); + Map completeEntities = new LinkedHashMap<>(); for (FullEntity entity : entities) { Entity completeEntity = null; if (entity.key() instanceof Key) { completeEntity = Entity.convert((FullEntity) entity); } if (completeEntity != null) { - if (completeEntities.contains(completeEntity)) { + if (completeEntities.put(completeEntity.key(), completeEntity) != null) { throw DatastoreException.throwInvalidRequest( "Duplicate entity with the key %s", entity.key()); } - completeEntities.add(completeEntity); } else { Preconditions.checkArgument(entity.hasKey(), "entity %s is missing a key", entity); } @@ -197,11 +196,11 @@ public List add(FullEntity... entities) { com.google.datastore.v1beta3.CommitResponse commitResponse = commitMutation(mutationsPb); Iterator mutationResults = commitResponse.getMutationResultsList().iterator(); - Iterator completeEntitiesIt = completeEntities.iterator(); ImmutableList.Builder responseBuilder = ImmutableList.builder(); for (FullEntity entity : entities) { - if (completeEntities.contains(entity)) { - responseBuilder.add(completeEntitiesIt.next()); + Entity completeEntity = completeEntities.get(entity.key()); + if (completeEntity != null) { + responseBuilder.add(completeEntity); mutationResults.next(); } else { responseBuilder.add( diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java index a354f7328959..fe318ef8720f 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java @@ -35,14 +35,11 @@ public class DatastoreOptions extends ServiceOptions { private static final long serialVersionUID = -8636602944160689193L; - private static final String DATASET_ENV_NAME = "DATASTORE_DATASET"; - private static final String HOST_ENV_NAME = "DATASTORE_HOST"; private static final String DATASTORE_SCOPE = "https://www.googleapis.com/auth/datastore"; private static final String USERINFO_SCOPE = "https://www.googleapis.com/auth/userinfo.email"; private static final Set SCOPES = ImmutableSet.of(DATASTORE_SCOPE, USERINFO_SCOPE); private final String namespace; - private final boolean force; private final boolean normalizeDataset; private transient DatastoreRpc datastoreRpc; @@ -50,7 +47,6 @@ public static class Builder extends ServiceOptions.Builder { private String namespace; - private boolean force; private boolean normalizeDataset = true; private Builder() { @@ -58,7 +54,6 @@ private Builder() { private Builder(DatastoreOptions options) { super(options); - force = options.force; namespace = options.namespace; normalizeDataset = options.normalizeDataset; } @@ -74,11 +69,6 @@ public Builder namespace(String namespace) { return this; } - public Builder force(boolean force) { - this.force = force; - return this; - } - Builder normalizeDataset(boolean normalizeDataset) { this.normalizeDataset = normalizeDataset; return this; @@ -89,7 +79,6 @@ private DatastoreOptions(Builder builder) { super(builder); normalizeDataset = builder.normalizeDataset; namespace = builder.namespace != null ? builder.namespace : defaultNamespace(); - force = builder.force; } private DatastoreOptions normalize() { @@ -126,13 +115,17 @@ private DatastoreOptions normalize() { @Override protected String defaultHost() { - String host = System.getProperty(HOST_ENV_NAME, System.getenv(HOST_ENV_NAME)); + String host = System.getProperty( + com.google.datastore.v1beta3.client.DatastoreHelper.LOCAL_HOST_ENV_VAR, + System.getenv(com.google.datastore.v1beta3.client.DatastoreHelper.LOCAL_HOST_ENV_VAR)); return host != null ? host : super.defaultHost(); } @Override protected String defaultProject() { - String projectId = System.getProperty(DATASET_ENV_NAME, System.getenv(DATASET_ENV_NAME)); + String projectId = System.getProperty( + com.google.datastore.v1beta3.client.DatastoreHelper.PROJECT_ID_ENV_VAR, + System.getenv(com.google.datastore.v1beta3.client.DatastoreHelper.PROJECT_ID_ENV_VAR)); if (projectId == null) { projectId = appEngineAppId(); } @@ -157,10 +150,6 @@ private static String defaultNamespace() { } } - public boolean force() { - return force; - } - @Override protected Set scopes() { return SCOPES; @@ -173,7 +162,7 @@ public Builder toBuilder() { @Override public int hashCode() { - return baseHashCode() ^ Objects.hash(namespace, force, normalizeDataset); + return baseHashCode() ^ Objects.hash(namespace, normalizeDataset); } @Override @@ -183,7 +172,6 @@ public boolean equals(Object obj) { } DatastoreOptions other = (DatastoreOptions) obj; return baseEquals(other) && Objects.equals(namespace, other.namespace) - && Objects.equals(force, other.force) && Objects.equals(normalizeDataset, other.normalizeDataset); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java index 3c82e2a93cc4..31fe2f8e0d66 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java @@ -50,22 +50,41 @@ public DefaultDatastoreRpc(DatastoreOptions options) { new com.google.datastore.v1beta3.client.DatastoreOptions.Builder() .projectId(options.projectId()) .initializer(options.httpRequestInitializer()); - if (options.host() != null) { + if (isLocalHost(options.host())) { + clientBuilder = clientBuilder.localHost(options.host()); + } else if (!options.host() + .equals(com.google.datastore.v1beta3.client.DatastoreFactory.DEFAULT_HOST)) { + String fullURL = options.host(); + if (fullURL.charAt(fullURL.length() - 1) != '/') { + fullURL = fullURL + '/'; + } + fullURL = fullURL + "datastore/v1beta3/projects/" + options.projectId(); + clientBuilder = clientBuilder.projectId(null).projectEndpoint(fullURL); + } + client = com.google.datastore.v1beta3.client.DatastoreFactory.get() + .create(clientBuilder.build()); + } + + private static boolean isLocalHost(String host) { + if (host != null) { try { - String normalizedHost = options.host(); - if (!normalizedHost.startsWith("http")) { + String normalizedHost = host; + if (!includesScheme(normalizedHost)) { normalizedHost = "http://" + normalizedHost; } InetAddress hostAddr = InetAddress.getByName(new URL(normalizedHost).getHost()); if (hostAddr.isAnyLocalAddress() || hostAddr.isLoopbackAddress()) { - clientBuilder = clientBuilder.localHost(options.host()); + return true; } } catch (UnknownHostException | MalformedURLException e) { // ignore } } - client = com.google.datastore.v1beta3.client.DatastoreFactory.get() - .create(clientBuilder.build()); + return false; + } + + private static boolean includesScheme(String url) { + return url.startsWith("http://") || url.startsWith("https://"); } private static DatastoreRpcException translate( diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java index 63657902d737..161dfc078f6c 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java @@ -68,12 +68,6 @@ public void testNamespace() throws Exception { assertEquals("ns1", options.namespace("ns1").build().namespace()); } - @Test - public void testForce() throws Exception { - assertFalse(options.build().force()); - assertTrue(options.force(true).build().force()); - } - @Test public void testDatastore() throws Exception { assertSame(datastoreRpcFactory, options.build().serviceRpcFactory()); @@ -82,12 +76,11 @@ public void testDatastore() throws Exception { @Test public void testToBuilder() throws Exception { - DatastoreOptions original = options.namespace("ns1").force(true).build(); + DatastoreOptions original = options.namespace("ns1").build(); DatastoreOptions copy = original.toBuilder().build(); assertEquals(original.projectId(), copy.projectId()); assertEquals(original.namespace(), copy.namespace()); assertEquals(original.host(), copy.host()); - assertEquals(original.force(), copy.force()); assertEquals(original.retryParams(), copy.retryParams()); assertEquals(original.authCredentials(), copy.authCredentials()); } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index 624689cd420e..bd4a683f9c9c 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -148,7 +148,6 @@ public void testServiceOptions() throws Exception { .namespace("ns1") .retryParams(RetryParams.getDefaultInstance()) .authCredentials(AuthCredentials.noCredentials()) - .force(true) .build(); serializedCopy = serializeAndDeserialize(options); assertEquals(options, serializedCopy); From 4d2fe25b88f32abb9cc4c3d4bc01fbfde1221a79 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 5 Oct 2015 08:03:49 -0700 Subject: [PATCH 006/375] Remove scheme from localhost and check if user-provided host is null/empty --- .../gcloud/spi/DefaultDatastoreRpc.java | 24 +++++++++++++------ .../gcloud/datastore/LocalGcdHelper.java | 3 ++- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java index 31fe2f8e0d66..c6e3f396e574 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java @@ -16,6 +16,7 @@ package com.google.gcloud.spi; +import com.google.common.base.Strings; import com.google.common.collect.ImmutableMap; import com.google.gcloud.datastore.DatastoreOptions; import com.google.gcloud.spi.DatastoreRpc.DatastoreRpcException.Reason; @@ -51,14 +52,16 @@ public DefaultDatastoreRpc(DatastoreOptions options) { .projectId(options.projectId()) .initializer(options.httpRequestInitializer()); if (isLocalHost(options.host())) { - clientBuilder = clientBuilder.localHost(options.host()); - } else if (!options.host() - .equals(com.google.datastore.v1beta3.client.DatastoreFactory.DEFAULT_HOST)) { + clientBuilder = clientBuilder.localHost(removeScheme(options.host())); + } else if (!com.google.datastore.v1beta3.client.DatastoreFactory.DEFAULT_HOST + .equals(options.host()) && !Strings.isNullOrEmpty(options.host())) { String fullURL = options.host(); if (fullURL.charAt(fullURL.length() - 1) != '/') { fullURL = fullURL + '/'; } - fullURL = fullURL + "datastore/v1beta3/projects/" + options.projectId(); + fullURL = fullURL + "datastore/" + + com.google.datastore.v1beta3.client.DatastoreFactory.VERSION + "/projects/" + + options.projectId(); clientBuilder = clientBuilder.projectId(null).projectEndpoint(fullURL); } client = com.google.datastore.v1beta3.client.DatastoreFactory.get() @@ -73,9 +76,7 @@ private static boolean isLocalHost(String host) { normalizedHost = "http://" + normalizedHost; } InetAddress hostAddr = InetAddress.getByName(new URL(normalizedHost).getHost()); - if (hostAddr.isAnyLocalAddress() || hostAddr.isLoopbackAddress()) { - return true; - } + return hostAddr.isAnyLocalAddress() || hostAddr.isLoopbackAddress(); } catch (UnknownHostException | MalformedURLException e) { // ignore } @@ -87,6 +88,15 @@ private static boolean includesScheme(String url) { return url.startsWith("http://") || url.startsWith("https://"); } + private static String removeScheme(String url) { + if (url.startsWith("https://")) { + return url.substring("https://".length()); + } else if (url.startsWith("http://")) { + return url.substring("http://".length()); + } + return url; + } + private static DatastoreRpcException translate( com.google.datastore.v1beta3.client.DatastoreException exception) { String reasonStr = ""; diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java index 1d692040c015..1054b461ab0d 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java @@ -309,7 +309,8 @@ public static void main(String... args) throws IOException, InterruptedException public static boolean isActive(String projectId) { try { StringBuilder urlBuilder = new StringBuilder("http://localhost:").append(PORT); - urlBuilder.append("/datastore/v1beta3/projects/").append(projectId).append(":lookup"); + urlBuilder.append("/datastore/" + com.google.datastore.v1beta3.client.DatastoreFactory.VERSION + + "/projects/").append(projectId).append(":lookup"); URL url = new URL(urlBuilder.toString()); try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), UTF_8))) { From e0aaaba871960a006fb82dc5972c015ea987c980 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 5 Oct 2015 09:27:23 -0700 Subject: [PATCH 007/375] Fix version in LocalGcdHelper and check for null values when removing URL scheme --- .../com/google/gcloud/spi/DefaultDatastoreRpc.java | 10 ++++++---- .../com/google/gcloud/datastore/LocalGcdHelper.java | 3 +-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java index c6e3f396e574..3063dda6eca3 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java @@ -89,10 +89,12 @@ private static boolean includesScheme(String url) { } private static String removeScheme(String url) { - if (url.startsWith("https://")) { - return url.substring("https://".length()); - } else if (url.startsWith("http://")) { - return url.substring("http://".length()); + if (url != null) { + if (url.startsWith("https://")) { + return url.substring("https://".length()); + } else if (url.startsWith("http://")) { + return url.substring("http://".length()); + } } return url; } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java index 1054b461ab0d..1d692040c015 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelper.java @@ -309,8 +309,7 @@ public static void main(String... args) throws IOException, InterruptedException public static boolean isActive(String projectId) { try { StringBuilder urlBuilder = new StringBuilder("http://localhost:").append(PORT); - urlBuilder.append("/datastore/" + com.google.datastore.v1beta3.client.DatastoreFactory.VERSION - + "/projects/").append(projectId).append(":lookup"); + urlBuilder.append("/datastore/v1beta3/projects/").append(projectId).append(":lookup"); URL url = new URL(urlBuilder.toString()); try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream(), UTF_8))) { From c029c378fd2d09928802c75f8ca9c21e2aafb477 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 5 Oct 2015 15:55:10 -0700 Subject: [PATCH 008/375] Update query-related datastore code to v1beta3 --- .../com/google/gcloud/datastore/Blob.java | 10 +- .../com/google/gcloud/datastore/Cursor.java | 15 +- .../gcloud/datastore/DatastoreImpl.java | 4 +- .../com/google/gcloud/datastore/GqlQuery.java | 129 ++++++------ .../com/google/gcloud/datastore/Query.java | 59 +++--- .../google/gcloud/datastore/QueryResults.java | 1 - .../gcloud/datastore/QueryResultsImpl.java | 44 ++-- .../gcloud/datastore/StructuredQuery.java | 191 ++++++++---------- .../gcloud/datastore/DatastoreTest.java | 19 +- .../gcloud/datastore/SerializationTest.java | 12 +- 10 files changed, 221 insertions(+), 263 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Blob.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Blob.java index 5a759240be38..fbe2887d9b35 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Blob.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Blob.java @@ -18,8 +18,6 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.api.services.datastore.DatastoreV1; -import com.google.api.services.datastore.DatastoreV1.Value; import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects.ToStringHelper; import com.google.protobuf.ByteString; @@ -37,7 +35,7 @@ * * @see Google Cloud Datastore Entities, Properties, and Keys */ -public final class Blob extends Serializable { +public final class Blob extends Serializable { private static final long serialVersionUID = 3835421019618247721L; @@ -146,12 +144,12 @@ public static Blob copyFrom(InputStream input) throws IOException { } @Override - protected Value toPb() { - return DatastoreV1.Value.newBuilder().setBlobValue(byteString).build(); + protected com.google.datastore.v1beta3.Value toPb() { + return com.google.datastore.v1beta3.Value.newBuilder().setBlobValue(byteString).build(); } @Override protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { - return new Blob(DatastoreV1.Value.parseFrom(bytesPb).getBlobValue()); + return new Blob(com.google.datastore.v1beta3.Value.parseFrom(bytesPb).getBlobValue()); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Cursor.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Cursor.java index 42a8cee8e5a2..df237e4d897c 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Cursor.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Cursor.java @@ -19,8 +19,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static java.nio.charset.StandardCharsets.UTF_8; -import com.google.api.services.datastore.DatastoreV1; -import com.google.api.services.datastore.DatastoreV1.Value; import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects.ToStringHelper; import com.google.common.base.Preconditions; @@ -37,7 +35,7 @@ * A Google Cloud Datastore cursor. * The cursor can be used to as a starting point or an ending point for a {@link Query} */ -public final class Cursor extends Serializable { +public final class Cursor extends Serializable { private static final long serialVersionUID = -1423744878777486541L; @@ -89,7 +87,8 @@ public String toUrlSafe() { public static Cursor fromUrlSafe(String urlSafe) { try { String utf8Str = URLDecoder.decode(urlSafe, UTF_8.name()); - DatastoreV1.Value.Builder builder = DatastoreV1.Value.newBuilder(); + com.google.datastore.v1beta3.Value.Builder builder = + com.google.datastore.v1beta3.Value.newBuilder(); TextFormat.merge(utf8Str, builder); return fromPb(builder.build()); } catch (UnsupportedEncodingException | ParseException e) { @@ -102,16 +101,16 @@ public static Cursor copyFrom(byte[] bytes) { } @Override - protected Value toPb() { - return DatastoreV1.Value.newBuilder().setBlobValue(byteString).build(); + protected com.google.datastore.v1beta3.Value toPb() { + return com.google.datastore.v1beta3.Value.newBuilder().setBlobValue(byteString).build(); } @Override protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { - return fromPb(DatastoreV1.Value.parseFrom(bytesPb)); + return fromPb(com.google.datastore.v1beta3.Value.parseFrom(bytesPb)); } - static Cursor fromPb(DatastoreV1.Value valuePb) { + static Cursor fromPb(com.google.datastore.v1beta3.Value valuePb) { return new Cursor(valuePb.getBlobValue()); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java index 59804831872c..fdd8917d11e2 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java @@ -99,9 +99,7 @@ public QueryResults run(Query query) { } QueryResults run(com.google.datastore.v1beta3.ReadOptions readOptionsPb, Query query) { - // TODO(ajaykannan): fix me! - //return new QueryResultsImpl<>(this, readOptionsPb, query); - return null; // TODO(ajaykannan): fix me! + return new QueryResultsImpl<>(this, readOptionsPb, query); } com.google.datastore.v1beta3.RunQueryResponse runQuery( diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java index 54110a89c3e0..2c02aa7b970c 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java @@ -19,7 +19,6 @@ import static com.google.common.base.Preconditions.checkNotNull; import static com.google.gcloud.datastore.Validator.validateNamespace; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -75,25 +74,22 @@ public final class GqlQuery extends Query { private final transient String queryString; private final transient boolean allowLiteral; - private final transient ImmutableList namedBindings; + private final transient ImmutableMap namedBindings; private final transient ImmutableList positionalBindings; - static final class Binding extends Serializable { + static final class Binding extends Serializable { private static final long serialVersionUID = 1976895435257636275L; - private final transient String name; private final transient Cursor cursor; private final transient Value value; - Binding(String name, Cursor cursor) { - this.name = name; + Binding(Cursor cursor) { this.cursor = checkNotNull(cursor); value = null; } - Binding(String name, Value value) { - this.name = name; + Binding(Value value) { this.value = checkNotNull(value); cursor = null; } @@ -102,13 +98,9 @@ Object cursorOrValue() { return MoreObjects.firstNonNull(cursor, value); } - String name() { - return name; - } - @Override public int hashCode() { - return Objects.hash(name, cursor, value); + return Objects.hash(cursor, value); } @Override @@ -120,40 +112,36 @@ public boolean equals(Object obj) { return false; } Binding other = (Binding) obj; - return Objects.equals(name, other.name) - && Objects.equals(cursor, other.cursor) - && Objects.equals(value, other.value); + return Objects.equals(cursor, other.cursor) && Objects.equals(value, other.value); } @Override - protected DatastoreV1.GqlQueryArg toPb() { - DatastoreV1.GqlQueryArg.Builder argPb = DatastoreV1.GqlQueryArg.newBuilder(); - if (name != null) { - argPb.setName(name); - } + protected com.google.datastore.v1beta3.GqlQueryParameter toPb() { + com.google.datastore.v1beta3.GqlQueryParameter.Builder argPb = + com.google.datastore.v1beta3.GqlQueryParameter.newBuilder(); if (cursor != null) { argPb.setCursor(cursor.byteString()); } if (value != null) { - // TODO(ajaykannan): fix me! - //argPb.setValue(value.toPb()); + argPb.setValue(value.toPb()); } return argPb.build(); } @Override protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { - return fromPb(DatastoreV1.GqlQueryArg.parseFrom(bytesPb)); + return fromPb(com.google.datastore.v1beta3.GqlQueryParameter.parseFrom(bytesPb)); } - static Binding fromPb(DatastoreV1.GqlQueryArg argPb) { - String name = argPb.hasName() ? argPb.getName() : null; - if (argPb.hasCursor()) { - return new Binding(name, new Cursor(argPb.getCursor())); + static Binding fromPb(com.google.datastore.v1beta3.GqlQueryParameter argPb) { + switch (argPb.getParameterTypeCase()) { + case CURSOR: + return new Binding(new Cursor(argPb.getCursor())); + case VALUE: + return new Binding(Value.fromPb(argPb.getValue())); + default: + return null; } - // TODO(ajaykannan): fix me! - //return new Binding(name, Value.fromPb(argPb.getValue())); - return new Binding(name, new Cursor(null)); // TODO(ajaykannan): fix me! } } @@ -196,52 +184,52 @@ public Builder clearBindings() { } public Builder setBinding(String name, Cursor cursor) { - namedBindings.put(name, new Binding(name, cursor)); + namedBindings.put(name, new Binding(cursor)); return this; } public Builder setBinding(String name, String... value) { - namedBindings.put(name, toBinding(name, StringValue.MARSHALLER, Arrays.asList(value))); + namedBindings.put(name, toBinding(StringValue.MARSHALLER, Arrays.asList(value))); return this; } public Builder setBinding(String name, long... value) { - namedBindings.put(name, toBinding(name, LongValue.MARSHALLER, Longs.asList(value))); + namedBindings.put(name, toBinding(LongValue.MARSHALLER, Longs.asList(value))); return this; } public Builder setBinding(String name, double... value) { - namedBindings.put(name, toBinding(name, DoubleValue.MARSHALLER, Doubles.asList(value))); + namedBindings.put(name, toBinding(DoubleValue.MARSHALLER, Doubles.asList(value))); return this; } public Builder setBinding(String name, boolean... value) { - namedBindings.put(name, toBinding(name, BooleanValue.MARSHALLER, Booleans.asList(value))); + namedBindings.put(name, toBinding(BooleanValue.MARSHALLER, Booleans.asList(value))); return this; } public Builder setBinding(String name, DateTime... value) { - namedBindings.put(name, toBinding(name, DateTimeValue.MARSHALLER, Arrays.asList(value))); + namedBindings.put(name, toBinding(DateTimeValue.MARSHALLER, Arrays.asList(value))); return this; } public Builder setBinding(String name, Key... value) { - namedBindings.put(name, toBinding(name, KeyValue.MARSHALLER, Arrays.asList(value))); + namedBindings.put(name, toBinding(KeyValue.MARSHALLER, Arrays.asList(value))); return this; } public Builder setBinding(String name, FullEntity... value) { - namedBindings.put(name, toBinding(name, EntityValue.MARSHALLER, Arrays.asList(value))); + namedBindings.put(name, toBinding(EntityValue.MARSHALLER, Arrays.asList(value))); return this; } public Builder setBinding(String name, Blob... value) { - namedBindings.put(name, toBinding(name, BlobValue.MARSHALLER, Arrays.asList(value))); + namedBindings.put(name, toBinding(BlobValue.MARSHALLER, Arrays.asList(value))); return this; } public Builder addBinding(Cursor cursor) { - positionalBindings.add(new Binding(null, cursor)); + positionalBindings.add(new Binding(cursor)); return this; } @@ -289,11 +277,7 @@ public GqlQuery build() { return new GqlQuery<>(this); } - private static Binding toBinding(Value.BuilderFactory builderFactory, List values) { - return toBinding(null, builderFactory, values); - } - - private static Binding toBinding(String name, Value.BuilderFactory builderFactory, + private static Binding toBinding(Value.BuilderFactory builderFactory, List values) { List> list = new ArrayList<>(values.size()); for (Object object : values) { @@ -309,7 +293,7 @@ private static Binding toBinding(String name, Value.BuilderFactory } else { value = new ListValue(list); } - return new Binding(name, value); + return new Binding(value); } } @@ -317,7 +301,7 @@ private GqlQuery(Builder builder) { super(builder.resultType, builder.namespace); queryString = builder.queryString; allowLiteral = builder.allowLiteral; - namedBindings = ImmutableList.copyOf(builder.namedBindings.values()); + namedBindings = ImmutableMap.copyOf(builder.namedBindings); positionalBindings = ImmutableList.copyOf(builder.positionalBindings); } @@ -334,8 +318,8 @@ public boolean allowLiteral() { */ public Map namedBindings() { ImmutableMap.Builder builder = ImmutableSortedMap.naturalOrder(); - for (Binding binding : namedBindings) { - builder.put(binding.name(), binding.cursorOrValue()); + for (Map.Entry binding : namedBindings.entrySet()) { + builder.put(binding.getKey(), binding.getValue().cursorOrValue()); } return builder.build(); } @@ -373,26 +357,29 @@ public boolean equals(Object obj) { } @Override - protected DatastoreV1.GqlQuery toPb() { - DatastoreV1.GqlQuery.Builder queryPb = DatastoreV1.GqlQuery.newBuilder(); + protected com.google.datastore.v1beta3.GqlQuery toPb() { + com.google.datastore.v1beta3.GqlQuery.Builder queryPb = + com.google.datastore.v1beta3.GqlQuery.newBuilder(); queryPb.setQueryString(queryString); - queryPb.setAllowLiteral(allowLiteral); - for (Binding argument : namedBindings) { - queryPb.addNameArg(argument.toPb()); + queryPb.setAllowLiterals(allowLiteral); + Map namedBindingsPb = + queryPb.getMutableNamedBindings(); + for (Map.Entry entry : namedBindings.entrySet()) { + namedBindingsPb.put(entry.getKey(), entry.getValue().toPb()); } for (Binding argument : positionalBindings) { - queryPb.addNumberArg(argument.toPb()); + queryPb.addPositionalBindings(argument.toPb()); } return queryPb.build(); } @Override - protected void populatePb(DatastoreV1.RunQueryRequest.Builder requestPb) { + protected void populatePb(com.google.datastore.v1beta3.RunQueryRequest.Builder requestPb) { requestPb.setGqlQuery(toPb()); } @Override - protected GqlQuery nextQuery(DatastoreV1.QueryResultBatch responsePb) { + protected GqlQuery nextQuery(com.google.datastore.v1beta3.QueryResultBatch responsePb) { // See issue #17 throw new UnsupportedOperationException("paging for this query is not implemented yet"); } @@ -400,23 +387,27 @@ protected GqlQuery nextQuery(DatastoreV1.QueryResultBatch responsePb) { @Override protected Object fromPb(ResultType resultType, String namespace, byte[] bytesPb) throws InvalidProtocolBufferException { - return fromPb(resultType, namespace, DatastoreV1.GqlQuery.parseFrom(bytesPb)); + return fromPb(resultType, namespace, com.google.datastore.v1beta3.GqlQuery.parseFrom(bytesPb)); } private static GqlQuery fromPb( - ResultType resultType, String ns, DatastoreV1.GqlQuery queryPb) { + ResultType resultType, String ns, com.google.datastore.v1beta3.GqlQuery queryPb) { Builder builder = new Builder<>(resultType, queryPb.getQueryString()); builder.namespace(ns); - if (queryPb.hasAllowLiteral()) { - builder.allowLiteral = queryPb.getAllowLiteral(); - } - for (DatastoreV1.GqlQueryArg nameArg : queryPb.getNameArgList()) { - Binding argument = Binding.fromPb(nameArg); - builder.namedBindings.put(argument.name(), argument); + builder.allowLiteral = queryPb.getAllowLiterals(); + for (Map.Entry nameArg + : queryPb.getNamedBindings().entrySet()) { + Binding currBinding = Binding.fromPb(nameArg.getValue()); + if (currBinding != null) { + builder.namedBindings.put(nameArg.getKey(), currBinding); + } } - for (DatastoreV1.GqlQueryArg numberArg : queryPb.getNumberArgList()) { - Binding argument = Binding.fromPb(numberArg); - builder.positionalBindings.add(argument); + for (com.google.datastore.v1beta3.GqlQueryParameter numberArg + : queryPb.getPositionalBindingsList()) { + Binding currBinding = Binding.fromPb(numberArg); + if (currBinding != null) { + builder.positionalBindings.add(currBinding); + } } return builder.build(); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java index 7fae120dd402..6e962d92fb2f 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java @@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects.ToStringHelper; import com.google.common.collect.Maps; @@ -54,68 +53,65 @@ public abstract class Query extends Serializable { public abstract static class ResultType implements java.io.Serializable { private static final long serialVersionUID = 2104157695425806623L; - private static final Map> - PB_TO_INSTANCE = Maps.newEnumMap(DatastoreV1.EntityResult.ResultType.class); + private static final Map> + PB_TO_INSTANCE = Maps.newEnumMap( + com.google.datastore.v1beta3.EntityResult.ResultType.class); static final ResultType UNKNOWN = new ResultType(null, Object.class) { private static final long serialVersionUID = 1602329532153860907L; - @Override protected Object convert(DatastoreV1.Entity entityPb) { - if (entityPb.getPropertyCount() == 0) { + @Override protected Object convert(com.google.datastore.v1beta3.Entity entityPb) { + if (entityPb.getProperties().size() == 0) { if (!entityPb.hasKey()) { return null; } - //TODO(ajaykannan): fix me! - //return Key.fromPb(entityPb.getKey()); + return Key.fromPb(entityPb.getKey()); } - // TODO(ajaykannan): fix me! - //return ProjectionEntity.fromPb(entityPb); - return ProjectionEntity.fromPb((com.google.datastore.v1beta3.Entity) null); // TODO(ajaykannan): fix me! + return ProjectionEntity.fromPb(entityPb); } }; public static final ResultType ENTITY = - new ResultType(DatastoreV1.EntityResult.ResultType.FULL, Entity.class) { + new ResultType( + com.google.datastore.v1beta3.EntityResult.ResultType.FULL, Entity.class) { private static final long serialVersionUID = 7712959777507168274L; - @Override protected Entity convert(DatastoreV1.Entity entityPb) { - // TODO(ajaykannan): fix me! - //return Entity.fromPb(entityPb); - return Entity.fromPb((com.google.datastore.v1beta3.Entity) null); // TODO(ajaykannan): fix me! + @Override protected Entity convert(com.google.datastore.v1beta3.Entity entityPb) { + return Entity.fromPb(entityPb); } }; public static final ResultType KEY = - new ResultType(DatastoreV1.EntityResult.ResultType.KEY_ONLY, Key.class) { + new ResultType( + com.google.datastore.v1beta3.EntityResult.ResultType.KEY_ONLY, Key.class) { private static final long serialVersionUID = -8514289244104446252L; - @Override protected Key convert(DatastoreV1.Entity entityPb) { - //TODO(ajaykannan): fix me! - //return Key.fromPb(entityPb.getKey()); - return Key.builder(null).build(); // TODO(ajaykannan): fix me! + @Override protected Key convert(com.google.datastore.v1beta3.Entity entityPb) { + return Key.fromPb(entityPb.getKey()); } }; public static final ResultType PROJECTION_ENTITY = - new ResultType(DatastoreV1.EntityResult.ResultType.PROJECTION, + new ResultType( + com.google.datastore.v1beta3.EntityResult.ResultType.PROJECTION, ProjectionEntity.class) { private static final long serialVersionUID = -7591409419690650246L; - @Override protected ProjectionEntity convert(DatastoreV1.Entity entityPb) { - // TODO(ajaykannan): fix me! - //return ProjectionEntity.fromPb(entityPb); - return ProjectionEntity.fromPb((com.google.datastore.v1beta3.Entity) null); // TODO(ajaykannan): fix me! + @Override protected ProjectionEntity convert( + com.google.datastore.v1beta3.Entity entityPb) { + return ProjectionEntity.fromPb(entityPb); } }; private final Class resultClass; - private final DatastoreV1.EntityResult.ResultType queryType; + private final com.google.datastore.v1beta3.EntityResult.ResultType queryType; - private ResultType(DatastoreV1.EntityResult.ResultType queryType, Class resultClass) { + private ResultType(com.google.datastore.v1beta3.EntityResult.ResultType queryType, + Class resultClass) { this.queryType = queryType; this.resultClass = resultClass; if (queryType != null) { @@ -156,9 +152,9 @@ boolean isAssignableFrom(ResultType otherResultType) { return resultClass.isAssignableFrom(otherResultType.resultClass); } - protected abstract V convert(DatastoreV1.Entity entityPb); + protected abstract V convert(com.google.datastore.v1beta3.Entity entityPb); - static ResultType fromPb(DatastoreV1.EntityResult.ResultType typePb) { + static ResultType fromPb(com.google.datastore.v1beta3.EntityResult.ResultType typePb) { return MoreObjects.firstNonNull(PB_TO_INSTANCE.get(typePb), UNKNOWN); } } @@ -193,9 +189,10 @@ protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { protected abstract Object fromPb(ResultType resultType, String namespace, byte[] bytesPb) throws InvalidProtocolBufferException; - protected abstract void populatePb(DatastoreV1.RunQueryRequest.Builder requestPb); + protected abstract void populatePb( + com.google.datastore.v1beta3.RunQueryRequest.Builder requestPb); - protected abstract Query nextQuery(DatastoreV1.QueryResultBatch responsePb); + protected abstract Query nextQuery(com.google.datastore.v1beta3.QueryResultBatch responsePb); /** * Returns a new {@link GqlQuery} builder. diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java index b23c56a7c395..5b4f71da3963 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java @@ -36,7 +36,6 @@ public interface QueryResults extends Iterator { /** * Returns the Cursor for point after the value returned in the last {@link #next} call. - * Not currently implemented (depends on v1beta3). */ Cursor cursorAfter(); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java index caf5d7f8a84f..b3c51ceb9eeb 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java @@ -16,11 +16,11 @@ package com.google.gcloud.datastore; -import com.google.api.services.datastore.DatastoreV1; -import com.google.api.services.datastore.DatastoreV1.QueryResultBatch.MoreResultsType; +import com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType; import com.google.common.base.Preconditions; import com.google.common.collect.AbstractIterator; import com.google.gcloud.datastore.Query.ResultType; +import com.google.protobuf.ByteString; import java.util.Iterator; import java.util.Objects; @@ -28,46 +28,49 @@ class QueryResultsImpl extends AbstractIterator implements QueryResults { private final DatastoreImpl datastore; - private final DatastoreV1.ReadOptions readOptionsPb; - private final DatastoreV1.PartitionId partitionIdPb; + private final com.google.datastore.v1beta3.ReadOptions readOptionsPb; + private final com.google.datastore.v1beta3.PartitionId partitionIdPb; private final ResultType queryResultType; private Query query; private ResultType actualResultType; - private DatastoreV1.QueryResultBatch queryResultBatchPb; + private com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb; private boolean lastBatch; - private Iterator entityResultPbIter; - //private ByteString cursor; // only available in v1beta3 + private Iterator entityResultPbIter; + private ByteString cursor; - QueryResultsImpl(DatastoreImpl datastore, DatastoreV1.ReadOptions readOptionsPb, + QueryResultsImpl(DatastoreImpl datastore, com.google.datastore.v1beta3.ReadOptions readOptionsPb, Query query) { this.datastore = datastore; this.readOptionsPb = readOptionsPb; this.query = query; queryResultType = query.type(); - DatastoreV1.PartitionId.Builder pbBuilder = DatastoreV1.PartitionId.newBuilder(); - pbBuilder.setDatasetId(datastore.options().projectId()); + com.google.datastore.v1beta3.PartitionId.Builder pbBuilder = + com.google.datastore.v1beta3.PartitionId.newBuilder(); + pbBuilder.setProjectId(datastore.options().projectId()); if (query.namespace() != null) { - pbBuilder.setNamespace(query.namespace()); + pbBuilder.setNamespaceId(query.namespace()); } else if (datastore.options().namespace() != null) { - pbBuilder.setNamespace(datastore.options().namespace()); + pbBuilder.setNamespaceId(datastore.options().namespace()); } partitionIdPb = pbBuilder.build(); sendRequest(); } private void sendRequest() { - DatastoreV1.RunQueryRequest.Builder requestPb = DatastoreV1.RunQueryRequest.newBuilder(); + com.google.datastore.v1beta3.RunQueryRequest.Builder requestPb = + com.google.datastore.v1beta3.RunQueryRequest.newBuilder(); if (readOptionsPb != null) { requestPb.setReadOptions(readOptionsPb); } requestPb.setPartitionId(partitionIdPb); query.populatePb(requestPb); - // TODO(ajaykannan): fix me! - //queryResultBatchPb = datastore.runQuery(requestPb.build()).getBatch(); + queryResultBatchPb = datastore.runQuery(requestPb.build()).getBatch(); lastBatch = queryResultBatchPb.getMoreResults() != MoreResultsType.NOT_FINISHED; - entityResultPbIter = queryResultBatchPb.getEntityResultList().iterator(); - // cursor = resultPb.getSkippedCursor(); // available in v1beta3, use startCursor if not skipped + entityResultPbIter = queryResultBatchPb.getEntityResultsList().iterator(); + if (queryResultBatchPb.getSkippedResults() > 0) { + cursor = queryResultBatchPb.getSkippedCursor(); + } actualResultType = ResultType.fromPb(queryResultBatchPb.getEntityResultType()); if (Objects.equals(queryResultType, ResultType.PROJECTION_ENTITY)) { // projection entity can represent all type of results @@ -86,8 +89,8 @@ protected T computeNext() { if (!entityResultPbIter.hasNext()) { return endOfData(); } - DatastoreV1.EntityResult entityResultPb = entityResultPbIter.next(); - //cursor = entityResultPb.getCursor(); // only available in v1beta3 + com.google.datastore.v1beta3.EntityResult entityResultPb = entityResultPbIter.next(); + cursor = entityResultPb.getCursor(); @SuppressWarnings("unchecked") T result = (T) actualResultType.convert(entityResultPb.getEntity()); return result; @@ -100,7 +103,6 @@ public Class resultClass() { @Override public Cursor cursorAfter() { - //return new Cursor(cursor); // only available in v1beta3 - return null; + return new Cursor(cursor); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java index 1dd35cb4f191..7c1cf815879e 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java @@ -25,7 +25,6 @@ import static com.google.gcloud.datastore.LongValue.of; import static com.google.gcloud.datastore.StringValue.of; -import com.google.api.services.datastore.DatastoreV1; import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects.ToStringHelper; import com.google.common.base.Preconditions; @@ -103,13 +102,17 @@ public abstract static class Filter implements Serializable { Filter() { } - protected abstract DatastoreV1.Filter toPb(); + protected abstract com.google.datastore.v1beta3.Filter toPb(); - static Filter fromPb(DatastoreV1.Filter filterPb) { - if (filterPb.hasCompositeFilter()) { - return CompositeFilter.fromPb(filterPb.getCompositeFilter()); + static Filter fromPb(com.google.datastore.v1beta3.Filter filterPb) { + switch (filterPb.getFilterTypeCase()) { + case COMPOSITE_FILTER: + return CompositeFilter.fromPb(filterPb.getCompositeFilter()); + case PROPERTY_FILTER: + return PropertyFilter.fromPb(filterPb.getPropertyFilter()); + default: + return null; } - return PropertyFilter.fromPb(filterPb.getPropertyFilter()); } } @@ -122,11 +125,11 @@ public static final class CompositeFilter extends Filter { enum Operator { AND; - DatastoreV1.CompositeFilter.Operator toPb() { - return DatastoreV1.CompositeFilter.Operator.valueOf(name()); + com.google.datastore.v1beta3.CompositeFilter.Operator toPb() { + return com.google.datastore.v1beta3.CompositeFilter.Operator.valueOf(name()); } - static Operator fromPb(DatastoreV1.CompositeFilter.Operator operatorPb) { + static Operator fromPb(com.google.datastore.v1beta3.CompositeFilter.Operator operatorPb) { return valueOf(operatorPb.name()); } } @@ -169,11 +172,14 @@ public boolean equals(Object obj) { && filters.equals(other.filters); } - static CompositeFilter fromPb(DatastoreV1.CompositeFilter compositeFilterPb) { - Operator operator = Operator.fromPb(compositeFilterPb.getOperator()); + static CompositeFilter fromPb(com.google.datastore.v1beta3.CompositeFilter compositeFilterPb) { + Operator operator = Operator.fromPb(compositeFilterPb.getOp()); ImmutableList.Builder filters = ImmutableList.builder(); - for (DatastoreV1.Filter filterPb : compositeFilterPb.getFilterList()) { - filters.add(Filter.fromPb(filterPb)); + for (com.google.datastore.v1beta3.Filter filterPb : compositeFilterPb.getFiltersList()) { + Filter currFilter = Filter.fromPb(filterPb); + if (currFilter != null) { + filters.add(currFilter); + } } return new CompositeFilter(operator, filters.build()); } @@ -183,12 +189,14 @@ public static CompositeFilter and(Filter first, Filter... other) { } @Override - protected DatastoreV1.Filter toPb() { - DatastoreV1.Filter.Builder filterPb = DatastoreV1.Filter.newBuilder(); - DatastoreV1.CompositeFilter.Builder compositeFilterPb = filterPb.getCompositeFilterBuilder(); - compositeFilterPb.setOperator(operator.toPb()); + protected com.google.datastore.v1beta3.Filter toPb() { + com.google.datastore.v1beta3.Filter.Builder filterPb = + com.google.datastore.v1beta3.Filter.newBuilder(); + com.google.datastore.v1beta3.CompositeFilter.Builder compositeFilterPb = + filterPb.getCompositeFilterBuilder(); + compositeFilterPb.setOp(operator.toPb()); for (Filter filter : filters) { - compositeFilterPb.addFilter(filter.toPb()); + compositeFilterPb.addFilters(filter.toPb()); } return filterPb.build(); } @@ -210,11 +218,11 @@ enum Operator { EQUAL, HAS_ANCESTOR; - DatastoreV1.PropertyFilter.Operator toPb() { - return DatastoreV1.PropertyFilter.Operator.valueOf(name()); + com.google.datastore.v1beta3.PropertyFilter.Operator toPb() { + return com.google.datastore.v1beta3.PropertyFilter.Operator.valueOf(name()); } - static Operator fromPb(DatastoreV1.PropertyFilter.Operator operatorPb) { + static Operator fromPb(com.google.datastore.v1beta3.PropertyFilter.Operator operatorPb) { return valueOf(operatorPb.name()); } } @@ -225,13 +233,11 @@ private PropertyFilter(String property, Operator operator, Value value) { this.value = checkNotNull(value); } - public static PropertyFilter fromPb(DatastoreV1.PropertyFilter propertyFilterPb) { + public static PropertyFilter fromPb(com.google.datastore.v1beta3.PropertyFilter propertyFilterPb) { String property = propertyFilterPb.getProperty().getName(); - Operator operator = Operator.fromPb(propertyFilterPb.getOperator()); - // TODO(ajaykannan): fix me! - //Value value = Value.fromPb(propertyFilterPb.getValue()); - //return new PropertyFilter(property, operator, value); - return new PropertyFilter(property, operator, null); // TODO(ajaykannan): fix me! + Operator operator = Operator.fromPb(propertyFilterPb.getOp()); + Value value = Value.fromPb(propertyFilterPb.getValue()); + return new PropertyFilter(property, operator, value); } @Override @@ -431,14 +437,15 @@ public static PropertyFilter isNull(String property) { } @Override - protected DatastoreV1.Filter toPb() { - DatastoreV1.Filter.Builder filterPb = DatastoreV1.Filter.newBuilder(); - DatastoreV1.PropertyFilter.Builder propertyFilterPb = filterPb.getPropertyFilterBuilder(); + protected com.google.datastore.v1beta3.Filter toPb() { + com.google.datastore.v1beta3.Filter.Builder filterPb = + com.google.datastore.v1beta3.Filter.newBuilder(); + com.google.datastore.v1beta3.PropertyFilter.Builder propertyFilterPb = + filterPb.getPropertyFilterBuilder(); propertyFilterPb.getPropertyBuilder().setName(property); - propertyFilterPb.setOperator(operator.toPb()); + propertyFilterPb.setOp(operator.toPb()); if (value != null) { - // TODO(ajaykannan): fix me! - //propertyFilterPb.setValue(value.toPb()); + propertyFilterPb.setValue(value.toPb()); } return filterPb.build(); } @@ -455,11 +462,11 @@ public enum Direction { ASCENDING, DESCENDING; - DatastoreV1.PropertyOrder.Direction toPb() { - return DatastoreV1.PropertyOrder.Direction.valueOf(name()); + com.google.datastore.v1beta3.PropertyOrder.Direction toPb() { + return com.google.datastore.v1beta3.PropertyOrder.Direction.valueOf(name()); } - static Direction fromPb(DatastoreV1.PropertyOrder.Direction directionPb) { + static Direction fromPb(com.google.datastore.v1beta3.PropertyOrder.Direction directionPb) { return valueOf(directionPb.name()); } } @@ -495,10 +502,11 @@ public Direction direction() { return direction; } - DatastoreV1.PropertyOrder toPb() { - return DatastoreV1.PropertyOrder.newBuilder() + com.google.datastore.v1beta3.PropertyOrder toPb() { + return com.google.datastore.v1beta3.PropertyOrder.newBuilder() .setDirection(direction.toPb()) - .setProperty(DatastoreV1.PropertyReference.newBuilder().setName(property).build()) + .setProperty(com.google.datastore.v1beta3.PropertyReference.newBuilder() + .setName(property).build()) .build(); } @@ -510,7 +518,7 @@ public static OrderBy desc(String property) { return new OrderBy(property, OrderBy.Direction.DESCENDING); } - static OrderBy fromPb(DatastoreV1.PropertyOrder propertyOrderPb) { + static OrderBy fromPb(com.google.datastore.v1beta3.PropertyOrder propertyOrderPb) { String property = propertyOrderPb.getProperty().getName(); Direction direction = Direction.fromPb(propertyOrderPb.getDirection()); return new OrderBy(property, direction); @@ -521,30 +529,15 @@ public static final class Projection implements Serializable { private static final long serialVersionUID = 3083707957256279470L; - private final Aggregate aggregate; private final String property; - public enum Aggregate { - - FIRST; - - DatastoreV1.PropertyExpression.AggregationFunction toPb() { - return DatastoreV1.PropertyExpression.AggregationFunction.valueOf(name()); - } - - static Aggregate fromPb(DatastoreV1.PropertyExpression.AggregationFunction aggregatePb) { - return valueOf(aggregatePb.name()); - } - } - - private Projection(Aggregate aggregate, String property) { - this.aggregate = aggregate; + private Projection(String property) { this.property = property; } @Override public int hashCode() { - return Objects.hash(property, aggregate); + return Objects.hash(property); } @Override @@ -555,51 +548,31 @@ public boolean equals(Object obj) { if (!(obj instanceof Projection)) { return false; } - Projection other = (Projection) obj; - return Objects.equals(property, other.property) - && Objects.equals(aggregate, other.aggregate); + return Objects.equals(property, ((Projection) obj).property); } @Override public String toString() { ToStringHelper toStringHelper = MoreObjects.toStringHelper(this); toStringHelper.add("property", property); - if (aggregate != null) { - toStringHelper.add("aggregate", aggregate); - } return toStringHelper.toString(); } - DatastoreV1.PropertyExpression toPb() { - DatastoreV1.PropertyExpression.Builder expressionPb = - DatastoreV1.PropertyExpression.newBuilder(); - if (aggregate != null) { - expressionPb.setAggregationFunction(aggregate.toPb()); - } + com.google.datastore.v1beta3.Projection toPb() { + com.google.datastore.v1beta3.Projection.Builder expressionPb = + com.google.datastore.v1beta3.Projection.newBuilder(); expressionPb.setProperty( - DatastoreV1.PropertyReference.newBuilder().setName(property).build()); + com.google.datastore.v1beta3.PropertyReference.newBuilder().setName(property).build()); return expressionPb.build(); } - public static Projection fromPb(DatastoreV1.PropertyExpression propertyExpressionPb) { - String property = propertyExpressionPb.getProperty().getName(); - Aggregate aggregate = null; - if (propertyExpressionPb.hasAggregationFunction()) { - aggregate = Aggregate.fromPb(propertyExpressionPb.getAggregationFunction()); - } - return new Projection(aggregate, property); + public static Projection fromPb( + com.google.datastore.v1beta3.Projection projectionPb) { + return new Projection(projectionPb.getProperty().getName()); } public static Projection property(String property) { - return new Projection(null, property); - } - - public static Projection aggregate(Aggregate aggregate, String property) { - return new Projection(aggregate, property); - } - - public static Projection first(String property) { - return new Projection(Aggregate.FIRST, property); + return new Projection(property); } } @@ -714,32 +687,34 @@ B addGroupBy(String property, String... others) { return self(); } - B mergeFrom(DatastoreV1.Query queryPb) { + B mergeFrom(com.google.datastore.v1beta3.Query queryPb) { if (queryPb.getKindCount() > 0) { kind(queryPb.getKind(0).getName()); } - if (queryPb.hasStartCursor()) { + if (!queryPb.getStartCursor().isEmpty()) { startCursor(new Cursor(queryPb.getStartCursor())); } - if (queryPb.hasEndCursor()) { + if (!queryPb.getEndCursor().isEmpty()) { endCursor(new Cursor(queryPb.getEndCursor())); } - if (queryPb.hasOffset()) { - offset(queryPb.getOffset()); - } + offset(queryPb.getOffset()); if (queryPb.hasLimit()) { - limit(queryPb.getLimit()); + limit(queryPb.getLimit().getValue()); } if (queryPb.hasFilter()) { - filter(Filter.fromPb(queryPb.getFilter())); + Filter currFilter = Filter.fromPb(queryPb.getFilter()); + if (currFilter != null) { + filter(currFilter); + } } - for (DatastoreV1.PropertyOrder orderByPb : queryPb.getOrderList()) { + for (com.google.datastore.v1beta3.PropertyOrder orderByPb : queryPb.getOrderList()) { addOrderBy(OrderBy.fromPb(orderByPb)); } - for (DatastoreV1.PropertyExpression projectionPb : queryPb.getProjectionList()) { + for (com.google.datastore.v1beta3.Projection projectionPb + : queryPb.getProjectionList()) { addProjection(Projection.fromPb(projectionPb)); } - for (DatastoreV1.PropertyReference groupByPb : queryPb.getGroupByList()) { + for (com.google.datastore.v1beta3.PropertyReference groupByPb : queryPb.getDistinctOnList()) { addGroupBy(groupByPb.getName()); } return self(); @@ -777,7 +752,7 @@ public static final class KeyQueryBuilder extends BaseBuilder nextQuery(DatastoreV1.QueryResultBatch responsePb) { + protected StructuredQuery nextQuery(com.google.datastore.v1beta3.QueryResultBatch responsePb) { Builder builder = new Builder<>(type()); builder.mergeFrom(toPb()); builder.startCursor(new Cursor(responsePb.getEndCursor())); @@ -929,15 +904,16 @@ protected StructuredQuery nextQuery(DatastoreV1.QueryResultBatch responsePb) } else { builder.offset(0); if (limit != null) { - builder.limit(limit - responsePb.getEntityResultCount()); + builder.limit(limit - responsePb.getEntityResultsCount()); } } return builder.build(); } @Override - protected DatastoreV1.Query toPb() { - DatastoreV1.Query.Builder queryPb = DatastoreV1.Query.newBuilder(); + protected com.google.datastore.v1beta3.Query toPb() { + com.google.datastore.v1beta3.Query.Builder queryPb = + com.google.datastore.v1beta3.Query.newBuilder(); if (kind != null) { queryPb.addKindBuilder().setName(kind); } @@ -951,7 +927,7 @@ protected DatastoreV1.Query toPb() { queryPb.setOffset(offset); } if (limit != null) { - queryPb.setLimit(limit); + queryPb.setLimit(com.google.protobuf.Int32Value.newBuilder().setValue(limit.intValue())); } if (filter != null) { queryPb.setFilter(filter.toPb()); @@ -960,7 +936,8 @@ protected DatastoreV1.Query toPb() { queryPb.addOrder(value.toPb()); } for (String value : groupBy) { - queryPb.addGroupBy(DatastoreV1.PropertyReference.newBuilder().setName(value).build()); + queryPb.addDistinctOn(com.google.datastore.v1beta3.PropertyReference.newBuilder() + .setName(value).build()); } for (Projection value : projection) { queryPb.addProjection(value.toPb()); @@ -971,11 +948,11 @@ protected DatastoreV1.Query toPb() { @Override protected Object fromPb(ResultType resultType, String namespace, byte[] bytesPb) throws InvalidProtocolBufferException { - return fromPb(resultType, namespace, DatastoreV1.Query.parseFrom(bytesPb)); + return fromPb(resultType, namespace, com.google.datastore.v1beta3.Query.parseFrom(bytesPb)); } private static StructuredQuery fromPb(ResultType resultType, String namespace, - DatastoreV1.Query queryPb) { + com.google.datastore.v1beta3.Query queryPb) { BaseBuilder builder; if (resultType.equals(ResultType.ENTITY)) { builder = new EntityQueryBuilder(); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index 689d2a7b8b6b..e3a71d8a8aa2 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -115,9 +115,9 @@ public void setUp() throws IOException, InterruptedException { .host("localhost:" + LocalGcdHelper.PORT) .build(); datastore = DatastoreFactory.instance().get(options); - //StructuredQuery query = Query.keyQueryBuilder().build(); - //QueryResults result = datastore.run(query); - //datastore.delete(Iterators.toArray(result, Key.class)); + StructuredQuery query = Query.keyQueryBuilder().build(); + QueryResults result = datastore.run(query); + datastore.delete(Iterators.toArray(result, Key.class)); datastore.add(ENTITY1, ENTITY2); } @@ -188,7 +188,7 @@ public void testTransactionWithRead() { assertEquals(DatastoreException.Code.ABORTED, expected.code()); } } - /* TODO(ajaykannan): fix me! + @Test public void testTransactionWithQuery() { Query query = Query.entityQueryBuilder() @@ -216,7 +216,7 @@ public void testTransactionWithQuery() { assertEquals(DatastoreException.Code.ABORTED, expected.code()); } } - */ + @Test public void testNewTransactionRollback() { Transaction transaction = datastore.newTransaction(); @@ -331,7 +331,7 @@ public void testNewBatch() { assertNull(entities.get(4)); assertEquals(5, entities.size()); } - /* TODO(ajaykannan): fix me! + @Test public void testRunGqlQueryNoCasting() { Query query1 = Query.gqlQueryBuilder(ResultType.ENTITY, "select * from " + KIND1).build(); @@ -431,7 +431,7 @@ public void testRunStructuredQuery() { StructuredQuery projectionQuery = Query.projectionEntityQueryBuilder() .kind(KIND2) - .projection(Projection.property("age"), Projection.first("name")) + .projection(Projection.property("age")) .filter(PropertyFilter.gt("age", 18)) .groupBy("age") .orderBy(OrderBy.asc("age")) @@ -443,12 +443,11 @@ public void testRunStructuredQuery() { ProjectionEntity entity = results4.next(); assertEquals(ENTITY2.key(), entity.key()); assertEquals(20, entity.getLong("age")); - assertEquals("Dan", entity.getString("name")); - assertEquals(2, entity.properties().size()); + assertEquals(1, entity.properties().size()); assertFalse(results4.hasNext()); // TODO(ozarov): construct a test to verify nextQuery/pagination } - */ + @Test public void testAllocateId() { KeyFactory keyFactory = datastore.newKeyFactory().kind(KIND1); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index bd4a683f9c9c..0c65ab76c681 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -122,9 +122,8 @@ public class SerializationTest { .put(ValueType.NULL, NULL_VALUE) .put(ValueType.KEY, KEY_VALUE) .put(ValueType.STRING, STRING_VALUE) - // TODO(ajaykannan): fix me! - //.putAll(ValueType.ENTITY, EMBEDDED_ENTITY_VALUE1, EMBEDDED_ENTITY_VALUE2, - // EMBEDDED_ENTITY_VALUE3) + .putAll(ValueType.ENTITY, EMBEDDED_ENTITY_VALUE1, EMBEDDED_ENTITY_VALUE2, + EMBEDDED_ENTITY_VALUE3) .put(ValueType.LIST, LIST_VALUE) .put(ValueType.LONG, LONG_VALUE) .put(ValueType.DOUBLE, DOUBLE_VALUE) @@ -169,10 +168,9 @@ public void testValues() throws Exception { @Test public void testTypes() throws Exception { - // TODO(ajaykannan): fix me! - Serializable[] types = { KEY1, KEY2, INCOMPLETE_KEY1, INCOMPLETE_KEY2, /*ENTITY1, ENTITY2, - ENTITY3, EMBEDDED_ENTITY, PROJECTION_ENTITY,*/ DATE_TIME1, BLOB1/*, CURSOR1, GQL1, GQL2, - QUERY1, QUERY2, QUERY3*/}; + Serializable[] types = { KEY1, KEY2, INCOMPLETE_KEY1, INCOMPLETE_KEY2, ENTITY1, ENTITY2, + ENTITY3, EMBEDDED_ENTITY, PROJECTION_ENTITY, DATE_TIME1, BLOB1, CURSOR1, GQL1, GQL2, + QUERY1, QUERY2, QUERY3}; for (Serializable obj : types) { Object copy = serializeAndDeserialize(obj); assertEquals(obj, obj); From 16afb0d0ba2f67f61f8027391440b9686479423f Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 13 Oct 2015 12:11:55 -0700 Subject: [PATCH 009/375] fix distinct and cursor code --- .../com/google/gcloud/datastore/GqlQuery.java | 15 +- .../com/google/gcloud/datastore/Query.java | 2 +- .../gcloud/datastore/QueryResultsImpl.java | 4 + .../gcloud/datastore/StructuredQuery.java | 150 +++++++----------- .../gcloud/datastore/DatastoreTest.java | 7 +- .../gcloud/datastore/SerializationTest.java | 5 +- 6 files changed, 73 insertions(+), 110 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java index 2c02aa7b970c..8e023c0c224e 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java @@ -20,6 +20,7 @@ import static com.google.gcloud.datastore.Validator.validateNamespace; import com.google.common.base.MoreObjects; +import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSortedMap; @@ -137,10 +138,8 @@ static Binding fromPb(com.google.datastore.v1beta3.GqlQueryParameter argPb) { switch (argPb.getParameterTypeCase()) { case CURSOR: return new Binding(new Cursor(argPb.getCursor())); - case VALUE: - return new Binding(Value.fromPb(argPb.getValue())); default: - return null; + return new Binding(Value.fromPb(argPb.getValue())); } } } @@ -398,16 +397,14 @@ private static GqlQuery fromPb( for (Map.Entry nameArg : queryPb.getNamedBindings().entrySet()) { Binding currBinding = Binding.fromPb(nameArg.getValue()); - if (currBinding != null) { - builder.namedBindings.put(nameArg.getKey(), currBinding); - } + Preconditions.checkState(currBinding != null); + builder.namedBindings.put(nameArg.getKey(), currBinding); } for (com.google.datastore.v1beta3.GqlQueryParameter numberArg : queryPb.getPositionalBindingsList()) { Binding currBinding = Binding.fromPb(numberArg); - if (currBinding != null) { - builder.positionalBindings.add(currBinding); - } + Preconditions.checkState(currBinding != null); + builder.positionalBindings.add(currBinding); } return builder.build(); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java index 6e962d92fb2f..c45efde3e30d 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java @@ -62,7 +62,7 @@ public abstract static class ResultType implements java.io.Serializable { private static final long serialVersionUID = 1602329532153860907L; @Override protected Object convert(com.google.datastore.v1beta3.Entity entityPb) { - if (entityPb.getProperties().size() == 0) { + if (entityPb.getProperties().isEmpty()) { if (!entityPb.hasKey()) { return null; } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java index b3c51ceb9eeb..40f1aee9dc5e 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java @@ -70,6 +70,10 @@ private void sendRequest() { entityResultPbIter = queryResultBatchPb.getEntityResultsList().iterator(); if (queryResultBatchPb.getSkippedResults() > 0) { cursor = queryResultBatchPb.getSkippedCursor(); + } else if (entityResultPbIter.hasNext()) { + cursor = queryResultBatchPb.getEntityResults(0).getCursor(); + } else { + cursor = queryResultBatchPb.getEndCursor(); } actualResultType = ResultType.fromPb(queryResultBatchPb.getEntityResultType()); if (Objects.equals(queryResultType, ResultType.PROJECTION_ENTITY)) { diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java index 7c1cf815879e..4151ae4b462c 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java @@ -68,7 +68,7 @@ * .kind(kind) * .projection(Projection.property("age"), Projection.first("name")) * .filter(PropertyFilter.gt("age", 18)) - * .groupBy("age") + * .distinct("age") * .orderBy(OrderBy.asc("age")) * .limit(10) * .build(); @@ -86,9 +86,9 @@ public class StructuredQuery extends Query { private static final String KEY_PROPERTY_NAME = "__key__"; private final transient String kind; - private final ImmutableList projection; + private final ImmutableList projection; private final transient Filter filter; - private final ImmutableList groupBy; + private final ImmutableList distinctOn; private final transient ImmutableList orderBy; private final transient Cursor startCursor; private final transient Cursor endCursor; @@ -108,10 +108,8 @@ static Filter fromPb(com.google.datastore.v1beta3.Filter filterPb) { switch (filterPb.getFilterTypeCase()) { case COMPOSITE_FILTER: return CompositeFilter.fromPb(filterPb.getCompositeFilter()); - case PROPERTY_FILTER: - return PropertyFilter.fromPb(filterPb.getPropertyFilter()); default: - return null; + return PropertyFilter.fromPb(filterPb.getPropertyFilter()); } } } @@ -525,65 +523,15 @@ static OrderBy fromPb(com.google.datastore.v1beta3.PropertyOrder propertyOrderPb } } - public static final class Projection implements Serializable { - - private static final long serialVersionUID = 3083707957256279470L; - - private final String property; - - private Projection(String property) { - this.property = property; - } - - @Override - public int hashCode() { - return Objects.hash(property); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof Projection)) { - return false; - } - return Objects.equals(property, ((Projection) obj).property); - } - - @Override - public String toString() { - ToStringHelper toStringHelper = MoreObjects.toStringHelper(this); - toStringHelper.add("property", property); - return toStringHelper.toString(); - } - - com.google.datastore.v1beta3.Projection toPb() { - com.google.datastore.v1beta3.Projection.Builder expressionPb = - com.google.datastore.v1beta3.Projection.newBuilder(); - expressionPb.setProperty( - com.google.datastore.v1beta3.PropertyReference.newBuilder().setName(property).build()); - return expressionPb.build(); - } - - public static Projection fromPb( - com.google.datastore.v1beta3.Projection projectionPb) { - return new Projection(projectionPb.getProperty().getName()); - } - - public static Projection property(String property) { - return new Projection(property); - } - } - static class BaseBuilder> { private final ResultType resultType; private String namespace; private String kind; - private final List projection = new LinkedList<>(); + private final List projection = new LinkedList<>(); private Filter filter; - private final List groupBy = new LinkedList<>(); + private boolean distinctOnAll = false; + private final List distinctOn = new LinkedList<>(); private final List orderBy = new LinkedList<>(); private Cursor startCursor; private Cursor endCursor; @@ -658,32 +606,39 @@ B clearProjection() { return self(); } - B projection(Projection projection, Projection... others) { + B projection(String projection, String... others) { clearProjection(); addProjection(projection, others); return self(); } - B addProjection(Projection projection, Projection... others) { + B addProjection(String projection, String... others) { this.projection.add(projection); Collections.addAll(this.projection, others); return self(); } - B clearGroupBy() { - groupBy.clear(); + B clearDistinct() { + distinctOn.clear(); + distinctOnAll = false; return self(); } - B groupBy(String property, String... others) { - clearGroupBy(); - addGroupBy(property, others); + B distinct(String... properties) { + clearDistinct(); + if (properties.length == 0) { + this.distinctOnAll = true; + } else if (properties.length == 1) { + addDistinct(properties[0]); + } else { + addDistinct(properties[0], Arrays.copyOfRange(properties, 1, properties.length)); + } return self(); } - B addGroupBy(String property, String... others) { - this.groupBy.add(property); - Collections.addAll(this.groupBy, others); + B addDistinct(String property, String... others) { + this.distinctOn.add(property); + Collections.addAll(this.distinctOn, others); return self(); } @@ -712,15 +667,20 @@ B mergeFrom(com.google.datastore.v1beta3.Query queryPb) { } for (com.google.datastore.v1beta3.Projection projectionPb : queryPb.getProjectionList()) { - addProjection(Projection.fromPb(projectionPb)); + addProjection(projectionPb.getProperty().getName()); } - for (com.google.datastore.v1beta3.PropertyReference groupByPb : queryPb.getDistinctOnList()) { - addGroupBy(groupByPb.getName()); + for (com.google.datastore.v1beta3.PropertyReference distinctOnPb : queryPb.getDistinctOnList()) { + addDistinct(distinctOnPb.getName()); } + distinctOnAll = false; return self(); } public StructuredQuery build() { + if (distinctOnAll) { + clearDistinct(); + this.distinctOn.addAll(this.projection); + } return new StructuredQuery<>(this); } } @@ -748,14 +708,14 @@ public static final class KeyQueryBuilder extends BaseBuilder projection() { + public List projection() { return projection; } @@ -865,8 +825,8 @@ public Filter filter() { return filter; } - public List groupBy() { - return groupBy; + public List distinct() { + return distinctOn; } public ImmutableList orderBy() { @@ -935,12 +895,16 @@ protected com.google.datastore.v1beta3.Query toPb() { for (OrderBy value : orderBy) { queryPb.addOrder(value.toPb()); } - for (String value : groupBy) { + for (String value : distinctOn) { queryPb.addDistinctOn(com.google.datastore.v1beta3.PropertyReference.newBuilder() .setName(value).build()); } - for (Projection value : projection) { - queryPb.addProjection(value.toPb()); + for (String value : projection) { + com.google.datastore.v1beta3.Projection.Builder expressionPb = + com.google.datastore.v1beta3.Projection.newBuilder(); + expressionPb.setProperty( + com.google.datastore.v1beta3.PropertyReference.newBuilder().setName(value).build()); + queryPb.addProjection(expressionPb.build()); } return queryPb.build(); } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index e3a71d8a8aa2..41f0c4df8d92 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -29,7 +29,6 @@ import com.google.gcloud.RetryParams; import com.google.gcloud.datastore.Query.ResultType; import com.google.gcloud.datastore.StructuredQuery.OrderBy; -import com.google.gcloud.datastore.StructuredQuery.Projection; import com.google.gcloud.datastore.StructuredQuery.PropertyFilter; import com.google.gcloud.spi.DatastoreRpc; import com.google.gcloud.spi.DatastoreRpc.DatastoreRpcException.Reason; @@ -421,7 +420,7 @@ public void testRunStructuredQuery() { StructuredQuery keyOnlyProjectionQuery = Query.projectionEntityQueryBuilder() - .kind(KIND1).projection(Projection.property("__key__")).build(); + .kind(KIND1).projection("__key__").build(); QueryResults results3 = datastore.run(keyOnlyProjectionQuery); assertTrue(results3.hasNext()); ProjectionEntity projectionEntity = results3.next(); @@ -431,9 +430,9 @@ public void testRunStructuredQuery() { StructuredQuery projectionQuery = Query.projectionEntityQueryBuilder() .kind(KIND2) - .projection(Projection.property("age")) + .projection("age") .filter(PropertyFilter.gt("age", 18)) - .groupBy("age") + .distinct("age") .orderBy(OrderBy.asc("age")) .limit(10) .build(); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index 0c65ab76c681..d946246db279 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -26,7 +26,6 @@ import com.google.gcloud.RetryParams; import com.google.gcloud.datastore.StructuredQuery.CompositeFilter; import com.google.gcloud.datastore.StructuredQuery.OrderBy; -import com.google.gcloud.datastore.StructuredQuery.Projection; import com.google.gcloud.datastore.StructuredQuery.PropertyFilter; import org.junit.Test; @@ -71,13 +70,13 @@ public class SerializationTest { private static final Query QUERY3 = Query.projectionEntityQueryBuilder() .kind("k") .namespace("ns1") - .projection(Projection.property("p")) + .projection("p") .limit(100) .offset(5) .startCursor(CURSOR1) .endCursor(CURSOR2) .filter(CompositeFilter.and(PropertyFilter.gt("p1", 10), PropertyFilter.eq("a", "v"))) - .addGroupBy("p") + .addDistinct("p") .addOrderBy(OrderBy.asc("p")) .build(); private static final KeyValue KEY_VALUE = KeyValue.of(KEY1); From acf2c4207f384d9e4d8f7ce958a1d7ac2263ff7a Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Wed, 14 Oct 2015 18:55:30 -0700 Subject: [PATCH 010/375] Include cursor workaround, fix distinct in StructuredQuery, and remove extra checks --- .../com/google/gcloud/datastore/GqlQuery.java | 7 +++---- .../gcloud/datastore/QueryResultsImpl.java | 14 ++++++------- .../gcloud/datastore/StructuredQuery.java | 20 ++++++++++--------- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java index 8e023c0c224e..7fcb562fea89 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java @@ -20,7 +20,6 @@ import static com.google.gcloud.datastore.Validator.validateNamespace; import com.google.common.base.MoreObjects; -import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSortedMap; @@ -138,8 +137,10 @@ static Binding fromPb(com.google.datastore.v1beta3.GqlQueryParameter argPb) { switch (argPb.getParameterTypeCase()) { case CURSOR: return new Binding(new Cursor(argPb.getCursor())); - default: + case VALUE: return new Binding(Value.fromPb(argPb.getValue())); + default: + throw new AssertionError("Unexpected enum value " + argPb.getParameterTypeCase()); } } } @@ -397,13 +398,11 @@ private static GqlQuery fromPb( for (Map.Entry nameArg : queryPb.getNamedBindings().entrySet()) { Binding currBinding = Binding.fromPb(nameArg.getValue()); - Preconditions.checkState(currBinding != null); builder.namedBindings.put(nameArg.getKey(), currBinding); } for (com.google.datastore.v1beta3.GqlQueryParameter numberArg : queryPb.getPositionalBindingsList()) { Binding currBinding = Binding.fromPb(numberArg); - Preconditions.checkState(currBinding != null); builder.positionalBindings.add(currBinding); } return builder.build(); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java index 40f1aee9dc5e..38eb3dd1c393 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java @@ -16,9 +16,9 @@ package com.google.gcloud.datastore; -import com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType; import com.google.common.base.Preconditions; import com.google.common.collect.AbstractIterator; +import com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType; import com.google.gcloud.datastore.Query.ResultType; import com.google.protobuf.ByteString; @@ -55,6 +55,11 @@ class QueryResultsImpl extends AbstractIterator implements QueryResults } partitionIdPb = pbBuilder.build(); sendRequest(); + if (queryResultBatchPb.getSkippedResults() > 0) { + cursor = queryResultBatchPb.getSkippedCursor(); + } else { + cursor = ByteString.EMPTY; + } } private void sendRequest() { @@ -68,13 +73,6 @@ private void sendRequest() { queryResultBatchPb = datastore.runQuery(requestPb.build()).getBatch(); lastBatch = queryResultBatchPb.getMoreResults() != MoreResultsType.NOT_FINISHED; entityResultPbIter = queryResultBatchPb.getEntityResultsList().iterator(); - if (queryResultBatchPb.getSkippedResults() > 0) { - cursor = queryResultBatchPb.getSkippedCursor(); - } else if (entityResultPbIter.hasNext()) { - cursor = queryResultBatchPb.getEntityResults(0).getCursor(); - } else { - cursor = queryResultBatchPb.getEndCursor(); - } actualResultType = ResultType.fromPb(queryResultBatchPb.getEntityResultType()); if (Objects.equals(queryResultType, ResultType.PROJECTION_ENTITY)) { // projection entity can represent all type of results diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java index 4151ae4b462c..c49ddddc9c02 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java @@ -108,8 +108,10 @@ static Filter fromPb(com.google.datastore.v1beta3.Filter filterPb) { switch (filterPb.getFilterTypeCase()) { case COMPOSITE_FILTER: return CompositeFilter.fromPb(filterPb.getCompositeFilter()); - default: + case PROPERTY_FILTER: return PropertyFilter.fromPb(filterPb.getPropertyFilter()); + default: + throw new AssertionError("Unexpected enum value " + filterPb.getFilterTypeCase()); } } } @@ -530,7 +532,7 @@ static class BaseBuilder> { private String kind; private final List projection = new LinkedList<>(); private Filter filter; - private boolean distinctOnAll = false; + private boolean distinct = false; private final List distinctOn = new LinkedList<>(); private final List orderBy = new LinkedList<>(); private Cursor startCursor; @@ -620,14 +622,16 @@ B addProjection(String projection, String... others) { B clearDistinct() { distinctOn.clear(); - distinctOnAll = false; + distinct = false; return self(); } B distinct(String... properties) { clearDistinct(); if (properties.length == 0) { - this.distinctOnAll = true; + clearDistinct(); + this.distinct = true; + this.distinctOn.addAll(this.projection); } else if (properties.length == 1) { addDistinct(properties[0]); } else { @@ -637,6 +641,9 @@ B distinct(String... properties) { } B addDistinct(String property, String... others) { + if (this.distinct) { + throw new IllegalStateException("\"distinct()\" is currently set."); + } this.distinctOn.add(property); Collections.addAll(this.distinctOn, others); return self(); @@ -672,15 +679,10 @@ B mergeFrom(com.google.datastore.v1beta3.Query queryPb) { for (com.google.datastore.v1beta3.PropertyReference distinctOnPb : queryPb.getDistinctOnList()) { addDistinct(distinctOnPb.getName()); } - distinctOnAll = false; return self(); } public StructuredQuery build() { - if (distinctOnAll) { - clearDistinct(); - this.distinctOn.addAll(this.projection); - } return new StructuredQuery<>(this); } } From 0c2f9e93ffb78aadb55c3abf558e47c616336c18 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Thu, 15 Oct 2015 15:52:50 -0700 Subject: [PATCH 011/375] standardize distinctOn naming --- .../gcloud/datastore/StructuredQuery.java | 45 +++++++------------ .../gcloud/datastore/DatastoreTest.java | 17 +++---- .../gcloud/datastore/SerializationTest.java | 25 ++++++----- 3 files changed, 38 insertions(+), 49 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java index c49ddddc9c02..1b82991cb8c8 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java @@ -68,7 +68,7 @@ * .kind(kind) * .projection(Projection.property("age"), Projection.first("name")) * .filter(PropertyFilter.gt("age", 18)) - * .distinct("age") + * .distinctOn("age") * .orderBy(OrderBy.asc("age")) * .limit(10) * .build(); @@ -532,7 +532,6 @@ static class BaseBuilder> { private String kind; private final List projection = new LinkedList<>(); private Filter filter; - private boolean distinct = false; private final List distinctOn = new LinkedList<>(); private final List orderBy = new LinkedList<>(); private Cursor startCursor; @@ -620,30 +619,18 @@ B addProjection(String projection, String... others) { return self(); } - B clearDistinct() { + B clearDistinctOn() { distinctOn.clear(); - distinct = false; return self(); } - B distinct(String... properties) { - clearDistinct(); - if (properties.length == 0) { - clearDistinct(); - this.distinct = true; - this.distinctOn.addAll(this.projection); - } else if (properties.length == 1) { - addDistinct(properties[0]); - } else { - addDistinct(properties[0], Arrays.copyOfRange(properties, 1, properties.length)); - } + B distinctOn(String property, String... others) { + clearDistinctOn(); + addDistinctOn(property, others); return self(); } - B addDistinct(String property, String... others) { - if (this.distinct) { - throw new IllegalStateException("\"distinct()\" is currently set."); - } + B addDistinctOn(String property, String... others) { this.distinctOn.add(property); Collections.addAll(this.distinctOn, others); return self(); @@ -677,7 +664,7 @@ B mergeFrom(com.google.datastore.v1beta3.Query queryPb) { addProjection(projectionPb.getProperty().getName()); } for (com.google.datastore.v1beta3.PropertyReference distinctOnPb : queryPb.getDistinctOnList()) { - addDistinct(distinctOnPb.getName()); + addDistinctOn(distinctOnPb.getName()); } return self(); } @@ -717,7 +704,7 @@ public static final class KeyQueryBuilder extends BaseBuilder distinct() { + public List distinctOn() { return distinctOn; } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index 41f0c4df8d92..f0fbd4ab96c0 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -428,14 +428,15 @@ public void testRunStructuredQuery() { assertTrue(projectionEntity.names().isEmpty()); assertFalse(results2.hasNext()); - StructuredQuery projectionQuery = Query.projectionEntityQueryBuilder() - .kind(KIND2) - .projection("age") - .filter(PropertyFilter.gt("age", 18)) - .distinct("age") - .orderBy(OrderBy.asc("age")) - .limit(10) - .build(); + StructuredQuery projectionQuery = + Query.projectionEntityQueryBuilder() + .kind(KIND2) + .projection("age") + .filter(PropertyFilter.gt("age", 18)) + .distinctOn("age") + .orderBy(OrderBy.asc("age")) + .limit(10) + .build(); QueryResults results4 = datastore.run(projectionQuery); assertTrue(results4.hasNext()); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index d946246db279..2e083250f35e 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -67,18 +67,19 @@ public class SerializationTest { .kind("k") .filter(PropertyFilter.eq("p1", "hello")) .build(); - private static final Query QUERY3 = Query.projectionEntityQueryBuilder() - .kind("k") - .namespace("ns1") - .projection("p") - .limit(100) - .offset(5) - .startCursor(CURSOR1) - .endCursor(CURSOR2) - .filter(CompositeFilter.and(PropertyFilter.gt("p1", 10), PropertyFilter.eq("a", "v"))) - .addDistinct("p") - .addOrderBy(OrderBy.asc("p")) - .build(); + private static final Query QUERY3 = + Query.projectionEntityQueryBuilder() + .kind("k") + .namespace("ns1") + .projection("p") + .limit(100) + .offset(5) + .startCursor(CURSOR1) + .endCursor(CURSOR2) + .filter(CompositeFilter.and(PropertyFilter.gt("p1", 10), PropertyFilter.eq("a", "v"))) + .addDistinctOn("p") + .addOrderBy(OrderBy.asc("p")) + .build(); private static final KeyValue KEY_VALUE = KeyValue.of(KEY1); private static final NullValue NULL_VALUE = NullValue.builder().excludeFromIndexes(true).build(); private static final StringValue STRING_VALUE = StringValue.of("hello"); From 35ea69a5a4102de920f7732b52e29ebc8372d974 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 16 Oct 2015 11:06:08 -0700 Subject: [PATCH 012/375] Add missing case for start_cursor --- .../com/google/gcloud/datastore/QueryResultsImpl.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java index 38eb3dd1c393..bb2b65fcc646 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java @@ -34,6 +34,7 @@ class QueryResultsImpl extends AbstractIterator implements QueryResults private Query query; private ResultType actualResultType; private com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb; + private com.google.datastore.v1beta3.Query mostRecentQueryPb; private boolean lastBatch; private Iterator entityResultPbIter; private ByteString cursor; @@ -58,7 +59,7 @@ class QueryResultsImpl extends AbstractIterator implements QueryResults if (queryResultBatchPb.getSkippedResults() > 0) { cursor = queryResultBatchPb.getSkippedCursor(); } else { - cursor = ByteString.EMPTY; + cursor = mostRecentQueryPb.getStartCursor(); } } @@ -70,7 +71,13 @@ private void sendRequest() { } requestPb.setPartitionId(partitionIdPb); query.populatePb(requestPb); - queryResultBatchPb = datastore.runQuery(requestPb.build()).getBatch(); + com.google.datastore.v1beta3.RunQueryResponse runQueryResponsePb = + datastore.runQuery(requestPb.build()); + queryResultBatchPb = runQueryResponsePb.getBatch(); + mostRecentQueryPb = runQueryResponsePb.getQuery(); + if (mostRecentQueryPb == null) { + mostRecentQueryPb = requestPb.getQuery(); + } lastBatch = queryResultBatchPb.getMoreResults() != MoreResultsType.NOT_FINISHED; entityResultPbIter = queryResultBatchPb.getEntityResultsList().iterator(); actualResultType = ResultType.fromPb(queryResultBatchPb.getEntityResultType()); From 02a56a831bd04734dd171a553dc569637d2059c6 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 16 Oct 2015 14:47:39 -0700 Subject: [PATCH 013/375] Don't allow user to set project id or namespace to null --- .../src/main/java/com/google/gcloud/ServiceOptions.java | 3 ++- .../src/main/java/com/google/gcloud/datastore/KeyFactory.java | 2 +- .../src/main/java/com/google/gcloud/datastore/Validator.java | 4 +--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java index 206e1fecaa58..066116e59c2f 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java @@ -122,7 +122,8 @@ protected B self() { } public B projectId(String projectId) { - this.projectId = projectId; + this.projectId = + checkNotNull(projectId, "Project ID cannot be set to null. Leave unset for default."); return self(); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java index c5b9d77a8cd7..7d645cf21945 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java @@ -29,7 +29,7 @@ public final class KeyFactory extends BaseKey.Builder { private final String ns; public KeyFactory(String projectId) { - this(projectId, null); + this(projectId, ""); } public KeyFactory(String projectId, String namespace) { diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Validator.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Validator.java index 791adec53101..dc7069cebf62 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Validator.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Validator.java @@ -45,9 +45,7 @@ static String validateDatabase(String projectId) { } static String validateNamespace(String namespace) { - if (Strings.isNullOrEmpty(namespace)) { - return ""; - } + checkArgument(namespace != null, "Namespace cannot be null. Leave unset for default."); checkArgument(namespace.length() <= MAX_NAMESPACE_LENGTH, "namespace must not contain more than 100 characters"); checkArgument(NAMESPACE_PATTERN.matcher(namespace).matches(), From a98d09640198c6d7effb6a8379a915664fb41b3f Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 16 Oct 2015 16:52:28 -0700 Subject: [PATCH 014/375] remove extra firstNonNull in KeyFactory --- .../src/main/java/com/google/gcloud/datastore/KeyFactory.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java index 7d645cf21945..7c4efb91762d 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java @@ -16,7 +16,6 @@ package com.google.gcloud.datastore; -import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; /** @@ -36,7 +35,7 @@ public KeyFactory(String projectId, String namespace) { super(projectId); namespace(namespace); this.pi = projectId; - this.ns = MoreObjects.firstNonNull(namespace, ""); + this.ns = namespace; } public IncompleteKey newKey() { From f6eedddbb5d0f8a297633a524cf0eee08046c53c Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 19 Oct 2015 13:08:54 -0700 Subject: [PATCH 015/375] Support GeoPoint value in Datastore v1beta3 --- .../google/gcloud/datastore/BaseEntity.java | 17 ++++ .../com/google/gcloud/datastore/GeoPoint.java | 83 ++++++++++++++++++ .../gcloud/datastore/GeoPointValue.java | 84 +++++++++++++++++++ .../com/google/gcloud/datastore/GqlQuery.java | 10 +++ .../gcloud/datastore/StructuredQuery.java | 5 ++ .../google/gcloud/datastore/ValueType.java | 6 +- .../gcloud/datastore/BaseEntityTest.java | 21 +++-- .../gcloud/datastore/DatastoreTest.java | 28 ++++--- .../google/gcloud/datastore/GeoPointTest.java | 77 +++++++++++++++++ .../gcloud/datastore/GeoPointValueTest.java | 52 ++++++++++++ .../gcloud/datastore/SerializationTest.java | 38 ++++----- .../google/gcloud/datastore/ValueTest.java | 2 + 12 files changed, 384 insertions(+), 39 deletions(-) create mode 100644 gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java create mode 100644 gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPointValue.java create mode 100644 gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointTest.java create mode 100644 gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointValueTest.java diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java index 97718e708e83..06ed0f419ac7 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java @@ -21,6 +21,7 @@ import static com.google.gcloud.datastore.DateTimeValue.of; import static com.google.gcloud.datastore.DoubleValue.of; import static com.google.gcloud.datastore.EntityValue.of; +import static com.google.gcloud.datastore.GeoPointValue.of; import static com.google.gcloud.datastore.KeyValue.of; import static com.google.gcloud.datastore.ListValue.of; import static com.google.gcloud.datastore.LongValue.of; @@ -159,6 +160,11 @@ public B set(String name, DateTime value) { return self(); } + public B set(String name, GeoPoint value) { + properties.put(name, of(value)); + return self(); + } + public B set(String name, Key value) { properties.put(name, of(value)); return self(); @@ -320,6 +326,17 @@ public DateTime getDateTime(String name) { return ((Value) getValue(name)).get(); } + /** + * Returns the property value as a GeoPoint. + * + * @throws DatastoreException if not such property. + * @throws ClassCastException if value is not a GeoPoint. + */ + @SuppressWarnings("unchecked") + public GeoPoint getGeoPoint(String name) { + return ((Value) getValue(name)).get(); + } + /** * Returns the property value as a Key. * diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java new file mode 100644 index 000000000000..5d7d87ebc121 --- /dev/null +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java @@ -0,0 +1,83 @@ +/* + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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.gcloud.datastore; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.protobuf.InvalidProtocolBufferException; + +import java.util.Objects; + +/** + * A Google Cloud Datastore GeoPoint (represented by latitude and longitude in degrees). + * This class is immutable. + * + * @see Google Cloud Datastore + * Entities, Properties, and Keys + */ +public final class GeoPoint extends Serializable { + + private static final long serialVersionUID = 9077060962655752073L; + + private final transient double latitude; + private final transient double longitude; + + GeoPoint(double latitude, double longitude) { + checkArgument( + latitude >= -90.0 && latitude <= 90.0, "latitude must be in the range [-90, 90] degrees"); + checkArgument( + longitude >= -180.0 && longitude <= 180.0, + "latitude must be in the range [-180, 180] degrees"); + this.latitude = latitude; + this.longitude = longitude; + } + + @Override + public String toString() { + return Double.toString(latitude) + ", " + Double.toString(longitude); + } + + @Override + public int hashCode() { + return Objects.hash(latitude, longitude); + } + + @Override + public boolean equals(Object obj) { + return obj == this + || (obj instanceof GeoPoint && new Double(this.latitude).equals(((GeoPoint) obj).latitude)) + && new Double(this.longitude).equals(((GeoPoint) obj).longitude); + } + + public static GeoPoint of(double latitude, double longitude) { + return new GeoPoint(latitude, longitude); + } + + @Override + protected com.google.type.LatLng toPb() { + return com.google.type.LatLng.newBuilder() + .setLatitude(latitude) + .setLongitude(longitude) + .build(); + } + + @Override + protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { + com.google.type.LatLng parsedLatLng = com.google.type.LatLng.parseFrom(bytesPb); + return new GeoPoint(parsedLatLng.getLatitude(), parsedLatLng.getLongitude()); + } +} diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPointValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPointValue.java new file mode 100644 index 000000000000..0f6b5c2003e6 --- /dev/null +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPointValue.java @@ -0,0 +1,84 @@ +/* + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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.gcloud.datastore; + +import static com.google.datastore.v1beta3.Value.GEO_POINT_VALUE_FIELD_NUMBER; + +public final class GeoPointValue extends Value { + + private static final long serialVersionUID = -5810614280642405898L; + + static final BaseMarshaller MARSHALLER = + new BaseMarshaller() { + + private static final long serialVersionUID = -3550567536035178649L; + + @Override + public int getProtoFieldId() { + return GEO_POINT_VALUE_FIELD_NUMBER; + } + + @Override + public Builder newBuilder(GeoPoint value) { + return builder(value); + } + + @Override + protected GeoPoint getValue(com.google.datastore.v1beta3.Value from) { + return new GeoPoint( + from.getGeoPointValue().getLatitude(), from.getGeoPointValue().getLongitude()); + } + + @Override + protected void setValue(GeoPointValue from, com.google.datastore.v1beta3.Value.Builder to) { + to.setGeoPointValue(from.get().toPb()); + } + }; + + public static final class Builder extends Value.BaseBuilder { + + private Builder() { + super(ValueType.GEO_POINT); + } + + @Override + public GeoPointValue build() { + return new GeoPointValue(this); + } + } + + public GeoPointValue(GeoPoint value) { + this(builder(value)); + } + + private GeoPointValue(Builder builder) { + super(builder); + } + + @Override + public Builder toBuilder() { + return new Builder().mergeFrom(this); + } + + public static GeoPointValue of(GeoPoint value) { + return new GeoPointValue(value); + } + + public static Builder builder(GeoPoint value) { + return new Builder().set(value); + } +} diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java index 7fcb562fea89..2205c7c270a3 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java @@ -212,6 +212,11 @@ public Builder setBinding(String name, DateTime... value) { namedBindings.put(name, toBinding(DateTimeValue.MARSHALLER, Arrays.asList(value))); return this; } + + public Builder setBinding(String name, GeoPoint... value) { + namedBindings.put(name, toBinding(GeoPointValue.MARSHALLER, Arrays.asList(value))); + return this; + } public Builder setBinding(String name, Key... value) { namedBindings.put(name, toBinding(KeyValue.MARSHALLER, Arrays.asList(value))); @@ -258,6 +263,11 @@ public Builder addBinding(DateTime... value) { return this; } + public Builder addBinding(GeoPoint... value) { + positionalBindings.add(toBinding(GeoPointValue.MARSHALLER, Arrays.asList(value))); + return this; + } + public Builder addBinding(Key... value) { positionalBindings.add(toBinding(KeyValue.MARSHALLER, Arrays.asList(value))); return this; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java index 1b82991cb8c8..87f92f6d05b4 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java @@ -21,6 +21,7 @@ import static com.google.gcloud.datastore.BooleanValue.of; import static com.google.gcloud.datastore.DateTimeValue.of; import static com.google.gcloud.datastore.DoubleValue.of; +import static com.google.gcloud.datastore.GeoPointValue.of; import static com.google.gcloud.datastore.KeyValue.of; import static com.google.gcloud.datastore.LongValue.of; import static com.google.gcloud.datastore.StringValue.of; @@ -420,6 +421,10 @@ public static PropertyFilter eq(String property, DateTime value) { return new PropertyFilter(property, Operator.EQUAL, of(value)); } + public static PropertyFilter eq(String property, GeoPoint value) { + return new PropertyFilter(property, Operator.EQUAL, of(value)); + } + public static PropertyFilter eq(String property, Key value) { return new PropertyFilter(property, Operator.EQUAL, of(value)); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java index 20c89a86e7a0..8326001c8fbc 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java @@ -78,12 +78,12 @@ public enum ValueType { /** * Represents a raw/unparsed value. */ - RAW_VALUE(RawValue.MARSHALLER); + RAW_VALUE(RawValue.MARSHALLER), /** - * TODO(ajaykannan): add GEO_POINT_VALUE - * Will represent a geolocation value in latitude/longitude + * Represents a {@link GeoPoint} value */ + GEO_POINT(GeoPointValue.MARSHALLER); private static final ImmutableMap DESCRIPTOR_TO_TYPE_MAP; diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java index 5ece01508d3a..8053b2d80b1d 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java @@ -35,6 +35,7 @@ public class BaseEntityTest { private static final Blob BLOB = Blob.copyFrom(new byte[]{1, 2}); private static final DateTime DATE_TIME = DateTime.now(); + private static final GeoPoint GEO_POINT = new GeoPoint(30.5, -40.5); private static final Key KEY = Key.builder("ds1", "k1", "n1").build(); private static final Entity ENTITY = Entity.builder(KEY).set("name", "foo").build(); private static final IncompleteKey INCOMPLETE_KEY = IncompleteKey.builder("ds1", "k1").build(); @@ -62,9 +63,9 @@ public void setUp() { builder = new Builder(); builder.set("blob", BLOB).set("boolean", true).set("dateTime", DATE_TIME); builder.set("double", 1.25).set("key", KEY).set("string", "hello world"); - builder.set("long", 125).setNull("null").set("entity", ENTITY); + builder.set("long", 125).setNull("null").set("entity", ENTITY).set("geoPoint", GEO_POINT); builder.set("partialEntity", PARTIAL_ENTITY).set("stringValue", StringValue.of("bla")); - builder.set("list1", NullValue.of(), StringValue.of("foo")); + builder.set("list1", NullValue.of(), StringValue.of("foo"), GeoPointValue.of(GEO_POINT)); builder.set("list2", ImmutableList.of(LongValue.of(10), DoubleValue.of(2))); builder.set("list3", Collections.singletonList(BooleanValue.of(true))); } @@ -149,6 +150,12 @@ public void testGetDateTime() throws Exception { assertEquals(dateTime, entity.getDateTime("dateTime")); } + @Test + public void testGetGeoPoint() throws Exception { + BaseEntity entity = builder.build(); + assertEquals(GEO_POINT, entity.getGeoPoint("geoPoint")); + } + @Test public void testGetKey() throws Exception { BaseEntity entity = builder.build(); @@ -171,9 +178,10 @@ public void testGetEntity() throws Exception { public void testGetList() throws Exception { BaseEntity entity = builder.build(); List> list = entity.getList("list1"); - assertEquals(2, list.size()); + assertEquals(3, list.size()); assertEquals(NullValue.of(), list.get(0)); assertEquals("foo", list.get(1).get()); + assertEquals(GEO_POINT, list.get(2).get()); list = entity.getList("list2"); assertEquals(2, list.size()); assertEquals(Long.valueOf(10), list.get(0).get()); @@ -196,9 +204,10 @@ public void testGetBlob() throws Exception { @Test public void testNames() throws Exception { - Set names = ImmutableSet.builder() - .add("string", "stringValue", "boolean", "double", "long", "list1", "list2", "list3") - .add("entity", "partialEntity", "null", "dateTime", "blob", "key") + Set names = + ImmutableSet.builder() + .add("string", "stringValue", "boolean", "double", "long", "list1", "list2", "list3") + .add("entity", "partialEntity", "null", "dateTime", "geoPoint", "blob", "key") .build(); BaseEntity entity = builder.build(); assertEquals(names, entity.names()); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index f0fbd4ab96c0..320c4f3d67c8 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -74,6 +74,7 @@ public class DatastoreTest { .build(); private static final ListValue LIST_VALUE2 = ListValue.of(Collections.singletonList(KEY_VALUE)); private static final DateTimeValue DATE_TIME_VALUE = new DateTimeValue(DateTime.now()); + private static final GeoPointValue GEO_POINT_VALUE = new GeoPointValue(new GeoPoint(30.5, 40.5)); private static final FullEntity PARTIAL_ENTITY1 = FullEntity.builder(INCOMPLETE_KEY2).set("str", STR_VALUE).set("bool", BOOL_VALUE) .set("list", LIST_VALUE1).build(); @@ -83,13 +84,15 @@ public class DatastoreTest { private static final FullEntity PARTIAL_ENTITY3 = FullEntity.builder(PARTIAL_ENTITY1).key(IncompleteKey.builder(PROJECT_ID, KIND3).build()) .build(); - private static final Entity ENTITY1 = Entity.builder(KEY1) - .set("str", STR_VALUE) - .set("date", DATE_TIME_VALUE) - .set("bool", BOOL_VALUE) - .set("partial1", EntityValue.of(PARTIAL_ENTITY1)) - .set("list", LIST_VALUE2) - .build(); + private static final Entity ENTITY1 = + Entity.builder(KEY1) + .set("str", STR_VALUE) + .set("date", DATE_TIME_VALUE) + .set("geoPoint", GEO_POINT_VALUE) + .set("bool", BOOL_VALUE) + .set("partial1", EntityValue.of(PARTIAL_ENTITY1)) + .set("list", LIST_VALUE2) + .build(); private static final Entity ENTITY2 = Entity.builder(ENTITY1).key(KEY2).remove("str") .set("name", "Dan").setNull("null").set("age", 20).build(); private static final Entity ENTITY3 = Entity.builder(ENTITY1).key(KEY3).remove("str") @@ -504,9 +507,11 @@ public void testGet() { assertEquals(LIST_VALUE2, value3); DateTimeValue value4 = entity.getValue("date"); assertEquals(DATE_TIME_VALUE, value4); - FullEntity value5 = entity.getEntity("partial1"); - assertEquals(PARTIAL_ENTITY1, value5); - assertEquals(5, entity.names().size()); + GeoPointValue value5 = entity.getValue("geoPoint"); + assertEquals(GEO_POINT_VALUE, value5); + FullEntity value6 = entity.getEntity("partial1"); + assertEquals(PARTIAL_ENTITY1, value6); + assertEquals(6, entity.names().size()); assertFalse(entity.contains("bla")); } @@ -528,7 +533,8 @@ public void testGetArray() { assertEquals(PARTIAL_ENTITY2, partial1); assertEquals(ENTITY2, partial2); assertEquals(ValueType.BOOLEAN, entity3.getValue("bool").type()); - assertEquals(6, entity3.names().size()); + assertEquals(GEO_POINT_VALUE, entity3.getValue("geoPoint")); + assertEquals(7, entity3.names().size()); assertFalse(entity3.contains("bla")); try { entity3.getString("str"); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointTest.java new file mode 100644 index 000000000000..61bcf0fd4f26 --- /dev/null +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointTest.java @@ -0,0 +1,77 @@ +/* + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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.gcloud.datastore; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class GeoPointTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + private static GeoPoint gp1 = new GeoPoint(10.5, 20.5); + private static GeoPoint gp2 = new GeoPoint(10.5, 30.5); + + private static final String INVALID_LAT_MESSAGE = + "latitude must be in the range [-90, 90] degrees"; + private static final String INVALID_LNG_MESSAGE = + "latitude must be in the range [-180, 180] degrees"; + + @Test + public void testEquals() { + assertEquals(gp1, gp1); + assertNotEquals(gp1, gp2); + } + + @Test + public void testUpperLatRange() { + new GeoPoint(90, 0); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage(INVALID_LAT_MESSAGE); + new GeoPoint(91, 0); + } + + @Test + public void testLowerLatRange() { + new GeoPoint(-90, 0); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage(INVALID_LAT_MESSAGE); + new GeoPoint(-91, 0); + } + + @Test + public void testUpperLngRange() { + new GeoPoint(0, 180); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage(INVALID_LNG_MESSAGE); + new GeoPoint(0, 181); + } + + @Test + public void testLowerLngRange() { + new GeoPoint(0, 180); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage(INVALID_LNG_MESSAGE); + new GeoPoint(0, -181); + } +} + diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointValueTest.java new file mode 100644 index 000000000000..82380efca8d3 --- /dev/null +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointValueTest.java @@ -0,0 +1,52 @@ +/* + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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.gcloud.datastore; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class GeoPointValueTest { + +private static final GeoPoint CONTENT = new GeoPoint(37.4, -122.1); + + @Test + public void testToBuilder() throws Exception { + GeoPointValue value = GeoPointValue.of(CONTENT); + assertEquals(value, value.toBuilder().build()); + } + + @SuppressWarnings("deprecation") + @Test + public void testOf() throws Exception { + GeoPointValue value = GeoPointValue.of(CONTENT); + assertEquals(CONTENT, value.get()); + assertFalse(value.excludeFromIndexes()); + } + + @SuppressWarnings("deprecation") + @Test + public void testBuilder() throws Exception { + GeoPointValue.Builder builder = GeoPointValue.builder(CONTENT); + GeoPointValue value = builder.meaning(1).excludeFromIndexes(true).build(); + assertEquals(CONTENT, value.get()); + assertEquals(1, value.meaning()); + assertTrue(value.excludeFromIndexes()); + } +} diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index 2e083250f35e..fe2be0a04b76 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -45,6 +45,7 @@ public class SerializationTest { IncompleteKey.builder(KEY1, "v").ancestors(PathElement.of("p", 1)).build(); private static final Key KEY2 = Key.builder(KEY1, "v", 2).build(); private static final DateTime DATE_TIME1 = DateTime.now(); + private static final GeoPoint GEO_POINT = new GeoPoint(30.5, 40.5); private static final Blob BLOB1 = Blob.copyFrom(UTF_8.encode("hello world")); private static final Cursor CURSOR1 = Cursor.copyFrom(new byte[] {1,2}); private static final Cursor CURSOR2 = Cursor.copyFrom(new byte[]{10}); @@ -89,10 +90,8 @@ public class SerializationTest { private static final DateTimeValue DATE_AND_TIME_VALUE = DateTimeValue.of(DateTime.now()); private static final BlobValue BLOB_VALUE = BlobValue.of(BLOB1); private static final RawValue RAW_VALUE = - RawValue.of(com.google.datastore.v1beta3.Value.newBuilder() - .setGeoPointValue(com.google.type.LatLng.newBuilder() - .setLatitude(0.0).setLongitude(0.0).build()) - .setMeaning(18).build()); + RawValue.of(com.google.datastore.v1beta3.Value.newBuilder().setMeaning(18).build()); + private static final GeoPointValue GEO_POINT_VALUE = GeoPointValue.of(GEO_POINT); private static final Entity ENTITY1 = Entity.builder(KEY1).build(); private static final Entity ENTITY2 = Entity.builder(KEY2).set("null", NullValue.of()).build(); @@ -119,19 +118,20 @@ public class SerializationTest { @SuppressWarnings("rawtypes") private static final Multimap TYPE_TO_VALUES = ImmutableMultimap.builder() - .put(ValueType.NULL, NULL_VALUE) - .put(ValueType.KEY, KEY_VALUE) - .put(ValueType.STRING, STRING_VALUE) - .putAll(ValueType.ENTITY, EMBEDDED_ENTITY_VALUE1, EMBEDDED_ENTITY_VALUE2, - EMBEDDED_ENTITY_VALUE3) - .put(ValueType.LIST, LIST_VALUE) - .put(ValueType.LONG, LONG_VALUE) - .put(ValueType.DOUBLE, DOUBLE_VALUE) - .put(ValueType.BOOLEAN, BOOLEAN_VALUE) - .put(ValueType.DATE_TIME, DATE_AND_TIME_VALUE) - .put(ValueType.BLOB, BLOB_VALUE) - .put(ValueType.RAW_VALUE, RAW_VALUE) - .build(); + .put(ValueType.NULL, NULL_VALUE) + .put(ValueType.KEY, KEY_VALUE) + .put(ValueType.STRING, STRING_VALUE) + .putAll(ValueType.ENTITY, EMBEDDED_ENTITY_VALUE1, EMBEDDED_ENTITY_VALUE2, + EMBEDDED_ENTITY_VALUE3) + .put(ValueType.LIST, LIST_VALUE) + .put(ValueType.LONG, LONG_VALUE) + .put(ValueType.DOUBLE, DOUBLE_VALUE) + .put(ValueType.BOOLEAN, BOOLEAN_VALUE) + .put(ValueType.DATE_TIME, DATE_AND_TIME_VALUE) + .put(ValueType.BLOB, BLOB_VALUE) + .put(ValueType.RAW_VALUE, RAW_VALUE) + .put(ValueType.GEO_POINT, GEO_POINT_VALUE) + .build(); @Test public void testServiceOptions() throws Exception { @@ -169,8 +169,8 @@ public void testValues() throws Exception { @Test public void testTypes() throws Exception { Serializable[] types = { KEY1, KEY2, INCOMPLETE_KEY1, INCOMPLETE_KEY2, ENTITY1, ENTITY2, - ENTITY3, EMBEDDED_ENTITY, PROJECTION_ENTITY, DATE_TIME1, BLOB1, CURSOR1, GQL1, GQL2, - QUERY1, QUERY2, QUERY3}; + ENTITY3, EMBEDDED_ENTITY, PROJECTION_ENTITY, DATE_TIME1, BLOB1, GEO_POINT, CURSOR1, GQL1, + GQL2, QUERY1, QUERY2, QUERY3}; for (Serializable obj : types) { Object copy = serializeAndDeserialize(obj); assertEquals(obj, obj); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java index 12908add4c8e..771b3c556a12 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java @@ -41,6 +41,7 @@ public class ValueTest { private static final NullValue NULL_VALUE = NullValue.of(); private static final StringValue STRING_VALUE = StringValue.of("hello"); private static final RawValue RAW_VALUE = RawValue.of(STRING_VALUE.toPb()); + private static final GeoPointValue GEO_POINT_VALUE = GeoPointValue.of(new GeoPoint(30.5, 40.5)); private static final ImmutableMap TYPES = ImmutableMap.builder() .put(ValueType.NULL, new Object[] {NullValue.class, NULL_VALUE.get()}) .put(ValueType.KEY, new Object[] {KeyValue.class, KEY}) @@ -53,6 +54,7 @@ public class ValueTest { new Object[] {ListValue.class, ImmutableList.of(NULL_VALUE, STRING_VALUE, RAW_VALUE)}) .put(ValueType.LONG, new Object[] {LongValue.class, 123L}) .put(ValueType.RAW_VALUE, new Object[] {RawValue.class, RAW_VALUE.get()}) + .put(ValueType.GEO_POINT, new Object[] {GeoPointValue.class, GEO_POINT_VALUE.get()}) .put(ValueType.STRING, new Object[] {StringValue.class, STRING_VALUE.get()}) .build(); From 3ccc7ed1660a1cc5eb0853bbdd2a38ba10e996e8 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 19 Oct 2015 17:01:57 -0700 Subject: [PATCH 016/375] Add getters, remove filtering --- .../java/com/google/gcloud/datastore/GeoPoint.java | 13 ++++++++++--- .../java/com/google/gcloud/datastore/GqlQuery.java | 10 ---------- .../google/gcloud/datastore/StructuredQuery.java | 5 ----- .../com/google/gcloud/datastore/BaseEntityTest.java | 2 +- .../com/google/gcloud/datastore/DatastoreTest.java | 3 ++- .../com/google/gcloud/datastore/GeoPointTest.java | 4 ++-- .../google/gcloud/datastore/SerializationTest.java | 2 +- 7 files changed, 16 insertions(+), 23 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java index 5d7d87ebc121..39dde9a9f85b 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java @@ -46,6 +46,14 @@ public final class GeoPoint extends Serializable { this.longitude = longitude; } + public double getLatitude() { + return latitude; + } + + public double getLongitude() { + return longitude; + } + @Override public String toString() { return Double.toString(latitude) + ", " + Double.toString(longitude); @@ -58,9 +66,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj == this - || (obj instanceof GeoPoint && new Double(this.latitude).equals(((GeoPoint) obj).latitude)) - && new Double(this.longitude).equals(((GeoPoint) obj).longitude); + return obj == this || (obj instanceof GeoPoint && this.latitude == ((GeoPoint) obj).latitude + && this.longitude == ((GeoPoint) obj).longitude); } public static GeoPoint of(double latitude, double longitude) { diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java index 2205c7c270a3..7fcb562fea89 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java @@ -212,11 +212,6 @@ public Builder setBinding(String name, DateTime... value) { namedBindings.put(name, toBinding(DateTimeValue.MARSHALLER, Arrays.asList(value))); return this; } - - public Builder setBinding(String name, GeoPoint... value) { - namedBindings.put(name, toBinding(GeoPointValue.MARSHALLER, Arrays.asList(value))); - return this; - } public Builder setBinding(String name, Key... value) { namedBindings.put(name, toBinding(KeyValue.MARSHALLER, Arrays.asList(value))); @@ -263,11 +258,6 @@ public Builder addBinding(DateTime... value) { return this; } - public Builder addBinding(GeoPoint... value) { - positionalBindings.add(toBinding(GeoPointValue.MARSHALLER, Arrays.asList(value))); - return this; - } - public Builder addBinding(Key... value) { positionalBindings.add(toBinding(KeyValue.MARSHALLER, Arrays.asList(value))); return this; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java index 87f92f6d05b4..1b82991cb8c8 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java @@ -21,7 +21,6 @@ import static com.google.gcloud.datastore.BooleanValue.of; import static com.google.gcloud.datastore.DateTimeValue.of; import static com.google.gcloud.datastore.DoubleValue.of; -import static com.google.gcloud.datastore.GeoPointValue.of; import static com.google.gcloud.datastore.KeyValue.of; import static com.google.gcloud.datastore.LongValue.of; import static com.google.gcloud.datastore.StringValue.of; @@ -421,10 +420,6 @@ public static PropertyFilter eq(String property, DateTime value) { return new PropertyFilter(property, Operator.EQUAL, of(value)); } - public static PropertyFilter eq(String property, GeoPoint value) { - return new PropertyFilter(property, Operator.EQUAL, of(value)); - } - public static PropertyFilter eq(String property, Key value) { return new PropertyFilter(property, Operator.EQUAL, of(value)); } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java index 8053b2d80b1d..5ca68bf848ce 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java @@ -35,7 +35,7 @@ public class BaseEntityTest { private static final Blob BLOB = Blob.copyFrom(new byte[]{1, 2}); private static final DateTime DATE_TIME = DateTime.now(); - private static final GeoPoint GEO_POINT = new GeoPoint(30.5, -40.5); + private static final GeoPoint GEO_POINT = new GeoPoint(37.422035, -122.084124); private static final Key KEY = Key.builder("ds1", "k1", "n1").build(); private static final Entity ENTITY = Entity.builder(KEY).set("name", "foo").build(); private static final IncompleteKey INCOMPLETE_KEY = IncompleteKey.builder("ds1", "k1").build(); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index 320c4f3d67c8..c890a6b67aa8 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -74,7 +74,8 @@ public class DatastoreTest { .build(); private static final ListValue LIST_VALUE2 = ListValue.of(Collections.singletonList(KEY_VALUE)); private static final DateTimeValue DATE_TIME_VALUE = new DateTimeValue(DateTime.now()); - private static final GeoPointValue GEO_POINT_VALUE = new GeoPointValue(new GeoPoint(30.5, 40.5)); + private static final GeoPointValue GEO_POINT_VALUE = + new GeoPointValue(new GeoPoint(37.422035, -122.084124)); private static final FullEntity PARTIAL_ENTITY1 = FullEntity.builder(INCOMPLETE_KEY2).set("str", STR_VALUE).set("bool", BOOL_VALUE) .set("list", LIST_VALUE1).build(); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointTest.java index 61bcf0fd4f26..2f076d915c15 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointTest.java @@ -28,8 +28,8 @@ public class GeoPointTest { @Rule public ExpectedException thrown = ExpectedException.none(); - private static GeoPoint gp1 = new GeoPoint(10.5, 20.5); - private static GeoPoint gp2 = new GeoPoint(10.5, 30.5); + private static GeoPoint gp1 = new GeoPoint(37.422035, -122.084124); + private static GeoPoint gp2 = new GeoPoint(0.0, 0.0); private static final String INVALID_LAT_MESSAGE = "latitude must be in the range [-90, 90] degrees"; diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index fe2be0a04b76..b2ee24862688 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -45,7 +45,7 @@ public class SerializationTest { IncompleteKey.builder(KEY1, "v").ancestors(PathElement.of("p", 1)).build(); private static final Key KEY2 = Key.builder(KEY1, "v", 2).build(); private static final DateTime DATE_TIME1 = DateTime.now(); - private static final GeoPoint GEO_POINT = new GeoPoint(30.5, 40.5); + private static final GeoPoint GEO_POINT = new GeoPoint(37.422035, -122.084124); private static final Blob BLOB1 = Blob.copyFrom(UTF_8.encode("hello world")); private static final Cursor CURSOR1 = Cursor.copyFrom(new byte[] {1,2}); private static final Cursor CURSOR2 = Cursor.copyFrom(new byte[]{10}); From d75b0da95b0da4419423a56c437830e668ebbcc6 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 19 Oct 2015 19:43:47 -0700 Subject: [PATCH 017/375] rename accessors in geopoint --- .../src/main/java/com/google/gcloud/datastore/GeoPoint.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java index 39dde9a9f85b..34532a30d927 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java @@ -46,11 +46,11 @@ public final class GeoPoint extends Serializable { this.longitude = longitude; } - public double getLatitude() { + public double latitude() { return latitude; } - public double getLongitude() { + public double longitude() { return longitude; } From 241960f2a24d4dbec27288589ccf72f91c431816 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 20 Oct 2015 08:27:04 -0700 Subject: [PATCH 018/375] rename geopoint to latlng --- .../google/gcloud/datastore/BaseEntity.java | 12 +++---- .../datastore/{GeoPoint.java => LatLng.java} | 16 ++++----- .../{GeoPointValue.java => LatLngValue.java} | 32 ++++++++--------- .../google/gcloud/datastore/ValueType.java | 4 +-- .../gcloud/datastore/BaseEntityTest.java | 14 ++++---- .../gcloud/datastore/DatastoreTest.java | 12 +++---- .../{GeoPointTest.java => LatLngTest.java} | 22 ++++++------ ...intValueTest.java => LatLngValueTest.java} | 12 +++---- .../gcloud/datastore/SerializationTest.java | 8 ++--- .../google/gcloud/datastore/ValueTest.java | 34 ++++++++++--------- 10 files changed, 84 insertions(+), 82 deletions(-) rename gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/{GeoPoint.java => LatLng.java} (79%) rename gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/{GeoPointValue.java => LatLngValue.java} (63%) rename gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/{GeoPointTest.java => LatLngTest.java} (83%) rename gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/{GeoPointValueTest.java => LatLngValueTest.java} (78%) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java index 06ed0f419ac7..1846c2a0e7ae 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java @@ -21,7 +21,7 @@ import static com.google.gcloud.datastore.DateTimeValue.of; import static com.google.gcloud.datastore.DoubleValue.of; import static com.google.gcloud.datastore.EntityValue.of; -import static com.google.gcloud.datastore.GeoPointValue.of; +import static com.google.gcloud.datastore.LatLngValue.of; import static com.google.gcloud.datastore.KeyValue.of; import static com.google.gcloud.datastore.ListValue.of; import static com.google.gcloud.datastore.LongValue.of; @@ -160,7 +160,7 @@ public B set(String name, DateTime value) { return self(); } - public B set(String name, GeoPoint value) { + public B set(String name, LatLng value) { properties.put(name, of(value)); return self(); } @@ -327,14 +327,14 @@ public DateTime getDateTime(String name) { } /** - * Returns the property value as a GeoPoint. + * Returns the property value as a LatLng. * * @throws DatastoreException if not such property. - * @throws ClassCastException if value is not a GeoPoint. + * @throws ClassCastException if value is not a LatLng. */ @SuppressWarnings("unchecked") - public GeoPoint getGeoPoint(String name) { - return ((Value) getValue(name)).get(); + public LatLng getLatLng(String name) { + return ((Value) getValue(name)).get(); } /** diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LatLng.java similarity index 79% rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LatLng.java index 34532a30d927..7e2b42fac4d3 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPoint.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LatLng.java @@ -23,20 +23,20 @@ import java.util.Objects; /** - * A Google Cloud Datastore GeoPoint (represented by latitude and longitude in degrees). + * A Google Cloud Datastore LatLng (represented by latitude and longitude in degrees). * This class is immutable. * * @see Google Cloud Datastore * Entities, Properties, and Keys */ -public final class GeoPoint extends Serializable { +public final class LatLng extends Serializable { private static final long serialVersionUID = 9077060962655752073L; private final transient double latitude; private final transient double longitude; - GeoPoint(double latitude, double longitude) { + LatLng(double latitude, double longitude) { checkArgument( latitude >= -90.0 && latitude <= 90.0, "latitude must be in the range [-90, 90] degrees"); checkArgument( @@ -66,12 +66,12 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj == this || (obj instanceof GeoPoint && this.latitude == ((GeoPoint) obj).latitude - && this.longitude == ((GeoPoint) obj).longitude); + return obj == this || (obj instanceof LatLng && this.latitude == ((LatLng) obj).latitude + && this.longitude == ((LatLng) obj).longitude); } - public static GeoPoint of(double latitude, double longitude) { - return new GeoPoint(latitude, longitude); + public static LatLng of(double latitude, double longitude) { + return new LatLng(latitude, longitude); } @Override @@ -85,6 +85,6 @@ protected com.google.type.LatLng toPb() { @Override protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { com.google.type.LatLng parsedLatLng = com.google.type.LatLng.parseFrom(bytesPb); - return new GeoPoint(parsedLatLng.getLatitude(), parsedLatLng.getLongitude()); + return new LatLng(parsedLatLng.getLatitude(), parsedLatLng.getLongitude()); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPointValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LatLngValue.java similarity index 63% rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPointValue.java rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LatLngValue.java index 0f6b5c2003e6..91723f710816 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GeoPointValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LatLngValue.java @@ -18,12 +18,12 @@ import static com.google.datastore.v1beta3.Value.GEO_POINT_VALUE_FIELD_NUMBER; -public final class GeoPointValue extends Value { +public final class LatLngValue extends Value { private static final long serialVersionUID = -5810614280642405898L; - static final BaseMarshaller MARSHALLER = - new BaseMarshaller() { + static final BaseMarshaller MARSHALLER = + new BaseMarshaller() { private static final long serialVersionUID = -3550567536035178649L; @@ -33,39 +33,39 @@ public int getProtoFieldId() { } @Override - public Builder newBuilder(GeoPoint value) { + public Builder newBuilder(LatLng value) { return builder(value); } @Override - protected GeoPoint getValue(com.google.datastore.v1beta3.Value from) { - return new GeoPoint( + protected LatLng getValue(com.google.datastore.v1beta3.Value from) { + return new LatLng( from.getGeoPointValue().getLatitude(), from.getGeoPointValue().getLongitude()); } @Override - protected void setValue(GeoPointValue from, com.google.datastore.v1beta3.Value.Builder to) { + protected void setValue(LatLngValue from, com.google.datastore.v1beta3.Value.Builder to) { to.setGeoPointValue(from.get().toPb()); } }; - public static final class Builder extends Value.BaseBuilder { + public static final class Builder extends Value.BaseBuilder { private Builder() { - super(ValueType.GEO_POINT); + super(ValueType.LAT_LNG); } @Override - public GeoPointValue build() { - return new GeoPointValue(this); + public LatLngValue build() { + return new LatLngValue(this); } } - public GeoPointValue(GeoPoint value) { + public LatLngValue(LatLng value) { this(builder(value)); } - private GeoPointValue(Builder builder) { + private LatLngValue(Builder builder) { super(builder); } @@ -74,11 +74,11 @@ public Builder toBuilder() { return new Builder().mergeFrom(this); } - public static GeoPointValue of(GeoPoint value) { - return new GeoPointValue(value); + public static LatLngValue of(LatLng value) { + return new LatLngValue(value); } - public static Builder builder(GeoPoint value) { + public static Builder builder(LatLng value) { return new Builder().set(value); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java index 8326001c8fbc..ab16126336f5 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java @@ -81,9 +81,9 @@ public enum ValueType { RAW_VALUE(RawValue.MARSHALLER), /** - * Represents a {@link GeoPoint} value + * Represents a {@link LatLng} value */ - GEO_POINT(GeoPointValue.MARSHALLER); + LAT_LNG(LatLngValue.MARSHALLER); private static final ImmutableMap DESCRIPTOR_TO_TYPE_MAP; diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java index 5ca68bf848ce..4be8b6c0d96a 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java @@ -35,7 +35,7 @@ public class BaseEntityTest { private static final Blob BLOB = Blob.copyFrom(new byte[]{1, 2}); private static final DateTime DATE_TIME = DateTime.now(); - private static final GeoPoint GEO_POINT = new GeoPoint(37.422035, -122.084124); + private static final LatLng LAT_LNG = new LatLng(37.422035, -122.084124); private static final Key KEY = Key.builder("ds1", "k1", "n1").build(); private static final Entity ENTITY = Entity.builder(KEY).set("name", "foo").build(); private static final IncompleteKey INCOMPLETE_KEY = IncompleteKey.builder("ds1", "k1").build(); @@ -63,9 +63,9 @@ public void setUp() { builder = new Builder(); builder.set("blob", BLOB).set("boolean", true).set("dateTime", DATE_TIME); builder.set("double", 1.25).set("key", KEY).set("string", "hello world"); - builder.set("long", 125).setNull("null").set("entity", ENTITY).set("geoPoint", GEO_POINT); + builder.set("long", 125).setNull("null").set("entity", ENTITY).set("latLng", LAT_LNG); builder.set("partialEntity", PARTIAL_ENTITY).set("stringValue", StringValue.of("bla")); - builder.set("list1", NullValue.of(), StringValue.of("foo"), GeoPointValue.of(GEO_POINT)); + builder.set("list1", NullValue.of(), StringValue.of("foo"), LatLngValue.of(LAT_LNG)); builder.set("list2", ImmutableList.of(LongValue.of(10), DoubleValue.of(2))); builder.set("list3", Collections.singletonList(BooleanValue.of(true))); } @@ -151,9 +151,9 @@ public void testGetDateTime() throws Exception { } @Test - public void testGetGeoPoint() throws Exception { + public void testGetLatLng() throws Exception { BaseEntity entity = builder.build(); - assertEquals(GEO_POINT, entity.getGeoPoint("geoPoint")); + assertEquals(LAT_LNG, entity.getLatLng("latLng")); } @Test @@ -181,7 +181,7 @@ public void testGetList() throws Exception { assertEquals(3, list.size()); assertEquals(NullValue.of(), list.get(0)); assertEquals("foo", list.get(1).get()); - assertEquals(GEO_POINT, list.get(2).get()); + assertEquals(LAT_LNG, list.get(2).get()); list = entity.getList("list2"); assertEquals(2, list.size()); assertEquals(Long.valueOf(10), list.get(0).get()); @@ -207,7 +207,7 @@ public void testNames() throws Exception { Set names = ImmutableSet.builder() .add("string", "stringValue", "boolean", "double", "long", "list1", "list2", "list3") - .add("entity", "partialEntity", "null", "dateTime", "geoPoint", "blob", "key") + .add("entity", "partialEntity", "null", "dateTime", "latLng", "blob", "key") .build(); BaseEntity entity = builder.build(); assertEquals(names, entity.names()); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index c890a6b67aa8..152aeea0a75e 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -74,8 +74,8 @@ public class DatastoreTest { .build(); private static final ListValue LIST_VALUE2 = ListValue.of(Collections.singletonList(KEY_VALUE)); private static final DateTimeValue DATE_TIME_VALUE = new DateTimeValue(DateTime.now()); - private static final GeoPointValue GEO_POINT_VALUE = - new GeoPointValue(new GeoPoint(37.422035, -122.084124)); + private static final LatLngValue LAT_LNG_VALUE = + new LatLngValue(new LatLng(37.422035, -122.084124)); private static final FullEntity PARTIAL_ENTITY1 = FullEntity.builder(INCOMPLETE_KEY2).set("str", STR_VALUE).set("bool", BOOL_VALUE) .set("list", LIST_VALUE1).build(); @@ -89,7 +89,7 @@ public class DatastoreTest { Entity.builder(KEY1) .set("str", STR_VALUE) .set("date", DATE_TIME_VALUE) - .set("geoPoint", GEO_POINT_VALUE) + .set("latLng", LAT_LNG_VALUE) .set("bool", BOOL_VALUE) .set("partial1", EntityValue.of(PARTIAL_ENTITY1)) .set("list", LIST_VALUE2) @@ -508,8 +508,8 @@ public void testGet() { assertEquals(LIST_VALUE2, value3); DateTimeValue value4 = entity.getValue("date"); assertEquals(DATE_TIME_VALUE, value4); - GeoPointValue value5 = entity.getValue("geoPoint"); - assertEquals(GEO_POINT_VALUE, value5); + LatLngValue value5 = entity.getValue("latLng"); + assertEquals(LAT_LNG_VALUE, value5); FullEntity value6 = entity.getEntity("partial1"); assertEquals(PARTIAL_ENTITY1, value6); assertEquals(6, entity.names().size()); @@ -534,7 +534,7 @@ public void testGetArray() { assertEquals(PARTIAL_ENTITY2, partial1); assertEquals(ENTITY2, partial2); assertEquals(ValueType.BOOLEAN, entity3.getValue("bool").type()); - assertEquals(GEO_POINT_VALUE, entity3.getValue("geoPoint")); + assertEquals(LAT_LNG_VALUE, entity3.getValue("latLng")); assertEquals(7, entity3.names().size()); assertFalse(entity3.contains("bla")); try { diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LatLngTest.java similarity index 83% rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointTest.java rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LatLngTest.java index 2f076d915c15..1955ec236300 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LatLngTest.java @@ -23,13 +23,13 @@ import org.junit.Test; import org.junit.rules.ExpectedException; -public class GeoPointTest { +public class LatLngTest { @Rule public ExpectedException thrown = ExpectedException.none(); - private static GeoPoint gp1 = new GeoPoint(37.422035, -122.084124); - private static GeoPoint gp2 = new GeoPoint(0.0, 0.0); + private static LatLng gp1 = new LatLng(37.422035, -122.084124); + private static LatLng gp2 = new LatLng(0.0, 0.0); private static final String INVALID_LAT_MESSAGE = "latitude must be in the range [-90, 90] degrees"; @@ -44,34 +44,34 @@ public void testEquals() { @Test public void testUpperLatRange() { - new GeoPoint(90, 0); + new LatLng(90, 0); thrown.expect(IllegalArgumentException.class); thrown.expectMessage(INVALID_LAT_MESSAGE); - new GeoPoint(91, 0); + new LatLng(91, 0); } @Test public void testLowerLatRange() { - new GeoPoint(-90, 0); + new LatLng(-90, 0); thrown.expect(IllegalArgumentException.class); thrown.expectMessage(INVALID_LAT_MESSAGE); - new GeoPoint(-91, 0); + new LatLng(-91, 0); } @Test public void testUpperLngRange() { - new GeoPoint(0, 180); + new LatLng(0, 180); thrown.expect(IllegalArgumentException.class); thrown.expectMessage(INVALID_LNG_MESSAGE); - new GeoPoint(0, 181); + new LatLng(0, 181); } @Test public void testLowerLngRange() { - new GeoPoint(0, 180); + new LatLng(0, 180); thrown.expect(IllegalArgumentException.class); thrown.expectMessage(INVALID_LNG_MESSAGE); - new GeoPoint(0, -181); + new LatLng(0, -181); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LatLngValueTest.java similarity index 78% rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointValueTest.java rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LatLngValueTest.java index 82380efca8d3..3a25078237d4 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/GeoPointValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LatLngValueTest.java @@ -22,20 +22,20 @@ import org.junit.Test; -public class GeoPointValueTest { +public class LatLngValueTest { -private static final GeoPoint CONTENT = new GeoPoint(37.4, -122.1); +private static final LatLng CONTENT = new LatLng(37.4, -122.1); @Test public void testToBuilder() throws Exception { - GeoPointValue value = GeoPointValue.of(CONTENT); + LatLngValue value = LatLngValue.of(CONTENT); assertEquals(value, value.toBuilder().build()); } @SuppressWarnings("deprecation") @Test public void testOf() throws Exception { - GeoPointValue value = GeoPointValue.of(CONTENT); + LatLngValue value = LatLngValue.of(CONTENT); assertEquals(CONTENT, value.get()); assertFalse(value.excludeFromIndexes()); } @@ -43,8 +43,8 @@ public void testOf() throws Exception { @SuppressWarnings("deprecation") @Test public void testBuilder() throws Exception { - GeoPointValue.Builder builder = GeoPointValue.builder(CONTENT); - GeoPointValue value = builder.meaning(1).excludeFromIndexes(true).build(); + LatLngValue.Builder builder = LatLngValue.builder(CONTENT); + LatLngValue value = builder.meaning(1).excludeFromIndexes(true).build(); assertEquals(CONTENT, value.get()); assertEquals(1, value.meaning()); assertTrue(value.excludeFromIndexes()); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index b2ee24862688..a8cbcb294b39 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -45,7 +45,7 @@ public class SerializationTest { IncompleteKey.builder(KEY1, "v").ancestors(PathElement.of("p", 1)).build(); private static final Key KEY2 = Key.builder(KEY1, "v", 2).build(); private static final DateTime DATE_TIME1 = DateTime.now(); - private static final GeoPoint GEO_POINT = new GeoPoint(37.422035, -122.084124); + private static final LatLng LAT_LNG = new LatLng(37.422035, -122.084124); private static final Blob BLOB1 = Blob.copyFrom(UTF_8.encode("hello world")); private static final Cursor CURSOR1 = Cursor.copyFrom(new byte[] {1,2}); private static final Cursor CURSOR2 = Cursor.copyFrom(new byte[]{10}); @@ -91,7 +91,7 @@ public class SerializationTest { private static final BlobValue BLOB_VALUE = BlobValue.of(BLOB1); private static final RawValue RAW_VALUE = RawValue.of(com.google.datastore.v1beta3.Value.newBuilder().setMeaning(18).build()); - private static final GeoPointValue GEO_POINT_VALUE = GeoPointValue.of(GEO_POINT); + private static final LatLngValue LAT_LNG_VALUE = LatLngValue.of(LAT_LNG); private static final Entity ENTITY1 = Entity.builder(KEY1).build(); private static final Entity ENTITY2 = Entity.builder(KEY2).set("null", NullValue.of()).build(); @@ -130,7 +130,7 @@ public class SerializationTest { .put(ValueType.DATE_TIME, DATE_AND_TIME_VALUE) .put(ValueType.BLOB, BLOB_VALUE) .put(ValueType.RAW_VALUE, RAW_VALUE) - .put(ValueType.GEO_POINT, GEO_POINT_VALUE) + .put(ValueType.LAT_LNG, LAT_LNG_VALUE) .build(); @Test @@ -169,7 +169,7 @@ public void testValues() throws Exception { @Test public void testTypes() throws Exception { Serializable[] types = { KEY1, KEY2, INCOMPLETE_KEY1, INCOMPLETE_KEY2, ENTITY1, ENTITY2, - ENTITY3, EMBEDDED_ENTITY, PROJECTION_ENTITY, DATE_TIME1, BLOB1, GEO_POINT, CURSOR1, GQL1, + ENTITY3, EMBEDDED_ENTITY, PROJECTION_ENTITY, DATE_TIME1, BLOB1, LAT_LNG, CURSOR1, GQL1, GQL2, QUERY1, QUERY2, QUERY3}; for (Serializable obj : types) { Object copy = serializeAndDeserialize(obj); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java index 771b3c556a12..e433ca9a0666 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java @@ -41,22 +41,24 @@ public class ValueTest { private static final NullValue NULL_VALUE = NullValue.of(); private static final StringValue STRING_VALUE = StringValue.of("hello"); private static final RawValue RAW_VALUE = RawValue.of(STRING_VALUE.toPb()); - private static final GeoPointValue GEO_POINT_VALUE = GeoPointValue.of(new GeoPoint(30.5, 40.5)); - private static final ImmutableMap TYPES = ImmutableMap.builder() - .put(ValueType.NULL, new Object[] {NullValue.class, NULL_VALUE.get()}) - .put(ValueType.KEY, new Object[] {KeyValue.class, KEY}) - .put(ValueType.BLOB, new Object[] {BlobValue.class, BLOB}) - .put(ValueType.BOOLEAN, new Object[] {BooleanValue.class, Boolean.TRUE}) - .put(ValueType.DATE_TIME, new Object[] {DateTimeValue.class, DATE_TIME}) - .put(ValueType.DOUBLE, new Object[] {DoubleValue.class, 1.25D}) - .put(ValueType.ENTITY, new Object[] {EntityValue.class, ENTITY}) - .put(ValueType.LIST, - new Object[] {ListValue.class, ImmutableList.of(NULL_VALUE, STRING_VALUE, RAW_VALUE)}) - .put(ValueType.LONG, new Object[] {LongValue.class, 123L}) - .put(ValueType.RAW_VALUE, new Object[] {RawValue.class, RAW_VALUE.get()}) - .put(ValueType.GEO_POINT, new Object[] {GeoPointValue.class, GEO_POINT_VALUE.get()}) - .put(ValueType.STRING, new Object[] {StringValue.class, STRING_VALUE.get()}) - .build(); + private static final LatLngValue LAT_LNG_VALUE = + LatLngValue.of(new LatLng(37.422035, -122.084124)); + private static final ImmutableMap TYPES = + ImmutableMap.builder() + .put(ValueType.NULL, new Object[] {NullValue.class, NULL_VALUE.get()}) + .put(ValueType.KEY, new Object[] {KeyValue.class, KEY}) + .put(ValueType.BLOB, new Object[] {BlobValue.class, BLOB}) + .put(ValueType.BOOLEAN, new Object[] {BooleanValue.class, Boolean.TRUE}) + .put(ValueType.DATE_TIME, new Object[] {DateTimeValue.class, DATE_TIME}) + .put(ValueType.DOUBLE, new Object[] {DoubleValue.class, 1.25D}) + .put(ValueType.ENTITY, new Object[] {EntityValue.class, ENTITY}) + .put(ValueType.LIST, new Object[] { + ListValue.class, ImmutableList.of(NULL_VALUE, STRING_VALUE, RAW_VALUE)}) + .put(ValueType.LONG, new Object[] {LongValue.class, 123L}) + .put(ValueType.RAW_VALUE, new Object[] {RawValue.class, RAW_VALUE.get()}) + .put(ValueType.LAT_LNG, new Object[] {LatLngValue.class, LAT_LNG_VALUE.get()}) + .put(ValueType.STRING, new Object[] {StringValue.class, STRING_VALUE.get()}) + .build(); private ImmutableMap> typeToValue; From 50a5a66b851831ce50d17b04aea16f4c54c71f65 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 19 Oct 2015 15:50:24 -0700 Subject: [PATCH 019/375] Query continuation implemented for GqlQuery + tests --- .../com/google/gcloud/datastore/GqlQuery.java | 8 +- .../com/google/gcloud/datastore/Query.java | 2 +- .../gcloud/datastore/QueryResultsImpl.java | 18 ++- .../gcloud/datastore/StructuredQuery.java | 29 +++-- .../gcloud/datastore/DatastoreTest.java | 113 +++++++++++++++++- 5 files changed, 142 insertions(+), 28 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java index 7fcb562fea89..e6f713c76a1c 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java @@ -379,9 +379,11 @@ protected void populatePb(com.google.datastore.v1beta3.RunQueryRequest.Builder r } @Override - protected GqlQuery nextQuery(com.google.datastore.v1beta3.QueryResultBatch responsePb) { - // See issue #17 - throw new UnsupportedOperationException("paging for this query is not implemented yet"); + protected StructuredQuery nextQuery(com.google.datastore.v1beta3.RunQueryResponse responsePb) { + return new StructuredQuery.Builder<>(type()) + .mergeFrom(responsePb.getQuery()) + .prepareNext(responsePb.getBatch()) + .build(); } @Override diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java index c45efde3e30d..cd7d1015deda 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java @@ -192,7 +192,7 @@ protected abstract Object fromPb(ResultType resultType, String namespace, byt protected abstract void populatePb( com.google.datastore.v1beta3.RunQueryRequest.Builder requestPb); - protected abstract Query nextQuery(com.google.datastore.v1beta3.QueryResultBatch responsePb); + protected abstract Query nextQuery(com.google.datastore.v1beta3.RunQueryResponse responsePb); /** * Returns a new {@link GqlQuery} builder. diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java index bb2b65fcc646..10f3eeda58ac 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java @@ -33,7 +33,7 @@ class QueryResultsImpl extends AbstractIterator implements QueryResults private final ResultType queryResultType; private Query query; private ResultType actualResultType; - private com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb; + private com.google.datastore.v1beta3.RunQueryResponse runQueryResponsePb; private com.google.datastore.v1beta3.Query mostRecentQueryPb; private boolean lastBatch; private Iterator entityResultPbIter; @@ -56,8 +56,8 @@ class QueryResultsImpl extends AbstractIterator implements QueryResults } partitionIdPb = pbBuilder.build(); sendRequest(); - if (queryResultBatchPb.getSkippedResults() > 0) { - cursor = queryResultBatchPb.getSkippedCursor(); + if (runQueryResponsePb.getBatch().getSkippedResults() > 0) { + cursor = runQueryResponsePb.getBatch().getSkippedCursor(); } else { cursor = mostRecentQueryPb.getStartCursor(); } @@ -71,16 +71,14 @@ private void sendRequest() { } requestPb.setPartitionId(partitionIdPb); query.populatePb(requestPb); - com.google.datastore.v1beta3.RunQueryResponse runQueryResponsePb = - datastore.runQuery(requestPb.build()); - queryResultBatchPb = runQueryResponsePb.getBatch(); + runQueryResponsePb = datastore.runQuery(requestPb.build()); mostRecentQueryPb = runQueryResponsePb.getQuery(); if (mostRecentQueryPb == null) { mostRecentQueryPb = requestPb.getQuery(); } - lastBatch = queryResultBatchPb.getMoreResults() != MoreResultsType.NOT_FINISHED; - entityResultPbIter = queryResultBatchPb.getEntityResultsList().iterator(); - actualResultType = ResultType.fromPb(queryResultBatchPb.getEntityResultType()); + lastBatch = runQueryResponsePb.getBatch().getMoreResults() != MoreResultsType.NOT_FINISHED; + entityResultPbIter = runQueryResponsePb.getBatch().getEntityResultsList().iterator(); + actualResultType = ResultType.fromPb(runQueryResponsePb.getBatch().getEntityResultType()); if (Objects.equals(queryResultType, ResultType.PROJECTION_ENTITY)) { // projection entity can represent all type of results actualResultType = ResultType.PROJECTION_ENTITY; @@ -92,7 +90,7 @@ private void sendRequest() { @Override protected T computeNext() { while (!entityResultPbIter.hasNext() && !lastBatch) { - query = query.nextQuery(queryResultBatchPb); + query = query.nextQuery(runQueryResponsePb); sendRequest(); } if (!entityResultPbIter.hasNext()) { diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java index 1b82991cb8c8..dcf4cef4721f 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java @@ -669,9 +669,23 @@ B mergeFrom(com.google.datastore.v1beta3.Query queryPb) { return self(); } + B prepareNext(com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb) { + startCursor(new Cursor(queryResultBatchPb.getEndCursor())); + if (offset > 0 && queryResultBatchPb.getSkippedResults() < offset) { + offset(offset - queryResultBatchPb.getSkippedResults()); + } else { + offset(0); + if (limit != null) { + limit(limit - queryResultBatchPb.getEntityResultsCount()); + } + } + return self(); + } + public StructuredQuery build() { return new StructuredQuery<>(this); } + } static final class Builder extends BaseBuilder> { @@ -844,19 +858,8 @@ protected void populatePb(com.google.datastore.v1beta3.RunQueryRequest.Builder r } @Override - protected StructuredQuery nextQuery(com.google.datastore.v1beta3.QueryResultBatch responsePb) { - Builder builder = new Builder<>(type()); - builder.mergeFrom(toPb()); - builder.startCursor(new Cursor(responsePb.getEndCursor())); - if (offset > 0 && responsePb.getSkippedResults() < offset) { - builder.offset(offset - responsePb.getSkippedResults()); - } else { - builder.offset(0); - if (limit != null) { - builder.limit(limit - responsePb.getEntityResultsCount()); - } - } - return builder.build(); + protected StructuredQuery nextQuery(com.google.datastore.v1beta3.RunQueryResponse responsePb) { + return new Builder<>(type()).mergeFrom(toPb()).prepareNext(responsePb.getBatch()).build(); } @Override diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index f0fbd4ab96c0..6bf907422a0f 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -31,6 +31,7 @@ import com.google.gcloud.datastore.StructuredQuery.OrderBy; import com.google.gcloud.datastore.StructuredQuery.PropertyFilter; import com.google.gcloud.spi.DatastoreRpc; +import com.google.gcloud.spi.DatastoreRpc.DatastoreRpcException; import com.google.gcloud.spi.DatastoreRpc.DatastoreRpcException.Reason; import com.google.gcloud.spi.DatastoreRpcFactory; @@ -43,6 +44,7 @@ import org.junit.runners.JUnit4; import java.io.IOException; +import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; @@ -403,6 +405,42 @@ public void testRunGqlQueryWithCasting() { assertFalse(results3.hasNext()); } + @Test + public void testGqlQueryPagination() { + DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); + DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); + EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) + .andReturn(rpcMock); + List responses = + buildResponsesForQueryPagination(); + for (int i = 0; i < responses.size(); i++) { + try { + EasyMock + .expect(rpcMock.runQuery( + EasyMock.anyObject(com.google.datastore.v1beta3.RunQueryRequest.class))) + .andReturn(responses.get(i)); + } catch (DatastoreRpcException e) { + fail("Unexpected DatastoreRpcException"); + } + } + EasyMock.replay(rpcFactoryMock, rpcMock); + DatastoreOptions options = + this.options.toBuilder() + .retryParams(RetryParams.getDefaultInstance()) + .serviceRpcFactory(rpcFactoryMock) + .build(); + Datastore mockDatastore = DatastoreFactory.instance().get(options); + QueryResults results = + mockDatastore.run(Query.gqlQueryBuilder(ResultType.KEY, "select __key__ from *").build()); + int count = 0; + while (results.hasNext()) { + count += 1; + results.next(); + } + assertEquals(count, responses.size()); + EasyMock.verify(rpcFactoryMock, rpcMock); + } + @Test public void testRunStructuredQuery() { Query query = @@ -445,7 +483,80 @@ public void testRunStructuredQuery() { assertEquals(20, entity.getLong("age")); assertEquals(1, entity.properties().size()); assertFalse(results4.hasNext()); - // TODO(ozarov): construct a test to verify nextQuery/pagination + } + + @Test + public void testStructuredQueryPagination() { + DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); + DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); + EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) + .andReturn(rpcMock); + List responses = + buildResponsesForQueryPagination(); + for (int i = 0; i < responses.size(); i++) { + try { + EasyMock + .expect(rpcMock.runQuery( + EasyMock.anyObject(com.google.datastore.v1beta3.RunQueryRequest.class))) + .andReturn(responses.get(i)); + } catch (DatastoreRpcException e) { + fail("Unexpected DatastoreRpcException"); + } + } + EasyMock.replay(rpcFactoryMock, rpcMock); + DatastoreOptions options = + this.options.toBuilder() + .retryParams(RetryParams.getDefaultInstance()) + .serviceRpcFactory(rpcFactoryMock) + .build(); + Datastore mockDatastore = DatastoreFactory.instance().get(options); + QueryResults results = mockDatastore.run(Query.keyQueryBuilder().build()); + int count = 0; + while (results.hasNext()) { + count += 1; + results.next(); + } + assertEquals(count, responses.size()); + EasyMock.verify(rpcFactoryMock, rpcMock); + } + + private List buildResponsesForQueryPagination() { + List responses = new ArrayList<>(); + Query query = Query.keyQueryBuilder().build(); + com.google.datastore.v1beta3.RunQueryRequest.Builder requestPb = + com.google.datastore.v1beta3.RunQueryRequest.newBuilder(); + query.populatePb(requestPb); + com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb = + com.google.datastore.v1beta3.RunQueryResponse.newBuilder() + .mergeFrom(((DatastoreImpl) datastore).runQuery(requestPb.build())) + .getBatch(); + com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb1 = + com.google.datastore.v1beta3.QueryResultBatch.newBuilder() + .mergeFrom(queryResultBatchPb) + .setMoreResults( + com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType.NOT_FINISHED) + .clearEntityResults() + .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(0, 1)) + .setEndCursor(queryResultBatchPb.getEntityResultsList().get(0).getCursor()) + .build(); + responses.add( + com.google.datastore.v1beta3.RunQueryResponse.newBuilder() + .setBatch(queryResultBatchPb1) + .build()); + com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb2 = + com.google.datastore.v1beta3.QueryResultBatch.newBuilder() + .mergeFrom(queryResultBatchPb) + .setMoreResults( + com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType.NO_MORE_RESULTS) + .clearEntityResults() + .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(1, 2)) + .setEndCursor(queryResultBatchPb.getEntityResultsList().get(1).getCursor()) + .build(); + responses.add( + com.google.datastore.v1beta3.RunQueryResponse.newBuilder() + .setBatch(queryResultBatchPb2) + .build()); + return responses; } @Test From b270c64f96c5cad1e07c717aab1120b10dd7025d Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Wed, 21 Oct 2015 13:08:18 -0700 Subject: [PATCH 020/375] Set namespace in Gql's nextQuery and add another batch to tests --- .../com/google/gcloud/datastore/GqlQuery.java | 1 + .../gcloud/datastore/DatastoreTest.java | 38 +++++++++++-------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java index e6f713c76a1c..ecb0aef1e701 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java @@ -381,6 +381,7 @@ protected void populatePb(com.google.datastore.v1beta3.RunQueryRequest.Builder r @Override protected StructuredQuery nextQuery(com.google.datastore.v1beta3.RunQueryResponse responsePb) { return new StructuredQuery.Builder<>(type()) + .namespace(namespace()) .mergeFrom(responsePb.getQuery()) .prepareNext(responsePb.getBatch()) .build(); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index 6bf907422a0f..6ea4e789ee34 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -406,7 +406,7 @@ public void testRunGqlQueryWithCasting() { } @Test - public void testGqlQueryPagination() { + public void testGqlQueryPagination() throws DatastoreRpcException { DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) @@ -414,14 +414,10 @@ public void testGqlQueryPagination() { List responses = buildResponsesForQueryPagination(); for (int i = 0; i < responses.size(); i++) { - try { EasyMock .expect(rpcMock.runQuery( EasyMock.anyObject(com.google.datastore.v1beta3.RunQueryRequest.class))) .andReturn(responses.get(i)); - } catch (DatastoreRpcException e) { - fail("Unexpected DatastoreRpcException"); - } } EasyMock.replay(rpcFactoryMock, rpcMock); DatastoreOptions options = @@ -437,7 +433,7 @@ public void testGqlQueryPagination() { count += 1; results.next(); } - assertEquals(count, responses.size()); + assertEquals(count, 5); EasyMock.verify(rpcFactoryMock, rpcMock); } @@ -486,7 +482,7 @@ public void testRunStructuredQuery() { } @Test - public void testStructuredQueryPagination() { + public void testStructuredQueryPagination() throws DatastoreRpcException { DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) @@ -494,14 +490,10 @@ public void testStructuredQueryPagination() { List responses = buildResponsesForQueryPagination(); for (int i = 0; i < responses.size(); i++) { - try { EasyMock .expect(rpcMock.runQuery( EasyMock.anyObject(com.google.datastore.v1beta3.RunQueryRequest.class))) .andReturn(responses.get(i)); - } catch (DatastoreRpcException e) { - fail("Unexpected DatastoreRpcException"); - } } EasyMock.replay(rpcFactoryMock, rpcMock); DatastoreOptions options = @@ -516,11 +508,14 @@ public void testStructuredQueryPagination() { count += 1; results.next(); } - assertEquals(count, responses.size()); + assertEquals(count, 5); EasyMock.verify(rpcFactoryMock, rpcMock); } private List buildResponsesForQueryPagination() { + Entity entity4 = Entity.builder(KEY4).set("value", StringValue.of("value")).build(); + Entity entity5 = Entity.builder(KEY5).set("value", "value").build(); + datastore.add(ENTITY3, entity4, entity5); List responses = new ArrayList<>(); Query query = Query.keyQueryBuilder().build(); com.google.datastore.v1beta3.RunQueryRequest.Builder requestPb = @@ -547,15 +542,28 @@ private List buildResponsesForQue com.google.datastore.v1beta3.QueryResultBatch.newBuilder() .mergeFrom(queryResultBatchPb) .setMoreResults( - com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType.NO_MORE_RESULTS) + com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType.NOT_FINISHED) .clearEntityResults() - .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(1, 2)) - .setEndCursor(queryResultBatchPb.getEntityResultsList().get(1).getCursor()) + .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(1, 3)) + .setEndCursor(queryResultBatchPb.getEntityResultsList().get(2).getCursor()) .build(); responses.add( com.google.datastore.v1beta3.RunQueryResponse.newBuilder() .setBatch(queryResultBatchPb2) .build()); + com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb3 = + com.google.datastore.v1beta3.QueryResultBatch.newBuilder() + .mergeFrom(queryResultBatchPb) + .setMoreResults( + com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType.NO_MORE_RESULTS) + .clearEntityResults() + .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(3, 5)) + .setEndCursor(queryResultBatchPb.getEntityResultsList().get(4).getCursor()) + .build(); + responses.add( + com.google.datastore.v1beta3.RunQueryResponse.newBuilder() + .setBatch(queryResultBatchPb3) + .build()); return responses; } From 6ffe9273596c10d38cef62db73a77b38ac8b8c3c Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Wed, 21 Oct 2015 15:47:34 -0700 Subject: [PATCH 021/375] remove changes to structured query's builder and instead use fromPb in GqlQuery's nextQuery --- .../com/google/gcloud/datastore/GqlQuery.java | 9 ++--- .../gcloud/datastore/StructuredQuery.java | 35 +++++++++---------- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java index ecb0aef1e701..6c746c7924d7 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java @@ -379,12 +379,9 @@ protected void populatePb(com.google.datastore.v1beta3.RunQueryRequest.Builder r } @Override - protected StructuredQuery nextQuery(com.google.datastore.v1beta3.RunQueryResponse responsePb) { - return new StructuredQuery.Builder<>(type()) - .namespace(namespace()) - .mergeFrom(responsePb.getQuery()) - .prepareNext(responsePb.getBatch()) - .build(); + protected Query nextQuery(com.google.datastore.v1beta3.RunQueryResponse responsePb) { + return StructuredQuery.fromPb(type(), namespace(), responsePb.getQuery()) + .nextQuery(responsePb); } @Override diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java index dcf4cef4721f..e519ce4fc3ff 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java @@ -669,23 +669,9 @@ B mergeFrom(com.google.datastore.v1beta3.Query queryPb) { return self(); } - B prepareNext(com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb) { - startCursor(new Cursor(queryResultBatchPb.getEndCursor())); - if (offset > 0 && queryResultBatchPb.getSkippedResults() < offset) { - offset(offset - queryResultBatchPb.getSkippedResults()); - } else { - offset(0); - if (limit != null) { - limit(limit - queryResultBatchPb.getEntityResultsCount()); - } - } - return self(); - } - public StructuredQuery build() { return new StructuredQuery<>(this); } - } static final class Builder extends BaseBuilder> { @@ -858,8 +844,19 @@ protected void populatePb(com.google.datastore.v1beta3.RunQueryRequest.Builder r } @Override - protected StructuredQuery nextQuery(com.google.datastore.v1beta3.RunQueryResponse responsePb) { - return new Builder<>(type()).mergeFrom(toPb()).prepareNext(responsePb.getBatch()).build(); + protected Query nextQuery(com.google.datastore.v1beta3.RunQueryResponse responsePb) { + Builder builder = new Builder<>(type()); + builder.mergeFrom(toPb()); + builder.startCursor(new Cursor(responsePb.getBatch().getEndCursor())); + if (offset > 0 && responsePb.getBatch().getSkippedResults() < offset) { + builder.offset(offset - responsePb.getBatch().getSkippedResults()); + } else { + builder.offset(0); + if (limit != null) { + builder.limit(limit - responsePb.getBatch().getEntityResultsCount()); + } + } + return builder.build(); } @Override @@ -907,7 +904,9 @@ protected Object fromPb(ResultType resultType, String namespace, byte[] bytes return fromPb(resultType, namespace, com.google.datastore.v1beta3.Query.parseFrom(bytesPb)); } - private static StructuredQuery fromPb(ResultType resultType, String namespace, + @SuppressWarnings("unchecked") + static StructuredQuery fromPb( + ResultType resultType, String namespace, com.google.datastore.v1beta3.Query queryPb) { BaseBuilder builder; if (resultType.equals(ResultType.ENTITY)) { @@ -917,6 +916,6 @@ private static StructuredQuery fromPb(ResultType resultType, String namesp } else { builder = new ProjectionEntityQueryBuilder(); } - return builder.namespace(namespace).mergeFrom(queryPb).build(); + return (StructuredQuery) builder.namespace(namespace).mergeFrom(queryPb).build(); } } From 3d7ea2c955bb4886ffc1954badd98ce0eff9a8a4 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 15 Jan 2016 15:26:57 -0800 Subject: [PATCH 022/375] update afterCursor javadoc --- .../google/gcloud/datastore/QueryResults.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java index 5b4f71da3963..110add0bbbe4 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java @@ -35,7 +35,21 @@ public interface QueryResults extends Iterator { Class resultClass(); /** - * Returns the Cursor for point after the value returned in the last {@link #next} call. + * Returns the Cursor for the point after the value returned in the last {@link #next} call. This + * cursor can be used to issue subsequent queries (with the same constraints) that may return + * additional results. + * + *

A simple use case: + *

 {@code
+   * Query query = Query.entityQueryBuilder()
+   *     .kind("Person")
+   *     .filter(PropertyFilter.eq("favoriteFood", "pizza"))
+   *     .build();
+   * QueryResults results = datastore.run(query);
+   * // Consume some results (using results.next()) and do any other actions as necessary.
+   * query = query.toBuilder().startCursor(results.cursorAfter()).build();
+   * results = datastore.run(query); // now we will iterate over all entities not yet consumed
+   * 
*/ Cursor cursorAfter(); } From 2bf4925cb3fa8fa782b78de164e3a841bf5fdf4f Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Fri, 15 Jan 2016 17:54:12 -0800 Subject: [PATCH 023/375] Initial project for Google Cloud DNS in gcloud-java --- gcloud-java-dns/pom.xml | 54 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 gcloud-java-dns/pom.xml diff --git a/gcloud-java-dns/pom.xml b/gcloud-java-dns/pom.xml new file mode 100644 index 000000000000..55d720bc0a36 --- /dev/null +++ b/gcloud-java-dns/pom.xml @@ -0,0 +1,54 @@ + + + 4.0.0 + com.google.gcloud + gcloud-java-dns + jar + GCloud Java DNS + + Java idiomatic client for Google Cloud DNS. + + + com.google.gcloud + gcloud-java-pom + 0.1.3-SNAPSHOT + + + gcloud-java-dns + + + + ${project.groupId} + gcloud-java-core + ${project.version} + + + com.google.apis + google-api-services-dns + v1-rev7-1.21.0 + compile + + + com.google.guava + guava-jdk5 + + + com.google.api-client + google-api-client + + + + + junit + junit + 4.12 + test + + + org.easymock + easymock + 3.3 + test + + + From fe4e137fce65882465ca0e092761e080f366fece Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Fri, 15 Jan 2016 17:56:24 -0800 Subject: [PATCH 024/375] Added DnsRecord as a part of the basic data model. ManagedZoneInfo is to be completed and it is included only as it is required as a builder parameter. This class will change in the near future. --- .../java/com/google/gcloud/dns/DnsRecord.java | 254 ++++++++++++++++++ .../google/gcloud/dns/ManagedZoneInfo.java | 44 +++ .../com/google/gcloud/dns/DnsRecordTest.java | 94 +++++++ 3 files changed, 392 insertions(+) create mode 100644 gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java create mode 100644 gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java create mode 100644 gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java new file mode 100644 index 000000000000..8abf335969f8 --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java @@ -0,0 +1,254 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.dns; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.collect.ImmutableList; + +import java.util.LinkedList; +import java.util.List; + +/** + * A class that represents Google Cloud DNS record set. + * + *

+ * A unit of data that will be returned by the DNS servers. + * + * @see Google + * Cloud DNS documentation + */ +public class DnsRecord { + + private String name; + private List rrdatas = new LinkedList<>(); + private Integer ttl = 86400; // the default ttl of 24 hours + private DnsRecordType type; + private String parentName; + private Long parentId; + + /** + * A private constructor. Obtain an instance using {@link DnsRecord#Builder}. + */ + private DnsRecord() { + } + + DnsRecord(Builder builder) { + this.name = builder.name; + this.rrdatas = ImmutableList.copyOf(builder.rrdatas); + this.ttl = builder.ttl; + this.type = builder.type; + this.parentName = builder.parentName; + this.parentId = builder.parentId; + } + + /** + * Enum for the DNS record types supported by Cloud DNS. + * + *

+ * Google Cloud DNS currently supports records of type A, AAAA, CNAME, MX + * NAPTR, NS, PTR, SOA, SPF, SRV, TXT. + * + * @see + * Cloud + * DNS supported record types + */ + public enum DnsRecordType { + A("A"), + AAAA("AAAA"), + CNAME("CNAME"), + MX("MX"), + NAPTR("NAPTR"), + NS("NS"), + PTR("PTR"), + SOA("SOA"), + SPF("SPF"), + SRV("SRV"), + TXT("TXT"); + + private final String type; + + private DnsRecordType(String type) { + this.type = type; + } + } + + public static class Builder { + + private List rrdatas = new LinkedList<>(); + private String name; + private Integer ttl = 86400; // default ttl of 24 hours + private DnsRecordType type; + private String parentName; + private Long parentId; + + private Builder() { + } + + /** + * Creates a builder and pre-populates attributes with the values from the + * provided DnsRecord instance. + */ + public Builder(DnsRecord record) { + this.name = record.name; + this.ttl = record.ttl; + this.type = record.type; + this.parentId = record.parentId; + this.parentName = record.parentName; + this.rrdatas.addAll(record.rrdatas); + } + + /** + * Adds a record to the record set. + * + *

+ * The records should be as defined in RFC 1035 (section 5) and RFC 1034 + * (section 3.6.1). Examples of records are available in + * Cloud + * DNS documentation. + */ + public Builder add(String record) { + this.rrdatas.add(checkNotNull(record)); + return this; + } + + /** + * Sets name for this DNS record set. For example, www.example.com. + */ + public Builder name(String name) { + this.name = checkNotNull(name); + return this; + } + + /** + * Sets the number of seconds that this record can be cached by resolvers. + * This number must be non-negative. + * + * @param ttl A non-negative number of seconds + */ + public Builder ttl(int ttl) { + // change only if + if (ttl < 0) { + throw new IllegalArgumentException( + "TTL cannot be negative. The supplied value was " + ttl + "." + ); + } + this.ttl = ttl; + return this; + } + + /** + * The identifier of a supported record type, for example, A, AAAA, MX, TXT, + * and so on. + */ + public Builder type(DnsRecordType type) { + this.type = checkNotNull(type); + return this; + } + + /** + * Builds the DNS record. + */ + public DnsRecord build() { + return new DnsRecord(this); + } + + /** + * Sets references to the managed zone that this DNS record belongs to. + */ + public Builder managedZone(ManagedZoneInfo parent) { + checkNotNull(parent); + this.parentId = parent.id(); + this.parentName = parent.name(); + return this; + } + } + + /** + * Creates a builder pre-populated with the attribute values of this instance. + */ + public Builder toBuilder() { + return new Builder(this); + } + + /** + * Creates an empty builder + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Get user assigned name of this DNS record. + * + * TODO: is this field mandatory? + */ + public String name() { + return name; + } + + /** + * Returns a list of DNS record stored in this record set. + */ + public List rrdatas() { + return rrdatas; + } + + /** + * Returns the number of seconds that this ResourceRecordSet can be cached by + * resolvers. + * + *

+ * This number is provided by the user. If this values is not set, we use + * default of 86400. + */ + public Integer ttl() { + return ttl; + } + + /** + * Returns the type of this DNS record. + */ + public DnsRecordType type() { + return type; + } + + /** + * Returns name of the managed zone that this record belongs to. + * + *

+ * The name of the managed zone is provided by the user when the managed zone + * is created. It is unique within a project. If this DNS record is not + * associated with a managed zone, this returns null. + */ + public String parentName() { + return parentName; + } + + /** + * Returns name of the managed zone that this record belongs to. + * + *

+ * The id of the managed zone is determined by the server when the managed + * zone is created. It is a read only value. If this DNS record is not + * associated with a managed zone, or if the id of the managed zone was not + * loaded from the cloud service, this returns null. + */ + public Long parentId() { + return parentId; + } + +} diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java new file mode 100644 index 000000000000..003854a91918 --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java @@ -0,0 +1,44 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.dns; + +/** + * TODO: Implement. + * TODO: Add documentation. + */ +public class ManagedZoneInfo { + + private final String name; + private final Long id; + + public String name() { + throw new UnsupportedOperationException("Not implemented yet."); + // TODO: Implement + } + + public Long id() { + return id; + // TODO: Implement + } + + private ManagedZoneInfo() { + name = null; + id = null; + throw new UnsupportedOperationException("Not implemented yet"); + // TODO: Implement + } + +} diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java new file mode 100644 index 000000000000..0709ca3bf0e4 --- /dev/null +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java @@ -0,0 +1,94 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.dns; + +import org.easymock.EasyMock; + +import org.junit.Test; +import org.junit.Before; + +import static org.junit.Assert.*; + +public class DnsRecordTest { + + private static final String NAME = "example.com."; + private static final Integer TTL = 3600; + private static final DnsRecord.DnsRecordType TYPE = DnsRecord.DnsRecordType.AAAA; + private static final ManagedZoneInfo MANAGED_ZONE_INFO_MOCK + = EasyMock.createMock(ManagedZoneInfo.class); + private static final Long PARENT_ID = 12L; + private static final String PARENT_NAME = "name"; + static { + EasyMock.expect(MANAGED_ZONE_INFO_MOCK.id()).andReturn(PARENT_ID); + EasyMock.expect(MANAGED_ZONE_INFO_MOCK.name()).andReturn(PARENT_NAME); + EasyMock.replay(MANAGED_ZONE_INFO_MOCK); + } + private static final DnsRecord RECORD = DnsRecord.builder() + .name(NAME) + .ttl(TTL) + .managedZone(MANAGED_ZONE_INFO_MOCK) + .build(); + private static final Integer DEFAULT_TTL = 86400; + + @Test + public void testDefaultDnsRecord() { + DnsRecord record = DnsRecord.builder().build(); + assertEquals(DEFAULT_TTL, record.ttl()); + assertEquals(0, record.rrdatas().size()); + } + + @Test + public void testBuilder() { + + assertEquals(NAME, RECORD.name()); + assertEquals(TTL, RECORD.ttl()); + + assertEquals(PARENT_ID, RECORD.parentId()); // this was never assigned + assertEquals(PARENT_NAME, RECORD.parentName()); + assertEquals(0, RECORD.rrdatas().size()); + // verify that one can add records to the record set + String testingRecord = "Testing record"; + String anotherTestingRecord = "Another record 123"; + DnsRecord anotherRecord = RECORD.toBuilder() + .add(testingRecord) + .add(anotherTestingRecord) + .build(); + assertEquals(2, anotherRecord.rrdatas().size()); + assertTrue(anotherRecord.rrdatas().contains(testingRecord)); + assertTrue(anotherRecord.rrdatas().contains(anotherTestingRecord)); + } + + @Test + public void testValidTtl() { + try { + DnsRecord.builder().ttl(-1); + fail("A negative value is not acceptable for ttl."); + } catch (IllegalArgumentException e) { + // ok + } + try { + DnsRecord.builder().ttl(0); + } catch (IllegalArgumentException e) { + fail("0 is a valid value."); + } + try { + DnsRecord.builder().ttl(Integer.MAX_VALUE); + } catch (Exception e) { + fail("Large numbers should be ok too."); + } + } + +} From f652277e166b7d3cb3f248e0dafd92ea063c0caf Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Tue, 19 Jan 2016 15:37:51 -0800 Subject: [PATCH 025/375] Implemented comments by @mziccard --- .../java/com/google/gcloud/dns/DnsRecord.java | 188 ++++++++++-------- .../google/gcloud/dns/ManagedZoneInfo.java | 10 +- .../com/google/gcloud/dns/DnsRecordTest.java | 82 +++++--- 3 files changed, 165 insertions(+), 115 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java index 8abf335969f8..56da63dc5fe3 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java @@ -15,35 +15,45 @@ */ package com.google.gcloud.dns; +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.collect.ImmutableList; +import java.io.Serializable; + import java.util.LinkedList; import java.util.List; +import java.util.Objects; /** * A class that represents Google Cloud DNS record set. * - *

- * A unit of data that will be returned by the DNS servers. + *

A unit of data that will be returned by the DNS servers. * - * @see Google - * Cloud DNS documentation + * @see Google Cloud DNS + * documentation */ -public class DnsRecord { +public class DnsRecord implements Serializable { - private String name; - private List rrdatas = new LinkedList<>(); - private Integer ttl = 86400; // the default ttl of 24 hours - private DnsRecordType type; - private String parentName; - private Long parentId; + private static final long serialVersionUID = 2016011914302204L; + private final String name; + private final List rrdatas; + private final Integer ttl; + private final DnsRecordType type; + private final String zoneName; + private final Long zoneId; /** * A private constructor. Obtain an instance using {@link DnsRecord#Builder}. */ private DnsRecord() { + this.name = null; + this.rrdatas = null; + this.ttl = null; + this.type = null; + this.zoneName = null; + this.zoneId = null; } DnsRecord(Builder builder) { @@ -51,74 +61,64 @@ private DnsRecord() { this.rrdatas = ImmutableList.copyOf(builder.rrdatas); this.ttl = builder.ttl; this.type = builder.type; - this.parentName = builder.parentName; - this.parentId = builder.parentId; + this.zoneName = builder.zoneName; + this.zoneId = builder.zoneId; } /** * Enum for the DNS record types supported by Cloud DNS. * - *

- * Google Cloud DNS currently supports records of type A, AAAA, CNAME, MX - * NAPTR, NS, PTR, SOA, SPF, SRV, TXT. + *

Google Cloud DNS currently supports records of type A, AAAA, CNAME, MX NAPTR, NS, PTR, SOA, + * SPF, SRV, TXT. * - * @see - * Cloud - * DNS supported record types + * @see Cloud DNS + * supported record types */ public enum DnsRecordType { - A("A"), - AAAA("AAAA"), - CNAME("CNAME"), - MX("MX"), - NAPTR("NAPTR"), - NS("NS"), - PTR("PTR"), - SOA("SOA"), - SPF("SPF"), - SRV("SRV"), - TXT("TXT"); - - private final String type; - - private DnsRecordType(String type) { - this.type = type; - } + A, + AAAA, + CNAME, + MX, + NAPTR, + NS, + PTR, + SOA, + SPF, + SRV, + TXT; } public static class Builder { private List rrdatas = new LinkedList<>(); private String name; - private Integer ttl = 86400; // default ttl of 24 hours + private Integer ttl; private DnsRecordType type; - private String parentName; - private Long parentId; + private String zoneName; + private Long zoneId; private Builder() { } /** - * Creates a builder and pre-populates attributes with the values from the - * provided DnsRecord instance. + * Creates a builder and pre-populates attributes with the values from the provided DnsRecord + * instance. */ public Builder(DnsRecord record) { this.name = record.name; this.ttl = record.ttl; this.type = record.type; - this.parentId = record.parentId; - this.parentName = record.parentName; + this.zoneId = record.zoneId; + this.zoneName = record.zoneName; this.rrdatas.addAll(record.rrdatas); } /** - * Adds a record to the record set. + * Adds a record to the record set. The records should be as defined in RFC 1035 (section 5) and + * RFC 1034 (section 3.6.1). Examples of records are available in Google DNS documentation. * - *

- * The records should be as defined in RFC 1035 (section 5) and RFC 1034 - * (section 3.6.1). Examples of records are available in - * Cloud - * DNS documentation. + * @see Google + * DNS documentation . */ public Builder add(String record) { this.rrdatas.add(checkNotNull(record)); @@ -134,25 +134,19 @@ public Builder name(String name) { } /** - * Sets the number of seconds that this record can be cached by resolvers. - * This number must be non-negative. + * Sets the number of seconds that this record can be cached by resolvers. This number must be + * non-negative. * * @param ttl A non-negative number of seconds */ public Builder ttl(int ttl) { - // change only if - if (ttl < 0) { - throw new IllegalArgumentException( - "TTL cannot be negative. The supplied value was " + ttl + "." - ); - } + checkArgument(ttl >= 0, "TTL cannot be negative. The supplied value was " + ttl + "."); this.ttl = ttl; return this; } /** - * The identifier of a supported record type, for example, A, AAAA, MX, TXT, - * and so on. + * The identifier of a supported record type, for example, A, AAAA, MX, TXT, and so on. */ public Builder type(DnsRecordType type) { this.type = checkNotNull(type); @@ -171,8 +165,8 @@ public DnsRecord build() { */ public Builder managedZone(ManagedZoneInfo parent) { checkNotNull(parent); - this.parentId = parent.id(); - this.parentName = parent.name(); + this.zoneId = parent.id(); + this.zoneName = parent.name(); return this; } } @@ -192,9 +186,7 @@ public static Builder builder() { } /** - * Get user assigned name of this DNS record. - * - * TODO: is this field mandatory? + * Get the mandatory user assigned name of this DNS record. */ public String name() { return name; @@ -204,16 +196,12 @@ public String name() { * Returns a list of DNS record stored in this record set. */ public List rrdatas() { - return rrdatas; + return ImmutableList.copyOf(rrdatas); } /** - * Returns the number of seconds that this ResourceRecordSet can be cached by - * resolvers. - * - *

- * This number is provided by the user. If this values is not set, we use - * default of 86400. + * Returns the number of seconds that this ResourceRecordSet can be cached by resolvers. This + * number is provided by the user. */ public Integer ttl() { return ttl; @@ -227,28 +215,56 @@ public DnsRecordType type() { } /** - * Returns name of the managed zone that this record belongs to. - * - *

- * The name of the managed zone is provided by the user when the managed zone - * is created. It is unique within a project. If this DNS record is not - * associated with a managed zone, this returns null. + * Returns name of the managed zone that this record belongs to. The name of the managed zone is + * provided by the user when the managed zone is created. It is unique within a project. If this + * DNS record is not associated with a managed zone, this returns null. */ - public String parentName() { - return parentName; + public String zoneName() { + return zoneName; } /** * Returns name of the managed zone that this record belongs to. * - *

- * The id of the managed zone is determined by the server when the managed - * zone is created. It is a read only value. If this DNS record is not - * associated with a managed zone, or if the id of the managed zone was not - * loaded from the cloud service, this returns null. + *

The id of the managed zone is determined by the server when the managed zone is created. It + * is a read only value. If this DNS record is not associated with a managed zone, or if the id of + * the managed zone was not loaded from the cloud service, this returns null. */ - public Long parentId() { - return parentId; + public Long zoneId() { + return zoneId; + } + + @Override + public int hashCode() { + return Objects.hash(name, rrdatas, ttl, type, zoneName, zoneId); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof DnsRecord) { + DnsRecord other = (DnsRecord) obj; + return zoneId == other.zoneId() + && zoneName == other.zoneName + && this.toRRSet().equals(other.toRRSet()); + } + return false; + } + + com.google.api.services.dns.model.ResourceRecordSet toRRSet() { + com.google.api.services.dns.model.ResourceRecordSet rrset = + new com.google.api.services.dns.model.ResourceRecordSet(); + rrset.setName(name); + rrset.setRrdatas(this.rrdatas()); + rrset.setTtl(ttl); + rrset.setType(type == null ? null : type.name()); + return rrset; + } + + @Override + public String toString() { + return "DnsRecord{" + "name=" + name + ", rrdatas=" + rrdatas + + ", ttl=" + ttl + ", type=" + type + ", zoneName=" + + zoneName + ", zoneId=" + zoneId + '}'; } } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java index 003854a91918..d5ed8351dc34 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java @@ -16,8 +16,8 @@ package com.google.gcloud.dns; /** - * TODO: Implement. - * TODO: Add documentation. + * todo(mderka): Implement. + * todo(mderka): Add documentation. */ public class ManagedZoneInfo { @@ -26,19 +26,19 @@ public class ManagedZoneInfo { public String name() { throw new UnsupportedOperationException("Not implemented yet."); - // TODO: Implement + // todo(mderka): Implement } public Long id() { return id; - // TODO: Implement + // todo(mderka): Implement } private ManagedZoneInfo() { name = null; id = null; throw new UnsupportedOperationException("Not implemented yet"); - // TODO: Implement + // todo(mderka): Implement } } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java index 0709ca3bf0e4..55c72d794e87 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java @@ -15,38 +15,42 @@ */ package com.google.gcloud.dns; -import org.easymock.EasyMock; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.junit.Assert.assertNotEquals; +import org.junit.BeforeClass; import org.junit.Test; -import org.junit.Before; -import static org.junit.Assert.*; +import org.easymock.EasyMock; + public class DnsRecordTest { private static final String NAME = "example.com."; private static final Integer TTL = 3600; private static final DnsRecord.DnsRecordType TYPE = DnsRecord.DnsRecordType.AAAA; - private static final ManagedZoneInfo MANAGED_ZONE_INFO_MOCK - = EasyMock.createMock(ManagedZoneInfo.class); - private static final Long PARENT_ID = 12L; - private static final String PARENT_NAME = "name"; + private static final ManagedZoneInfo MANAGED_ZONE_INFO_MOCK = + EasyMock.createMock(ManagedZoneInfo.class); + private static final Long ZONE_ID = 12L; + private static final String ZONE_NAME = "name"; + static { - EasyMock.expect(MANAGED_ZONE_INFO_MOCK.id()).andReturn(PARENT_ID); - EasyMock.expect(MANAGED_ZONE_INFO_MOCK.name()).andReturn(PARENT_NAME); + EasyMock.expect(MANAGED_ZONE_INFO_MOCK.id()).andReturn(ZONE_ID); + EasyMock.expect(MANAGED_ZONE_INFO_MOCK.name()).andReturn(ZONE_NAME); EasyMock.replay(MANAGED_ZONE_INFO_MOCK); } + private static final DnsRecord RECORD = DnsRecord.builder() .name(NAME) .ttl(TTL) .managedZone(MANAGED_ZONE_INFO_MOCK) .build(); - private static final Integer DEFAULT_TTL = 86400; @Test public void testDefaultDnsRecord() { DnsRecord record = DnsRecord.builder().build(); - assertEquals(DEFAULT_TTL, record.ttl()); assertEquals(0, record.rrdatas().size()); } @@ -56,8 +60,8 @@ public void testBuilder() { assertEquals(NAME, RECORD.name()); assertEquals(TTL, RECORD.ttl()); - assertEquals(PARENT_ID, RECORD.parentId()); // this was never assigned - assertEquals(PARENT_NAME, RECORD.parentName()); + assertEquals(ZONE_ID, RECORD.zoneId()); // this was never assigned + assertEquals(ZONE_NAME, RECORD.zoneName()); assertEquals(0, RECORD.rrdatas().size()); // verify that one can add records to the record set String testingRecord = "Testing record"; @@ -77,18 +81,48 @@ public void testValidTtl() { DnsRecord.builder().ttl(-1); fail("A negative value is not acceptable for ttl."); } catch (IllegalArgumentException e) { - // ok - } - try { - DnsRecord.builder().ttl(0); - } catch (IllegalArgumentException e) { - fail("0 is a valid value."); - } - try { - DnsRecord.builder().ttl(Integer.MAX_VALUE); - } catch (Exception e) { - fail("Large numbers should be ok too."); + // expected } + DnsRecord.builder().ttl(0); + DnsRecord.builder().ttl(Integer.MAX_VALUE); + } + + @Test + public void testEqualsAndNotEquals() { + DnsRecord clone = RECORD.toBuilder().build(); + assertEquals(clone, RECORD); + clone = RECORD.toBuilder().add("another record").build(); + final String differentName = "totally different name"; + clone = RECORD.toBuilder().name(differentName).build(); + assertNotEquals(clone, RECORD); + clone = RECORD.toBuilder().ttl(RECORD.ttl() + 1).build(); + assertNotEquals(clone, RECORD); + clone = RECORD.toBuilder().type(DnsRecord.DnsRecordType.TXT).build(); + assertNotEquals(clone, RECORD); + ManagedZoneInfo anotherMock = EasyMock.createMock(ManagedZoneInfo.class); + EasyMock.expect(anotherMock.id()).andReturn(ZONE_ID + 1); + EasyMock.expect(anotherMock.name()).andReturn(ZONE_NAME + "more text"); + EasyMock.replay(anotherMock); + clone = RECORD.toBuilder().managedZone(anotherMock).build(); + assertNotEquals(clone, RECORD); + } + + @Test + public void testSameHashCodeOnEquals() { + int hash = RECORD.hashCode(); + DnsRecord clone = RECORD.toBuilder().build(); + assertEquals(clone.hashCode(), hash); + } + + @Test + public void testDifferentHashCodeOnDifferent() { + int hash = RECORD.hashCode(); + final String differentName = "totally different name"; + DnsRecord clone = RECORD.toBuilder().name(differentName).build(); + assertNotEquals(differentName, RECORD.name()); + assertNotEquals(clone.hashCode(), hash); + DnsRecord anotherClone = RECORD.toBuilder().add("another record").build(); + assertNotEquals(anotherClone.hashCode(), hash); } } From b29945fd1fd920571d115b746185dfef36d2a0ab Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Wed, 20 Jan 2016 11:14:09 -0800 Subject: [PATCH 026/375] Second round of comments from @mziccard --- .../java/com/google/gcloud/dns/DnsRecord.java | 68 +++++++++------- .../com/google/gcloud/dns/DnsRecordTest.java | 78 ++++++++++--------- 2 files changed, 80 insertions(+), 66 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java index 56da63dc5fe3..91278fa2a1e7 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java @@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; import java.io.Serializable; @@ -29,7 +30,7 @@ /** * A class that represents Google Cloud DNS record set. * - *

A unit of data that will be returned by the DNS servers. + *

A unit of data that will be returned by the DNS servers. * * @see Google Cloud DNS * documentation @@ -44,9 +45,6 @@ public class DnsRecord implements Serializable { private final String zoneName; private final Long zoneId; - /** - * A private constructor. Obtain an instance using {@link DnsRecord#Builder}. - */ private DnsRecord() { this.name = null; this.rrdatas = null; @@ -68,7 +66,7 @@ private DnsRecord() { /** * Enum for the DNS record types supported by Cloud DNS. * - *

Google Cloud DNS currently supports records of type A, AAAA, CNAME, MX NAPTR, NS, PTR, SOA, + *

Google Cloud DNS currently supports records of type A, AAAA, CNAME, MX NAPTR, NS, PTR, SOA, * SPF, SRV, TXT. * * @see Cloud DNS @@ -85,7 +83,7 @@ public enum DnsRecordType { SOA, SPF, SRV, - TXT; + TXT } public static class Builder { @@ -162,13 +160,23 @@ public DnsRecord build() { /** * Sets references to the managed zone that this DNS record belongs to. + * + * todo(mderka): consider if this method is needed; may not be possible when listing records */ - public Builder managedZone(ManagedZoneInfo parent) { + Builder managedZone(ManagedZoneInfo parent) { checkNotNull(parent); this.zoneId = parent.id(); this.zoneName = parent.name(); return this; } + + /** + * Sets name reference to the managed zone that this DNS record belongs to. + */ + Builder managedZone(String managedZoneName) { + this.zoneName = checkNotNull(managedZoneName); + return this; + } } /** @@ -196,12 +204,12 @@ public String name() { * Returns a list of DNS record stored in this record set. */ public List rrdatas() { - return ImmutableList.copyOf(rrdatas); + return rrdatas; } /** - * Returns the number of seconds that this ResourceRecordSet can be cached by resolvers. This - * number is provided by the user. + * Returns the number of seconds that this DnsResource can be cached by resolvers. This number is + * provided by the user. */ public Integer ttl() { return ttl; @@ -224,9 +232,9 @@ public String zoneName() { } /** - * Returns name of the managed zone that this record belongs to. + * Returns id of the managed zone that this record belongs to. * - *

The id of the managed zone is determined by the server when the managed zone is created. It + *

The id of the managed zone is determined by the server when the managed zone is created. It * is a read only value. If this DNS record is not associated with a managed zone, or if the id of * the managed zone was not loaded from the cloud service, this returns null. */ @@ -241,30 +249,32 @@ public int hashCode() { @Override public boolean equals(Object obj) { - if (obj instanceof DnsRecord) { - DnsRecord other = (DnsRecord) obj; - return zoneId == other.zoneId() - && zoneName == other.zoneName - && this.toRRSet().equals(other.toRRSet()); - } - return false; + return (obj instanceof DnsRecord) && Objects.equals(this.toPb(), ((DnsRecord) obj).toPb()) + && this.zoneId().equals(((DnsRecord) obj).zoneId()) + && this.zoneName().equals(((DnsRecord) obj).zoneName()); + } - com.google.api.services.dns.model.ResourceRecordSet toRRSet() { - com.google.api.services.dns.model.ResourceRecordSet rrset = + com.google.api.services.dns.model.ResourceRecordSet toPb() { + com.google.api.services.dns.model.ResourceRecordSet pb = new com.google.api.services.dns.model.ResourceRecordSet(); - rrset.setName(name); - rrset.setRrdatas(this.rrdatas()); - rrset.setTtl(ttl); - rrset.setType(type == null ? null : type.name()); - return rrset; + pb.setName(this.name()); + pb.setRrdatas(this.rrdatas()); + pb.setTtl(this.ttl()); + pb.setType(this.type() == null ? null : this.type().name()); + return pb; } @Override public String toString() { - return "DnsRecord{" + "name=" + name + ", rrdatas=" + rrdatas - + ", ttl=" + ttl + ", type=" + type + ", zoneName=" - + zoneName + ", zoneId=" + zoneId + '}'; + return MoreObjects.toStringHelper(this) + .add("name", name()) + .add("rrdatas", rrdatas()) + .add("ttl", ttl()) + .add("type", type()) + .add("zoneName", zoneName()) + .add("zoneId", zoneId()) + .toString(); } } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java index 55c72d794e87..ee9e6e58d61d 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java @@ -25,29 +25,30 @@ import org.easymock.EasyMock; - public class DnsRecordTest { private static final String NAME = "example.com."; private static final Integer TTL = 3600; private static final DnsRecord.DnsRecordType TYPE = DnsRecord.DnsRecordType.AAAA; - private static final ManagedZoneInfo MANAGED_ZONE_INFO_MOCK = - EasyMock.createMock(ManagedZoneInfo.class); private static final Long ZONE_ID = 12L; private static final String ZONE_NAME = "name"; - - static { - EasyMock.expect(MANAGED_ZONE_INFO_MOCK.id()).andReturn(ZONE_ID); - EasyMock.expect(MANAGED_ZONE_INFO_MOCK.name()).andReturn(ZONE_NAME); - EasyMock.replay(MANAGED_ZONE_INFO_MOCK); + // the following is initialized in @BeforeClass setUp() + private static DnsRecord record; + private static ManagedZoneInfo managedZoneInfoMock; + + @BeforeClass + public static void setUp() { + managedZoneInfoMock = EasyMock.createMock(ManagedZoneInfo.class); + EasyMock.expect(managedZoneInfoMock.id()).andReturn(ZONE_ID); + EasyMock.expect(managedZoneInfoMock.name()).andReturn(ZONE_NAME); + EasyMock.replay(managedZoneInfoMock); + record = DnsRecord.builder() + .name(NAME) + .ttl(TTL) + .managedZone(managedZoneInfoMock) + .build(); } - private static final DnsRecord RECORD = DnsRecord.builder() - .name(NAME) - .ttl(TTL) - .managedZone(MANAGED_ZONE_INFO_MOCK) - .build(); - @Test public void testDefaultDnsRecord() { DnsRecord record = DnsRecord.builder().build(); @@ -57,20 +58,23 @@ public void testDefaultDnsRecord() { @Test public void testBuilder() { - assertEquals(NAME, RECORD.name()); - assertEquals(TTL, RECORD.ttl()); + assertEquals(NAME, record.name()); + assertEquals(TTL, record.ttl()); - assertEquals(ZONE_ID, RECORD.zoneId()); // this was never assigned - assertEquals(ZONE_NAME, RECORD.zoneName()); - assertEquals(0, RECORD.rrdatas().size()); + assertEquals(ZONE_ID, record.zoneId()); // this was never assigned + assertEquals(ZONE_NAME, record.zoneName()); + assertEquals(0, record.rrdatas().size()); // verify that one can add records to the record set String testingRecord = "Testing record"; String anotherTestingRecord = "Another record 123"; - DnsRecord anotherRecord = RECORD.toBuilder() + String differentName = ZONE_NAME + "something"; + DnsRecord anotherRecord = record.toBuilder() .add(testingRecord) .add(anotherTestingRecord) + .managedZone(differentName) .build(); assertEquals(2, anotherRecord.rrdatas().size()); + assertEquals(differentName, anotherRecord.zoneName()); assertTrue(anotherRecord.rrdatas().contains(testingRecord)); assertTrue(anotherRecord.rrdatas().contains(anotherTestingRecord)); } @@ -89,39 +93,39 @@ public void testValidTtl() { @Test public void testEqualsAndNotEquals() { - DnsRecord clone = RECORD.toBuilder().build(); - assertEquals(clone, RECORD); - clone = RECORD.toBuilder().add("another record").build(); + DnsRecord clone = record.toBuilder().build(); + assertEquals(clone, record); + clone = record.toBuilder().add("another record").build(); final String differentName = "totally different name"; - clone = RECORD.toBuilder().name(differentName).build(); - assertNotEquals(clone, RECORD); - clone = RECORD.toBuilder().ttl(RECORD.ttl() + 1).build(); - assertNotEquals(clone, RECORD); - clone = RECORD.toBuilder().type(DnsRecord.DnsRecordType.TXT).build(); - assertNotEquals(clone, RECORD); + clone = record.toBuilder().name(differentName).build(); + assertNotEquals(clone, record); + clone = record.toBuilder().ttl(record.ttl() + 1).build(); + assertNotEquals(clone, record); + clone = record.toBuilder().type(DnsRecord.DnsRecordType.TXT).build(); + assertNotEquals(clone, record); ManagedZoneInfo anotherMock = EasyMock.createMock(ManagedZoneInfo.class); EasyMock.expect(anotherMock.id()).andReturn(ZONE_ID + 1); EasyMock.expect(anotherMock.name()).andReturn(ZONE_NAME + "more text"); EasyMock.replay(anotherMock); - clone = RECORD.toBuilder().managedZone(anotherMock).build(); - assertNotEquals(clone, RECORD); + clone = record.toBuilder().managedZone(anotherMock).build(); + assertNotEquals(clone, record); } @Test public void testSameHashCodeOnEquals() { - int hash = RECORD.hashCode(); - DnsRecord clone = RECORD.toBuilder().build(); + int hash = record.hashCode(); + DnsRecord clone = record.toBuilder().build(); assertEquals(clone.hashCode(), hash); } @Test public void testDifferentHashCodeOnDifferent() { - int hash = RECORD.hashCode(); + int hash = record.hashCode(); final String differentName = "totally different name"; - DnsRecord clone = RECORD.toBuilder().name(differentName).build(); - assertNotEquals(differentName, RECORD.name()); + DnsRecord clone = record.toBuilder().name(differentName).build(); + assertNotEquals(differentName, record.name()); assertNotEquals(clone.hashCode(), hash); - DnsRecord anotherClone = RECORD.toBuilder().add("another record").build(); + DnsRecord anotherClone = record.toBuilder().add("another record").build(); assertNotEquals(anotherClone.hashCode(), hash); } From 1fc0e3275e352706734dc935c6d4bab77976fb1c Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Wed, 20 Jan 2016 17:55:43 -0800 Subject: [PATCH 027/375] Implemented comments by @aozarov. Also removed incomplete ManagedZoneInfo.java. --- .../java/com/google/gcloud/dns/DnsRecord.java | 170 ++++++++++-------- .../google/gcloud/dns/ManagedZoneInfo.java | 44 ----- .../com/google/gcloud/dns/DnsRecordTest.java | 68 ++----- 3 files changed, 105 insertions(+), 177 deletions(-) delete mode 100644 gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java index 91278fa2a1e7..9cc21acfa0a5 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.google.gcloud.dns; import static com.google.common.base.Preconditions.checkArgument; @@ -20,6 +21,7 @@ import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; import java.io.Serializable; @@ -30,7 +32,10 @@ /** * A class that represents Google Cloud DNS record set. * - *

A unit of data that will be returned by the DNS servers. + *

A DnsRecord is the unit of data that will be returned by the DNS servers upon a DNS request + * for a specific domain. The DnsRecord holds the current state of the DNS records that make up a + * managed zone. You can read the records but you do not modify them directly. Rather, you edit + * the records in a managed zone by creating a {@link ChangeRequest}. * * @see Google Cloud DNS * documentation @@ -42,26 +47,6 @@ public class DnsRecord implements Serializable { private final List rrdatas; private final Integer ttl; private final DnsRecordType type; - private final String zoneName; - private final Long zoneId; - - private DnsRecord() { - this.name = null; - this.rrdatas = null; - this.ttl = null; - this.type = null; - this.zoneName = null; - this.zoneId = null; - } - - DnsRecord(Builder builder) { - this.name = builder.name; - this.rrdatas = ImmutableList.copyOf(builder.rrdatas); - this.ttl = builder.ttl; - this.type = builder.type; - this.zoneName = builder.zoneName; - this.zoneId = builder.zoneId; - } /** * Enum for the DNS record types supported by Cloud DNS. @@ -73,16 +58,51 @@ private DnsRecord() { * supported record types */ public enum DnsRecordType { + /** + * Address record, which is used to map host names to their IPv4 address. + */ A, + /** + * IPv6 Address record, which is used to map host names to their IPv6 address. + */ AAAA, + /** + * Canonical name record, which is used to alias names. + */ CNAME, + /** + * Mail exchange record, which is used in routing requests to mail servers. + */ MX, + /** + * Naming authority pointer record, defined by RFC3403. + */ NAPTR, + /** + * Name server record, which delegates a DNS zone to an authoritative server. + */ NS, + /** + * Pointer record, which is often used for reverse DNS lookups. + */ PTR, + /** + * Start of authority record, which specifies authoritative information about a DNS zone. + */ SOA, + /** + * Sender policy framework record, which is used in email validation systems. + */ SPF, + /** + * Service locator record, which is used by some voice over IP, instant messaging protocols and + * other applications. + */ SRV, + /** + * Text record, which can contain arbitrary text and can also be used to define machine readable + * data such as security or abuse prevention information. + */ TXT } @@ -92,8 +112,6 @@ public static class Builder { private String name; private Integer ttl; private DnsRecordType type; - private String zoneName; - private Long zoneId; private Builder() { } @@ -102,12 +120,10 @@ private Builder() { * Creates a builder and pre-populates attributes with the values from the provided DnsRecord * instance. */ - public Builder(DnsRecord record) { + private Builder(DnsRecord record) { this.name = record.name; this.ttl = record.ttl; this.type = record.type; - this.zoneId = record.zoneId; - this.zoneName = record.zoneName; this.rrdatas.addAll(record.rrdatas); } @@ -118,11 +134,46 @@ public Builder(DnsRecord record) { * @see Google * DNS documentation . */ - public Builder add(String record) { + public Builder addRecord(String record) { this.rrdatas.add(checkNotNull(record)); return this; } + /** + * Removes a record from the set. An exact match is required. + */ + public Builder removerRecord(String record) { + this.rrdatas.remove(checkNotNull(record)); + return this; + } + + /** + * Removes a record on the given index from the set. + */ + public Builder removerRecord(int index) { + checkArgument(index >= 0 && index < this.rrdatas.size(), "The index is out of bounds. An " + + "integer between 0 and " + (this.rrdatas.size() - 1) + " is required. The provided " + + "value was " + index + "."); + this.rrdatas.remove(index); + return this; + } + + /** + * Removes all the records. + */ + public Builder clearRecords() { + this.rrdatas.clear(); + return this; + } + + /** + * Replaces the current records with the provided list of records. + */ + public Builder records(List records) { + this.rrdatas = Lists.newLinkedList(checkNotNull(records)); + return this; + } + /** * Sets name for this DNS record set. For example, www.example.com. */ @@ -157,26 +208,13 @@ public Builder type(DnsRecordType type) { public DnsRecord build() { return new DnsRecord(this); } + } - /** - * Sets references to the managed zone that this DNS record belongs to. - * - * todo(mderka): consider if this method is needed; may not be possible when listing records - */ - Builder managedZone(ManagedZoneInfo parent) { - checkNotNull(parent); - this.zoneId = parent.id(); - this.zoneName = parent.name(); - return this; - } - - /** - * Sets name reference to the managed zone that this DNS record belongs to. - */ - Builder managedZone(String managedZoneName) { - this.zoneName = checkNotNull(managedZoneName); - return this; - } + DnsRecord(Builder builder) { + this.name = builder.name; + this.rrdatas = ImmutableList.copyOf(builder.rrdatas); + this.ttl = builder.ttl; + this.type = builder.type; } /** @@ -187,7 +225,7 @@ public Builder toBuilder() { } /** - * Creates an empty builder + * Creates an empty builder. */ public static Builder builder() { return new Builder(); @@ -203,13 +241,12 @@ public String name() { /** * Returns a list of DNS record stored in this record set. */ - public List rrdatas() { + public List records() { return rrdatas; } /** - * Returns the number of seconds that this DnsResource can be cached by resolvers. This number is - * provided by the user. + * Returns the number of seconds that this DnsResource can be cached by resolvers. */ public Integer ttl() { return ttl; @@ -222,44 +259,21 @@ public DnsRecordType type() { return type; } - /** - * Returns name of the managed zone that this record belongs to. The name of the managed zone is - * provided by the user when the managed zone is created. It is unique within a project. If this - * DNS record is not associated with a managed zone, this returns null. - */ - public String zoneName() { - return zoneName; - } - - /** - * Returns id of the managed zone that this record belongs to. - * - *

The id of the managed zone is determined by the server when the managed zone is created. It - * is a read only value. If this DNS record is not associated with a managed zone, or if the id of - * the managed zone was not loaded from the cloud service, this returns null. - */ - public Long zoneId() { - return zoneId; - } - @Override public int hashCode() { - return Objects.hash(name, rrdatas, ttl, type, zoneName, zoneId); + return Objects.hash(name, rrdatas, ttl, type); } @Override public boolean equals(Object obj) { - return (obj instanceof DnsRecord) && Objects.equals(this.toPb(), ((DnsRecord) obj).toPb()) - && this.zoneId().equals(((DnsRecord) obj).zoneId()) - && this.zoneName().equals(((DnsRecord) obj).zoneName()); - + return (obj instanceof DnsRecord) && Objects.equals(this.toPb(), ((DnsRecord) obj).toPb()); } com.google.api.services.dns.model.ResourceRecordSet toPb() { com.google.api.services.dns.model.ResourceRecordSet pb = new com.google.api.services.dns.model.ResourceRecordSet(); pb.setName(this.name()); - pb.setRrdatas(this.rrdatas()); + pb.setRrdatas(this.records()); pb.setTtl(this.ttl()); pb.setType(this.type() == null ? null : this.type().name()); return pb; @@ -269,11 +283,9 @@ com.google.api.services.dns.model.ResourceRecordSet toPb() { public String toString() { return MoreObjects.toStringHelper(this) .add("name", name()) - .add("rrdatas", rrdatas()) + .add("rrdatas", records()) .add("ttl", ttl()) .add("type", type()) - .add("zoneName", zoneName()) - .add("zoneId", zoneId()) .toString(); } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java deleted file mode 100644 index d5ed8351dc34..000000000000 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2016 Google Inc. All Rights Reserved. - * - * 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.gcloud.dns; - -/** - * todo(mderka): Implement. - * todo(mderka): Add documentation. - */ -public class ManagedZoneInfo { - - private final String name; - private final Long id; - - public String name() { - throw new UnsupportedOperationException("Not implemented yet."); - // todo(mderka): Implement - } - - public Long id() { - return id; - // todo(mderka): Implement - } - - private ManagedZoneInfo() { - name = null; - id = null; - throw new UnsupportedOperationException("Not implemented yet"); - // todo(mderka): Implement - } - -} diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java index ee9e6e58d61d..4c03306ffb02 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java @@ -20,63 +20,40 @@ import static org.junit.Assert.fail; import static org.junit.Assert.assertNotEquals; -import org.junit.BeforeClass; import org.junit.Test; -import org.easymock.EasyMock; - public class DnsRecordTest { private static final String NAME = "example.com."; private static final Integer TTL = 3600; private static final DnsRecord.DnsRecordType TYPE = DnsRecord.DnsRecordType.AAAA; - private static final Long ZONE_ID = 12L; - private static final String ZONE_NAME = "name"; - // the following is initialized in @BeforeClass setUp() - private static DnsRecord record; - private static ManagedZoneInfo managedZoneInfoMock; - - @BeforeClass - public static void setUp() { - managedZoneInfoMock = EasyMock.createMock(ManagedZoneInfo.class); - EasyMock.expect(managedZoneInfoMock.id()).andReturn(ZONE_ID); - EasyMock.expect(managedZoneInfoMock.name()).andReturn(ZONE_NAME); - EasyMock.replay(managedZoneInfoMock); - record = DnsRecord.builder() - .name(NAME) - .ttl(TTL) - .managedZone(managedZoneInfoMock) - .build(); - } + private static final DnsRecord record = DnsRecord.builder() + .name(NAME) + .ttl(TTL) + .type(TYPE) + .build(); @Test public void testDefaultDnsRecord() { DnsRecord record = DnsRecord.builder().build(); - assertEquals(0, record.rrdatas().size()); + assertEquals(0, record.records().size()); } @Test public void testBuilder() { - assertEquals(NAME, record.name()); assertEquals(TTL, record.ttl()); - - assertEquals(ZONE_ID, record.zoneId()); // this was never assigned - assertEquals(ZONE_NAME, record.zoneName()); - assertEquals(0, record.rrdatas().size()); + assertEquals(0, record.records().size()); // verify that one can add records to the record set String testingRecord = "Testing record"; String anotherTestingRecord = "Another record 123"; - String differentName = ZONE_NAME + "something"; DnsRecord anotherRecord = record.toBuilder() - .add(testingRecord) - .add(anotherTestingRecord) - .managedZone(differentName) + .addRecord(testingRecord) + .addRecord(anotherTestingRecord) .build(); - assertEquals(2, anotherRecord.rrdatas().size()); - assertEquals(differentName, anotherRecord.zoneName()); - assertTrue(anotherRecord.rrdatas().contains(testingRecord)); - assertTrue(anotherRecord.rrdatas().contains(anotherTestingRecord)); + assertEquals(2, anotherRecord.records().size()); + assertTrue(anotherRecord.records().contains(testingRecord)); + assertTrue(anotherRecord.records().contains(anotherTestingRecord)); } @Test @@ -95,7 +72,8 @@ public void testValidTtl() { public void testEqualsAndNotEquals() { DnsRecord clone = record.toBuilder().build(); assertEquals(clone, record); - clone = record.toBuilder().add("another record").build(); + clone = record.toBuilder().addRecord("another record").build(); + assertNotEquals(clone, record); final String differentName = "totally different name"; clone = record.toBuilder().name(differentName).build(); assertNotEquals(clone, record); @@ -103,12 +81,6 @@ public void testEqualsAndNotEquals() { assertNotEquals(clone, record); clone = record.toBuilder().type(DnsRecord.DnsRecordType.TXT).build(); assertNotEquals(clone, record); - ManagedZoneInfo anotherMock = EasyMock.createMock(ManagedZoneInfo.class); - EasyMock.expect(anotherMock.id()).andReturn(ZONE_ID + 1); - EasyMock.expect(anotherMock.name()).andReturn(ZONE_NAME + "more text"); - EasyMock.replay(anotherMock); - clone = record.toBuilder().managedZone(anotherMock).build(); - assertNotEquals(clone, record); } @Test @@ -117,16 +89,4 @@ public void testSameHashCodeOnEquals() { DnsRecord clone = record.toBuilder().build(); assertEquals(clone.hashCode(), hash); } - - @Test - public void testDifferentHashCodeOnDifferent() { - int hash = record.hashCode(); - final String differentName = "totally different name"; - DnsRecord clone = record.toBuilder().name(differentName).build(); - assertNotEquals(differentName, record.name()); - assertNotEquals(clone.hashCode(), hash); - DnsRecord anotherClone = record.toBuilder().add("another record").build(); - assertNotEquals(anotherClone.hashCode(), hash); - } - } From 01662be5e9f6bf11496d84b909676f97ca0401b9 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Thu, 21 Jan 2016 10:00:41 -0800 Subject: [PATCH 028/375] Implements comments by @ajkannan --- gcloud-java-dns/pom.xml | 12 +++--- .../java/com/google/gcloud/dns/DnsRecord.java | 37 ++++++++++++------- .../com/google/gcloud/dns/DnsRecordTest.java | 36 ++++++++++++++---- pom.xml | 1 + 4 files changed, 59 insertions(+), 27 deletions(-) diff --git a/gcloud-java-dns/pom.xml b/gcloud-java-dns/pom.xml index 55d720bc0a36..5f04f261d500 100644 --- a/gcloud-java-dns/pom.xml +++ b/gcloud-java-dns/pom.xml @@ -1,5 +1,7 @@ - + 4.0.0 com.google.gcloud gcloud-java-dns @@ -28,10 +30,10 @@ v1-rev7-1.21.0 compile - - com.google.guava - guava-jdk5 - + + com.google.guava + guava-jdk5 + com.google.api-client google-api-client diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java index 9cc21acfa0a5..f73c880f22f3 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java @@ -24,18 +24,17 @@ import com.google.common.collect.Lists; import java.io.Serializable; - import java.util.LinkedList; import java.util.List; import java.util.Objects; /** - * A class that represents Google Cloud DNS record set. + * A class that represents a Google Cloud DNS record set. * - *

A DnsRecord is the unit of data that will be returned by the DNS servers upon a DNS request - * for a specific domain. The DnsRecord holds the current state of the DNS records that make up a - * managed zone. You can read the records but you do not modify them directly. Rather, you edit - * the records in a managed zone by creating a {@link ChangeRequest}. + *

A {@code DnsRecord} is the unit of data that will be returned by the DNS servers upon a DNS + * request for a specific domain. The {@code DnsRecord} holds the current state of the DNS records + * that make up a managed zone. You can read the records but you do not modify them directly. + * Rather, you edit the records in a managed zone by creating a ChangeRequest. * * @see Google Cloud DNS * documentation @@ -117,8 +116,8 @@ private Builder() { } /** - * Creates a builder and pre-populates attributes with the values from the provided DnsRecord - * instance. + * Creates a builder and pre-populates attributes with the values from the provided {@code + * DnsRecord} instance. */ private Builder(DnsRecord record) { this.name = record.name; @@ -142,7 +141,7 @@ public Builder addRecord(String record) { /** * Removes a record from the set. An exact match is required. */ - public Builder removerRecord(String record) { + public Builder removeRecord(String record) { this.rrdatas.remove(checkNotNull(record)); return this; } @@ -150,7 +149,7 @@ public Builder removerRecord(String record) { /** * Removes a record on the given index from the set. */ - public Builder removerRecord(int index) { + public Builder removeRecord(int index) { checkArgument(index >= 0 && index < this.rrdatas.size(), "The index is out of bounds. An " + "integer between 0 and " + (this.rrdatas.size() - 1) + " is required. The provided " + "value was " + index + "."); @@ -225,10 +224,10 @@ public Builder toBuilder() { } /** - * Creates an empty builder. + * Creates a builder for {@code DnsRecord} with mandatorily set name and type of the record. */ - public static Builder builder() { - return new Builder(); + public static Builder builder(String name, DnsRecordType type) { + return new Builder().name(name).type(type); } /** @@ -279,6 +278,17 @@ com.google.api.services.dns.model.ResourceRecordSet toPb() { return pb; } + static DnsRecord fromPb(com.google.api.services.dns.model.ResourceRecordSet pb) { + Builder b = builder(pb.getName(), DnsRecordType.valueOf(pb.getType())); + if (pb.getRrdatas() != null) { + b.records(pb.getRrdatas()); + } + if (pb.getTtl() != null) { + b.ttl(pb.getTtl()); + } + return b.build(); + } + @Override public String toString() { return MoreObjects.toStringHelper(this) @@ -288,5 +298,4 @@ public String toString() { .add("type", type()) .toString(); } - } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java index 4c03306ffb02..e5b283a20acc 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java @@ -27,15 +27,13 @@ public class DnsRecordTest { private static final String NAME = "example.com."; private static final Integer TTL = 3600; private static final DnsRecord.DnsRecordType TYPE = DnsRecord.DnsRecordType.AAAA; - private static final DnsRecord record = DnsRecord.builder() - .name(NAME) + private static final DnsRecord record = DnsRecord.builder(NAME, TYPE) .ttl(TTL) - .type(TYPE) .build(); @Test public void testDefaultDnsRecord() { - DnsRecord record = DnsRecord.builder().build(); + DnsRecord record = DnsRecord.builder(NAME, TYPE).build(); assertEquals(0, record.records().size()); } @@ -59,13 +57,13 @@ public void testBuilder() { @Test public void testValidTtl() { try { - DnsRecord.builder().ttl(-1); + DnsRecord.builder(NAME, TYPE).ttl(-1); fail("A negative value is not acceptable for ttl."); } catch (IllegalArgumentException e) { // expected } - DnsRecord.builder().ttl(0); - DnsRecord.builder().ttl(Integer.MAX_VALUE); + DnsRecord.builder(NAME, TYPE).ttl(0); + DnsRecord.builder(NAME, TYPE).ttl(Integer.MAX_VALUE); } @Test @@ -89,4 +87,26 @@ public void testSameHashCodeOnEquals() { DnsRecord clone = record.toBuilder().build(); assertEquals(clone.hashCode(), hash); } -} + + @Test + public void testToAndFromPb() { + assertEquals(record, DnsRecord.fromPb(record.toPb())); + DnsRecord partial = DnsRecord.builder(NAME, TYPE).build(); + assertEquals(partial, DnsRecord.fromPb(partial.toPb())); + partial = DnsRecord.builder(NAME, TYPE).addRecord("test").build(); + assertEquals(partial, DnsRecord.fromPb(partial.toPb())); + partial = DnsRecord.builder(NAME, TYPE).ttl(15).build(); + assertEquals(partial, DnsRecord.fromPb(partial.toPb())); + } + + @Test + public void testToBuilder() { + assertEquals(record, record.toBuilder().build()); + DnsRecord partial = DnsRecord.builder(NAME, TYPE).build(); + assertEquals(partial, partial.toBuilder().build()); + partial = DnsRecord.builder(NAME, TYPE).addRecord("test").build(); + assertEquals(partial, partial.toBuilder().build()); + partial = DnsRecord.builder(NAME, TYPE).ttl(15).build(); + assertEquals(partial, partial.toBuilder().build()); + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index cd5c19720cd8..7a435cc1dbae 100644 --- a/pom.xml +++ b/pom.xml @@ -70,6 +70,7 @@ gcloud-java-bigquery gcloud-java-core gcloud-java-datastore + gcloud-java-dns gcloud-java-examples gcloud-java-resourcemanager gcloud-java-storage From 1c657158857a343c2ad4c761cb287d535f396704 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Thu, 21 Jan 2016 13:44:40 -0800 Subject: [PATCH 029/375] Removed the method for removing a record by index. --- .../main/java/com/google/gcloud/dns/DnsRecord.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java index f73c880f22f3..41a8569d3937 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java @@ -146,17 +146,6 @@ public Builder removeRecord(String record) { return this; } - /** - * Removes a record on the given index from the set. - */ - public Builder removeRecord(int index) { - checkArgument(index >= 0 && index < this.rrdatas.size(), "The index is out of bounds. An " + - "integer between 0 and " + (this.rrdatas.size() - 1) + " is required. The provided " + - "value was " + index + "."); - this.rrdatas.remove(index); - return this; - } - /** * Removes all the records. */ From f994057f1d2e8bf4f6b1196d4ae578ba3321951b Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Fri, 22 Jan 2016 10:17:34 -0800 Subject: [PATCH 030/375] Another round of comments from @aozarov. --- .../java/com/google/gcloud/dns/DnsRecord.java | 47 ++++++++++--------- .../com/google/gcloud/dns/DnsRecordTest.java | 41 ++++++++++++---- 2 files changed, 58 insertions(+), 30 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java index 41a8569d3937..c41e72a77400 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java @@ -33,7 +33,7 @@ * *

A {@code DnsRecord} is the unit of data that will be returned by the DNS servers upon a DNS * request for a specific domain. The {@code DnsRecord} holds the current state of the DNS records - * that make up a managed zone. You can read the records but you do not modify them directly. + * that make up a managed zone. You can read the records but you cannot modify them directly. * Rather, you edit the records in a managed zone by creating a ChangeRequest. * * @see Google Cloud DNS @@ -45,7 +45,7 @@ public class DnsRecord implements Serializable { private final String name; private final List rrdatas; private final Integer ttl; - private final DnsRecordType type; + private final Type type; /** * Enum for the DNS record types supported by Cloud DNS. @@ -56,7 +56,7 @@ public class DnsRecord implements Serializable { * @see Cloud DNS * supported record types */ - public enum DnsRecordType { + public enum Type { /** * Address record, which is used to map host names to their IPv4 address. */ @@ -105,14 +105,19 @@ public enum DnsRecordType { TXT } + /** + * A builder of {@link DnsRecord}. + */ public static class Builder { private List rrdatas = new LinkedList<>(); private String name; private Integer ttl; - private DnsRecordType type; + private Type type; - private Builder() { + private Builder(String name, Type type) { + this.name = checkNotNull(name); + this.type = checkNotNull(type); } /** @@ -177,7 +182,7 @@ public Builder name(String name) { * @param ttl A non-negative number of seconds */ public Builder ttl(int ttl) { - checkArgument(ttl >= 0, "TTL cannot be negative. The supplied value was " + ttl + "."); + checkArgument(ttl >= 0, "TTL cannot be negative. The supplied value was %s.", ttl); this.ttl = ttl; return this; } @@ -185,7 +190,7 @@ public Builder ttl(int ttl) { /** * The identifier of a supported record type, for example, A, AAAA, MX, TXT, and so on. */ - public Builder type(DnsRecordType type) { + public Builder type(Type type) { this.type = checkNotNull(type); return this; } @@ -198,7 +203,7 @@ public DnsRecord build() { } } - DnsRecord(Builder builder) { + private DnsRecord(Builder builder) { this.name = builder.name; this.rrdatas = ImmutableList.copyOf(builder.rrdatas); this.ttl = builder.ttl; @@ -213,14 +218,14 @@ public Builder toBuilder() { } /** - * Creates a builder for {@code DnsRecord} with mandatorily set name and type of the record. + * Creates a {@code DnsRecord} builder for the given {@code name} and {@code type}. */ - public static Builder builder(String name, DnsRecordType type) { - return new Builder().name(name).type(type); + public static Builder builder(String name, Type type) { + return new Builder(name, type); } /** - * Get the mandatory user assigned name of this DNS record. + * Returns the user-assigned name of this DNS record. */ public String name() { return name; @@ -243,7 +248,7 @@ public Integer ttl() { /** * Returns the type of this DNS record. */ - public DnsRecordType type() { + public Type type() { return type; } @@ -259,16 +264,16 @@ public boolean equals(Object obj) { com.google.api.services.dns.model.ResourceRecordSet toPb() { com.google.api.services.dns.model.ResourceRecordSet pb = - new com.google.api.services.dns.model.ResourceRecordSet(); + new com.google.api.services.dns.model.ResourceRecordSet(); pb.setName(this.name()); pb.setRrdatas(this.records()); pb.setTtl(this.ttl()); - pb.setType(this.type() == null ? null : this.type().name()); + pb.setType(this.type().name()); return pb; } static DnsRecord fromPb(com.google.api.services.dns.model.ResourceRecordSet pb) { - Builder b = builder(pb.getName(), DnsRecordType.valueOf(pb.getType())); + Builder b = builder(pb.getName(), Type.valueOf(pb.getType())); if (pb.getRrdatas() != null) { b.records(pb.getRrdatas()); } @@ -281,10 +286,10 @@ static DnsRecord fromPb(com.google.api.services.dns.model.ResourceRecordSet pb) @Override public String toString() { return MoreObjects.toStringHelper(this) - .add("name", name()) - .add("rrdatas", records()) - .add("ttl", ttl()) - .add("type", type()) - .toString(); + .add("name", name()) + .add("rrdatas", records()) + .add("ttl", ttl()) + .add("type", type()) + .toString(); } } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java index e5b283a20acc..43ced20cf207 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java @@ -26,29 +26,32 @@ public class DnsRecordTest { private static final String NAME = "example.com."; private static final Integer TTL = 3600; - private static final DnsRecord.DnsRecordType TYPE = DnsRecord.DnsRecordType.AAAA; + private static final DnsRecord.Type TYPE = DnsRecord.Type.AAAA; private static final DnsRecord record = DnsRecord.builder(NAME, TYPE) - .ttl(TTL) - .build(); + .ttl(TTL) + .build(); @Test public void testDefaultDnsRecord() { DnsRecord record = DnsRecord.builder(NAME, TYPE).build(); assertEquals(0, record.records().size()); + assertEquals(TYPE, record.type()); + assertEquals(NAME, record.name()); } @Test public void testBuilder() { assertEquals(NAME, record.name()); assertEquals(TTL, record.ttl()); + assertEquals(TYPE, record.type()); assertEquals(0, record.records().size()); // verify that one can add records to the record set String testingRecord = "Testing record"; String anotherTestingRecord = "Another record 123"; DnsRecord anotherRecord = record.toBuilder() - .addRecord(testingRecord) - .addRecord(anotherTestingRecord) - .build(); + .addRecord(testingRecord) + .addRecord(anotherTestingRecord) + .build(); assertEquals(2, anotherRecord.records().size()); assertTrue(anotherRecord.records().contains(testingRecord)); assertTrue(anotherRecord.records().contains(anotherTestingRecord)); @@ -72,12 +75,12 @@ public void testEqualsAndNotEquals() { assertEquals(clone, record); clone = record.toBuilder().addRecord("another record").build(); assertNotEquals(clone, record); - final String differentName = "totally different name"; + String differentName = "totally different name"; clone = record.toBuilder().name(differentName).build(); assertNotEquals(clone, record); clone = record.toBuilder().ttl(record.ttl() + 1).build(); assertNotEquals(clone, record); - clone = record.toBuilder().type(DnsRecord.DnsRecordType.TXT).build(); + clone = record.toBuilder().type(DnsRecord.Type.TXT).build(); assertNotEquals(clone, record); } @@ -109,4 +112,24 @@ public void testToBuilder() { partial = DnsRecord.builder(NAME, TYPE).ttl(15).build(); assertEquals(partial, partial.toBuilder().build()); } -} \ No newline at end of file + + @Test + public void clearRecordSet() { + // make sure that we are starting not empty + DnsRecord clone = record.toBuilder().addRecord("record").addRecord("another").build(); + assertNotEquals(0, clone.records().size()); + clone = clone.toBuilder().clearRecords().build(); + assertEquals(0, clone.records().size()); + clone.toPb(); // verify that pb allows it + } + + @Test + public void removeFromRecordSet() { + String recordString = "record"; + // make sure that we are starting not empty + DnsRecord clone = record.toBuilder().addRecord(recordString).build(); + assertNotEquals(0, clone.records().size()); + clone = clone.toBuilder().removeRecord(recordString).build(); + assertEquals(0, clone.records().size()); + } +} From e8dd142fb0a6db4322fb83b79e999d97bd88e94e Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Tue, 19 Jan 2016 16:34:50 -0800 Subject: [PATCH 031/375] Created a ManagedZoneInfo class as part of the model. --- .../google/gcloud/dns/ManagedZoneInfo.java | 334 ++++++++++++++++++ .../gcloud/dns/ManagedZoneInfoTest.java | 198 +++++++++++ 2 files changed, 532 insertions(+) create mode 100644 gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java create mode 100644 gcloud-java-dns/src/test/java/com/google/gcloud/dns/ManagedZoneInfoTest.java diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java new file mode 100644 index 000000000000..e5b50b3e6669 --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java @@ -0,0 +1,334 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.dns; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableList; + +import org.joda.time.DateTime; +import org.joda.time.format.ISODateTimeFormat; + +import java.io.Serializable; +import java.math.BigInteger; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; + +/** + * This class is a container for the managed zone metainformation. Managed zone is a resource that + * represents a DNS zone hosted by the Cloud DNS service. See Google + * Cloud DNS documentation for more information. + */ +public class ManagedZoneInfo implements Serializable { + + private static final long serialVersionUID = 201601191647L; + private final String name; + private final Long id; + private final Long creationTimeMillis; + private final String dnsName; + private final String description; + private final String nameServerSet; + private final List nameServers; + + /** + * A builder for {@code ManagedZoneInfo}. + */ + public static class Builder { + private String name; + private Long id; + private Long creationTimeMillis; + private String dnsName; + private String description; + private String nameServerSet; + private List nameServers = new LinkedList<>(); + + private Builder() { + } + + private Builder(Long id) { + this.id = checkNotNull(id); + } + + private Builder(String name) { + this.name = checkNotNull(name); + } + + private Builder(String name, Long id) { + this.name = checkNotNull(name); + this.id = checkNotNull(id); + } + + /** + * Creates a builder from an existing ManagedZoneInfo object. + */ + Builder(ManagedZoneInfo info) { + this.name = info.name; + this.id = info.id; + this.creationTimeMillis = info.creationTimeMillis; + this.dnsName = info.dnsName; + this.description = info.description; + this.nameServerSet = info.nameServerSet; + this.nameServers.addAll(info.nameServers); + } + + /** + * Sets a mandatory user-provided name for the zone. It must be unique within the project. + */ + public Builder name(String name) { + this.name = checkNotNull(name); + return this; + } + + /** + * Sets an id for the managed zone which is assigned to the managed zone by the server. + */ + public Builder id(long id) { + this.id = id; + return this; + } + + /** + * Sets the time when this managed zone was created. + */ + Builder creationTimeMillis(long creationTimeMillis) { + checkArgument(creationTimeMillis >= 0, "The timestamp cannot be negative."); + this.creationTimeMillis = creationTimeMillis; + return this; + } + + /** + * Sets a mandatory DNS name of this managed zone, for instance "example.com.". + */ + public Builder dnsName(String dnsName) { + this.dnsName = checkNotNull(dnsName); + return this; + } + + /** + * Sets a mandatory description for this managed zone. The value is a string of at most 1024 + * characters (this limit is posed by Google Cloud DNS; gcloud-java does not enforce the limit) + * which has no effect on the managed zone's function. + */ + public Builder description(String description) { + this.description = checkNotNull(description); + return this; + } + + /** + * Optionally specifies the NameServerSet for this managed zone. A NameServerSet is a set of DNS + * name servers that all host the same ManagedZones. + */ + public Builder nameServerSet(String nameServerSet) { + // todo(mderka) add more to the doc when questions are answered by the service owner + this.nameServerSet = checkNotNull(nameServerSet); + return this; + } + + /** + * Sets a list of servers that hold the information about the managed zone. This information is + * provided by Google Cloud DNS and is read only. + */ + Builder nameServers(List nameServers) { + this.nameServers.addAll(checkNotNull(nameServers)); + return this; + } + + /** + * Removes all the nameservers from the list. + */ + Builder clearNameServers() { + this.nameServers.clear(); + return this; + } + + /** + * Builds the instance of ManagedZoneInfo based on the information set here. + */ + public ManagedZoneInfo build() { + return new ManagedZoneInfo(this); + } + } + + private ManagedZoneInfo(Builder builder) { + this.name = builder.name; + this.id = builder.id; + this.creationTimeMillis = builder.creationTimeMillis; + this.dnsName = builder.dnsName; + this.description = builder.description; + this.nameServerSet = builder.nameServerSet; + this.nameServers = ImmutableList.copyOf(builder.nameServers); + } + + /** + * Returns a builder for {@code ManagedZoneInfo} with an assigned {@code name}. + */ + public static Builder builder(String name) { + return new Builder(name); + } + + /** + * Returns a builder for {@code ManagedZoneInfo} with an assigned {@code id}. + */ + public static Builder builder(Long id) { + return new Builder(id); + } + + /** + * Returns a builder for {@code ManagedZoneInfo} with an assigned {@code name} and {@code id}. + */ + public static Builder builder(String name, Long id) { + return new Builder(name, id); + } + + /** + * Returns an empty builder for {@code ManagedZoneInfo}. We use it internally in {@code toPb()}. + */ + private static Builder builder() { + return new Builder(); + } + + /** + * Returns the user-defined name of the managed zone. + */ + public String name() { + return name; + } + + /** + * Returns the read-only managed zone id assigned by the server. + */ + public Long id() { + return id; + } + + /** + * Returns the time when this time that this managed zone was created on the server. + */ + public Long creationTimeMillis() { + return creationTimeMillis; + } + + /** + * Returns the DNS name of this managed zone, for instance "example.com.". + */ + public String dnsName() { + return dnsName; + } + + /** + * Returns the description of this managed zone. This is at most 1024 long mandatory string + * provided by the user. + */ + public String description() { + return description; + } + + /** + * Returns the optionally specified set of DNS name servers that all host this managed zone. + */ + public String nameServerSet() { + // todo(mderka) update this doc after finding out more about this from the service owners + return nameServerSet; + } + + /** + * The nameservers that the managed zone should be delegated to. This is defined by the Google DNS + * cloud. + */ + public List nameServers() { + return nameServers; + } + + /** + * Returns a builder for {@code ManagedZoneInfo} prepopulated with the metadata of this managed + * zone. + */ + public Builder toBuilder() { + return new Builder(this); + } + + com.google.api.services.dns.model.ManagedZone toPb() { + com.google.api.services.dns.model.ManagedZone pb = + new com.google.api.services.dns.model.ManagedZone(); + pb.setDescription(this.description()); + pb.setDnsName(this.dnsName()); + if (this.id() != null) { + pb.setId(BigInteger.valueOf(this.id())); + } + pb.setName(this.name()); + pb.setNameServers(this.nameServers()); + pb.setNameServerSet(this.nameServerSet()); + if (this.creationTimeMillis() != null) { + pb.setCreationTime(ISODateTimeFormat.dateTime() + .withZoneUTC() + .print(this.creationTimeMillis())); + } + return pb; + } + + static ManagedZoneInfo fromPb(com.google.api.services.dns.model.ManagedZone pb) { + Builder b = builder(); + if (pb.getDescription() != null) { + b.description(pb.getDescription()); + } + if (pb.getDnsName() != null) { + b.dnsName(pb.getDnsName()); + } + if (pb.getId() != null) { + b.id(pb.getId().longValue()); + } + if (pb.getName() != null) { + b.name(pb.getName()); + } + if (pb.getNameServers() != null) { + b.nameServers(pb.getNameServers()); + } + if (pb.getNameServerSet() != null) { + b.nameServerSet(pb.getNameServerSet()); + } + if (pb.getCreationTime() != null) { + b.creationTimeMillis(DateTime.parse(pb.getCreationTime()).getMillis()); + } + return b.build(); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof ManagedZoneInfo && Objects.equals(toPb(), ((ManagedZoneInfo) obj).toPb()); + } + + @Override + public int hashCode() { + return Objects.hash(name, id, creationTimeMillis, dnsName, + description, nameServerSet, nameServers); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("name", name()) + .add("id", id()) + .add("description", description()) + .add("dnsName", dnsName()) + .add("nameServerSet", nameServerSet()) + .add("nameServers", nameServers()) + .toString(); + } +} diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ManagedZoneInfoTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ManagedZoneInfoTest.java new file mode 100644 index 000000000000..6516c7577d2f --- /dev/null +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ManagedZoneInfoTest.java @@ -0,0 +1,198 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.dns; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.google.common.collect.Lists; + +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.LinkedList; +import java.util.List; + +public class ManagedZoneInfoTest { + + private static final String NAME = "mz-example.com"; + private static final Long ID = 123L; + private static final Long CREATION_TIME_MILLIS = 1123468321321L; + private static final String DNS_NAME = "example.com."; + private static final String DESCRIPTION = "description for the zone"; + private static final String NAME_SERVER_SET = "some set"; + private static final String NS1 = "name server 1"; + private static final String NS2 = "name server 2"; + private static final String NS3 = "name server 3"; + private static List nameServers = new LinkedList<>(); + private static ManagedZoneInfo info; + + @BeforeClass + public static void setUp() { + nameServers.add(NS1); + nameServers.add(NS2); + nameServers.add(NS3); + assertEquals(3, nameServers.size()); + info = ManagedZoneInfo.builder(NAME, ID) + .creationTimeMillis(CREATION_TIME_MILLIS) + .dnsName(DNS_NAME) + .description(DESCRIPTION) + .nameServerSet(NAME_SERVER_SET) + .nameServers(nameServers) + .build(); + System.out.println(info); + } + + @Test + public void testDefaultBuilders() { + ManagedZoneInfo withName = ManagedZoneInfo.builder(NAME).build(); + assertTrue(withName.nameServers().isEmpty()); + assertEquals(NAME, withName.name()); + assertNull(withName.id()); + assertNull(withName.creationTimeMillis()); + assertNull(withName.nameServerSet()); + assertNull(withName.description()); + assertNull(withName.dnsName()); + ManagedZoneInfo withId = ManagedZoneInfo.builder(ID).build(); + assertTrue(withId.nameServers().isEmpty()); + assertEquals(ID, withId.id()); + assertNull(withId.name()); + assertNull(withId.creationTimeMillis()); + assertNull(withId.nameServerSet()); + assertNull(withId.description()); + assertNull(withId.dnsName()); + ManagedZoneInfo withBoth = ManagedZoneInfo.builder(NAME, ID).build(); + assertTrue(withBoth.nameServers().isEmpty()); + assertEquals(ID, withBoth.id()); + assertEquals(NAME, withBoth.name()); + assertNull(withBoth.creationTimeMillis()); + assertNull(withBoth.nameServerSet()); + assertNull(withBoth.description()); + assertNull(withBoth.dnsName()); + } + + @Test + public void testBuilder() { + assertEquals(3, info.nameServers().size()); + assertEquals(NS1, info.nameServers().get(0)); + assertEquals(NS2, info.nameServers().get(1)); + assertEquals(NS3, info.nameServers().get(2)); + assertEquals(NAME, info.name()); + assertEquals(ID, info.id()); + assertEquals(CREATION_TIME_MILLIS, info.creationTimeMillis()); + assertEquals(NAME_SERVER_SET, info.nameServerSet()); + assertEquals(DESCRIPTION, info.description()); + assertEquals(DNS_NAME, info.dnsName()); + } + + @Test + public void testValidCreationTime() { + try { + ManagedZoneInfo.builder(NAME).creationTimeMillis(-1); + fail("A negative value is not acceptable for creation time."); + } catch (IllegalArgumentException e) { + // expected + } + ManagedZoneInfo.builder(NAME).creationTimeMillis(0); + ManagedZoneInfo.builder(NAME).creationTimeMillis(Long.MAX_VALUE); + } + + @Test + public void testEqualsAndNotEquals() { + ManagedZoneInfo clone = info.toBuilder().build(); + assertEquals(clone, info); + List moreServers = Lists.newLinkedList(nameServers); + moreServers.add(NS1); + clone = info.toBuilder().nameServers(moreServers).build(); + assertNotEquals(clone, info); + String differentName = "totally different name"; + clone = info.toBuilder().name(differentName).build(); + assertNotEquals(clone, info); + clone = info.toBuilder().creationTimeMillis(info.creationTimeMillis() + 1).build(); + assertNotEquals(clone, info); + clone = info.toBuilder().description(info.description() + "aaaa").build(); + assertNotEquals(clone, info); + clone = info.toBuilder().dnsName(differentName).build(); + assertNotEquals(clone, info); + clone = info.toBuilder().id(info.id() + 1).build(); + assertNotEquals(clone, info); + clone = info.toBuilder().nameServerSet(info.nameServerSet() + "salt").build(); + assertNotEquals(clone, info); + } + + @Test + public void testSameHashCodeOnEquals() { + int hash = info.hashCode(); + ManagedZoneInfo clone = info.toBuilder().build(); + assertEquals(clone.hashCode(), hash); + } + + @Test + public void testToBuilder() { + assertEquals(info, info.toBuilder().build()); + ManagedZoneInfo partial = ManagedZoneInfo.builder(NAME).build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ManagedZoneInfo.builder(ID).build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ManagedZoneInfo.builder(NAME).description(DESCRIPTION).build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ManagedZoneInfo.builder(NAME).dnsName(DNS_NAME).build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ManagedZoneInfo.builder(NAME).creationTimeMillis(CREATION_TIME_MILLIS).build(); + assertEquals(partial, partial.toBuilder().build()); + List nameServers = new LinkedList<>(); + nameServers.add(NS1); + partial = ManagedZoneInfo.builder(NAME).nameServers(nameServers).build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ManagedZoneInfo.builder(NAME).nameServerSet(NAME_SERVER_SET).build(); + assertEquals(partial, partial.toBuilder().build()); + } + + @Test + public void testToAndFromPb() { + assertEquals(info, ManagedZoneInfo.fromPb(info.toPb())); + ManagedZoneInfo partial = ManagedZoneInfo.builder(NAME).build(); + assertEquals(partial, ManagedZoneInfo.fromPb(partial.toPb())); + partial = ManagedZoneInfo.builder(ID).build(); + assertEquals(partial, ManagedZoneInfo.fromPb(partial.toPb())); + partial = ManagedZoneInfo.builder(NAME).description(DESCRIPTION).build(); + assertEquals(partial, ManagedZoneInfo.fromPb(partial.toPb())); + partial = ManagedZoneInfo.builder(NAME).dnsName(DNS_NAME).build(); + assertEquals(partial, ManagedZoneInfo.fromPb(partial.toPb())); + partial = ManagedZoneInfo.builder(NAME).creationTimeMillis(CREATION_TIME_MILLIS).build(); + assertEquals(partial, ManagedZoneInfo.fromPb(partial.toPb())); + List nameServers = new LinkedList<>(); + nameServers.add(NS1); + partial = ManagedZoneInfo.builder(NAME).nameServers(nameServers).build(); + assertEquals(partial, ManagedZoneInfo.fromPb(partial.toPb())); + partial = ManagedZoneInfo.builder(NAME).nameServerSet(NAME_SERVER_SET).build(); + assertEquals(partial, ManagedZoneInfo.fromPb(partial.toPb())); + } + + @Test + public void testClearNameServers() { + ManagedZoneInfo clone = info.toBuilder().build(); + assertFalse(clone.nameServers().isEmpty()); + clone = clone.toBuilder().clearNameServers().build(); + assertTrue(clone.nameServers().isEmpty()); + clone.toPb(); // test that this is allowed + } +} From c95c3aaa0c514ba573f29ee8d19a7619a0bf0e1c Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Fri, 22 Jan 2016 18:38:10 -0800 Subject: [PATCH 032/375] Implemented comments by @aozarov. --- .../google/gcloud/dns/ManagedZoneInfo.java | 65 ++++++++----------- .../gcloud/dns/ManagedZoneInfoTest.java | 43 ++++++------ 2 files changed, 49 insertions(+), 59 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java index e5b50b3e6669..191d41967124 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java @@ -16,11 +16,11 @@ package com.google.gcloud.dns; -import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; import org.joda.time.DateTime; import org.joda.time.format.ISODateTimeFormat; @@ -32,15 +32,16 @@ import java.util.Objects; /** - * This class is a container for the managed zone metainformation. Managed zone is a resource that - * represents a DNS zone hosted by the Cloud DNS service. See Google - * Cloud DNS documentation for more information. + * A {@code ManagedZone} represents a DNS zone hosted by the Google Cloud DNS service. A zone is a + * subtree of the DNS namespace under one administrative responsibility. See Google Cloud DNS documentation for + * more information. */ public class ManagedZoneInfo implements Serializable { private static final long serialVersionUID = 201601191647L; private final String name; - private final Long id; + private final BigInteger id; private final Long creationTimeMillis; private final String dnsName; private final String description; @@ -52,17 +53,21 @@ public class ManagedZoneInfo implements Serializable { */ public static class Builder { private String name; - private Long id; + private BigInteger id; private Long creationTimeMillis; private String dnsName; private String description; private String nameServerSet; private List nameServers = new LinkedList<>(); + /** + * Returns an empty builder for {@code ManagedZoneInfo}. We use it internally in {@code + * toPb()}. + */ private Builder() { } - private Builder(Long id) { + private Builder(BigInteger id) { this.id = checkNotNull(id); } @@ -70,7 +75,7 @@ private Builder(String name) { this.name = checkNotNull(name); } - private Builder(String name, Long id) { + private Builder(String name, BigInteger id) { this.name = checkNotNull(name); this.id = checkNotNull(id); } @@ -99,7 +104,7 @@ public Builder name(String name) { /** * Sets an id for the managed zone which is assigned to the managed zone by the server. */ - public Builder id(long id) { + Builder id(BigInteger id) { this.id = id; return this; } @@ -108,7 +113,6 @@ public Builder id(long id) { * Sets the time when this managed zone was created. */ Builder creationTimeMillis(long creationTimeMillis) { - checkArgument(creationTimeMillis >= 0, "The timestamp cannot be negative."); this.creationTimeMillis = creationTimeMillis; return this; } @@ -123,8 +127,7 @@ public Builder dnsName(String dnsName) { /** * Sets a mandatory description for this managed zone. The value is a string of at most 1024 - * characters (this limit is posed by Google Cloud DNS; gcloud-java does not enforce the limit) - * which has no effect on the managed zone's function. + * characters which has no effect on the managed zone's function. */ public Builder description(String description) { this.description = checkNotNull(description); @@ -133,7 +136,8 @@ public Builder description(String description) { /** * Optionally specifies the NameServerSet for this managed zone. A NameServerSet is a set of DNS - * name servers that all host the same ManagedZones. + * name servers that all host the same ManagedZones. Most users will not need to specify this + * value. */ public Builder nameServerSet(String nameServerSet) { // todo(mderka) add more to the doc when questions are answered by the service owner @@ -146,20 +150,13 @@ public Builder nameServerSet(String nameServerSet) { * provided by Google Cloud DNS and is read only. */ Builder nameServers(List nameServers) { - this.nameServers.addAll(checkNotNull(nameServers)); + checkNotNull(nameServers); + this.nameServers = Lists.newLinkedList(nameServers); return this; } /** - * Removes all the nameservers from the list. - */ - Builder clearNameServers() { - this.nameServers.clear(); - return this; - } - - /** - * Builds the instance of ManagedZoneInfo based on the information set here. + * Builds the instance of {@code ManagedZoneInfo} based on the information set by this builder. */ public ManagedZoneInfo build() { return new ManagedZoneInfo(this); @@ -186,24 +183,17 @@ public static Builder builder(String name) { /** * Returns a builder for {@code ManagedZoneInfo} with an assigned {@code id}. */ - public static Builder builder(Long id) { + public static Builder builder(BigInteger id) { return new Builder(id); } /** * Returns a builder for {@code ManagedZoneInfo} with an assigned {@code name} and {@code id}. */ - public static Builder builder(String name, Long id) { + public static Builder builder(String name, BigInteger id) { return new Builder(name, id); } - /** - * Returns an empty builder for {@code ManagedZoneInfo}. We use it internally in {@code toPb()}. - */ - private static Builder builder() { - return new Builder(); - } - /** * Returns the user-defined name of the managed zone. */ @@ -214,7 +204,7 @@ public String name() { /** * Returns the read-only managed zone id assigned by the server. */ - public Long id() { + public BigInteger id() { return id; } @@ -233,8 +223,7 @@ public String dnsName() { } /** - * Returns the description of this managed zone. This is at most 1024 long mandatory string - * provided by the user. + * Returns the description of this managed zone. */ public String description() { return description; @@ -270,7 +259,7 @@ com.google.api.services.dns.model.ManagedZone toPb() { pb.setDescription(this.description()); pb.setDnsName(this.dnsName()); if (this.id() != null) { - pb.setId(BigInteger.valueOf(this.id())); + pb.setId(this.id()); } pb.setName(this.name()); pb.setNameServers(this.nameServers()); @@ -284,7 +273,7 @@ com.google.api.services.dns.model.ManagedZone toPb() { } static ManagedZoneInfo fromPb(com.google.api.services.dns.model.ManagedZone pb) { - Builder b = builder(); + Builder b = new Builder(); if (pb.getDescription() != null) { b.description(pb.getDescription()); } @@ -292,7 +281,7 @@ static ManagedZoneInfo fromPb(com.google.api.services.dns.model.ManagedZone pb) b.dnsName(pb.getDnsName()); } if (pb.getId() != null) { - b.id(pb.getId().longValue()); + b.id(pb.getId()); } if (pb.getName() != null) { b.name(pb.getName()); diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ManagedZoneInfoTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ManagedZoneInfoTest.java index 6516c7577d2f..89c9426f5b81 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ManagedZoneInfoTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ManagedZoneInfoTest.java @@ -17,24 +17,23 @@ package com.google.gcloud.dns; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import com.google.common.collect.Lists; -import org.junit.BeforeClass; +import org.junit.Before; import org.junit.Test; +import java.math.BigInteger; import java.util.LinkedList; import java.util.List; public class ManagedZoneInfoTest { private static final String NAME = "mz-example.com"; - private static final Long ID = 123L; + private static final BigInteger ID = BigInteger.valueOf(123L); private static final Long CREATION_TIME_MILLIS = 1123468321321L; private static final String DNS_NAME = "example.com."; private static final String DESCRIPTION = "description for the zone"; @@ -42,15 +41,14 @@ public class ManagedZoneInfoTest { private static final String NS1 = "name server 1"; private static final String NS2 = "name server 2"; private static final String NS3 = "name server 3"; - private static List nameServers = new LinkedList<>(); - private static ManagedZoneInfo info; + private List nameServers = new LinkedList<>(); + private ManagedZoneInfo info; - @BeforeClass - public static void setUp() { + @Before + public void setUp() { nameServers.add(NS1); nameServers.add(NS2); nameServers.add(NS3); - assertEquals(3, nameServers.size()); info = ManagedZoneInfo.builder(NAME, ID) .creationTimeMillis(CREATION_TIME_MILLIS) .dnsName(DNS_NAME) @@ -58,7 +56,6 @@ public static void setUp() { .nameServerSet(NAME_SERVER_SET) .nameServers(nameServers) .build(); - System.out.println(info); } @Test @@ -105,12 +102,7 @@ public void testBuilder() { @Test public void testValidCreationTime() { - try { - ManagedZoneInfo.builder(NAME).creationTimeMillis(-1); - fail("A negative value is not acceptable for creation time."); - } catch (IllegalArgumentException e) { - // expected - } + ManagedZoneInfo.builder(NAME).creationTimeMillis(-1); ManagedZoneInfo.builder(NAME).creationTimeMillis(0); ManagedZoneInfo.builder(NAME).creationTimeMillis(Long.MAX_VALUE); } @@ -132,7 +124,7 @@ public void testEqualsAndNotEquals() { assertNotEquals(clone, info); clone = info.toBuilder().dnsName(differentName).build(); assertNotEquals(clone, info); - clone = info.toBuilder().id(info.id() + 1).build(); + clone = info.toBuilder().id(info.id().add(BigInteger.ONE)).build(); assertNotEquals(clone, info); clone = info.toBuilder().nameServerSet(info.nameServerSet() + "salt").build(); assertNotEquals(clone, info); @@ -188,11 +180,20 @@ public void testToAndFromPb() { } @Test - public void testClearNameServers() { - ManagedZoneInfo clone = info.toBuilder().build(); - assertFalse(clone.nameServers().isEmpty()); - clone = clone.toBuilder().clearNameServers().build(); + public void testEmptyNameServers() { + ManagedZoneInfo clone = info.toBuilder().nameServers(new LinkedList()).build(); assertTrue(clone.nameServers().isEmpty()); clone.toPb(); // test that this is allowed } + + @Test + public void testDateParsing() { + com.google.api.services.dns.model.ManagedZone pb = + info.toPb(); + pb.setCreationTime("2016-01-19T18:00:12.854Z"); // a real value obtained from Google Cloud DNS + ManagedZoneInfo mz = ManagedZoneInfo.fromPb(pb); // parses the string timestamp to millis + com.google.api.services.dns.model.ManagedZone pbClone = mz.toPb(); // converts it back to string + assertEquals(pb, pbClone); + assertEquals(pb.getCreationTime(), pbClone.getCreationTime()); + } } From dacea19f586e0ae5f344da65f4ebc5c248818288 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Mon, 25 Jan 2016 09:06:33 -0800 Subject: [PATCH 033/375] Another round of comments from @aozarov. --- .../google/gcloud/dns/ManagedZoneInfo.java | 1 + .../com/google/gcloud/dns/DnsRecordTest.java | 10 +- .../gcloud/dns/ManagedZoneInfoTest.java | 100 ++++++++---------- 3 files changed, 48 insertions(+), 63 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java index 191d41967124..d27e134ad908 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java @@ -318,6 +318,7 @@ public String toString() { .add("dnsName", dnsName()) .add("nameServerSet", nameServerSet()) .add("nameServers", nameServers()) + .add("creationTimeMillis", creationTimeMillis()) .toString(); } } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java index 43ced20cf207..412aa2ce08ad 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java @@ -72,16 +72,16 @@ public void testValidTtl() { @Test public void testEqualsAndNotEquals() { DnsRecord clone = record.toBuilder().build(); - assertEquals(clone, record); + assertEquals(record, clone); clone = record.toBuilder().addRecord("another record").build(); - assertNotEquals(clone, record); + assertNotEquals(record, clone); String differentName = "totally different name"; clone = record.toBuilder().name(differentName).build(); - assertNotEquals(clone, record); + assertNotEquals(record, clone); clone = record.toBuilder().ttl(record.ttl() + 1).build(); - assertNotEquals(clone, record); + assertNotEquals(record, clone); clone = record.toBuilder().type(DnsRecord.Type.TXT).build(); - assertNotEquals(clone, record); + assertNotEquals(record, clone); } @Test diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ManagedZoneInfoTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ManagedZoneInfoTest.java index 89c9426f5b81..936164c81723 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ManagedZoneInfoTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ManagedZoneInfoTest.java @@ -21,9 +21,9 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; -import org.junit.Before; import org.junit.Test; import java.math.BigInteger; @@ -41,22 +41,14 @@ public class ManagedZoneInfoTest { private static final String NS1 = "name server 1"; private static final String NS2 = "name server 2"; private static final String NS3 = "name server 3"; - private List nameServers = new LinkedList<>(); - private ManagedZoneInfo info; - - @Before - public void setUp() { - nameServers.add(NS1); - nameServers.add(NS2); - nameServers.add(NS3); - info = ManagedZoneInfo.builder(NAME, ID) - .creationTimeMillis(CREATION_TIME_MILLIS) - .dnsName(DNS_NAME) - .description(DESCRIPTION) - .nameServerSet(NAME_SERVER_SET) - .nameServers(nameServers) - .build(); - } + private static final List NAME_SERVERS = ImmutableList.of(NS1, NS2, NS3); + private static final ManagedZoneInfo INFO = ManagedZoneInfo.builder(NAME, ID) + .creationTimeMillis(CREATION_TIME_MILLIS) + .dnsName(DNS_NAME) + .description(DESCRIPTION) + .nameServerSet(NAME_SERVER_SET) + .nameServers(NAME_SERVERS) + .build(); @Test public void testDefaultBuilders() { @@ -88,58 +80,51 @@ public void testDefaultBuilders() { @Test public void testBuilder() { - assertEquals(3, info.nameServers().size()); - assertEquals(NS1, info.nameServers().get(0)); - assertEquals(NS2, info.nameServers().get(1)); - assertEquals(NS3, info.nameServers().get(2)); - assertEquals(NAME, info.name()); - assertEquals(ID, info.id()); - assertEquals(CREATION_TIME_MILLIS, info.creationTimeMillis()); - assertEquals(NAME_SERVER_SET, info.nameServerSet()); - assertEquals(DESCRIPTION, info.description()); - assertEquals(DNS_NAME, info.dnsName()); - } - - @Test - public void testValidCreationTime() { - ManagedZoneInfo.builder(NAME).creationTimeMillis(-1); - ManagedZoneInfo.builder(NAME).creationTimeMillis(0); - ManagedZoneInfo.builder(NAME).creationTimeMillis(Long.MAX_VALUE); + assertEquals(3, INFO.nameServers().size()); + assertEquals(NS1, INFO.nameServers().get(0)); + assertEquals(NS2, INFO.nameServers().get(1)); + assertEquals(NS3, INFO.nameServers().get(2)); + assertEquals(NAME, INFO.name()); + assertEquals(ID, INFO.id()); + assertEquals(CREATION_TIME_MILLIS, INFO.creationTimeMillis()); + assertEquals(NAME_SERVER_SET, INFO.nameServerSet()); + assertEquals(DESCRIPTION, INFO.description()); + assertEquals(DNS_NAME, INFO.dnsName()); } @Test public void testEqualsAndNotEquals() { - ManagedZoneInfo clone = info.toBuilder().build(); - assertEquals(clone, info); - List moreServers = Lists.newLinkedList(nameServers); + ManagedZoneInfo clone = INFO.toBuilder().build(); + assertEquals(INFO, clone); + List moreServers = Lists.newLinkedList(NAME_SERVERS); moreServers.add(NS1); - clone = info.toBuilder().nameServers(moreServers).build(); - assertNotEquals(clone, info); + clone = INFO.toBuilder().nameServers(moreServers).build(); + assertNotEquals(INFO, clone); String differentName = "totally different name"; - clone = info.toBuilder().name(differentName).build(); - assertNotEquals(clone, info); - clone = info.toBuilder().creationTimeMillis(info.creationTimeMillis() + 1).build(); - assertNotEquals(clone, info); - clone = info.toBuilder().description(info.description() + "aaaa").build(); - assertNotEquals(clone, info); - clone = info.toBuilder().dnsName(differentName).build(); - assertNotEquals(clone, info); - clone = info.toBuilder().id(info.id().add(BigInteger.ONE)).build(); - assertNotEquals(clone, info); - clone = info.toBuilder().nameServerSet(info.nameServerSet() + "salt").build(); - assertNotEquals(clone, info); + clone = INFO.toBuilder().name(differentName).build(); + assertNotEquals(INFO, clone); + clone = INFO.toBuilder().creationTimeMillis(INFO.creationTimeMillis() + 1).build(); + assertNotEquals(INFO, clone); + clone = INFO.toBuilder().description(INFO.description() + "aaaa").build(); + assertNotEquals(INFO, clone); + clone = INFO.toBuilder().dnsName(differentName).build(); + assertNotEquals(INFO, clone); + clone = INFO.toBuilder().id(INFO.id().add(BigInteger.ONE)).build(); + assertNotEquals(INFO, clone); + clone = INFO.toBuilder().nameServerSet(INFO.nameServerSet() + "salt").build(); + assertNotEquals(INFO, clone); } @Test public void testSameHashCodeOnEquals() { - int hash = info.hashCode(); - ManagedZoneInfo clone = info.toBuilder().build(); + int hash = INFO.hashCode(); + ManagedZoneInfo clone = INFO.toBuilder().build(); assertEquals(clone.hashCode(), hash); } @Test public void testToBuilder() { - assertEquals(info, info.toBuilder().build()); + assertEquals(INFO, INFO.toBuilder().build()); ManagedZoneInfo partial = ManagedZoneInfo.builder(NAME).build(); assertEquals(partial, partial.toBuilder().build()); partial = ManagedZoneInfo.builder(ID).build(); @@ -160,7 +145,7 @@ public void testToBuilder() { @Test public void testToAndFromPb() { - assertEquals(info, ManagedZoneInfo.fromPb(info.toPb())); + assertEquals(INFO, ManagedZoneInfo.fromPb(INFO.toPb())); ManagedZoneInfo partial = ManagedZoneInfo.builder(NAME).build(); assertEquals(partial, ManagedZoneInfo.fromPb(partial.toPb())); partial = ManagedZoneInfo.builder(ID).build(); @@ -181,15 +166,14 @@ public void testToAndFromPb() { @Test public void testEmptyNameServers() { - ManagedZoneInfo clone = info.toBuilder().nameServers(new LinkedList()).build(); + ManagedZoneInfo clone = INFO.toBuilder().nameServers(new LinkedList()).build(); assertTrue(clone.nameServers().isEmpty()); clone.toPb(); // test that this is allowed } @Test public void testDateParsing() { - com.google.api.services.dns.model.ManagedZone pb = - info.toPb(); + com.google.api.services.dns.model.ManagedZone pb = INFO.toPb(); pb.setCreationTime("2016-01-19T18:00:12.854Z"); // a real value obtained from Google Cloud DNS ManagedZoneInfo mz = ManagedZoneInfo.fromPb(pb); // parses the string timestamp to millis com.google.api.services.dns.model.ManagedZone pbClone = mz.toPb(); // converts it back to string From 273b4418df7ed3d1dae00f6f66228c1dcee3b1ac Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Mon, 25 Jan 2016 17:11:34 -0800 Subject: [PATCH 034/375] Implemented ChangeRequest. --- .../com/google/gcloud/dns/ChangeRequest.java | 340 ++++++++++++++++++ .../com/google/gcloud/dns/DnsRecordTest.java | 1 + 2 files changed, 341 insertions(+) create mode 100644 gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java new file mode 100644 index 000000000000..40c6ff0ad151 --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java @@ -0,0 +1,340 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.dns; + +import com.google.common.base.MoreObjects; +import com.google.common.collect.Lists; + +import org.joda.time.DateTime; +import org.joda.time.format.ISODateTimeFormat; + +import java.io.Serializable; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * A class representing a change. A change is an atomic update to a collection of {@link DnsRecord}s + * within a {@code ManagedZone}. + * + * @see Google Cloud DNS documentation + */ +public class ChangeRequest implements Serializable { + + private static final long serialVersionUID = 201601251649L; + private final List additions; + private final List deletions; + private final String id; + private final Long startTimeMillis; + private final Status status; + + /** + * This enumerates the possible states of a {@code ChangeRequest}. + * + * @see Google Cloud DNS + * documentation + */ + public enum Status { + PENDING("pending"), + DONE("done"); + + private final String status; + + Status(String status) { + this.status = status; + } + + static Status translate(String status) { + if ("pending".equals(status)) { + return PENDING; + } else if ("done".equals(status)) { + return DONE; + } else { + throw new IllegalArgumentException("Such a status is unknown."); + } + } + } + + /** + * A builder for {@code ChangeRequest}s. + */ + public static class Builder { + + private List additions = new LinkedList<>(); + private List deletions = new LinkedList<>(); + private String id; + private Long startTimeMillis; + private Status status; + + private Builder(ChangeRequest cr) { + this.additions = Lists.newLinkedList(cr.additions()); + this.deletions = Lists.newLinkedList(cr.deletions()); + this.id = cr.id(); + this.startTimeMillis = cr.startTimeMillis(); + this.status = cr.status(); + } + + private Builder() { + } + + /** + * Sets a collection of {@link DnsRecord}s which are to be added to the zone upon executing this + * {@code ChangeRequest}. + */ + public Builder additions(List additions) { + this.additions = Lists.newLinkedList(checkNotNull(additions)); + return this; + } + + /** + * Adds a {@link DnsRecord} which to be added to the zone upon executing this + * {@code ChangeRequest}. + */ + public Builder add(DnsRecord record) { + this.additions.add(checkNotNull(record)); + return this; + } + + /** + * Adds a {@link DnsRecord} which to be deleted to the zone upon executing this + * {@code ChangeRequest}. + */ + public Builder delete(DnsRecord record) { + this.deletions.add(checkNotNull(record)); + return this; + } + + /** + * Clears the collection of {@link DnsRecord}s which are to be added to the zone upon executing + * this {@code ChangeRequest}. + */ + public Builder clearAdditions() { + this.additions.clear(); + return this; + } + + /** + * Clears the collection of {@link DnsRecord}s which are to be deleted from the zone upon + * executing this {@code ChangeRequest}. + */ + public Builder clearDeletions() { + this.deletions.clear(); + return this; + } + + /** + * Removes a single {@link DnsRecord} from the collection of of records to be + * added to the zone upon executing this {@code ChangeRequest}. + */ + public Builder removeAddition(DnsRecord record) { + this.additions.remove(record); + return this; + } + + /** + * Removes a single {@link DnsRecord} from the collection of of records to be + * deleted from the zone upon executing this {@code ChangeRequest}. + */ + public Builder removeDeletion(DnsRecord record) { + this.deletions.remove(record); + return this; + } + + /** + * Sets a collection of {@link DnsRecord}s which are to be deleted from the zone upon executing + * this {@code ChangeRequest}. + */ + public Builder deletions(List deletions) { + this.deletions = Lists.newLinkedList(checkNotNull(deletions)); + return this; + } + + /** + * Associates a server-assigned id to this {@code ChangeRequest}. + */ + Builder id(String id) { + this.id = checkNotNull(id); + return this; + } + + /** + * Sets the time when this {@code ChangeRequest} was started by a server. + */ + Builder startTimeMillis(long startTimeMillis) { + this.startTimeMillis = startTimeMillis; + return this; + } + + /** + * Sets the current status of this {@code ChangeRequest}. + */ + Builder status(Status status) { + this.status = checkNotNull(status); + return this; + } + + /** + * Creates a {@code ChangeRequest} instance populated by the values associated with this + * builder. + */ + public ChangeRequest build() { + return new ChangeRequest(this); + } + } + + private ChangeRequest(Builder builder) { + this.additions = builder.additions; + this.deletions = builder.deletions; + this.id = builder.id; + this.startTimeMillis = builder.startTimeMillis; + this.status = builder.status; + } + + /** + * Returns an empty builder for the {@code ChangeRequest} class. + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Creates a builder populated with values of this {@code ChangeRequest}. + */ + public Builder toBuilder() { + return new Builder(this); + } + + /** + * Returns the list of {@link DnsRecord}s to be added to the zone upon executing this {@code + * ChangeRequest}. + */ + public List additions() { + return additions; + } + + /** + * Returns the list of {@link DnsRecord}s to be deleted from the zone upon executing this {@code + * ChangeRequest}. + */ + public List deletions() { + return deletions; + } + + /** + * Returns the id assigned to this {@code ChangeRequest} by the server. + */ + public String id() { + return id; + } + + /** + * Returns the time when this {@code ChangeRequest} was started by the server. + */ + public Long startTimeMillis() { + return startTimeMillis; + } + + /** + * Returns the status of this {@code ChangeRequest}. + */ + public Status status() { + return status; + } + + com.google.api.services.dns.model.Change toPb() { + com.google.api.services.dns.model.Change pb = + new com.google.api.services.dns.model.Change(); + // set id + if (id() != null) { + pb.setId(id()); + } + // set timestamp + if (startTimeMillis() != null) { + pb.setStartTime(ISODateTimeFormat.dateTime().withZoneUTC().print(startTimeMillis())); + } + // set status + if (status() != null) { + pb.setStatus(status().status); + } + // set a list of additions + if (additions() != null) { + LinkedList additionsPb = + new LinkedList<>(); + for (DnsRecord addition : additions()) { + additionsPb.add(addition.toPb()); + } + pb.setAdditions(additionsPb); + } + // set a list of deletions + if (deletions() != null) { + LinkedList deletionsPb = + new LinkedList<>(); + for (DnsRecord deletion : deletions()) { + deletionsPb.add(deletion.toPb()); + } + pb.setDeletions(deletionsPb); + } + return pb; + } + + static ChangeRequest fromPb(com.google.api.services.dns.model.Change pb) { + Builder b = builder(); + if (pb.getId() != null) { + b.id(pb.getId()); + } + if (pb.getStartTime() != null) { + b.startTimeMillis(DateTime.parse(pb.getStartTime()).getMillis()); + } + if (pb.getStatus() != null) { + b.status(ChangeRequest.Status.translate(pb.getStatus())); + } + if (pb.getDeletions() != null) { + for (com.google.api.services.dns.model.ResourceRecordSet deletion : pb.getDeletions()) { + b.delete(DnsRecord.fromPb(deletion)); + } + } + if (pb.getAdditions() != null) { + for (com.google.api.services.dns.model.ResourceRecordSet addition : pb.getAdditions()) { + b.add(DnsRecord.fromPb(addition)); + } + } + return b.build(); + } + + @Override + public boolean equals(Object o) { + return (o instanceof ChangeRequest) && this.toPb().equals(((ChangeRequest) o).toPb()); + } + + @Override + public int hashCode() { + return Objects.hash(additions, deletions, id, startTimeMillis, status); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("additions", additions) + .add("deletions", deletions) + .add("id", id) + .add("startTimeMillis", startTimeMillis) + .add("status", status) + .toString(); + } +} diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java index 43ced20cf207..312cf564cbf2 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package com.google.gcloud.dns; import static org.junit.Assert.assertEquals; From 35cfd616b7294419d16aed9232fe40bb94321884 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Tue, 26 Jan 2016 14:31:39 -0800 Subject: [PATCH 035/375] Added test for ChangeRequest. --- .../google/gcloud/dns/ChangeRequestTest.java | 231 ++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java new file mode 100644 index 000000000000..da8006da8b51 --- /dev/null +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java @@ -0,0 +1,231 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.dns; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.google.common.collect.ImmutableList; + +import org.junit.Test; + +import java.util.List; + +public class ChangeRequestTest { + + private static final String ID = "cr-id-1"; + private static final Long START_TIME_MILLIS = 12334567890L; + private static final ChangeRequest.Status STATUS = ChangeRequest.Status.PENDING; + private static final String NAME1 = "dns1"; + private static final DnsRecord.Type TYPE1 = DnsRecord.Type.A; + private static final String NAME2 = "dns2"; + private static final DnsRecord.Type TYPE2 = DnsRecord.Type.AAAA; + private static final String NAME3 = "dns3"; + private static final DnsRecord.Type TYPE3 = DnsRecord.Type.MX; + private static final DnsRecord RECORD1 = DnsRecord.builder(NAME1, TYPE1).build(); + private static final DnsRecord RECORD2 = DnsRecord.builder(NAME2, TYPE2).build(); + private static final DnsRecord RECORD3 = DnsRecord.builder(NAME3, TYPE3).build(); + private static final List ADDITIONS = ImmutableList.of(RECORD1, RECORD2); + private static final List DELETIONS = ImmutableList.of(RECORD3); + private static final ChangeRequest CHANGE = ChangeRequest.builder() + .add(RECORD1) + .add(RECORD2) + .delete(RECORD3) + .startTimeMillis(START_TIME_MILLIS) + .status(STATUS) + .id(ID) + .build(); + + @Test + public void testEmptyBuilder() { + ChangeRequest cr = ChangeRequest.builder().build(); + assertNotNull(cr.deletions()); + assertTrue(cr.deletions().isEmpty()); + assertNotNull(cr.additions()); + assertTrue(cr.additions().isEmpty()); + } + + @Test + public void testBuilder() { + assertEquals(ID, CHANGE.id()); + assertEquals(STATUS, CHANGE.status()); + assertEquals(START_TIME_MILLIS, CHANGE.startTimeMillis()); + assertEquals(ADDITIONS, CHANGE.additions()); + assertEquals(DELETIONS, CHANGE.deletions()); + List recordList = ImmutableList.of(RECORD1); + ChangeRequest another = CHANGE.toBuilder().additions(recordList).build(); + assertEquals(recordList, another.additions()); + assertEquals(CHANGE.deletions(), another.deletions()); + another = CHANGE.toBuilder().deletions(recordList).build(); + assertEquals(recordList, another.deletions()); + assertEquals(CHANGE.additions(), another.additions()); + } + + @Test + public void testEqualsAndNotEquals() { + ChangeRequest clone = CHANGE.toBuilder().build(); + assertEquals(CHANGE, clone); + clone = ChangeRequest.fromPb(CHANGE.toPb()); + assertEquals(CHANGE, clone); + clone = CHANGE.toBuilder().id("some-other-id").build(); + assertNotEquals(CHANGE, clone); + clone = CHANGE.toBuilder().startTimeMillis(CHANGE.startTimeMillis() + 1).build(); + assertNotEquals(CHANGE, clone); + clone = CHANGE.toBuilder().add(RECORD3).build(); + assertNotEquals(CHANGE, clone); + clone = CHANGE.toBuilder().delete(RECORD1).build(); + assertNotEquals(CHANGE, clone); + ChangeRequest empty = ChangeRequest.builder().build(); + assertNotEquals(CHANGE, empty); + assertEquals(empty, ChangeRequest.builder().build()); + } + + @Test + public void testSameHashCodeOnEquals() { + ChangeRequest clone = CHANGE.toBuilder().build(); + assertEquals(CHANGE, clone); + assertEquals(CHANGE.hashCode(), clone.hashCode()); + ChangeRequest empty = ChangeRequest.builder().build(); + assertEquals(empty.hashCode(), ChangeRequest.builder().build().hashCode()); + } + + @Test + public void testToAndFromPb() { + assertEquals(CHANGE, ChangeRequest.fromPb(CHANGE.toPb())); + ChangeRequest partial = ChangeRequest.builder().build(); + assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); + partial = ChangeRequest.builder().id(ID).build(); + assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); + partial = ChangeRequest.builder().add(RECORD1).build(); + assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); + partial = ChangeRequest.builder().delete(RECORD1).build(); + assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); + partial = ChangeRequest.builder().additions(ADDITIONS).build(); + assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); + partial = ChangeRequest.builder().deletions(DELETIONS).build(); + assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); + partial = ChangeRequest.builder().startTimeMillis(START_TIME_MILLIS).build(); + assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); + partial = ChangeRequest.builder().status(STATUS).build(); + assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); + } + + @Test + public void testToBuilder() { + assertEquals(CHANGE, CHANGE.toBuilder().build()); + ChangeRequest partial = ChangeRequest.builder().build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ChangeRequest.builder().id(ID).build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ChangeRequest.builder().add(RECORD1).build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ChangeRequest.builder().delete(RECORD1).build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ChangeRequest.builder().additions(ADDITIONS).build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ChangeRequest.builder().deletions(DELETIONS).build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ChangeRequest.builder().startTimeMillis(START_TIME_MILLIS).build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ChangeRequest.builder().status(STATUS).build(); + assertEquals(partial, partial.toBuilder().build()); + } + + @Test + public void testClearAdditions() { + ChangeRequest clone = CHANGE.toBuilder().clearAdditions().build(); + assertTrue(clone.additions().isEmpty()); + assertFalse(clone.deletions().isEmpty()); + } + + @Test + public void testAddAddition() { + try { + CHANGE.toBuilder().add(null).build(); + fail("Should not be able to add null DnsRecord."); + } catch (NullPointerException e) { + // expected + } + ChangeRequest clone = CHANGE.toBuilder().add(RECORD1).build(); + assertEquals(CHANGE.additions().size() + 1, clone.additions().size()); + } + + @Test + public void testAddDeletion() { + try { + ChangeRequest clone = CHANGE.toBuilder().delete(null).build(); + fail("Should not be able to delete null DnsRecord."); + } catch (NullPointerException e) { + // expected + } + ChangeRequest clone = CHANGE.toBuilder().delete(RECORD1).build(); + assertEquals(CHANGE.deletions().size() + 1, clone.deletions().size()); + } + + @Test + public void testClearDeletions() { + ChangeRequest clone = CHANGE.toBuilder().clearDeletions().build(); + assertTrue(clone.deletions().isEmpty()); + assertFalse(clone.additions().isEmpty()); + } + + @Test + public void testRemoveAddition() { + ChangeRequest clone = CHANGE.toBuilder().removeAddition(RECORD1).build(); + assertTrue(clone.additions().contains(RECORD2)); + assertFalse(clone.additions().contains(RECORD1)); + assertTrue(clone.deletions().contains(RECORD3)); + clone = CHANGE.toBuilder().removeAddition(RECORD2).removeAddition(RECORD1).build(); + assertFalse(clone.additions().contains(RECORD2)); + assertFalse(clone.additions().contains(RECORD1)); + assertTrue(clone.additions().isEmpty()); + assertTrue(clone.deletions().contains(RECORD3)); + } + + @Test + public void testRemoveDeletion() { + ChangeRequest clone = CHANGE.toBuilder().removeDeletion(RECORD3).build(); + assertFalse(clone.deletions().contains(RECORD3)); + assertTrue(clone.deletions().isEmpty()); + } + + @Test + public void testDateParsing() { + String startTime = "2016-01-26T18:33:43.512Z"; // obtained from service + com.google.api.services.dns.model.Change change = CHANGE.toPb().setStartTime(startTime); + ChangeRequest converted = ChangeRequest.fromPb(change); + assertNotNull(converted.startTimeMillis()); + assertEquals(change, converted.toPb()); + assertEquals(change.getStartTime(), converted.toPb().getStartTime()); + } + + @Test + public void testStatusTranslation() { + assertEquals(ChangeRequest.Status.DONE, ChangeRequest.Status.translate("done")); + assertEquals(ChangeRequest.Status.PENDING, ChangeRequest.Status.translate("pending")); + try { + ChangeRequest.Status.translate("another"); + fail("Such a status does not exist."); + } catch (IllegalArgumentException e) { + // expected + } + } +} From 6f9e1c09b831b39def386076826eecf20daa1bc2 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Tue, 26 Jan 2016 17:15:14 -0800 Subject: [PATCH 036/375] Implements comments from @ajkannan and @aozarov. --- .../com/google/gcloud/dns/ChangeRequest.java | 126 ++++++++---------- .../java/com/google/gcloud/dns/DnsRecord.java | 8 +- .../google/gcloud/dns/ChangeRequestTest.java | 17 +-- .../com/google/gcloud/dns/DnsRecordTest.java | 2 +- 4 files changed, 62 insertions(+), 91 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java index 40c6ff0ad151..5ed03b1ea071 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java @@ -16,7 +16,12 @@ package com.google.gcloud.dns; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.api.services.dns.model.ResourceRecordSet; +import com.google.common.base.Function; import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import org.joda.time.DateTime; @@ -27,17 +32,29 @@ import java.util.List; import java.util.Objects; -import static com.google.common.base.Preconditions.checkNotNull; - /** - * A class representing a change. A change is an atomic update to a collection of {@link DnsRecord}s - * within a {@code ManagedZone}. + * A class representing an atomic update to a collection of {@link DnsRecord}s within a {@code + * ManagedZone}. * * @see Google Cloud DNS documentation */ public class ChangeRequest implements Serializable { - private static final long serialVersionUID = 201601251649L; + private static final Function FROM_PB_FUNCTION = + new Function() { + @Override + public DnsRecord apply(com.google.api.services.dns.model.ResourceRecordSet pb) { + return DnsRecord.fromPb(pb); + } + }; + private static final Function TO_PB_FUNCTION = + new Function() { + @Override + public com.google.api.services.dns.model.ResourceRecordSet apply(DnsRecord error) { + return error.toPb(); + } + }; + private static final long serialVersionUID = -8703939628990291682L; private final List additions; private final List deletions; private final String id; @@ -51,24 +68,8 @@ public class ChangeRequest implements Serializable { * documentation */ public enum Status { - PENDING("pending"), - DONE("done"); - - private final String status; - - Status(String status) { - this.status = status; - } - - static Status translate(String status) { - if ("pending".equals(status)) { - return PENDING; - } else if ("done".equals(status)) { - return DONE; - } else { - throw new IllegalArgumentException("Such a status is unknown."); - } - } + PENDING, + DONE } /** @@ -101,10 +102,19 @@ public Builder additions(List additions) { this.additions = Lists.newLinkedList(checkNotNull(additions)); return this; } + + /** + * Sets a collection of {@link DnsRecord}s which are to be deleted from the zone upon executing + * this {@code ChangeRequest}. + */ + public Builder deletions(List deletions) { + this.deletions = Lists.newLinkedList(checkNotNull(deletions)); + return this; + } /** - * Adds a {@link DnsRecord} which to be added to the zone upon executing this - * {@code ChangeRequest}. + * Adds a {@link DnsRecord} to be added to the zone upon executing this {@code + * ChangeRequest}. */ public Builder add(DnsRecord record) { this.additions.add(checkNotNull(record)); @@ -112,7 +122,7 @@ public Builder add(DnsRecord record) { } /** - * Adds a {@link DnsRecord} which to be deleted to the zone upon executing this + * Adds a {@link DnsRecord} to be deleted to the zone upon executing this * {@code ChangeRequest}. */ public Builder delete(DnsRecord record) { @@ -139,7 +149,7 @@ public Builder clearDeletions() { } /** - * Removes a single {@link DnsRecord} from the collection of of records to be + * Removes a single {@link DnsRecord} from the collection of records to be * added to the zone upon executing this {@code ChangeRequest}. */ public Builder removeAddition(DnsRecord record) { @@ -148,7 +158,7 @@ public Builder removeAddition(DnsRecord record) { } /** - * Removes a single {@link DnsRecord} from the collection of of records to be + * Removes a single {@link DnsRecord} from the collection of records to be * deleted from the zone upon executing this {@code ChangeRequest}. */ public Builder removeDeletion(DnsRecord record) { @@ -156,15 +166,6 @@ public Builder removeDeletion(DnsRecord record) { return this; } - /** - * Sets a collection of {@link DnsRecord}s which are to be deleted from the zone upon executing - * this {@code ChangeRequest}. - */ - public Builder deletions(List deletions) { - this.deletions = Lists.newLinkedList(checkNotNull(deletions)); - return this; - } - /** * Associates a server-assigned id to this {@code ChangeRequest}. */ @@ -199,8 +200,8 @@ public ChangeRequest build() { } private ChangeRequest(Builder builder) { - this.additions = builder.additions; - this.deletions = builder.deletions; + this.additions = ImmutableList.copyOf(builder.additions); + this.deletions = ImmutableList.copyOf(builder.deletions); this.id = builder.id; this.startTimeMillis = builder.startTimeMillis; this.status = builder.status; @@ -221,7 +222,7 @@ public Builder toBuilder() { } /** - * Returns the list of {@link DnsRecord}s to be added to the zone upon executing this {@code + * Returns the list of {@link DnsRecord}s to be added to the zone upon submitting this {@code * ChangeRequest}. */ public List additions() { @@ -229,7 +230,7 @@ public List additions() { } /** - * Returns the list of {@link DnsRecord}s to be deleted from the zone upon executing this {@code + * Returns the list of {@link DnsRecord}s to be deleted from the zone upon submitting this {@code * ChangeRequest}. */ public List deletions() { @@ -270,56 +271,39 @@ com.google.api.services.dns.model.Change toPb() { } // set status if (status() != null) { - pb.setStatus(status().status); + pb.setStatus(status().name().toLowerCase()); } // set a list of additions - if (additions() != null) { - LinkedList additionsPb = - new LinkedList<>(); - for (DnsRecord addition : additions()) { - additionsPb.add(addition.toPb()); - } - pb.setAdditions(additionsPb); - } + pb.setAdditions(Lists.transform(additions(), TO_PB_FUNCTION)); // set a list of deletions - if (deletions() != null) { - LinkedList deletionsPb = - new LinkedList<>(); - for (DnsRecord deletion : deletions()) { - deletionsPb.add(deletion.toPb()); - } - pb.setDeletions(deletionsPb); - } + pb.setDeletions(Lists.transform(deletions(), TO_PB_FUNCTION)); return pb; } static ChangeRequest fromPb(com.google.api.services.dns.model.Change pb) { - Builder b = builder(); + Builder builder = builder(); if (pb.getId() != null) { - b.id(pb.getId()); + builder.id(pb.getId()); } if (pb.getStartTime() != null) { - b.startTimeMillis(DateTime.parse(pb.getStartTime()).getMillis()); + builder.startTimeMillis(DateTime.parse(pb.getStartTime()).getMillis()); } if (pb.getStatus() != null) { - b.status(ChangeRequest.Status.translate(pb.getStatus())); + // we are assuming that status indicated in pb is a lower case version of the enum name + builder.status(ChangeRequest.Status.valueOf(pb.getStatus().toUpperCase())); } if (pb.getDeletions() != null) { - for (com.google.api.services.dns.model.ResourceRecordSet deletion : pb.getDeletions()) { - b.delete(DnsRecord.fromPb(deletion)); - } + builder.deletions(Lists.transform(pb.getDeletions(), FROM_PB_FUNCTION)); } if (pb.getAdditions() != null) { - for (com.google.api.services.dns.model.ResourceRecordSet addition : pb.getAdditions()) { - b.add(DnsRecord.fromPb(addition)); - } + builder.additions(Lists.transform(pb.getAdditions(), FROM_PB_FUNCTION)); } - return b.build(); + return builder.build(); } @Override - public boolean equals(Object o) { - return (o instanceof ChangeRequest) && this.toPb().equals(((ChangeRequest) o).toPb()); + public boolean equals(Object other) { + return (other instanceof ChangeRequest) && toPb().equals(((ChangeRequest) other).toPb()); } @Override diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java index c41e72a77400..4236d9c1c561 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java @@ -273,14 +273,14 @@ com.google.api.services.dns.model.ResourceRecordSet toPb() { } static DnsRecord fromPb(com.google.api.services.dns.model.ResourceRecordSet pb) { - Builder b = builder(pb.getName(), Type.valueOf(pb.getType())); + Builder builder = builder(pb.getName(), Type.valueOf(pb.getType())); if (pb.getRrdatas() != null) { - b.records(pb.getRrdatas()); + builder.records(pb.getRrdatas()); } if (pb.getTtl() != null) { - b.ttl(pb.getTtl()); + builder.ttl(pb.getTtl()); } - return b.build(); + return builder.build(); } @Override diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java index da8006da8b51..8b40a4dcff34 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java @@ -159,7 +159,7 @@ public void testClearAdditions() { @Test public void testAddAddition() { try { - CHANGE.toBuilder().add(null).build(); + CHANGE.toBuilder().add(null); fail("Should not be able to add null DnsRecord."); } catch (NullPointerException e) { // expected @@ -171,7 +171,7 @@ public void testAddAddition() { @Test public void testAddDeletion() { try { - ChangeRequest clone = CHANGE.toBuilder().delete(null).build(); + CHANGE.toBuilder().delete(null); fail("Should not be able to delete null DnsRecord."); } catch (NullPointerException e) { // expected @@ -203,7 +203,6 @@ public void testRemoveAddition() { @Test public void testRemoveDeletion() { ChangeRequest clone = CHANGE.toBuilder().removeDeletion(RECORD3).build(); - assertFalse(clone.deletions().contains(RECORD3)); assertTrue(clone.deletions().isEmpty()); } @@ -216,16 +215,4 @@ public void testDateParsing() { assertEquals(change, converted.toPb()); assertEquals(change.getStartTime(), converted.toPb().getStartTime()); } - - @Test - public void testStatusTranslation() { - assertEquals(ChangeRequest.Status.DONE, ChangeRequest.Status.translate("done")); - assertEquals(ChangeRequest.Status.PENDING, ChangeRequest.Status.translate("pending")); - try { - ChangeRequest.Status.translate("another"); - fail("Such a status does not exist."); - } catch (IllegalArgumentException e) { - // expected - } - } } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java index 312cf564cbf2..60eb6f033ce0 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java @@ -17,9 +17,9 @@ package com.google.gcloud.dns; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.junit.Assert.assertNotEquals; import org.junit.Test; From 9b4ff48b64c2192a42d914a672d9004e59a4b822 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Mon, 25 Jan 2016 16:23:48 -0800 Subject: [PATCH 037/375] Added ProjectInfo. --- .../com/google/gcloud/dns/ProjectInfo.java | 284 ++++++++++++++++++ .../google/gcloud/dns/ProjectInfoTest.java | 118 ++++++++ 2 files changed, 402 insertions(+) create mode 100644 gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java create mode 100644 gcloud-java-dns/src/test/java/com/google/gcloud/dns/ProjectInfoTest.java diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java new file mode 100644 index 000000000000..614b9033a18e --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java @@ -0,0 +1,284 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.dns; + +import static com.google.api.client.repackaged.com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; + +import java.io.Serializable; +import java.math.BigInteger; +import java.util.Objects; + +/** + * The class that encapsulates information about a project in Google Cloud DNS. A project is a top + * level container for resources including {@link ManagedZone}s. Projects can be created only in the + * APIs console. + * + * @see Google Cloud DNS documentation + */ +public class ProjectInfo implements Serializable { + + private static final long serialVersionUID = 201601251420L; + private final String id; + private final BigInteger number; + private final Quota quota; + + /** + * This class represents quotas assigned to the {@code ProjectInfo}. + * + * @see Google Cloud DNS documentation + */ + public static class Quota { + + private Integer zones; + private Integer resourceRecordsPerRrset; + private Integer rrsetAdditionsPerChange; + private Integer rrsetDeletionsPerChange; + private Integer rrsetsPerManagedZone; + private Integer totalRrdataSizePerChange; + + /** + * Creates an instance of {@code Quota}. + * + * This is the only way of creating an instance of {@code Quota}. As the service does not allow + * for specifying options, quota is an "all-or-nothing object" and we do not need a builder. + */ + Quota(Integer zones, + Integer resourceRecordsPerRrset, + Integer rrsetAdditionsPerChange, + Integer rrsetDeletionsPerChange, + Integer rrsetsPerManagedZone, + Integer totalRrdataSizePerChange) { + this.zones = checkNotNull(zones); + this.resourceRecordsPerRrset = checkNotNull(resourceRecordsPerRrset); + this.rrsetAdditionsPerChange = checkNotNull(rrsetAdditionsPerChange); + this.rrsetDeletionsPerChange = checkNotNull(rrsetDeletionsPerChange); + this.rrsetsPerManagedZone = checkNotNull(rrsetsPerManagedZone); + this.totalRrdataSizePerChange = checkNotNull(totalRrdataSizePerChange); + } + + /** + * Returns the maximum allowed number of managed zones in the project. + */ + public Integer zones() { + return zones; + } + + /** + * Returns the maximum allowed number of records per {@link DnsRecord}. + */ + public Integer resourceRecordsPerRrset() { + return resourceRecordsPerRrset; + } + + /** + * Returns the maximum allowed number of {@link DnsRecord}s to add per {@code ChangesRequest}. + */ + public Integer rrsetAdditionsPerChange() { + return rrsetAdditionsPerChange; + } + + /** + * Returns the maximum allowed number of {@link DnsRecord}s to delete per {@code + * ChangesRequest}. + */ + public Integer rrsetDeletionsPerChange() { + return rrsetDeletionsPerChange; + } + + /** + * Returns the maximum allowed number of {@link DnsRecord}s per {@link ManagedZone} in the + * project. + */ + public Integer rrsetsPerManagedZone() { + return rrsetsPerManagedZone; + } + + /** + * Returns the maximum allowed size for total records in one ChangesRequest in bytes. + */ + public Integer totalRrdataSizePerChange() { + return totalRrdataSizePerChange; + } + + @Override + public boolean equals(Object o) { + return (o instanceof Quota) && this.toPb().equals(((Quota) o).toPb()); + } + + @Override + public int hashCode() { + return Objects.hash(zones, resourceRecordsPerRrset, rrsetAdditionsPerChange, + rrsetDeletionsPerChange, rrsetsPerManagedZone, totalRrdataSizePerChange); + } + + com.google.api.services.dns.model.Quota toPb() { + com.google.api.services.dns.model.Quota pb = new com.google.api.services.dns.model.Quota(); + pb.setManagedZones(zones); + pb.setResourceRecordsPerRrset(resourceRecordsPerRrset); + pb.setRrsetAdditionsPerChange(rrsetAdditionsPerChange); + pb.setRrsetDeletionsPerChange(rrsetDeletionsPerChange); + pb.setRrsetsPerManagedZone(rrsetsPerManagedZone); + pb.setTotalRrdataSizePerChange(totalRrdataSizePerChange); + return pb; + } + + static Quota fromPb(com.google.api.services.dns.model.Quota pb) { + Quota q = new Quota(pb.getManagedZones(), + pb.getResourceRecordsPerRrset(), + pb.getRrsetAdditionsPerChange(), + pb.getRrsetDeletionsPerChange(), + pb.getRrsetsPerManagedZone(), + pb.getTotalRrdataSizePerChange() + ); + return q; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("zones", zones) + .add("resourceRecordsPerRrset", resourceRecordsPerRrset) + .add("rrsetAdditionsPerChange", rrsetAdditionsPerChange) + .add("rrsetDeletionsPerChange", rrsetDeletionsPerChange) + .add("rrsetsPerManagedZone", rrsetsPerManagedZone) + .add("totalRrdataSizePerChange", totalRrdataSizePerChange) + .toString(); + } + } + + /** + * A builder for {@code ProjectInfo}. + */ + static class Builder { + private String id; + private BigInteger number; + private Quota quota; + + private Builder() { + } + + /** + * Sets an id of the project. + */ + Builder id(String id) { + this.id = checkNotNull(id); + return this; + } + + /** + * Sets a number of the project. + */ + Builder number(BigInteger number) { + this.number = checkNotNull(number); + return this; + } + + /** + * Sets quotas assigned to the project. + */ + Builder quota(Quota quota) { + this.quota = checkNotNull(quota); + return this; + } + + /** + * Builds an instance of the {@code ProjectInfo}. + */ + ProjectInfo build() { + return new ProjectInfo(this); + } + } + + private ProjectInfo(Builder b) { + this.id = b.id; + this.number = b.number; + this.quota = b.quota; + } + + /** + * Returns a builder for {@code ProjectInfo}. + */ + static Builder builder() { + return new Builder(); + } + + /** + * Returns the user-assigned unique identifier for the project. + */ + public String id() { + return id; + } + + /** + * Returns the unique numeric identifier for the project. + */ + public BigInteger number() { + return number; + } + + /** + * Returns the {@code Quota} object which contains quotas assigned to this project. + */ + public Quota quota() { + return quota; + } + + com.google.api.services.dns.model.Project toPb() { + com.google.api.services.dns.model.Project pb = new com.google.api.services.dns.model.Project(); + pb.setId(id()); + pb.setNumber(number()); + if (this.quota() != null) { + pb.setQuota(quota().toPb()); + } + return pb; + } + + static ProjectInfo fromPb(com.google.api.services.dns.model.Project pb) { + Builder b = builder(); + if (pb.getId() != null) { + b.id(pb.getId()); + } + if (pb.getNumber() != null) { + b.number(pb.getNumber()); + } + if (pb.getQuota() != null) { + b.quota(Quota.fromPb(pb.getQuota())); + } + return b.build(); + } + + @Override + public boolean equals(Object o) { + return (o instanceof ProjectInfo) && this.toPb().equals(((ProjectInfo) o).toPb()); + } + + @Override + public int hashCode() { + return Objects.hash(id, number, quota); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id) + .add("number", number) + .add("quota", quota) + .toString(); + } +} diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ProjectInfoTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ProjectInfoTest.java new file mode 100644 index 000000000000..2c5e1ffa7100 --- /dev/null +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ProjectInfoTest.java @@ -0,0 +1,118 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.dns; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Test; + +import java.math.BigInteger; + +public class ProjectInfoTest { + + private static final String ID = "project-id-123"; + private static final BigInteger NUMBER = new BigInteger("123"); + private static final ProjectInfo.Quota QUOTA = new ProjectInfo.Quota(1, 2, 3, 4, 5, 6); + private static final ProjectInfo PROJECT_INFO = ProjectInfo.builder() + .id(ID).number(NUMBER).quota(QUOTA).build(); + + @Test + public void testBuilder() { + ProjectInfo withId = ProjectInfo.builder().id(ID).build(); + assertEquals(ID, withId.id()); + assertNull(withId.number()); + assertNull(withId.quota()); + ProjectInfo withNumber = ProjectInfo.builder().number(NUMBER).build(); + assertEquals(NUMBER, withNumber.number()); + assertNull(withNumber.quota()); + assertNull(withNumber.id()); + ProjectInfo withQuota = ProjectInfo.builder().quota(QUOTA).build(); + assertEquals(QUOTA, withQuota.quota()); + assertNull(withQuota.id()); + assertNull(withQuota.number()); + assertEquals(QUOTA, PROJECT_INFO.quota()); + assertEquals(NUMBER, PROJECT_INFO.number()); + assertEquals(ID, PROJECT_INFO.id()); + } + + @Test + public void testQuotaConstructor() { + assertEquals(Integer.valueOf(1), QUOTA.zones()); + assertEquals(Integer.valueOf(2), QUOTA.resourceRecordsPerRrset()); + assertEquals(Integer.valueOf(3), QUOTA.rrsetAdditionsPerChange()); + assertEquals(Integer.valueOf(4), QUOTA.rrsetDeletionsPerChange()); + assertEquals(Integer.valueOf(5), QUOTA.rrsetsPerManagedZone()); + assertEquals(Integer.valueOf(6), QUOTA.totalRrdataSizePerChange()); + } + + @Test + public void testEqualsAndNotEqualsQuota() { + ProjectInfo.Quota clone = new ProjectInfo.Quota(6, 5, 4, 3, 2, 1); + assertNotEquals(QUOTA, clone); + clone = ProjectInfo.Quota.fromPb(QUOTA.toPb()); + assertEquals(QUOTA, clone); + } + + @Test + public void testSameHashCodeOnEqualsQuota() { + ProjectInfo.Quota clone = ProjectInfo.Quota.fromPb(QUOTA.toPb()); + assertEquals(QUOTA, clone); + assertEquals(QUOTA.hashCode(), clone.hashCode()); + } + + @Test + public void testEqualsAndNotEquals() { + ProjectInfo clone = ProjectInfo.builder().build(); + assertNotEquals(PROJECT_INFO, clone); + clone = ProjectInfo.builder().id(PROJECT_INFO.id()).number(PROJECT_INFO.number()).build(); + assertNotEquals(PROJECT_INFO, clone); + clone = ProjectInfo.builder().id(PROJECT_INFO.id()).quota(PROJECT_INFO.quota()).build(); + assertNotEquals(PROJECT_INFO, clone); + clone = ProjectInfo.builder().number(PROJECT_INFO.number()).quota(PROJECT_INFO.quota()).build(); + assertNotEquals(PROJECT_INFO, clone); + clone = ProjectInfo.fromPb(PROJECT_INFO.toPb()); + assertEquals(PROJECT_INFO, clone); + } + + @Test + public void testSameHashCodeOnEquals() { + ProjectInfo clone = ProjectInfo.fromPb(PROJECT_INFO.toPb()); + assertEquals(PROJECT_INFO, clone); + assertEquals(PROJECT_INFO.hashCode(), clone.hashCode()); + } + + @Test + public void testToAndFromPb() { + assertEquals(PROJECT_INFO, ProjectInfo.fromPb(PROJECT_INFO.toPb())); + ProjectInfo partial = ProjectInfo.builder().id(ID).build(); + assertEquals(partial, PROJECT_INFO.fromPb(partial.toPb())); + partial = ProjectInfo.builder().number(NUMBER).build(); + assertEquals(partial, PROJECT_INFO.fromPb(partial.toPb())); + partial = ProjectInfo.builder().quota(QUOTA).build(); + assertEquals(partial, PROJECT_INFO.fromPb(partial.toPb())); + assertNotEquals(PROJECT_INFO, partial); + } + + @Test + public void testToAndFromPbQuota() { + assertEquals(QUOTA, ProjectInfo.Quota.fromPb(QUOTA.toPb())); + ProjectInfo.Quota wrong = new ProjectInfo.Quota(5, 6, 3, 6, 2, 1); + assertNotEquals(QUOTA, ProjectInfo.Quota.fromPb(wrong.toPb())); + } +} From a47158db527eeb220534189ee24c7837f75bddda Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Wed, 27 Jan 2016 12:35:32 -0800 Subject: [PATCH 038/375] Fixed serialization, javadoc and checkstyle. --- .../com/google/gcloud/dns/ProjectInfo.java | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java index 614b9033a18e..dc9c2e6ef55e 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java @@ -26,14 +26,14 @@ /** * The class that encapsulates information about a project in Google Cloud DNS. A project is a top - * level container for resources including {@link ManagedZone}s. Projects can be created only in the + * level container for resources including {@code ManagedZone}s. Projects can be created only in the * APIs console. * * @see Google Cloud DNS documentation */ public class ProjectInfo implements Serializable { - private static final long serialVersionUID = 201601251420L; + private static final long serialVersionUID = 8696578863323485036L; private final String id; private final BigInteger number; private final Quota quota; @@ -55,8 +55,9 @@ public static class Quota { /** * Creates an instance of {@code Quota}. * - * This is the only way of creating an instance of {@code Quota}. As the service does not allow - * for specifying options, quota is an "all-or-nothing object" and we do not need a builder. + *

This is the only way of creating an instance of {@code Quota}. As the service does not + * allow for specifying options, quota is an "all-or-nothing object" and we do not need a + * builder. */ Quota(Integer zones, Integer resourceRecordsPerRrset, @@ -102,7 +103,7 @@ public Integer rrsetDeletionsPerChange() { } /** - * Returns the maximum allowed number of {@link DnsRecord}s per {@link ManagedZone} in the + * Returns the maximum allowed number of {@link DnsRecord}s per {@code ManagedZone} in the * project. */ public Integer rrsetsPerManagedZone() { @@ -117,8 +118,8 @@ public Integer totalRrdataSizePerChange() { } @Override - public boolean equals(Object o) { - return (o instanceof Quota) && this.toPb().equals(((Quota) o).toPb()); + public boolean equals(Object other) { + return (other instanceof Quota) && this.toPb().equals(((Quota) other).toPb()); } @Override @@ -139,14 +140,14 @@ com.google.api.services.dns.model.Quota toPb() { } static Quota fromPb(com.google.api.services.dns.model.Quota pb) { - Quota q = new Quota(pb.getManagedZones(), + Quota quota = new Quota(pb.getManagedZones(), pb.getResourceRecordsPerRrset(), pb.getRrsetAdditionsPerChange(), pb.getRrsetDeletionsPerChange(), pb.getRrsetsPerManagedZone(), pb.getTotalRrdataSizePerChange() ); - return q; + return quota; } @Override @@ -205,10 +206,10 @@ ProjectInfo build() { } } - private ProjectInfo(Builder b) { - this.id = b.id; - this.number = b.number; - this.quota = b.quota; + private ProjectInfo(Builder builder) { + this.id = builder.id; + this.number = builder.number; + this.quota = builder.quota; } /** @@ -250,22 +251,22 @@ com.google.api.services.dns.model.Project toPb() { } static ProjectInfo fromPb(com.google.api.services.dns.model.Project pb) { - Builder b = builder(); + Builder builder = builder(); if (pb.getId() != null) { - b.id(pb.getId()); + builder.id(pb.getId()); } if (pb.getNumber() != null) { - b.number(pb.getNumber()); + builder.number(pb.getNumber()); } if (pb.getQuota() != null) { - b.quota(Quota.fromPb(pb.getQuota())); + builder.quota(Quota.fromPb(pb.getQuota())); } - return b.build(); + return builder.build(); } @Override - public boolean equals(Object o) { - return (o instanceof ProjectInfo) && this.toPb().equals(((ProjectInfo) o).toPb()); + public boolean equals(Object other) { + return (other instanceof ProjectInfo) && this.toPb().equals(((ProjectInfo) other).toPb()); } @Override From 9db27d44a072233955a57670c4c77a8a1f72afca Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Wed, 27 Jan 2016 16:00:44 -0800 Subject: [PATCH 039/375] Implements comment from @aozarov and @ajkannan into ProjectInfo. --- .../com/google/gcloud/dns/ProjectInfo.java | 83 ++++++++++--------- .../google/gcloud/dns/ProjectInfoTest.java | 12 +-- 2 files changed, 48 insertions(+), 47 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java index dc9c2e6ef55e..f8b2e33a1e9f 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java @@ -25,9 +25,9 @@ import java.util.Objects; /** - * The class that encapsulates information about a project in Google Cloud DNS. A project is a top - * level container for resources including {@code ManagedZone}s. Projects can be created only in the - * APIs console. + * The class provides the Google Cloud DNS information associated with this project. A project is a + * top level container for resources including {@code ManagedZone}s. Projects can be created only in + * the APIs console. * * @see Google Cloud DNS documentation */ @@ -41,16 +41,17 @@ public class ProjectInfo implements Serializable { /** * This class represents quotas assigned to the {@code ProjectInfo}. * - * @see Google Cloud DNS documentation + * @see Google Cloud DNS + * documentation */ public static class Quota { - private Integer zones; - private Integer resourceRecordsPerRrset; - private Integer rrsetAdditionsPerChange; - private Integer rrsetDeletionsPerChange; - private Integer rrsetsPerManagedZone; - private Integer totalRrdataSizePerChange; + private final int zones; + private final int resourceRecordsPerRrset; + private final int rrsetAdditionsPerChange; + private final int rrsetDeletionsPerChange; + private final int rrsetsPerManagedZone; + private final int totalRrdataSizePerChange; /** * Creates an instance of {@code Quota}. @@ -59,38 +60,38 @@ public static class Quota { * allow for specifying options, quota is an "all-or-nothing object" and we do not need a * builder. */ - Quota(Integer zones, - Integer resourceRecordsPerRrset, - Integer rrsetAdditionsPerChange, - Integer rrsetDeletionsPerChange, - Integer rrsetsPerManagedZone, - Integer totalRrdataSizePerChange) { - this.zones = checkNotNull(zones); - this.resourceRecordsPerRrset = checkNotNull(resourceRecordsPerRrset); - this.rrsetAdditionsPerChange = checkNotNull(rrsetAdditionsPerChange); - this.rrsetDeletionsPerChange = checkNotNull(rrsetDeletionsPerChange); - this.rrsetsPerManagedZone = checkNotNull(rrsetsPerManagedZone); - this.totalRrdataSizePerChange = checkNotNull(totalRrdataSizePerChange); + Quota(int zones, + int resourceRecordsPerRrset, + int rrsetAdditionsPerChange, + int rrsetDeletionsPerChange, + int rrsetsPerManagedZone, + int totalRrdataSizePerChange) { + this.zones = zones; + this.resourceRecordsPerRrset = resourceRecordsPerRrset; + this.rrsetAdditionsPerChange = rrsetAdditionsPerChange; + this.rrsetDeletionsPerChange = rrsetDeletionsPerChange; + this.rrsetsPerManagedZone = rrsetsPerManagedZone; + this.totalRrdataSizePerChange = totalRrdataSizePerChange; } /** * Returns the maximum allowed number of managed zones in the project. */ - public Integer zones() { + public int zones() { return zones; } /** * Returns the maximum allowed number of records per {@link DnsRecord}. */ - public Integer resourceRecordsPerRrset() { + public int resourceRecordsPerRrset() { return resourceRecordsPerRrset; } /** * Returns the maximum allowed number of {@link DnsRecord}s to add per {@code ChangesRequest}. */ - public Integer rrsetAdditionsPerChange() { + public int rrsetAdditionsPerChange() { return rrsetAdditionsPerChange; } @@ -98,7 +99,7 @@ public Integer rrsetAdditionsPerChange() { * Returns the maximum allowed number of {@link DnsRecord}s to delete per {@code * ChangesRequest}. */ - public Integer rrsetDeletionsPerChange() { + public int rrsetDeletionsPerChange() { return rrsetDeletionsPerChange; } @@ -106,14 +107,14 @@ public Integer rrsetDeletionsPerChange() { * Returns the maximum allowed number of {@link DnsRecord}s per {@code ManagedZone} in the * project. */ - public Integer rrsetsPerManagedZone() { + public int rrsetsPerManagedZone() { return rrsetsPerManagedZone; } /** * Returns the maximum allowed size for total records in one ChangesRequest in bytes. */ - public Integer totalRrdataSizePerChange() { + public int totalRrdataSizePerChange() { return totalRrdataSizePerChange; } @@ -220,32 +221,32 @@ static Builder builder() { } /** - * Returns the user-assigned unique identifier for the project. + * Returns the {@code Quota} object which contains quotas assigned to this project. */ - public String id() { - return id; + public Quota quota() { + return quota; } /** - * Returns the unique numeric identifier for the project. + * Returns project number. For internal use only. */ - public BigInteger number() { + BigInteger number() { return number; } /** - * Returns the {@code Quota} object which contains quotas assigned to this project. + * Returns project id. For internal use only. */ - public Quota quota() { - return quota; + String id() { + return id; } com.google.api.services.dns.model.Project toPb() { com.google.api.services.dns.model.Project pb = new com.google.api.services.dns.model.Project(); - pb.setId(id()); - pb.setNumber(number()); - if (this.quota() != null) { - pb.setQuota(quota().toPb()); + pb.setId(id); + pb.setNumber(number); + if (this.quota != null) { + pb.setQuota(quota.toPb()); } return pb; } @@ -266,7 +267,7 @@ static ProjectInfo fromPb(com.google.api.services.dns.model.Project pb) { @Override public boolean equals(Object other) { - return (other instanceof ProjectInfo) && this.toPb().equals(((ProjectInfo) other).toPb()); + return (other instanceof ProjectInfo) && toPb().equals(((ProjectInfo) other).toPb()); } @Override diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ProjectInfoTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ProjectInfoTest.java index 2c5e1ffa7100..2af8b5ad3995 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ProjectInfoTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ProjectInfoTest.java @@ -53,12 +53,12 @@ public void testBuilder() { @Test public void testQuotaConstructor() { - assertEquals(Integer.valueOf(1), QUOTA.zones()); - assertEquals(Integer.valueOf(2), QUOTA.resourceRecordsPerRrset()); - assertEquals(Integer.valueOf(3), QUOTA.rrsetAdditionsPerChange()); - assertEquals(Integer.valueOf(4), QUOTA.rrsetDeletionsPerChange()); - assertEquals(Integer.valueOf(5), QUOTA.rrsetsPerManagedZone()); - assertEquals(Integer.valueOf(6), QUOTA.totalRrdataSizePerChange()); + assertEquals(1, QUOTA.zones()); + assertEquals(2, QUOTA.resourceRecordsPerRrset()); + assertEquals(3, QUOTA.rrsetAdditionsPerChange()); + assertEquals(4, QUOTA.rrsetDeletionsPerChange()); + assertEquals(5, QUOTA.rrsetsPerManagedZone()); + assertEquals(6, QUOTA.totalRrdataSizePerChange()); } @Test From 4412c7304cda6bd5d3846161b6451740972bc929 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Wed, 27 Jan 2016 16:13:37 -0800 Subject: [PATCH 040/375] Changed documentation @code to @link where applicable. --- .../src/main/java/com/google/gcloud/dns/ProjectInfo.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java index f8b2e33a1e9f..e65524913920 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java @@ -89,22 +89,22 @@ public int resourceRecordsPerRrset() { } /** - * Returns the maximum allowed number of {@link DnsRecord}s to add per {@code ChangesRequest}. + * Returns the maximum allowed number of {@link DnsRecord}s to add per {@link ChangeRequest}. */ public int rrsetAdditionsPerChange() { return rrsetAdditionsPerChange; } /** - * Returns the maximum allowed number of {@link DnsRecord}s to delete per {@code - * ChangesRequest}. + * Returns the maximum allowed number of {@link DnsRecord}s to delete per {@link + * ChangeRequest}. */ public int rrsetDeletionsPerChange() { return rrsetDeletionsPerChange; } /** - * Returns the maximum allowed number of {@link DnsRecord}s per {@code ManagedZone} in the + * Returns the maximum allowed number of {@link DnsRecord}s per {@link ManagedZoneInfo} in the * project. */ public int rrsetsPerManagedZone() { From 81a46d8429909998bdbf65cdc0726e9a404d62b1 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Wed, 27 Jan 2016 18:01:27 -0800 Subject: [PATCH 041/375] Renames ManagedZone to Zone. Acommodates codecheck. Fixes #579. --- .../com/google/gcloud/dns/ChangeRequest.java | 4 +- .../java/com/google/gcloud/dns/DnsRecord.java | 4 +- .../com/google/gcloud/dns/ProjectInfo.java | 6 +- .../{ManagedZoneInfo.java => ZoneInfo.java} | 88 +++++++++---------- ...gedZoneInfoTest.java => ZoneInfoTest.java} | 62 ++++++------- 5 files changed, 80 insertions(+), 84 deletions(-) rename gcloud-java-dns/src/main/java/com/google/gcloud/dns/{ManagedZoneInfo.java => ZoneInfo.java} (70%) rename gcloud-java-dns/src/test/java/com/google/gcloud/dns/{ManagedZoneInfoTest.java => ZoneInfoTest.java} (72%) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java index 5ed03b1ea071..582dd2b2e05b 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java @@ -34,7 +34,7 @@ /** * A class representing an atomic update to a collection of {@link DnsRecord}s within a {@code - * ManagedZone}. + * Zone}. * * @see Google Cloud DNS documentation */ @@ -102,7 +102,7 @@ public Builder additions(List additions) { this.additions = Lists.newLinkedList(checkNotNull(additions)); return this; } - + /** * Sets a collection of {@link DnsRecord}s which are to be deleted from the zone upon executing * this {@code ChangeRequest}. diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java index 4236d9c1c561..b9e8134d9921 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java @@ -33,8 +33,8 @@ * *

A {@code DnsRecord} is the unit of data that will be returned by the DNS servers upon a DNS * request for a specific domain. The {@code DnsRecord} holds the current state of the DNS records - * that make up a managed zone. You can read the records but you cannot modify them directly. - * Rather, you edit the records in a managed zone by creating a ChangeRequest. + * that make up a zone. You can read the records but you cannot modify them directly. + * Rather, you edit the records in a zone by creating a ChangeRequest. * * @see Google Cloud DNS * documentation diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java index e65524913920..b7933956ed88 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java @@ -26,7 +26,7 @@ /** * The class provides the Google Cloud DNS information associated with this project. A project is a - * top level container for resources including {@code ManagedZone}s. Projects can be created only in + * top level container for resources including {@code Zone}s. Projects can be created only in * the APIs console. * * @see Google Cloud DNS documentation @@ -75,7 +75,7 @@ public static class Quota { } /** - * Returns the maximum allowed number of managed zones in the project. + * Returns the maximum allowed number of zones in the project. */ public int zones() { return zones; @@ -104,7 +104,7 @@ public int rrsetDeletionsPerChange() { } /** - * Returns the maximum allowed number of {@link DnsRecord}s per {@link ManagedZoneInfo} in the + * Returns the maximum allowed number of {@link DnsRecord}s per {@link ZoneInfo} in the * project. */ public int rrsetsPerManagedZone() { diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java similarity index 70% rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java rename to gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java index d27e134ad908..3e8afd9a30f9 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java @@ -32,12 +32,12 @@ import java.util.Objects; /** - * A {@code ManagedZone} represents a DNS zone hosted by the Google Cloud DNS service. A zone is a - * subtree of the DNS namespace under one administrative responsibility. See Google Cloud DNS documentation for * more information. */ -public class ManagedZoneInfo implements Serializable { +public class ZoneInfo implements Serializable { private static final long serialVersionUID = 201601191647L; private final String name; @@ -49,7 +49,7 @@ public class ManagedZoneInfo implements Serializable { private final List nameServers; /** - * A builder for {@code ManagedZoneInfo}. + * A builder for {@code ZoneInfo}. */ public static class Builder { private String name; @@ -61,8 +61,7 @@ public static class Builder { private List nameServers = new LinkedList<>(); /** - * Returns an empty builder for {@code ManagedZoneInfo}. We use it internally in {@code - * toPb()}. + * Returns an empty builder for {@code ZoneInfo}. We use it internally in {@code toPb()}. */ private Builder() { } @@ -81,9 +80,9 @@ private Builder(String name, BigInteger id) { } /** - * Creates a builder from an existing ManagedZoneInfo object. + * Creates a builder from an existing ZoneInfo object. */ - Builder(ManagedZoneInfo info) { + Builder(ZoneInfo info) { this.name = info.name; this.id = info.id; this.creationTimeMillis = info.creationTimeMillis; @@ -102,7 +101,7 @@ public Builder name(String name) { } /** - * Sets an id for the managed zone which is assigned to the managed zone by the server. + * Sets an id for the zone which is assigned to the zone by the server. */ Builder id(BigInteger id) { this.id = id; @@ -110,7 +109,7 @@ Builder id(BigInteger id) { } /** - * Sets the time when this managed zone was created. + * Sets the time when this zone was created. */ Builder creationTimeMillis(long creationTimeMillis) { this.creationTimeMillis = creationTimeMillis; @@ -118,7 +117,7 @@ Builder creationTimeMillis(long creationTimeMillis) { } /** - * Sets a mandatory DNS name of this managed zone, for instance "example.com.". + * Sets a mandatory DNS name of this zone, for instance "example.com.". */ public Builder dnsName(String dnsName) { this.dnsName = checkNotNull(dnsName); @@ -126,8 +125,8 @@ public Builder dnsName(String dnsName) { } /** - * Sets a mandatory description for this managed zone. The value is a string of at most 1024 - * characters which has no effect on the managed zone's function. + * Sets a mandatory description for this zone. The value is a string of at most 1024 characters + * which has no effect on the zone's function. */ public Builder description(String description) { this.description = checkNotNull(description); @@ -135,9 +134,8 @@ public Builder description(String description) { } /** - * Optionally specifies the NameServerSet for this managed zone. A NameServerSet is a set of DNS - * name servers that all host the same ManagedZones. Most users will not need to specify this - * value. + * Optionally specifies the NameServerSet for this zone. A NameServerSet is a set of DNS name + * servers that all host the same zones. Most users will not need to specify this value. */ public Builder nameServerSet(String nameServerSet) { // todo(mderka) add more to the doc when questions are answered by the service owner @@ -146,8 +144,8 @@ public Builder nameServerSet(String nameServerSet) { } /** - * Sets a list of servers that hold the information about the managed zone. This information is - * provided by Google Cloud DNS and is read only. + * Sets a list of servers that hold the information about the zone. This information is provided + * by Google Cloud DNS and is read only. */ Builder nameServers(List nameServers) { checkNotNull(nameServers); @@ -156,14 +154,14 @@ Builder nameServers(List nameServers) { } /** - * Builds the instance of {@code ManagedZoneInfo} based on the information set by this builder. + * Builds the instance of {@code ZoneInfo} based on the information set by this builder. */ - public ManagedZoneInfo build() { - return new ManagedZoneInfo(this); + public ZoneInfo build() { + return new ZoneInfo(this); } } - private ManagedZoneInfo(Builder builder) { + private ZoneInfo(Builder builder) { this.name = builder.name; this.id = builder.id; this.creationTimeMillis = builder.creationTimeMillis; @@ -174,63 +172,63 @@ private ManagedZoneInfo(Builder builder) { } /** - * Returns a builder for {@code ManagedZoneInfo} with an assigned {@code name}. + * Returns a builder for {@code ZoneInfo} with an assigned {@code name}. */ public static Builder builder(String name) { return new Builder(name); } /** - * Returns a builder for {@code ManagedZoneInfo} with an assigned {@code id}. + * Returns a builder for {@code ZoneInfo} with an assigned {@code id}. */ public static Builder builder(BigInteger id) { return new Builder(id); } /** - * Returns a builder for {@code ManagedZoneInfo} with an assigned {@code name} and {@code id}. + * Returns a builder for {@code ZoneInfo} with an assigned {@code name} and {@code id}. */ public static Builder builder(String name, BigInteger id) { return new Builder(name, id); } /** - * Returns the user-defined name of the managed zone. + * Returns the user-defined name of the zone. */ public String name() { return name; } /** - * Returns the read-only managed zone id assigned by the server. + * Returns the read-only zone id assigned by the server. */ public BigInteger id() { return id; } /** - * Returns the time when this time that this managed zone was created on the server. + * Returns the time when this time that this zone was created on the server. */ public Long creationTimeMillis() { return creationTimeMillis; } /** - * Returns the DNS name of this managed zone, for instance "example.com.". + * Returns the DNS name of this zone, for instance "example.com.". */ public String dnsName() { return dnsName; } /** - * Returns the description of this managed zone. + * Returns the description of this zone. */ public String description() { return description; } /** - * Returns the optionally specified set of DNS name servers that all host this managed zone. + * Returns the optionally specified set of DNS name servers that all host this zone. */ public String nameServerSet() { // todo(mderka) update this doc after finding out more about this from the service owners @@ -238,16 +236,14 @@ public String nameServerSet() { } /** - * The nameservers that the managed zone should be delegated to. This is defined by the Google DNS - * cloud. + * The nameservers that the zone should be delegated to. This is defined by the Google DNS cloud. */ public List nameServers() { return nameServers; } /** - * Returns a builder for {@code ManagedZoneInfo} prepopulated with the metadata of this managed - * zone. + * Returns a builder for {@code ZoneInfo} prepopulated with the metadata of this zone. */ public Builder toBuilder() { return new Builder(this); @@ -272,35 +268,35 @@ com.google.api.services.dns.model.ManagedZone toPb() { return pb; } - static ManagedZoneInfo fromPb(com.google.api.services.dns.model.ManagedZone pb) { - Builder b = new Builder(); + static ZoneInfo fromPb(com.google.api.services.dns.model.ManagedZone pb) { + Builder builder = new Builder(); if (pb.getDescription() != null) { - b.description(pb.getDescription()); + builder.description(pb.getDescription()); } if (pb.getDnsName() != null) { - b.dnsName(pb.getDnsName()); + builder.dnsName(pb.getDnsName()); } if (pb.getId() != null) { - b.id(pb.getId()); + builder.id(pb.getId()); } if (pb.getName() != null) { - b.name(pb.getName()); + builder.name(pb.getName()); } if (pb.getNameServers() != null) { - b.nameServers(pb.getNameServers()); + builder.nameServers(pb.getNameServers()); } if (pb.getNameServerSet() != null) { - b.nameServerSet(pb.getNameServerSet()); + builder.nameServerSet(pb.getNameServerSet()); } if (pb.getCreationTime() != null) { - b.creationTimeMillis(DateTime.parse(pb.getCreationTime()).getMillis()); + builder.creationTimeMillis(DateTime.parse(pb.getCreationTime()).getMillis()); } - return b.build(); + return builder.build(); } @Override public boolean equals(Object obj) { - return obj instanceof ManagedZoneInfo && Objects.equals(toPb(), ((ManagedZoneInfo) obj).toPb()); + return obj instanceof ZoneInfo && Objects.equals(toPb(), ((ZoneInfo) obj).toPb()); } @Override diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ManagedZoneInfoTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java similarity index 72% rename from gcloud-java-dns/src/test/java/com/google/gcloud/dns/ManagedZoneInfoTest.java rename to gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java index 936164c81723..2c9fea8f7bde 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ManagedZoneInfoTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java @@ -30,7 +30,7 @@ import java.util.LinkedList; import java.util.List; -public class ManagedZoneInfoTest { +public class ZoneInfoTest { private static final String NAME = "mz-example.com"; private static final BigInteger ID = BigInteger.valueOf(123L); @@ -42,7 +42,7 @@ public class ManagedZoneInfoTest { private static final String NS2 = "name server 2"; private static final String NS3 = "name server 3"; private static final List NAME_SERVERS = ImmutableList.of(NS1, NS2, NS3); - private static final ManagedZoneInfo INFO = ManagedZoneInfo.builder(NAME, ID) + private static final ZoneInfo INFO = ZoneInfo.builder(NAME, ID) .creationTimeMillis(CREATION_TIME_MILLIS) .dnsName(DNS_NAME) .description(DESCRIPTION) @@ -52,7 +52,7 @@ public class ManagedZoneInfoTest { @Test public void testDefaultBuilders() { - ManagedZoneInfo withName = ManagedZoneInfo.builder(NAME).build(); + ZoneInfo withName = ZoneInfo.builder(NAME).build(); assertTrue(withName.nameServers().isEmpty()); assertEquals(NAME, withName.name()); assertNull(withName.id()); @@ -60,7 +60,7 @@ public void testDefaultBuilders() { assertNull(withName.nameServerSet()); assertNull(withName.description()); assertNull(withName.dnsName()); - ManagedZoneInfo withId = ManagedZoneInfo.builder(ID).build(); + ZoneInfo withId = ZoneInfo.builder(ID).build(); assertTrue(withId.nameServers().isEmpty()); assertEquals(ID, withId.id()); assertNull(withId.name()); @@ -68,7 +68,7 @@ public void testDefaultBuilders() { assertNull(withId.nameServerSet()); assertNull(withId.description()); assertNull(withId.dnsName()); - ManagedZoneInfo withBoth = ManagedZoneInfo.builder(NAME, ID).build(); + ZoneInfo withBoth = ZoneInfo.builder(NAME, ID).build(); assertTrue(withBoth.nameServers().isEmpty()); assertEquals(ID, withBoth.id()); assertEquals(NAME, withBoth.name()); @@ -94,7 +94,7 @@ public void testBuilder() { @Test public void testEqualsAndNotEquals() { - ManagedZoneInfo clone = INFO.toBuilder().build(); + ZoneInfo clone = INFO.toBuilder().build(); assertEquals(INFO, clone); List moreServers = Lists.newLinkedList(NAME_SERVERS); moreServers.add(NS1); @@ -118,55 +118,55 @@ public void testEqualsAndNotEquals() { @Test public void testSameHashCodeOnEquals() { int hash = INFO.hashCode(); - ManagedZoneInfo clone = INFO.toBuilder().build(); + ZoneInfo clone = INFO.toBuilder().build(); assertEquals(clone.hashCode(), hash); } @Test public void testToBuilder() { assertEquals(INFO, INFO.toBuilder().build()); - ManagedZoneInfo partial = ManagedZoneInfo.builder(NAME).build(); + ZoneInfo partial = ZoneInfo.builder(NAME).build(); assertEquals(partial, partial.toBuilder().build()); - partial = ManagedZoneInfo.builder(ID).build(); + partial = ZoneInfo.builder(ID).build(); assertEquals(partial, partial.toBuilder().build()); - partial = ManagedZoneInfo.builder(NAME).description(DESCRIPTION).build(); + partial = ZoneInfo.builder(NAME).description(DESCRIPTION).build(); assertEquals(partial, partial.toBuilder().build()); - partial = ManagedZoneInfo.builder(NAME).dnsName(DNS_NAME).build(); + partial = ZoneInfo.builder(NAME).dnsName(DNS_NAME).build(); assertEquals(partial, partial.toBuilder().build()); - partial = ManagedZoneInfo.builder(NAME).creationTimeMillis(CREATION_TIME_MILLIS).build(); + partial = ZoneInfo.builder(NAME).creationTimeMillis(CREATION_TIME_MILLIS).build(); assertEquals(partial, partial.toBuilder().build()); List nameServers = new LinkedList<>(); nameServers.add(NS1); - partial = ManagedZoneInfo.builder(NAME).nameServers(nameServers).build(); + partial = ZoneInfo.builder(NAME).nameServers(nameServers).build(); assertEquals(partial, partial.toBuilder().build()); - partial = ManagedZoneInfo.builder(NAME).nameServerSet(NAME_SERVER_SET).build(); + partial = ZoneInfo.builder(NAME).nameServerSet(NAME_SERVER_SET).build(); assertEquals(partial, partial.toBuilder().build()); } @Test public void testToAndFromPb() { - assertEquals(INFO, ManagedZoneInfo.fromPb(INFO.toPb())); - ManagedZoneInfo partial = ManagedZoneInfo.builder(NAME).build(); - assertEquals(partial, ManagedZoneInfo.fromPb(partial.toPb())); - partial = ManagedZoneInfo.builder(ID).build(); - assertEquals(partial, ManagedZoneInfo.fromPb(partial.toPb())); - partial = ManagedZoneInfo.builder(NAME).description(DESCRIPTION).build(); - assertEquals(partial, ManagedZoneInfo.fromPb(partial.toPb())); - partial = ManagedZoneInfo.builder(NAME).dnsName(DNS_NAME).build(); - assertEquals(partial, ManagedZoneInfo.fromPb(partial.toPb())); - partial = ManagedZoneInfo.builder(NAME).creationTimeMillis(CREATION_TIME_MILLIS).build(); - assertEquals(partial, ManagedZoneInfo.fromPb(partial.toPb())); + assertEquals(INFO, ZoneInfo.fromPb(INFO.toPb())); + ZoneInfo partial = ZoneInfo.builder(NAME).build(); + assertEquals(partial, ZoneInfo.fromPb(partial.toPb())); + partial = ZoneInfo.builder(ID).build(); + assertEquals(partial, ZoneInfo.fromPb(partial.toPb())); + partial = ZoneInfo.builder(NAME).description(DESCRIPTION).build(); + assertEquals(partial, ZoneInfo.fromPb(partial.toPb())); + partial = ZoneInfo.builder(NAME).dnsName(DNS_NAME).build(); + assertEquals(partial, ZoneInfo.fromPb(partial.toPb())); + partial = ZoneInfo.builder(NAME).creationTimeMillis(CREATION_TIME_MILLIS).build(); + assertEquals(partial, ZoneInfo.fromPb(partial.toPb())); List nameServers = new LinkedList<>(); nameServers.add(NS1); - partial = ManagedZoneInfo.builder(NAME).nameServers(nameServers).build(); - assertEquals(partial, ManagedZoneInfo.fromPb(partial.toPb())); - partial = ManagedZoneInfo.builder(NAME).nameServerSet(NAME_SERVER_SET).build(); - assertEquals(partial, ManagedZoneInfo.fromPb(partial.toPb())); + partial = ZoneInfo.builder(NAME).nameServers(nameServers).build(); + assertEquals(partial, ZoneInfo.fromPb(partial.toPb())); + partial = ZoneInfo.builder(NAME).nameServerSet(NAME_SERVER_SET).build(); + assertEquals(partial, ZoneInfo.fromPb(partial.toPb())); } @Test public void testEmptyNameServers() { - ManagedZoneInfo clone = INFO.toBuilder().nameServers(new LinkedList()).build(); + ZoneInfo clone = INFO.toBuilder().nameServers(new LinkedList()).build(); assertTrue(clone.nameServers().isEmpty()); clone.toPb(); // test that this is allowed } @@ -175,7 +175,7 @@ public void testEmptyNameServers() { public void testDateParsing() { com.google.api.services.dns.model.ManagedZone pb = INFO.toPb(); pb.setCreationTime("2016-01-19T18:00:12.854Z"); // a real value obtained from Google Cloud DNS - ManagedZoneInfo mz = ManagedZoneInfo.fromPb(pb); // parses the string timestamp to millis + ZoneInfo mz = ZoneInfo.fromPb(pb); // parses the string timestamp to millis com.google.api.services.dns.model.ManagedZone pbClone = mz.toPb(); // converts it back to string assertEquals(pb, pbClone); assertEquals(pb.getCreationTime(), pbClone.getCreationTime()); From c364ff322187be6404c1a9cd0e1673b8f64a7c35 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Thu, 28 Jan 2016 09:30:55 -0800 Subject: [PATCH 042/375] Modified ttl to accept time unit. Fixed #581. --- .../java/com/google/gcloud/dns/DnsRecord.java | 30 +++++++++----- .../com/google/gcloud/dns/DnsRecordTest.java | 39 ++++++++++++------- 2 files changed, 46 insertions(+), 23 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java index b9e8134d9921..a3a673b99cc6 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java @@ -27,14 +27,15 @@ import java.util.LinkedList; import java.util.List; import java.util.Objects; +import java.util.concurrent.TimeUnit; /** * A class that represents a Google Cloud DNS record set. * *

A {@code DnsRecord} is the unit of data that will be returned by the DNS servers upon a DNS * request for a specific domain. The {@code DnsRecord} holds the current state of the DNS records - * that make up a zone. You can read the records but you cannot modify them directly. - * Rather, you edit the records in a zone by creating a ChangeRequest. + * that make up a zone. You can read the records but you cannot modify them directly. Rather, you + * edit the records in a zone by creating a ChangeRequest. * * @see Google Cloud DNS * documentation @@ -44,7 +45,7 @@ public class DnsRecord implements Serializable { private static final long serialVersionUID = 2016011914302204L; private final String name; private final List rrdatas; - private final Integer ttl; + private final Integer ttl; // this is in seconds private final Type type; /** @@ -176,14 +177,23 @@ public Builder name(String name) { } /** - * Sets the number of seconds that this record can be cached by resolvers. This number must be - * non-negative. + * Sets the time that this record can be cached by resolvers. This number must be non-negative. + * The maximum duration must be equivalent to at most {@link Integer#MAX_VALUE} seconds. * - * @param ttl A non-negative number of seconds + * @param duration A non-negative number of time units + * @param unit The unit of the ttl parameter */ - public Builder ttl(int ttl) { - checkArgument(ttl >= 0, "TTL cannot be negative. The supplied value was %s.", ttl); - this.ttl = ttl; + public Builder ttl(int duration, TimeUnit unit) { + checkArgument(duration >= 0, + "Duration cannot be negative. The supplied value was %s.", duration); + checkNotNull(unit); + // convert to seconds and check that we are not overflowing int + // we cannot do that because pb does not support it + long converted = unit.toSeconds(duration); + checkArgument(converted <= Integer.MAX_VALUE, + "The duration converted to seconds is out of range of int. The value converts to %s sec.", + converted); + ttl = (int) converted; return this; } @@ -278,7 +288,7 @@ static DnsRecord fromPb(com.google.api.services.dns.model.ResourceRecordSet pb) builder.records(pb.getRrdatas()); } if (pb.getTtl() != null) { - builder.ttl(pb.getTtl()); + builder.ttl(pb.getTtl(), TimeUnit.SECONDS); } return builder.build(); } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java index 7a7daf8aac3c..5fc972cede78 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java @@ -16,6 +16,7 @@ package com.google.gcloud.dns; +import static com.google.gcloud.dns.DnsRecord.builder; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; @@ -23,18 +24,22 @@ import org.junit.Test; +import java.util.concurrent.TimeUnit; + public class DnsRecordTest { private static final String NAME = "example.com."; private static final Integer TTL = 3600; + private static final TimeUnit UNIT = TimeUnit.HOURS; + private static final Integer UNIT_TTL = 1; private static final DnsRecord.Type TYPE = DnsRecord.Type.AAAA; - private static final DnsRecord record = DnsRecord.builder(NAME, TYPE) - .ttl(TTL) + private static final DnsRecord record = builder(NAME, TYPE) + .ttl(UNIT_TTL, UNIT) .build(); @Test public void testDefaultDnsRecord() { - DnsRecord record = DnsRecord.builder(NAME, TYPE).build(); + DnsRecord record = builder(NAME, TYPE).build(); assertEquals(0, record.records().size()); assertEquals(TYPE, record.type()); assertEquals(NAME, record.name()); @@ -61,13 +66,21 @@ public void testBuilder() { @Test public void testValidTtl() { try { - DnsRecord.builder(NAME, TYPE).ttl(-1); + builder(NAME, TYPE).ttl(-1, TimeUnit.SECONDS); fail("A negative value is not acceptable for ttl."); } catch (IllegalArgumentException e) { // expected } - DnsRecord.builder(NAME, TYPE).ttl(0); - DnsRecord.builder(NAME, TYPE).ttl(Integer.MAX_VALUE); + builder(NAME, TYPE).ttl(0, TimeUnit.SECONDS); + builder(NAME, TYPE).ttl(Integer.MAX_VALUE, TimeUnit.SECONDS); + try { + builder(NAME, TYPE).ttl(Integer.MAX_VALUE, TimeUnit.HOURS); + fail("This value is too large for int."); + } catch (IllegalArgumentException e) { + // expected + } + DnsRecord record = DnsRecord.builder(NAME, TYPE).ttl(UNIT_TTL, UNIT).build(); + assertEquals(TTL, record.ttl()); } @Test @@ -79,7 +92,7 @@ public void testEqualsAndNotEquals() { String differentName = "totally different name"; clone = record.toBuilder().name(differentName).build(); assertNotEquals(record, clone); - clone = record.toBuilder().ttl(record.ttl() + 1).build(); + clone = record.toBuilder().ttl(record.ttl() + 1, TimeUnit.SECONDS).build(); assertNotEquals(record, clone); clone = record.toBuilder().type(DnsRecord.Type.TXT).build(); assertNotEquals(record, clone); @@ -95,22 +108,22 @@ public void testSameHashCodeOnEquals() { @Test public void testToAndFromPb() { assertEquals(record, DnsRecord.fromPb(record.toPb())); - DnsRecord partial = DnsRecord.builder(NAME, TYPE).build(); + DnsRecord partial = builder(NAME, TYPE).build(); assertEquals(partial, DnsRecord.fromPb(partial.toPb())); - partial = DnsRecord.builder(NAME, TYPE).addRecord("test").build(); + partial = builder(NAME, TYPE).addRecord("test").build(); assertEquals(partial, DnsRecord.fromPb(partial.toPb())); - partial = DnsRecord.builder(NAME, TYPE).ttl(15).build(); + partial = builder(NAME, TYPE).ttl(15, TimeUnit.SECONDS).build(); assertEquals(partial, DnsRecord.fromPb(partial.toPb())); } @Test public void testToBuilder() { assertEquals(record, record.toBuilder().build()); - DnsRecord partial = DnsRecord.builder(NAME, TYPE).build(); + DnsRecord partial = builder(NAME, TYPE).build(); assertEquals(partial, partial.toBuilder().build()); - partial = DnsRecord.builder(NAME, TYPE).addRecord("test").build(); + partial = builder(NAME, TYPE).addRecord("test").build(); assertEquals(partial, partial.toBuilder().build()); - partial = DnsRecord.builder(NAME, TYPE).ttl(15).build(); + partial = builder(NAME, TYPE).ttl(15, TimeUnit.SECONDS).build(); assertEquals(partial, partial.toBuilder().build()); } From 7bcff48454c09e73ab94b1b995563e390200d081 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Thu, 28 Jan 2016 10:27:21 -0800 Subject: [PATCH 043/375] Implemented comments by @aozarov. --- .../java/com/google/gcloud/dns/DnsRecord.java | 9 +++------ .../java/com/google/gcloud/dns/ProjectInfo.java | 16 ++++++++-------- .../java/com/google/gcloud/dns/ZoneInfo.java | 2 +- .../com/google/gcloud/dns/ProjectInfoTest.java | 8 ++++---- 4 files changed, 16 insertions(+), 19 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java index a3a673b99cc6..99ca20386419 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java @@ -22,6 +22,7 @@ import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; +import com.google.common.primitives.Ints; import java.io.Serializable; import java.util.LinkedList; @@ -187,13 +188,9 @@ public Builder ttl(int duration, TimeUnit unit) { checkArgument(duration >= 0, "Duration cannot be negative. The supplied value was %s.", duration); checkNotNull(unit); - // convert to seconds and check that we are not overflowing int - // we cannot do that because pb does not support it + // we cannot have long because pb does not support it long converted = unit.toSeconds(duration); - checkArgument(converted <= Integer.MAX_VALUE, - "The duration converted to seconds is out of range of int. The value converts to %s sec.", - converted); - ttl = (int) converted; + ttl = Ints.checkedCast(converted); return this; } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java index b7933956ed88..4db0497946b1 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java @@ -50,7 +50,7 @@ public static class Quota { private final int resourceRecordsPerRrset; private final int rrsetAdditionsPerChange; private final int rrsetDeletionsPerChange; - private final int rrsetsPerManagedZone; + private final int rrsetsPerZone; private final int totalRrdataSizePerChange; /** @@ -64,13 +64,13 @@ public static class Quota { int resourceRecordsPerRrset, int rrsetAdditionsPerChange, int rrsetDeletionsPerChange, - int rrsetsPerManagedZone, + int rrsetsPerZone, int totalRrdataSizePerChange) { this.zones = zones; this.resourceRecordsPerRrset = resourceRecordsPerRrset; this.rrsetAdditionsPerChange = rrsetAdditionsPerChange; this.rrsetDeletionsPerChange = rrsetDeletionsPerChange; - this.rrsetsPerManagedZone = rrsetsPerManagedZone; + this.rrsetsPerZone = rrsetsPerZone; this.totalRrdataSizePerChange = totalRrdataSizePerChange; } @@ -107,8 +107,8 @@ public int rrsetDeletionsPerChange() { * Returns the maximum allowed number of {@link DnsRecord}s per {@link ZoneInfo} in the * project. */ - public int rrsetsPerManagedZone() { - return rrsetsPerManagedZone; + public int rrsetsPerZone() { + return rrsetsPerZone; } /** @@ -126,7 +126,7 @@ public boolean equals(Object other) { @Override public int hashCode() { return Objects.hash(zones, resourceRecordsPerRrset, rrsetAdditionsPerChange, - rrsetDeletionsPerChange, rrsetsPerManagedZone, totalRrdataSizePerChange); + rrsetDeletionsPerChange, rrsetsPerZone, totalRrdataSizePerChange); } com.google.api.services.dns.model.Quota toPb() { @@ -135,7 +135,7 @@ com.google.api.services.dns.model.Quota toPb() { pb.setResourceRecordsPerRrset(resourceRecordsPerRrset); pb.setRrsetAdditionsPerChange(rrsetAdditionsPerChange); pb.setRrsetDeletionsPerChange(rrsetDeletionsPerChange); - pb.setRrsetsPerManagedZone(rrsetsPerManagedZone); + pb.setRrsetsPerManagedZone(rrsetsPerZone); pb.setTotalRrdataSizePerChange(totalRrdataSizePerChange); return pb; } @@ -158,7 +158,7 @@ public String toString() { .add("resourceRecordsPerRrset", resourceRecordsPerRrset) .add("rrsetAdditionsPerChange", rrsetAdditionsPerChange) .add("rrsetDeletionsPerChange", rrsetDeletionsPerChange) - .add("rrsetsPerManagedZone", rrsetsPerManagedZone) + .add("rrsetsPerZone", rrsetsPerZone) .add("totalRrdataSizePerChange", totalRrdataSizePerChange) .toString(); } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java index 3e8afd9a30f9..524309eaa8e9 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java @@ -207,7 +207,7 @@ public BigInteger id() { } /** - * Returns the time when this time that this zone was created on the server. + * Returns the time when this zone was created on the server. */ public Long creationTimeMillis() { return creationTimeMillis; diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ProjectInfoTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ProjectInfoTest.java index 2af8b5ad3995..d959d44d4351 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ProjectInfoTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ProjectInfoTest.java @@ -57,7 +57,7 @@ public void testQuotaConstructor() { assertEquals(2, QUOTA.resourceRecordsPerRrset()); assertEquals(3, QUOTA.rrsetAdditionsPerChange()); assertEquals(4, QUOTA.rrsetDeletionsPerChange()); - assertEquals(5, QUOTA.rrsetsPerManagedZone()); + assertEquals(5, QUOTA.rrsetsPerZone()); assertEquals(6, QUOTA.totalRrdataSizePerChange()); } @@ -101,11 +101,11 @@ public void testSameHashCodeOnEquals() { public void testToAndFromPb() { assertEquals(PROJECT_INFO, ProjectInfo.fromPb(PROJECT_INFO.toPb())); ProjectInfo partial = ProjectInfo.builder().id(ID).build(); - assertEquals(partial, PROJECT_INFO.fromPb(partial.toPb())); + assertEquals(partial, ProjectInfo.fromPb(partial.toPb())); partial = ProjectInfo.builder().number(NUMBER).build(); - assertEquals(partial, PROJECT_INFO.fromPb(partial.toPb())); + assertEquals(partial, ProjectInfo.fromPb(partial.toPb())); partial = ProjectInfo.builder().quota(QUOTA).build(); - assertEquals(partial, PROJECT_INFO.fromPb(partial.toPb())); + assertEquals(partial, ProjectInfo.fromPb(partial.toPb())); assertNotEquals(PROJECT_INFO, partial); } From f9b6f6a4762484da32ceee58e5281f1d615a1a12 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Thu, 28 Jan 2016 15:55:06 -0800 Subject: [PATCH 044/375] Added DnsService interface. --- .../com/google/gcloud/dns/DnsService.java | 507 ++++++++++++++++++ 1 file changed, 507 insertions(+) create mode 100644 gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsService.java diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsService.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsService.java new file mode 100644 index 000000000000..694b0b288154 --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsService.java @@ -0,0 +1,507 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.dns; + +import com.google.common.base.Joiner; +import com.google.common.collect.Sets; +import com.google.gcloud.spi.DnsServiceRpc; + +import java.io.Serializable; +import java.util.Set; + +/** + * An interface for the Google Cloud DNS service. + * + * @see Google Cloud DNS + */ +public interface DnsService extends Service { + + /** + * The fields of a project. + * + *

These values can be used to specify the fields to include in a partial response when calling + * {@code DnsService#getProjectInfo(ProjectOptions...)}. Project ID is always returned, even if + * not specified. + */ + enum ProjectField { + PROJECT_ID("id"), + PROJECT_NUMBER("number"), + QUOTA("quota"); + + private final String selector; + + ProjectField(String selector) { + this.selector = selector; + } + + public String selector() { + return selector; + } + + static String selector(ProjectField... fields) { + Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); + fieldStrings.add(PROJECT_ID.selector()); + for (ProjectField field : fields) { + fieldStrings.add(field.selector()); + } + return Joiner.on(',').join(fieldStrings); + } + } + + /** + * The fields of a zone. + * + *

These values can be used to specify the fields to include in a partial response when calling + * {@code DnsService#getZone(BigInteger, ZoneFieldOptions...)} or {@code + * DnsService#getZone(String, ZoneFieldOptions...)}. The ID is always returned, even if not + * specified. + */ + enum ZoneField { + CREATION_TIME("creationTime"), + DESCRIPTION("description"), + DNS_NAME("dnsName"), + ZONE_ID("id"), + NAME("name"), + NAME_SERVER_SET("nameServerSet"), + NAME_SERVERS("nameServers"); + + private final String selector; + + ZoneField(String selector) { + this.selector = selector; + } + + public String selector() { + return selector; + } + + static String selector(ZoneField... fields) { + Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); + fieldStrings.add(ZONE_ID.selector()); + for (ZoneField field : fields) { + fieldStrings.add(field.selector()); + } + return Joiner.on(',').join(fieldStrings); + } + } + + /** + * The fields of a DNS record. + * + *

These values can be used to specify the fields to include in a partial response when calling + * {@code DnsService#listDnsRecords(BigInteger, DnsRecordOptions...)} or {@code + * DnsService#listDnsRecords(String, DnsRecordOptions...)}. The name is always returned even if + * not selected. + */ + enum DnsRecordField { + DNS_RECORDS("rrdatas"), + NAME("name"), + TTL("ttl"), + TYPE("type"); + + private final String selector; + + DnsRecordField(String selector) { + this.selector = selector; + } + + public String selector() { + return selector; + } + + static String selector(DnsRecordField... fields) { + Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); + fieldStrings.add(NAME.selector()); + for (DnsRecordField field : fields) { + fieldStrings.add(field.selector()); + } + return Joiner.on(',').join(fieldStrings); + } + } + + /** + * The fields of a change request. + * + *

These values can be used to specify the fields to include in a partial response when calling + * {@code DnsService#applyChangeRequest(ChangeRequest, BigInteger, ChangeRequestFieldOptions...)} + * or {@code DnsService#applyChangeRequest(ChangeRequest, String, ChangeRequestFieldOptions...)} + * The ID is always returned even if not selected. + */ + enum ChangeRequestField { + ID("id"), + START_TIME("startTime"), + STATUS("status"), + ADDITIONS("additions"), + DELETIONS("deletions"); + + private final String selector; + + ChangeRequestField(String selector) { + this.selector = selector; + } + + public String selector() { + return selector; + } + + static String selector(ChangeRequestField... fields) { + Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); + fieldStrings.add(ID.selector()); + for (ChangeRequestField field : fields) { + fieldStrings.add(field.selector()); + } + return Joiner.on(',').join(fieldStrings); + } + } + + /** + * The sorting keys for listing change requests. The only currently supported sorting key is the + * change sequence. + */ + enum ChangeRequestSortingKey { + CHANGE_SEQUENCE("changeSequence"); + + private final String selector; + + ChangeRequestSortingKey(String selector) { + this.selector = selector; + } + + public String selector() { + return selector; + } + } + + /** + * The sorting order for listing change requests. + */ + enum ChangeRequestSortingOrder { + DESCENDING, ASCENDING; + + public String selector() { + return this.name().toLowerCase(); + } + } + + /** + * Class that for specifying DNS record options. + */ + class DnsRecordOptions extends AbstractOption implements Serializable { + + private static final long serialVersionUID = 201601261646L; + + DnsRecordOptions(DnsServiceRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify the DNS record's fields to be returned by the RPC call. + * + *

If this option is not provided all record fields are returned. {@code + * DnsRecordField.fields} can be used to specify only the fields of interest. The name of the + * DNS record always returned, even if not specified. {@link DnsRecordField} provides a list of + * fields that can be used. + */ + public static DnsRecordOptions fields(DnsRecordField... fields) { + StringBuilder builder = new StringBuilder(); + builder.append("rrsets(").append(DnsRecordField.selector(fields)).append(")"); + return new DnsRecordOptions(DnsServiceRpc.Option.FIELDS, builder.toString()); + } + + /** + * Returns an option to specify a page token. + * + *

The page token (returned from a previous call to list) indicates from where listing should + * continue. + */ + public static DnsRecordOptions pageToken(String pageToken) { + return new DnsRecordOptions(DnsServiceRpc.Option.PAGE_TOKEN, pageToken); + } + + /** + * The maximum number of DNS records to return per RPC. + * + *

The server can return fewer records than requested. When there are more results than the + * page size, the server will return a page token that can be used to fetch other results. + */ + public static DnsRecordOptions pageSize(int pageSize) { + return new DnsRecordOptions(DnsServiceRpc.Option.PAGE_SIZE, pageSize); + } + + /** + * Restricts the list to return only zones with this fully qualified domain name. + */ + public static DnsRecordOptions dnsName(String dnsName) { + return new DnsRecordOptions(DnsServiceRpc.Option.DNS_NAME, dnsName); + } + } + + /** + * Class for specifying zone field options. + */ + class ZoneFieldOptions extends AbstractOption implements Serializable { + + private static final long serialVersionUID = -7294186261285469986L; + + ZoneFieldOptions(DnsServiceRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify the zones's fields to be returned by the RPC call. + * + *

If this option is not provided all zone fields are returned. {@code + * ZoneFieldOptions.fields} can be used to specify only the fields of interest. Zone ID is + * always returned, even if not specified. {@link ZoneField} provides a list of fields that can + * be used. + */ + public static ZoneFieldOptions fields(ZoneField... fields) { + return new ZoneFieldOptions(DnsServiceRpc.Option.FIELDS, ZoneField.selector(fields)); + } + } + + /** + * Class for specifying zone listing options. + */ + class ZoneListOptions extends AbstractOption implements Serializable { + + private static final long serialVersionUID = -7922038132321229290L; + + ZoneListOptions(DnsServiceRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify the zones's fields to be returned by the RPC call. + * + *

If this option is not provided all zone fields are returned. {@code + * ZoneFieldOptions.fields} can be used to specify only the fields of interest. Zone ID is + * always returned, even if not specified. {@link ZoneField} provides a list of fields that can + * be used. + */ + public static ZoneListOptions fields(ZoneField... fields) { + return new ZoneListOptions(DnsServiceRpc.Option.FIELDS, ZoneField.selector(fields)); + } + + /** + * Returns an option to specify a page token. + * + *

The page token (returned from a previous call to list) indicates from where listing should + * continue. + */ + public static ZoneListOptions pageToken(String pageToken) { + return new ZoneListOptions(DnsServiceRpc.Option.PAGE_TOKEN, pageToken); + } + + /** + * The maximum number of zones to return per RPC. + * + *

The server can return fewer zones than requested. When there are more results than the + * page size, the server will return a page token that can be used to fetch other results. + */ + public static ZoneListOptions pageSize(int pageSize) { + return new ZoneListOptions(DnsServiceRpc.Option.PAGE_SIZE, pageSize); + } + + /** + * Restricts the list to return only zones with this fully qualified domain name. + */ + public static ZoneListOptions dnsName(String dnsName) { + return new ZoneListOptions(DnsServiceRpc.Option.DNS_NAME, dnsName); + } + } + + /** + * Class for specifying project options. + */ + class ProjectOptions extends AbstractOption implements Serializable { + + private static final long serialVersionUID = 6817937338218847748L; + + ProjectOptions(DnsServiceRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify the project's fields to be returned by the RPC call. + * + *

If this option is not provided all project fields are returned. {@code + * ProjectOptions.fields} can be used to specify only the fields of interest. Project ID is + * always returned, even if not specified. {@link ProjectField} provides a list of fields that + * can be used. + */ + public static ProjectOptions fields(ProjectField... fields) { + return new ProjectOptions(DnsServiceRpc.Option.FIELDS, ProjectField.selector(fields)); + } + } + + /** + * Class for specifying change request field options. + */ + class ChangeRequestFieldOptions extends AbstractOption implements Serializable { + + private static final long serialVersionUID = 1067273695061077782L; + + ChangeRequestFieldOptions(DnsServiceRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify which fields of DNS records to be added by the {@link + * ChangeRequest} should be returned by the service. + * + *

If this option is not provided, all record fields are returned. {@code + * ChangeRequestFieldOptions.additionsFields} can be used to specify only the fields of + * interest. The name of the DNS record always returned, even if not specified. {@link + * DnsRecordField} provides a list of fields that can be used. + */ + public static ChangeRequestFieldOptions additionsFields(DnsRecordField... fields) { + StringBuilder builder = new StringBuilder(); + builder.append("additions(").append(DnsRecordField.selector(fields)).append(")"); + return new ChangeRequestFieldOptions(DnsServiceRpc.Option.FIELDS, builder.toString()); + } + + /** + * Returns an option to specify which fields of DNS records to be deleted by the {@link + * ChangeRequest} should be returned by the service. + * + *

If this option is not provided, all record fields are returned. {@code + * ChangeRequestFieldOptions.deletionsFields} can be used to specify only the fields of + * interest. The name of the DNS record always returned, even if not specified. {@link + * DnsRecordField} provides a list of fields that can be used. + */ + public static ChangeRequestFieldOptions deletionsFields(DnsRecordField... fields) { + StringBuilder builder = new StringBuilder(); + builder.append("deletions(").append(DnsRecordField.selector(fields)).append(")"); + return new ChangeRequestFieldOptions(DnsServiceRpc.Option.FIELDS, builder.toString()); + + } + + /** + * Returns an option to specify which fields of {@link ChangeRequest} should be returned by the + * service. + * + *

If this option is not provided all change request fields are returned. {@code + * ChangeRequestFieldOptions.fields} can be used to specify only the fields of interest. The ID + * of the change request is always returned, even if not specified. {@link ChangeRequestField} + * provides a list of fields that can be used. + */ + public static ChangeRequestFieldOptions fields(ChangeRequestField... fields) { + return new ChangeRequestFieldOptions( + DnsServiceRpc.Option.FIELDS, + ChangeRequestField.selector(fields) + ); + } + } + + /** + * Class for specifying change request listing options. + */ + class ChangeRequestListOptions extends AbstractOption implements Serializable { + + private static final long serialVersionUID = -900209143895376089L; + + ChangeRequestListOptions(DnsServiceRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify which fields of DNS records to be added by the {@link + * ChangeRequest} should be returned by the service. + * + *

If this option is not provided, all record fields are returned. {@code + * ChangeRequestFieldOptions.additionsFields} can be used to specify only the fields of + * interest. The name of the DNS record always returned, even if not specified. {@link + * DnsRecordField} provides a list of fields that can be used. + */ + public static ChangeRequestListOptions additionsFields(DnsRecordField... fields) { + StringBuilder builder = new StringBuilder(); + builder.append("changes(additions(").append(DnsRecordField.selector(fields)).append("))"); + return new ChangeRequestListOptions(DnsServiceRpc.Option.FIELDS, builder.toString()); + } + + /** + * Returns an option to specify which fields of DNS records to be deleted by the {@link + * ChangeRequest} should be returned by the service. + * + *

If this option is not provided, all record fields are returned. {@code + * ChangeRequestFieldOptions.deletionsFields} can be used to specify only the fields of + * interest. The name of the DNS record always returned, even if not specified. {@link + * DnsRecordField} provides a list of fields that can be used. + */ + public static ChangeRequestListOptions deletionsFields(DnsRecordField... fields) { + StringBuilder builder = new StringBuilder(); + builder.append("changes(deletions(").append(DnsRecordField.selector(fields)).append("))"); + return new ChangeRequestListOptions(DnsServiceRpc.Option.FIELDS, builder.toString()); + } + + /** + * Returns an option to specify which fields of{@link ChangeRequest} should be returned by the + * service. + * + *

If this option is not provided all change request fields are returned. {@code + * ChangeRequestFieldOptions.fields} can be used to specify only the fields of interest. The ID + * of the change request is always returned, even if not specified. {@link ChangeRequestField} + * provides a list of fields that can be used. + */ + public static ChangeRequestListOptions fields(ChangeRequestField... fields) { + return new ChangeRequestListOptions( + DnsServiceRpc.Option.FIELDS, + ChangeRequestField.selector(fields) + ); + } + + /** + * Returns an option to specify a page token. + * + *

The page token (returned from a previous call to list) indicates from where listing should + * continue. + */ + public static ChangeRequestListOptions pageToken(String pageToken) { + return new ChangeRequestListOptions(DnsServiceRpc.Option.PAGE_TOKEN, pageToken); + } + + /** + * The maximum number of change requests to return per RPC. + * + *

The server can return fewer change requests than requested. When there are more results + * than the page size, the server will return a page token that can be used to fetch other + * results. + */ + public static ChangeRequestListOptions pageSize(int pageSize) { + return new ChangeRequestListOptions(DnsServiceRpc.Option.PAGE_SIZE, pageSize); + } + + /** + * Returns an option for specifying the sorting criterion of change requests. Note the the only + * currently supported criterion is the change sequence. + */ + public static ChangeRequestListOptions sortBy(ChangeRequestSortingKey key) { + return new ChangeRequestListOptions(DnsServiceRpc.Option.SORTING_KEY, key.selector()); + } + + /** + * Returns an option to specify whether the the change requests should be listed in ascending or + * descending order. + */ + public static ChangeRequestListOptions sortOrder(ChangeRequestSortingOrder order) { + return new ChangeRequestListOptions(DnsServiceRpc.Option.SORTING_ORDER, order.selector()); + } + } + + // TODO(mderka) Add methods. Created issue #596. +} From 4fdc8ee53b189a137aa990dca366db369e47cf9c Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Thu, 28 Jan 2016 15:57:12 -0800 Subject: [PATCH 045/375] Added AbstractOption. --- .../com/google/gcloud/dns/AbstractOption.java | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 gcloud-java-dns/src/main/java/com/google/gcloud/dns/AbstractOption.java diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/AbstractOption.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/AbstractOption.java new file mode 100644 index 000000000000..6b6fbbf0606e --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/AbstractOption.java @@ -0,0 +1,69 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.dns; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; +import com.google.gcloud.spi.DnsServiceRpc; + +import java.io.Serializable; +import java.util.Objects; + +/** + * A base class for options. + */ +public abstract class AbstractOption implements Serializable { + + private static final long serialVersionUID = 201601261704L; + private final Object value; + private final DnsServiceRpc.Option rpcOption; + + AbstractOption(DnsServiceRpc.Option rpcOption, Object value) { + this.rpcOption = checkNotNull(rpcOption); + this.value = value; + } + + Object value() { + return value; + } + + DnsServiceRpc.Option rpcOption() { + return rpcOption; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof AbstractOption)) { + return false; + } + AbstractOption other = (AbstractOption) obj; + return Objects.equals(value, other.value); + } + + @Override + public int hashCode() { + return Objects.hash(value); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("value", value) + .toString(); + } +} From 06becd885dc0d4c45cd779a06be448b5179e77d1 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Thu, 28 Jan 2016 15:58:13 -0800 Subject: [PATCH 046/375] Added DnsException. --- .../com/google/gcloud/dns/DnsException.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java new file mode 100644 index 000000000000..ab4a3df0f457 --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java @@ -0,0 +1,37 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.dns; + +import com.google.gcloud.BaseServiceException; + +/** + * DNS service exception. + */ +public class DnsException extends BaseServiceException { + + private static final long serialVersionUID = 490302380416260252L; + + public DnsException(int code, String message, boolean retryable) { + super(code, message, retryable); + } + + public DnsException(int code, String message, boolean retryable, Exception cause) { + super(code, message, retryable, cause); + } + + //TODO(mderka) Add translation and retry functionality. Created issue #593. +} From 81cedc4edf78e745817c831c1d7cde7653dfc4f8 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Thu, 28 Jan 2016 16:00:19 -0800 Subject: [PATCH 047/375] Added DnsServiceRpc. --- .../com/google/gcloud/spi/DnsServiceRpc.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsServiceRpc.java diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsServiceRpc.java b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsServiceRpc.java new file mode 100644 index 000000000000..e97ee9a1b001 --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsServiceRpc.java @@ -0,0 +1,56 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.spi; + +import java.util.Map; + +public interface DnsServiceRpc { + + enum Option { + FIELDS("fields"), + PAGE_SIZE("maxSize"), + PAGE_TOKEN("pageToken"), + DNS_NAME("dnsName"), + SORTING_KEY("sortBy"), + SORTING_ORDER("sortOrder"); + + private final String value; + + Option(String value) { + this.value = value; + } + + public String value() { + return value; + } + + @SuppressWarnings("unchecked") + T get(Map options) { + return (T) options.get(this); + } + + String getString(Map options) { + return get(options); + } + + Integer getInt(Map options) { + return get(options); + } + } + + //TODO(mderka) add supported operations. Created issue #594. +} From bf1361c034633137ba395f6e565a1579fb4797fb Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Thu, 28 Jan 2016 16:38:21 -0800 Subject: [PATCH 048/375] Added DnsServiceOptions and necessary dependencies. --- .../com/google/gcloud/dns/DnsService.java | 1 + .../google/gcloud/dns/DnsServiceFactory.java | 25 ++++++ .../google/gcloud/dns/DnsServiceOptions.java | 85 +++++++++++++++++++ .../gcloud/spi/DnsServiceRpcFactory.java | 26 ++++++ 4 files changed, 137 insertions(+) create mode 100644 gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsServiceFactory.java create mode 100644 gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsServiceOptions.java create mode 100644 gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsServiceRpcFactory.java diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsService.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsService.java index 694b0b288154..9cbd60eccf5a 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsService.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsService.java @@ -18,6 +18,7 @@ import com.google.common.base.Joiner; import com.google.common.collect.Sets; +import com.google.gcloud.Service; import com.google.gcloud.spi.DnsServiceRpc; import java.io.Serializable; diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsServiceFactory.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsServiceFactory.java new file mode 100644 index 000000000000..aaa0dfb68e1b --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsServiceFactory.java @@ -0,0 +1,25 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.dns; + +import com.google.gcloud.ServiceFactory; + +/** + * An interface for DnsService factories. + */ +public interface DnsServiceFactory extends ServiceFactory { +} diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsServiceOptions.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsServiceOptions.java new file mode 100644 index 000000000000..84eb9c33dcaa --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsServiceOptions.java @@ -0,0 +1,85 @@ +/* + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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.gcloud.dns; + +import com.google.gcloud.ServiceOptions; +import com.google.gcloud.spi.DnsServiceRpc; +import com.google.gcloud.spi.DnsServiceRpcFactory; + +import java.util.Set; + +public class DnsServiceOptions + extends ServiceOptions { + + private static final long serialVersionUID = -5311219368450107146L; + + // TODO(mderka) Finish implementation. Created issue #595. + + public static class DefaultDnsServiceFactory implements DnsServiceFactory { + private static final DnsServiceFactory INSTANCE = new DefaultDnsServiceFactory(); + + @Override + public DnsService create(DnsServiceOptions options) { + // TODO(mderka) Implement. Created issue #595. + return null; + } + } + + public static class Builder extends ServiceOptions.Builder { + + private Builder() { + } + + private Builder(DnsServiceOptions options) { + super(options); + } + + @Override + public DnsServiceOptions build() { + return new DnsServiceOptions(this); + } + } + + private DnsServiceOptions(Builder builder) { + super(DnsServiceFactory.class, DnsServiceRpcFactory.class, builder); + } + + @Override + protected DnsServiceFactory defaultServiceFactory() { + return DefaultDnsServiceFactory.INSTANCE; + } + + @Override + protected DnsServiceRpcFactory defaultRpcFactory() { + return null; + } + + @Override + protected Set scopes() { + return null; + } + + @Override + public Builder toBuilder() { + return new Builder(this); + } + + public static Builder builder() { + return new Builder(); + } +} diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsServiceRpcFactory.java b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsServiceRpcFactory.java new file mode 100644 index 000000000000..13ec9fe881c8 --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsServiceRpcFactory.java @@ -0,0 +1,26 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.spi; + +import com.google.gcloud.dns.DnsServiceOptions; + +/** + * An interface for DnsServiceRpc factory. Implementation will be loaded via {@link + * java.util.ServiceLoader}. + */ +public interface DnsServiceRpcFactory extends ServiceRpcFactory { +} From 465f5327d81035666a12c1ef37bab0a1bfd55300 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Thu, 28 Jan 2016 18:15:47 -0800 Subject: [PATCH 049/375] Modified DnsException to pass tests. --- .../main/java/com/google/gcloud/dns/DnsException.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java index ab4a3df0f457..d18f6163a881 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java @@ -18,6 +18,8 @@ import com.google.gcloud.BaseServiceException; +import java.io.IOException; + /** * DNS service exception. */ @@ -25,12 +27,8 @@ public class DnsException extends BaseServiceException { private static final long serialVersionUID = 490302380416260252L; - public DnsException(int code, String message, boolean retryable) { - super(code, message, retryable); - } - - public DnsException(int code, String message, boolean retryable, Exception cause) { - super(code, message, retryable, cause); + public DnsException(IOException exception, boolean idempotent) { + super(exception, idempotent); } //TODO(mderka) Add translation and retry functionality. Created issue #593. From 71d91aa5b6f603e02285207662e5faae5b1c8a7f Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Thu, 28 Jan 2016 18:22:03 -0800 Subject: [PATCH 050/375] Fixed missed merge conflict --- .../java/com/google/gcloud/datastore/QueryResults.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java index cd851f690ca5..a6e5971936dd 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java @@ -36,7 +36,6 @@ public interface QueryResults extends Iterator { Class resultClass(); /** -<<<<<<< HEAD * Returns the Cursor for the point after the value returned in the last {@link #next} call. This * cursor can be used to issue subsequent queries (with the same constraints) that may return * additional results. @@ -51,11 +50,7 @@ public interface QueryResults extends Iterator { * // Consume some results (using results.next()) and do any other actions as necessary. * query = query.toBuilder().startCursor(results.cursorAfter()).build(); * results = datastore.run(query); // now we will iterate over all entities not yet consumed - * -======= - * Returns the Cursor for the point after the value returned in the last {@link #next} call. - * Currently, {@code cursorAfter} returns null in all cases but the last result. ->>>>>>> upstream/master + * } */ Cursor cursorAfter(); } From a8bee9c1e07337d1e710d378d7a600215e26c1ba Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Fri, 29 Jan 2016 16:10:25 -0800 Subject: [PATCH 051/375] Implements comments by @aozarov. --- .../com/google/gcloud/dns/AbstractOption.java | 17 +- .../gcloud/dns/{DnsService.java => Dns.java} | 229 +++++++----------- ...DnsServiceFactory.java => DnsFactory.java} | 4 +- ...DnsServiceOptions.java => DnsOptions.java} | 38 +-- .../spi/{DnsServiceRpc.java => DnsRpc.java} | 3 +- ...viceRpcFactory.java => DnsRpcFactory.java} | 6 +- 6 files changed, 120 insertions(+), 177 deletions(-) rename gcloud-java-dns/src/main/java/com/google/gcloud/dns/{DnsService.java => Dns.java} (51%) rename gcloud-java-dns/src/main/java/com/google/gcloud/dns/{DnsServiceFactory.java => DnsFactory.java} (84%) rename gcloud-java-dns/src/main/java/com/google/gcloud/dns/{DnsServiceOptions.java => DnsOptions.java} (59%) rename gcloud-java-dns/src/main/java/com/google/gcloud/spi/{DnsServiceRpc.java => DnsRpc.java} (96%) rename gcloud-java-dns/src/main/java/com/google/gcloud/spi/{DnsServiceRpcFactory.java => DnsRpcFactory.java} (74%) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/AbstractOption.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/AbstractOption.java index 6b6fbbf0606e..a148468d14b5 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/AbstractOption.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/AbstractOption.java @@ -19,7 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.MoreObjects; -import com.google.gcloud.spi.DnsServiceRpc; +import com.google.gcloud.spi.DnsRpc; import java.io.Serializable; import java.util.Objects; @@ -27,13 +27,13 @@ /** * A base class for options. */ -public abstract class AbstractOption implements Serializable { +abstract class AbstractOption implements Serializable { - private static final long serialVersionUID = 201601261704L; + private static final long serialVersionUID = -5912727967831484228L; private final Object value; - private final DnsServiceRpc.Option rpcOption; + private final DnsRpc.Option rpcOption; - AbstractOption(DnsServiceRpc.Option rpcOption, Object value) { + AbstractOption(DnsRpc.Option rpcOption, Object value) { this.rpcOption = checkNotNull(rpcOption); this.value = value; } @@ -42,7 +42,7 @@ Object value() { return value; } - DnsServiceRpc.Option rpcOption() { + DnsRpc.Option rpcOption() { return rpcOption; } @@ -52,18 +52,19 @@ public boolean equals(Object obj) { return false; } AbstractOption other = (AbstractOption) obj; - return Objects.equals(value, other.value); + return Objects.equals(value, other.value) && Objects.equals(rpcOption, other.rpcOption); } @Override public int hashCode() { - return Objects.hash(value); + return Objects.hash(value, rpcOption); } @Override public String toString() { return MoreObjects.toStringHelper(this) .add("value", value) + .add("rpcOption", rpcOption) .toString(); } } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsService.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java similarity index 51% rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsService.java rename to gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index 9cbd60eccf5a..737ec1a38699 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsService.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -19,7 +19,7 @@ import com.google.common.base.Joiner; import com.google.common.collect.Sets; import com.google.gcloud.Service; -import com.google.gcloud.spi.DnsServiceRpc; +import com.google.gcloud.spi.DnsRpc; import java.io.Serializable; import java.util.Set; @@ -29,13 +29,13 @@ * * @see Google Cloud DNS */ -public interface DnsService extends Service { +public interface Dns extends Service { /** * The fields of a project. * *

These values can be used to specify the fields to include in a partial response when calling - * {@code DnsService#getProjectInfo(ProjectOptions...)}. Project ID is always returned, even if + * {@code Dns#getProjectInfo(ProjectGetOption...)}. Project ID is always returned, even if * not specified. */ enum ProjectField { @@ -49,7 +49,7 @@ enum ProjectField { this.selector = selector; } - public String selector() { + String selector() { return selector; } @@ -67,9 +67,8 @@ static String selector(ProjectField... fields) { * The fields of a zone. * *

These values can be used to specify the fields to include in a partial response when calling - * {@code DnsService#getZone(BigInteger, ZoneFieldOptions...)} or {@code - * DnsService#getZone(String, ZoneFieldOptions...)}. The ID is always returned, even if not - * specified. + * {@code Dns#getZone(BigInteger, ZoneFieldOption...)} or {@code Dns#getZone(String, + * ZoneFieldOption...)}. The ID is always returned, even if not specified. */ enum ZoneField { CREATION_TIME("creationTime"), @@ -86,7 +85,7 @@ enum ZoneField { this.selector = selector; } - public String selector() { + String selector() { return selector; } @@ -104,8 +103,8 @@ static String selector(ZoneField... fields) { * The fields of a DNS record. * *

These values can be used to specify the fields to include in a partial response when calling - * {@code DnsService#listDnsRecords(BigInteger, DnsRecordOptions...)} or {@code - * DnsService#listDnsRecords(String, DnsRecordOptions...)}. The name is always returned even if + * {@code Dns#listDnsRecords(BigInteger, DnsRecordListOption...)} or {@code + * Dns#listDnsRecords(String, DnsRecordListOption...)}. The name is always returned even if * not selected. */ enum DnsRecordField { @@ -120,7 +119,7 @@ enum DnsRecordField { this.selector = selector; } - public String selector() { + String selector() { return selector; } @@ -138,8 +137,8 @@ static String selector(DnsRecordField... fields) { * The fields of a change request. * *

These values can be used to specify the fields to include in a partial response when calling - * {@code DnsService#applyChangeRequest(ChangeRequest, BigInteger, ChangeRequestFieldOptions...)} - * or {@code DnsService#applyChangeRequest(ChangeRequest, String, ChangeRequestFieldOptions...)} + * {@code Dns#applyChangeRequest(ChangeRequest, BigInteger, ChangeRequestOption...)} + * or {@code Dns#applyChangeRequest(ChangeRequest, String, ChangeRequestOption...)} * The ID is always returned even if not selected. */ enum ChangeRequestField { @@ -155,7 +154,7 @@ enum ChangeRequestField { this.selector = selector; } - public String selector() { + String selector() { return selector; } @@ -171,10 +170,10 @@ static String selector(ChangeRequestField... fields) { /** * The sorting keys for listing change requests. The only currently supported sorting key is the - * change sequence. + * when the change request was created. */ enum ChangeRequestSortingKey { - CHANGE_SEQUENCE("changeSequence"); + TIME_CREATED("changeSequence"); private final String selector; @@ -182,15 +181,15 @@ enum ChangeRequestSortingKey { this.selector = selector; } - public String selector() { + String selector() { return selector; } } /** - * The sorting order for listing change requests. + * The sorting order for listing. */ - enum ChangeRequestSortingOrder { + enum SortingOrder { DESCENDING, ASCENDING; public String selector() { @@ -201,11 +200,11 @@ public String selector() { /** * Class that for specifying DNS record options. */ - class DnsRecordOptions extends AbstractOption implements Serializable { + class DnsRecordListOption extends AbstractOption implements Serializable { - private static final long serialVersionUID = 201601261646L; + private static final long serialVersionUID = 1009627025381096098L; - DnsRecordOptions(DnsServiceRpc.Option option, Object value) { + DnsRecordListOption(DnsRpc.Option option, Object value) { super(option, value); } @@ -217,10 +216,10 @@ class DnsRecordOptions extends AbstractOption implements Serializable { * DNS record always returned, even if not specified. {@link DnsRecordField} provides a list of * fields that can be used. */ - public static DnsRecordOptions fields(DnsRecordField... fields) { + public static DnsRecordListOption fields(DnsRecordField... fields) { StringBuilder builder = new StringBuilder(); - builder.append("rrsets(").append(DnsRecordField.selector(fields)).append(")"); - return new DnsRecordOptions(DnsServiceRpc.Option.FIELDS, builder.toString()); + builder.append("rrsets(").append(DnsRecordField.selector(fields)).append(')'); + return new DnsRecordListOption(DnsRpc.Option.FIELDS, builder.toString()); } /** @@ -229,8 +228,8 @@ public static DnsRecordOptions fields(DnsRecordField... fields) { *

The page token (returned from a previous call to list) indicates from where listing should * continue. */ - public static DnsRecordOptions pageToken(String pageToken) { - return new DnsRecordOptions(DnsServiceRpc.Option.PAGE_TOKEN, pageToken); + public static DnsRecordListOption pageToken(String pageToken) { + return new DnsRecordListOption(DnsRpc.Option.PAGE_TOKEN, pageToken); } /** @@ -239,26 +238,34 @@ public static DnsRecordOptions pageToken(String pageToken) { *

The server can return fewer records than requested. When there are more results than the * page size, the server will return a page token that can be used to fetch other results. */ - public static DnsRecordOptions pageSize(int pageSize) { - return new DnsRecordOptions(DnsServiceRpc.Option.PAGE_SIZE, pageSize); + public static DnsRecordListOption pageSize(int pageSize) { + return new DnsRecordListOption(DnsRpc.Option.PAGE_SIZE, pageSize); } /** - * Restricts the list to return only zones with this fully qualified domain name. + * Restricts the list to only DNS records with this fully qualified domain name. */ - public static DnsRecordOptions dnsName(String dnsName) { - return new DnsRecordOptions(DnsServiceRpc.Option.DNS_NAME, dnsName); + public static DnsRecordListOption dnsName(String dnsName) { + return new DnsRecordListOption(DnsRpc.Option.DNS_NAME, dnsName); + } + + /** + * Restricts the list to return only records of this type. If present, {@link + * Dns.DnsRecordListOption#dnsName(String)} must also be present. + */ + public static DnsRecordListOption type(DnsRecord.Type type) { + return new DnsRecordListOption(DnsRpc.Option.DNS_TYPE, type); } } /** * Class for specifying zone field options. */ - class ZoneFieldOptions extends AbstractOption implements Serializable { + class ZoneFieldOption extends AbstractOption implements Serializable { - private static final long serialVersionUID = -7294186261285469986L; + private static final long serialVersionUID = -8065564464895945037L; - ZoneFieldOptions(DnsServiceRpc.Option option, Object value) { + ZoneFieldOption(DnsRpc.Option option, Object value) { super(option, value); } @@ -266,23 +273,23 @@ class ZoneFieldOptions extends AbstractOption implements Serializable { * Returns an option to specify the zones's fields to be returned by the RPC call. * *

If this option is not provided all zone fields are returned. {@code - * ZoneFieldOptions.fields} can be used to specify only the fields of interest. Zone ID is - * always returned, even if not specified. {@link ZoneField} provides a list of fields that can - * be used. + * ZoneFieldOption.fields} can be used to specify only the fields of interest. Zone ID is always + * returned, even if not specified. {@link ZoneField} provides a list of fields that can be + * used. */ - public static ZoneFieldOptions fields(ZoneField... fields) { - return new ZoneFieldOptions(DnsServiceRpc.Option.FIELDS, ZoneField.selector(fields)); + public static ZoneFieldOption fields(ZoneField... fields) { + return new ZoneFieldOption(DnsRpc.Option.FIELDS, ZoneField.selector(fields)); } } /** * Class for specifying zone listing options. */ - class ZoneListOptions extends AbstractOption implements Serializable { + class ZoneListOption extends AbstractOption implements Serializable { - private static final long serialVersionUID = -7922038132321229290L; + private static final long serialVersionUID = -2830645032124504717L; - ZoneListOptions(DnsServiceRpc.Option option, Object value) { + ZoneListOption(DnsRpc.Option option, Object value) { super(option, value); } @@ -290,12 +297,12 @@ class ZoneListOptions extends AbstractOption implements Serializable { * Returns an option to specify the zones's fields to be returned by the RPC call. * *

If this option is not provided all zone fields are returned. {@code - * ZoneFieldOptions.fields} can be used to specify only the fields of interest. Zone ID is - * always returned, even if not specified. {@link ZoneField} provides a list of fields that can - * be used. + * ZoneFieldOption.fields} can be used to specify only the fields of interest. Zone ID is always + * returned, even if not specified. {@link ZoneField} provides a list of fields that can be + * used. */ - public static ZoneListOptions fields(ZoneField... fields) { - return new ZoneListOptions(DnsServiceRpc.Option.FIELDS, ZoneField.selector(fields)); + public static ZoneListOption fields(ZoneField... fields) { + return new ZoneListOption(DnsRpc.Option.FIELDS, ZoneField.selector(fields)); } /** @@ -304,8 +311,8 @@ public static ZoneListOptions fields(ZoneField... fields) { *

The page token (returned from a previous call to list) indicates from where listing should * continue. */ - public static ZoneListOptions pageToken(String pageToken) { - return new ZoneListOptions(DnsServiceRpc.Option.PAGE_TOKEN, pageToken); + public static ZoneListOption pageToken(String pageToken) { + return new ZoneListOption(DnsRpc.Option.PAGE_TOKEN, pageToken); } /** @@ -314,26 +321,19 @@ public static ZoneListOptions pageToken(String pageToken) { *

The server can return fewer zones than requested. When there are more results than the * page size, the server will return a page token that can be used to fetch other results. */ - public static ZoneListOptions pageSize(int pageSize) { - return new ZoneListOptions(DnsServiceRpc.Option.PAGE_SIZE, pageSize); - } - - /** - * Restricts the list to return only zones with this fully qualified domain name. - */ - public static ZoneListOptions dnsName(String dnsName) { - return new ZoneListOptions(DnsServiceRpc.Option.DNS_NAME, dnsName); + public static ZoneListOption pageSize(int pageSize) { + return new ZoneListOption(DnsRpc.Option.PAGE_SIZE, pageSize); } } /** * Class for specifying project options. */ - class ProjectOptions extends AbstractOption implements Serializable { + class ProjectGetOption extends AbstractOption implements Serializable { private static final long serialVersionUID = 6817937338218847748L; - ProjectOptions(DnsServiceRpc.Option option, Object value) { + ProjectGetOption(DnsRpc.Option option, Object value) { super(option, value); } @@ -341,69 +341,38 @@ class ProjectOptions extends AbstractOption implements Serializable { * Returns an option to specify the project's fields to be returned by the RPC call. * *

If this option is not provided all project fields are returned. {@code - * ProjectOptions.fields} can be used to specify only the fields of interest. Project ID is + * ProjectGetOption.fields} can be used to specify only the fields of interest. Project ID is * always returned, even if not specified. {@link ProjectField} provides a list of fields that * can be used. */ - public static ProjectOptions fields(ProjectField... fields) { - return new ProjectOptions(DnsServiceRpc.Option.FIELDS, ProjectField.selector(fields)); + public static ProjectGetOption fields(ProjectField... fields) { + return new ProjectGetOption(DnsRpc.Option.FIELDS, ProjectField.selector(fields)); } } /** * Class for specifying change request field options. */ - class ChangeRequestFieldOptions extends AbstractOption implements Serializable { + class ChangeRequestOption extends AbstractOption implements Serializable { private static final long serialVersionUID = 1067273695061077782L; - ChangeRequestFieldOptions(DnsServiceRpc.Option option, Object value) { + ChangeRequestOption(DnsRpc.Option option, Object value) { super(option, value); } - /** - * Returns an option to specify which fields of DNS records to be added by the {@link - * ChangeRequest} should be returned by the service. - * - *

If this option is not provided, all record fields are returned. {@code - * ChangeRequestFieldOptions.additionsFields} can be used to specify only the fields of - * interest. The name of the DNS record always returned, even if not specified. {@link - * DnsRecordField} provides a list of fields that can be used. - */ - public static ChangeRequestFieldOptions additionsFields(DnsRecordField... fields) { - StringBuilder builder = new StringBuilder(); - builder.append("additions(").append(DnsRecordField.selector(fields)).append(")"); - return new ChangeRequestFieldOptions(DnsServiceRpc.Option.FIELDS, builder.toString()); - } - - /** - * Returns an option to specify which fields of DNS records to be deleted by the {@link - * ChangeRequest} should be returned by the service. - * - *

If this option is not provided, all record fields are returned. {@code - * ChangeRequestFieldOptions.deletionsFields} can be used to specify only the fields of - * interest. The name of the DNS record always returned, even if not specified. {@link - * DnsRecordField} provides a list of fields that can be used. - */ - public static ChangeRequestFieldOptions deletionsFields(DnsRecordField... fields) { - StringBuilder builder = new StringBuilder(); - builder.append("deletions(").append(DnsRecordField.selector(fields)).append(")"); - return new ChangeRequestFieldOptions(DnsServiceRpc.Option.FIELDS, builder.toString()); - - } - /** * Returns an option to specify which fields of {@link ChangeRequest} should be returned by the * service. * *

If this option is not provided all change request fields are returned. {@code - * ChangeRequestFieldOptions.fields} can be used to specify only the fields of interest. The ID + * ChangeRequestOption.fields} can be used to specify only the fields of interest. The ID * of the change request is always returned, even if not specified. {@link ChangeRequestField} * provides a list of fields that can be used. */ - public static ChangeRequestFieldOptions fields(ChangeRequestField... fields) { - return new ChangeRequestFieldOptions( - DnsServiceRpc.Option.FIELDS, + public static ChangeRequestOption fields(ChangeRequestField... fields) { + return new ChangeRequestOption( + DnsRpc.Option.FIELDS, ChangeRequestField.selector(fields) ); } @@ -412,56 +381,26 @@ public static ChangeRequestFieldOptions fields(ChangeRequestField... fields) { /** * Class for specifying change request listing options. */ - class ChangeRequestListOptions extends AbstractOption implements Serializable { + class ChangeRequestListOption extends AbstractOption implements Serializable { private static final long serialVersionUID = -900209143895376089L; - ChangeRequestListOptions(DnsServiceRpc.Option option, Object value) { + ChangeRequestListOption(DnsRpc.Option option, Object value) { super(option, value); } - /** - * Returns an option to specify which fields of DNS records to be added by the {@link - * ChangeRequest} should be returned by the service. - * - *

If this option is not provided, all record fields are returned. {@code - * ChangeRequestFieldOptions.additionsFields} can be used to specify only the fields of - * interest. The name of the DNS record always returned, even if not specified. {@link - * DnsRecordField} provides a list of fields that can be used. - */ - public static ChangeRequestListOptions additionsFields(DnsRecordField... fields) { - StringBuilder builder = new StringBuilder(); - builder.append("changes(additions(").append(DnsRecordField.selector(fields)).append("))"); - return new ChangeRequestListOptions(DnsServiceRpc.Option.FIELDS, builder.toString()); - } - - /** - * Returns an option to specify which fields of DNS records to be deleted by the {@link - * ChangeRequest} should be returned by the service. - * - *

If this option is not provided, all record fields are returned. {@code - * ChangeRequestFieldOptions.deletionsFields} can be used to specify only the fields of - * interest. The name of the DNS record always returned, even if not specified. {@link - * DnsRecordField} provides a list of fields that can be used. - */ - public static ChangeRequestListOptions deletionsFields(DnsRecordField... fields) { - StringBuilder builder = new StringBuilder(); - builder.append("changes(deletions(").append(DnsRecordField.selector(fields)).append("))"); - return new ChangeRequestListOptions(DnsServiceRpc.Option.FIELDS, builder.toString()); - } - /** * Returns an option to specify which fields of{@link ChangeRequest} should be returned by the * service. * *

If this option is not provided all change request fields are returned. {@code - * ChangeRequestFieldOptions.fields} can be used to specify only the fields of interest. The ID + * ChangeRequestOption.fields} can be used to specify only the fields of interest. The ID * of the change request is always returned, even if not specified. {@link ChangeRequestField} * provides a list of fields that can be used. */ - public static ChangeRequestListOptions fields(ChangeRequestField... fields) { - return new ChangeRequestListOptions( - DnsServiceRpc.Option.FIELDS, + public static ChangeRequestListOption fields(ChangeRequestField... fields) { + return new ChangeRequestListOption( + DnsRpc.Option.FIELDS, ChangeRequestField.selector(fields) ); } @@ -472,8 +411,8 @@ public static ChangeRequestListOptions fields(ChangeRequestField... fields) { *

The page token (returned from a previous call to list) indicates from where listing should * continue. */ - public static ChangeRequestListOptions pageToken(String pageToken) { - return new ChangeRequestListOptions(DnsServiceRpc.Option.PAGE_TOKEN, pageToken); + public static ChangeRequestListOption pageToken(String pageToken) { + return new ChangeRequestListOption(DnsRpc.Option.PAGE_TOKEN, pageToken); } /** @@ -483,24 +422,24 @@ public static ChangeRequestListOptions pageToken(String pageToken) { * than the page size, the server will return a page token that can be used to fetch other * results. */ - public static ChangeRequestListOptions pageSize(int pageSize) { - return new ChangeRequestListOptions(DnsServiceRpc.Option.PAGE_SIZE, pageSize); + public static ChangeRequestListOption pageSize(int pageSize) { + return new ChangeRequestListOption(DnsRpc.Option.PAGE_SIZE, pageSize); } /** * Returns an option for specifying the sorting criterion of change requests. Note the the only * currently supported criterion is the change sequence. */ - public static ChangeRequestListOptions sortBy(ChangeRequestSortingKey key) { - return new ChangeRequestListOptions(DnsServiceRpc.Option.SORTING_KEY, key.selector()); + public static ChangeRequestListOption sortBy(ChangeRequestSortingKey key) { + return new ChangeRequestListOption(DnsRpc.Option.SORTING_KEY, key.selector()); } /** * Returns an option to specify whether the the change requests should be listed in ascending or * descending order. */ - public static ChangeRequestListOptions sortOrder(ChangeRequestSortingOrder order) { - return new ChangeRequestListOptions(DnsServiceRpc.Option.SORTING_ORDER, order.selector()); + public static ChangeRequestListOption sortOrder(SortingOrder order) { + return new ChangeRequestListOption(DnsRpc.Option.SORTING_ORDER, order.selector()); } } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsServiceFactory.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsFactory.java similarity index 84% rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsServiceFactory.java rename to gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsFactory.java index aaa0dfb68e1b..734652afb24d 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsServiceFactory.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsFactory.java @@ -19,7 +19,7 @@ import com.google.gcloud.ServiceFactory; /** - * An interface for DnsService factories. + * An interface for Dns factories. */ -public interface DnsServiceFactory extends ServiceFactory { +public interface DnsFactory extends ServiceFactory { } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsServiceOptions.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java similarity index 59% rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsServiceOptions.java rename to gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java index 84eb9c33dcaa..3663211d3b41 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsServiceOptions.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java @@ -16,62 +16,64 @@ package com.google.gcloud.dns; +import com.google.common.collect.Sets; import com.google.gcloud.ServiceOptions; -import com.google.gcloud.spi.DnsServiceRpc; -import com.google.gcloud.spi.DnsServiceRpcFactory; +import com.google.gcloud.spi.DnsRpc; +import com.google.gcloud.spi.DnsRpcFactory; import java.util.Set; -public class DnsServiceOptions - extends ServiceOptions { +public class DnsOptions + extends ServiceOptions { private static final long serialVersionUID = -5311219368450107146L; // TODO(mderka) Finish implementation. Created issue #595. - public static class DefaultDnsServiceFactory implements DnsServiceFactory { - private static final DnsServiceFactory INSTANCE = new DefaultDnsServiceFactory(); + public static class DefaultDnsFactory implements DnsFactory { + private static final DnsFactory INSTANCE = new DefaultDnsFactory(); @Override - public DnsService create(DnsServiceOptions options) { + public Dns create(DnsOptions options) { // TODO(mderka) Implement. Created issue #595. return null; } } - public static class Builder extends ServiceOptions.Builder { + public static class Builder extends ServiceOptions.Builder { private Builder() { } - private Builder(DnsServiceOptions options) { + private Builder(DnsOptions options) { super(options); } @Override - public DnsServiceOptions build() { - return new DnsServiceOptions(this); + public DnsOptions build() { + return new DnsOptions(this); } } - private DnsServiceOptions(Builder builder) { - super(DnsServiceFactory.class, DnsServiceRpcFactory.class, builder); + private DnsOptions(Builder builder) { + super(DnsFactory.class, DnsRpcFactory.class, builder); } @Override - protected DnsServiceFactory defaultServiceFactory() { - return DefaultDnsServiceFactory.INSTANCE; + protected DnsFactory defaultServiceFactory() { + return DefaultDnsFactory.INSTANCE; } @Override - protected DnsServiceRpcFactory defaultRpcFactory() { + protected DnsRpcFactory defaultRpcFactory() { return null; } @Override protected Set scopes() { - return null; + // TODO(mderka) Verify. + return Sets.newHashSet("ndev.clouddns.readwrite"); } @Override diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsServiceRpc.java b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java similarity index 96% rename from gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsServiceRpc.java rename to gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java index e97ee9a1b001..02afb7309c6a 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsServiceRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java @@ -18,13 +18,14 @@ import java.util.Map; -public interface DnsServiceRpc { +public interface DnsRpc { enum Option { FIELDS("fields"), PAGE_SIZE("maxSize"), PAGE_TOKEN("pageToken"), DNS_NAME("dnsName"), + DNS_TYPE("type"), SORTING_KEY("sortBy"), SORTING_ORDER("sortOrder"); diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsServiceRpcFactory.java b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpcFactory.java similarity index 74% rename from gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsServiceRpcFactory.java rename to gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpcFactory.java index 13ec9fe881c8..3d25f09bb1e5 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsServiceRpcFactory.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpcFactory.java @@ -16,11 +16,11 @@ package com.google.gcloud.spi; -import com.google.gcloud.dns.DnsServiceOptions; +import com.google.gcloud.dns.DnsOptions; /** - * An interface for DnsServiceRpc factory. Implementation will be loaded via {@link + * An interface for DnsRpc factory. Implementation will be loaded via {@link * java.util.ServiceLoader}. */ -public interface DnsServiceRpcFactory extends ServiceRpcFactory { +public interface DnsRpcFactory extends ServiceRpcFactory { } From 762483b94f6c95aa3f860803ead53a962f41d336 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Fri, 29 Jan 2016 16:11:13 -0800 Subject: [PATCH 052/375] Makes ProjectInfo.Quota serializable. Fixed #599. --- .../src/main/java/com/google/gcloud/dns/ProjectInfo.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java index 4db0497946b1..f7b12b94bae8 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java @@ -44,8 +44,9 @@ public class ProjectInfo implements Serializable { * @see Google Cloud DNS * documentation */ - public static class Quota { + public static class Quota implements Serializable { + private static final long serialVersionUID = 6854685970605363639L; private final int zones; private final int resourceRecordsPerRrset; private final int rrsetAdditionsPerChange; From e17bedb4640e6d5c434670eb03a4ea6b2f9028c9 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Fri, 29 Jan 2016 17:50:18 -0800 Subject: [PATCH 053/375] Implemented DnsOptions up to two unavailable classes. --- .../com/google/gcloud/dns/DnsOptions.java | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java index 3663211d3b41..a5c689f4c719 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java @@ -16,7 +16,7 @@ package com.google.gcloud.dns; -import com.google.common.collect.Sets; +import com.google.common.collect.ImmutableSet; import com.google.gcloud.ServiceOptions; import com.google.gcloud.spi.DnsRpc; import com.google.gcloud.spi.DnsRpcFactory; @@ -26,16 +26,28 @@ public class DnsOptions extends ServiceOptions { - private static final long serialVersionUID = -5311219368450107146L; - - // TODO(mderka) Finish implementation. Created issue #595. + private static final long serialVersionUID = -519128051411747771L; + private static final String GC_DNS_RW = "https://www.googleapis.com/auth/ndev.clouddns.readwrite"; + private static final String GC_DNS_R = "https://www.googleapis.com/auth/ndev.clouddns.readonly"; + private static final Set SCOPES = ImmutableSet.of(GC_DNS_RW, GC_DNS_R); public static class DefaultDnsFactory implements DnsFactory { private static final DnsFactory INSTANCE = new DefaultDnsFactory(); @Override public Dns create(DnsOptions options) { - // TODO(mderka) Implement. Created issue #595. + // TODO(mderka) Implement when DnsImpl is available. Created issue #595. + return null; + } + } + + public static class DefaultDnsRpcFactory implements DnsRpcFactory { + + private static final DnsRpcFactory INSTANCE = new DefaultDnsRpcFactory(); + + @Override + public DnsRpc create(DnsOptions options) { + // TODO(mderka) Implement when DefaultDnsRpc is available. Created issue #595. return null; } } @@ -60,11 +72,13 @@ private DnsOptions(Builder builder) { super(DnsFactory.class, DnsRpcFactory.class, builder); } + @SuppressWarnings("unchecked") @Override protected DnsFactory defaultServiceFactory() { return DefaultDnsFactory.INSTANCE; } + @SuppressWarnings("unchecked") @Override protected DnsRpcFactory defaultRpcFactory() { return null; @@ -72,10 +86,10 @@ protected DnsRpcFactory defaultRpcFactory() { @Override protected Set scopes() { - // TODO(mderka) Verify. - return Sets.newHashSet("ndev.clouddns.readwrite"); + return SCOPES; } + @SuppressWarnings("unchecked") @Override public Builder toBuilder() { return new Builder(this); From adf5c1cda7b849d7e1064dba7dae24e1fea5061d Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Mon, 1 Feb 2016 09:12:51 -0800 Subject: [PATCH 054/375] Added test for AbstractOption. --- .../main/java/com/google/gcloud/dns/Dns.java | 2 +- .../google/gcloud/dns/AbstractOptionTest.java | 70 +++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 gcloud-java-dns/src/test/java/com/google/gcloud/dns/AbstractOptionTest.java diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index 737ec1a38699..76b11972bb7e 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -193,7 +193,7 @@ enum SortingOrder { DESCENDING, ASCENDING; public String selector() { - return this.name().toLowerCase(); + return name().toLowerCase(); } } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/AbstractOptionTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/AbstractOptionTest.java new file mode 100644 index 000000000000..3c578c53d0d1 --- /dev/null +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/AbstractOptionTest.java @@ -0,0 +1,70 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.dns; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.fail; + +import com.google.gcloud.spi.DnsRpc; + +import org.junit.Test; + +public class AbstractOptionTest { + + private static final DnsRpc.Option RPC_OPTION = DnsRpc.Option.DNS_TYPE; + private static final DnsRpc.Option ANOTHER_RPC_OPTION = DnsRpc.Option.DNS_NAME; + private static final String VALUE = "some value"; + private static final String OTHER_VALUE = "another value"; + private static final AbstractOption OPTION = new AbstractOption(RPC_OPTION, VALUE) { + }; + private static final AbstractOption OPTION_EQUALS = new AbstractOption(RPC_OPTION, VALUE) { + }; + private static final AbstractOption OPTION_NOT_EQUALS1 = + new AbstractOption(RPC_OPTION, OTHER_VALUE) { + }; + private static final AbstractOption OPTION_NOT_EQUALS2 = + new AbstractOption(ANOTHER_RPC_OPTION, VALUE) { + }; + + @Test + public void testEquals() { + assertEquals(OPTION, OPTION_EQUALS); + assertNotEquals(OPTION, OPTION_NOT_EQUALS1); + assertNotEquals(OPTION, OPTION_NOT_EQUALS2); + } + + @Test + public void testHashCode() { + assertEquals(OPTION.hashCode(), OPTION_EQUALS.hashCode()); + } + + @Test + public void testConstructor() { + assertEquals(RPC_OPTION, OPTION.rpcOption()); + assertEquals(VALUE, OPTION.value()); + try { + new AbstractOption(null, VALUE) { + }; + fail("Cannot build with empty option."); + } catch (NullPointerException e) { + // expected + } + new AbstractOption(RPC_OPTION, null) { + }; // null value is ok + } +} From a9cc927e002277face656af9f059175192d31c3d Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Mon, 1 Feb 2016 14:20:33 -0800 Subject: [PATCH 055/375] Implemented comments by @aozarov. Added test for option accessors. --- .../main/java/com/google/gcloud/dns/Dns.java | 86 ++++------- .../com/google/gcloud/dns/DnsOptions.java | 3 +- .../java/com/google/gcloud/spi/DnsRpc.java | 1 - .../java/com/google/gcloud/dns/DnsTest.java | 141 ++++++++++++++++++ 4 files changed, 173 insertions(+), 58 deletions(-) create mode 100644 gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index 76b11972bb7e..352c7791e18d 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -31,12 +31,14 @@ */ public interface Dns extends Service { + + /** * The fields of a project. * *

These values can be used to specify the fields to include in a partial response when calling - * {@code Dns#getProjectInfo(ProjectGetOption...)}. Project ID is always returned, even if - * not specified. + * {@code Dns#getProjectInfo(ProjectGetOption...)}. Project ID is always returned, even if not + * specified. */ enum ProjectField { PROJECT_ID("id"), @@ -67,8 +69,8 @@ static String selector(ProjectField... fields) { * The fields of a zone. * *

These values can be used to specify the fields to include in a partial response when calling - * {@code Dns#getZone(BigInteger, ZoneFieldOption...)} or {@code Dns#getZone(String, - * ZoneFieldOption...)}. The ID is always returned, even if not specified. + * {@code Dns#getZone(BigInteger, ZoneOption...)} or {@code Dns#getZone(String, ZoneOption...)}. + * The ID is always returned, even if not specified. */ enum ZoneField { CREATION_TIME("creationTime"), @@ -104,8 +106,8 @@ static String selector(ZoneField... fields) { * *

These values can be used to specify the fields to include in a partial response when calling * {@code Dns#listDnsRecords(BigInteger, DnsRecordListOption...)} or {@code - * Dns#listDnsRecords(String, DnsRecordListOption...)}. The name is always returned even if - * not selected. + * Dns#listDnsRecords(String, DnsRecordListOption...)}. The name is always returned even if not + * selected. */ enum DnsRecordField { DNS_RECORDS("rrdatas"), @@ -137,9 +139,9 @@ static String selector(DnsRecordField... fields) { * The fields of a change request. * *

These values can be used to specify the fields to include in a partial response when calling - * {@code Dns#applyChangeRequest(ChangeRequest, BigInteger, ChangeRequestOption...)} - * or {@code Dns#applyChangeRequest(ChangeRequest, String, ChangeRequestOption...)} - * The ID is always returned even if not selected. + * {@code Dns#applyChangeRequest(ChangeRequest, BigInteger, ChangeRequestOption...)} or {@code + * Dns#applyChangeRequest(ChangeRequest, String, ChangeRequestOption...)} The ID is always + * returned even if not selected. */ enum ChangeRequestField { ID("id"), @@ -168,24 +170,6 @@ static String selector(ChangeRequestField... fields) { } } - /** - * The sorting keys for listing change requests. The only currently supported sorting key is the - * when the change request was created. - */ - enum ChangeRequestSortingKey { - TIME_CREATED("changeSequence"); - - private final String selector; - - ChangeRequestSortingKey(String selector) { - this.selector = selector; - } - - String selector() { - return selector; - } - } - /** * The sorting order for listing. */ @@ -261,24 +245,23 @@ public static DnsRecordListOption type(DnsRecord.Type type) { /** * Class for specifying zone field options. */ - class ZoneFieldOption extends AbstractOption implements Serializable { + class ZoneOption extends AbstractOption implements Serializable { private static final long serialVersionUID = -8065564464895945037L; - ZoneFieldOption(DnsRpc.Option option, Object value) { + ZoneOption(DnsRpc.Option option, Object value) { super(option, value); } /** * Returns an option to specify the zones's fields to be returned by the RPC call. * - *

If this option is not provided all zone fields are returned. {@code - * ZoneFieldOption.fields} can be used to specify only the fields of interest. Zone ID is always - * returned, even if not specified. {@link ZoneField} provides a list of fields that can be - * used. + *

If this option is not provided all zone fields are returned. {@code ZoneOption.fields} can + * be used to specify only the fields of interest. Zone ID is always returned, even if not + * specified. {@link ZoneField} provides a list of fields that can be used. */ - public static ZoneFieldOption fields(ZoneField... fields) { - return new ZoneFieldOption(DnsRpc.Option.FIELDS, ZoneField.selector(fields)); + public static ZoneOption fields(ZoneField... fields) { + return new ZoneOption(DnsRpc.Option.FIELDS, ZoneField.selector(fields)); } } @@ -296,10 +279,9 @@ class ZoneListOption extends AbstractOption implements Serializable { /** * Returns an option to specify the zones's fields to be returned by the RPC call. * - *

If this option is not provided all zone fields are returned. {@code - * ZoneFieldOption.fields} can be used to specify only the fields of interest. Zone ID is always - * returned, even if not specified. {@link ZoneField} provides a list of fields that can be - * used. + *

If this option is not provided all zone fields are returned. {@code ZoneOption.fields} can + * be used to specify only the fields of interest. Zone ID is always returned, even if not + * specified. {@link ZoneField} provides a list of fields that can be used. */ public static ZoneListOption fields(ZoneField... fields) { return new ZoneListOption(DnsRpc.Option.FIELDS, ZoneField.selector(fields)); @@ -366,9 +348,9 @@ class ChangeRequestOption extends AbstractOption implements Serializable { * service. * *

If this option is not provided all change request fields are returned. {@code - * ChangeRequestOption.fields} can be used to specify only the fields of interest. The ID - * of the change request is always returned, even if not specified. {@link ChangeRequestField} - * provides a list of fields that can be used. + * ChangeRequestOption.fields} can be used to specify only the fields of interest. The ID of the + * change request is always returned, even if not specified. {@link ChangeRequestField} provides + * a list of fields that can be used. */ public static ChangeRequestOption fields(ChangeRequestField... fields) { return new ChangeRequestOption( @@ -394,9 +376,9 @@ class ChangeRequestListOption extends AbstractOption implements Serializable { * service. * *

If this option is not provided all change request fields are returned. {@code - * ChangeRequestOption.fields} can be used to specify only the fields of interest. The ID - * of the change request is always returned, even if not specified. {@link ChangeRequestField} - * provides a list of fields that can be used. + * ChangeRequestOption.fields} can be used to specify only the fields of interest. The ID of the + * change request is always returned, even if not specified. {@link ChangeRequestField} provides + * a list of fields that can be used. */ public static ChangeRequestListOption fields(ChangeRequestField... fields) { return new ChangeRequestListOption( @@ -427,16 +409,10 @@ public static ChangeRequestListOption pageSize(int pageSize) { } /** - * Returns an option for specifying the sorting criterion of change requests. Note the the only - * currently supported criterion is the change sequence. - */ - public static ChangeRequestListOption sortBy(ChangeRequestSortingKey key) { - return new ChangeRequestListOption(DnsRpc.Option.SORTING_KEY, key.selector()); - } - - /** - * Returns an option to specify whether the the change requests should be listed in ascending or - * descending order. + * Returns an option to specify whether the the change requests should be listed in ascending + * (most-recent last) or descending (most-recent first) order with respect to when the change + * request was accepted by the server. If this option is not provided, the listing order is + * undefined. */ public static ChangeRequestListOption sortOrder(SortingOrder order) { return new ChangeRequestListOption(DnsRpc.Option.SORTING_ORDER, order.selector()); diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java index a5c689f4c719..1845467c2537 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java @@ -28,8 +28,7 @@ public class DnsOptions private static final long serialVersionUID = -519128051411747771L; private static final String GC_DNS_RW = "https://www.googleapis.com/auth/ndev.clouddns.readwrite"; - private static final String GC_DNS_R = "https://www.googleapis.com/auth/ndev.clouddns.readonly"; - private static final Set SCOPES = ImmutableSet.of(GC_DNS_RW, GC_DNS_R); + private static final Set SCOPES = ImmutableSet.of(GC_DNS_RW); public static class DefaultDnsFactory implements DnsFactory { private static final DnsFactory INSTANCE = new DefaultDnsFactory(); diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java index 02afb7309c6a..f6a0f330a327 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java @@ -26,7 +26,6 @@ enum Option { PAGE_TOKEN("pageToken"), DNS_NAME("dnsName"), DNS_TYPE("type"), - SORTING_KEY("sortBy"), SORTING_ORDER("sortOrder"); private final String value; diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java new file mode 100644 index 000000000000..2e98dbd46de4 --- /dev/null +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java @@ -0,0 +1,141 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.dns; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import com.google.gcloud.spi.DnsRpc; + +import org.junit.Test; + +public class DnsTest { + + private static final Integer PAGE_SIZE = 20; + private static final String PAGE_TOKEN = "page token"; + + @Test + public void testDnsRecordListOption() { + // dns name + String dnsName = "some name"; + Dns.DnsRecordListOption dnsRecordListOption = Dns.DnsRecordListOption.dnsName(dnsName); + assertEquals(dnsName, dnsRecordListOption.value()); + assertEquals(DnsRpc.Option.DNS_NAME, dnsRecordListOption.rpcOption()); + // page token + dnsRecordListOption = Dns.DnsRecordListOption.pageToken(PAGE_TOKEN); + assertEquals(PAGE_TOKEN, dnsRecordListOption.value()); + assertEquals(DnsRpc.Option.PAGE_TOKEN, dnsRecordListOption.rpcOption()); + // page size + dnsRecordListOption = Dns.DnsRecordListOption.pageSize(PAGE_SIZE); + assertEquals(PAGE_SIZE, dnsRecordListOption.value()); + assertEquals(DnsRpc.Option.PAGE_SIZE, dnsRecordListOption.rpcOption()); + // record type + DnsRecord.Type recordType = DnsRecord.Type.AAAA; + dnsRecordListOption = Dns.DnsRecordListOption.type(recordType); + assertEquals(recordType, dnsRecordListOption.value()); + assertEquals(DnsRpc.Option.DNS_TYPE, dnsRecordListOption.rpcOption()); + // fields + dnsRecordListOption = Dns.DnsRecordListOption.fields(Dns.DnsRecordField.NAME, + Dns.DnsRecordField.TTL); + assertEquals(DnsRpc.Option.FIELDS, dnsRecordListOption.rpcOption()); + assertTrue(dnsRecordListOption.value() instanceof String); + assertTrue(((String) dnsRecordListOption.value()).contains( + Dns.DnsRecordField.NAME.selector())); + assertTrue(((String) dnsRecordListOption.value()).contains( + Dns.DnsRecordField.TTL.selector())); + assertTrue(((String) dnsRecordListOption.value()).contains( + Dns.DnsRecordField.NAME.selector())); + } + + @Test + public void testZoneOption() { + Dns.ZoneOption fields = Dns.ZoneOption.fields(Dns.ZoneField.CREATION_TIME, + Dns.ZoneField.DESCRIPTION); + assertEquals(DnsRpc.Option.FIELDS, fields.rpcOption()); + assertTrue(fields.value() instanceof String); + assertTrue(((String) fields.value()).contains(Dns.ZoneField.CREATION_TIME.selector())); + assertTrue(((String) fields.value()).contains(Dns.ZoneField.DESCRIPTION.selector())); + } + + @Test + public void testZoneList() { + // fields + Dns.ZoneListOption fields = Dns.ZoneListOption.fields(Dns.ZoneField.CREATION_TIME, + Dns.ZoneField.DESCRIPTION); + assertEquals(DnsRpc.Option.FIELDS, fields.rpcOption()); + assertTrue(fields.value() instanceof String); + assertTrue(((String) fields.value()).contains(Dns.ZoneField.CREATION_TIME.selector())); + assertTrue(((String) fields.value()).contains(Dns.ZoneField.DESCRIPTION.selector())); + assertTrue(((String) fields.value()).contains(Dns.ZoneField.ZONE_ID.selector())); + // page token + Dns.ZoneListOption option = Dns.ZoneListOption.pageToken(PAGE_TOKEN); + assertEquals(PAGE_TOKEN, option.value()); + assertEquals(DnsRpc.Option.PAGE_TOKEN, option.rpcOption()); + // page size + option = Dns.ZoneListOption.pageSize(PAGE_SIZE); + assertEquals(PAGE_SIZE, option.value()); + assertEquals(DnsRpc.Option.PAGE_SIZE, option.rpcOption()); + } + + @Test + public void testProjectGetOption() { + // fields + Dns.ProjectGetOption fields = Dns.ProjectGetOption.fields(Dns.ProjectField.QUOTA); + assertEquals(DnsRpc.Option.FIELDS, fields.rpcOption()); + assertTrue(fields.value() instanceof String); + assertTrue(((String) fields.value()).contains(Dns.ProjectField.QUOTA.selector())); + assertTrue(((String) fields.value()).contains(Dns.ProjectField.PROJECT_ID.selector())); + } + + @Test + public void testChangeRequestOption() { + // fields + Dns.ChangeRequestOption fields = Dns.ChangeRequestOption.fields( + Dns.ChangeRequestField.START_TIME, Dns.ChangeRequestField.STATUS); + assertEquals(DnsRpc.Option.FIELDS, fields.rpcOption()); + assertTrue(fields.value() instanceof String); + assertTrue(((String) fields.value()).contains( + Dns.ChangeRequestField.START_TIME.selector())); + assertTrue(((String) fields.value()).contains(Dns.ChangeRequestField.STATUS.selector())); + assertTrue(((String) fields.value()).contains(Dns.ChangeRequestField.ID.selector())); + } + + @Test + public void testChangeRequestListOption() { + // fields + Dns.ChangeRequestListOption fields = Dns.ChangeRequestListOption.fields( + Dns.ChangeRequestField.START_TIME, Dns.ChangeRequestField.STATUS); + assertEquals(DnsRpc.Option.FIELDS, fields.rpcOption()); + assertTrue(fields.value() instanceof String); + assertTrue(((String) fields.value()).contains( + Dns.ChangeRequestField.START_TIME.selector())); + assertTrue(((String) fields.value()).contains(Dns.ChangeRequestField.STATUS.selector())); + assertTrue(((String) fields.value()).contains(Dns.ChangeRequestField.ID.selector())); + // page token + Dns.ChangeRequestListOption option = Dns.ChangeRequestListOption.pageToken(PAGE_TOKEN); + assertEquals(PAGE_TOKEN, option.value()); + assertEquals(DnsRpc.Option.PAGE_TOKEN, option.rpcOption()); + // page size + option = Dns.ChangeRequestListOption.pageSize(PAGE_SIZE); + assertEquals(PAGE_SIZE, option.value()); + assertEquals(DnsRpc.Option.PAGE_SIZE, option.rpcOption()); + // sort order + option = Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING); + assertEquals(DnsRpc.Option.SORTING_ORDER, option.rpcOption()); + assertEquals(Dns.SortingOrder.ASCENDING.selector(), option.value()); + } +} From 6ecde35c355ca8e38e726044e9a0012f5a3935ab Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Mon, 1 Feb 2016 16:07:24 -0800 Subject: [PATCH 056/375] Comments by @aozarov second round. --- .../main/java/com/google/gcloud/dns/Dns.java | 15 ++++++----- .../google/gcloud/dns/AbstractOptionTest.java | 26 +++++++------------ 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index 352c7791e18d..28e79104cf58 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -24,6 +24,8 @@ import java.io.Serializable; import java.util.Set; +import static com.google.gcloud.dns.Dns.ZoneField.selector; + /** * An interface for the Google Cloud DNS service. * @@ -31,8 +33,6 @@ */ public interface Dns extends Service { - - /** * The fields of a project. * @@ -284,7 +284,9 @@ class ZoneListOption extends AbstractOption implements Serializable { * specified. {@link ZoneField} provides a list of fields that can be used. */ public static ZoneListOption fields(ZoneField... fields) { - return new ZoneListOption(DnsRpc.Option.FIELDS, ZoneField.selector(fields)); + StringBuilder builder = new StringBuilder(); + builder.append("managedZones(").append(selector(fields)).append(')'); + return new ZoneListOption(DnsRpc.Option.FIELDS, builder.toString()); } /** @@ -381,10 +383,9 @@ class ChangeRequestListOption extends AbstractOption implements Serializable { * a list of fields that can be used. */ public static ChangeRequestListOption fields(ChangeRequestField... fields) { - return new ChangeRequestListOption( - DnsRpc.Option.FIELDS, - ChangeRequestField.selector(fields) - ); + StringBuilder builder = new StringBuilder(); + builder.append("changes(").append(ChangeRequestField.selector(fields)).append(')'); + return new ChangeRequestListOption(DnsRpc.Option.FIELDS, builder.toString()); } /** diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/AbstractOptionTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/AbstractOptionTest.java index 3c578c53d0d1..e3f2896bd10b 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/AbstractOptionTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/AbstractOptionTest.java @@ -16,30 +16,26 @@ package com.google.gcloud.dns; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.fail; - import com.google.gcloud.spi.DnsRpc; import org.junit.Test; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.fail; + public class AbstractOptionTest { private static final DnsRpc.Option RPC_OPTION = DnsRpc.Option.DNS_TYPE; private static final DnsRpc.Option ANOTHER_RPC_OPTION = DnsRpc.Option.DNS_NAME; private static final String VALUE = "some value"; private static final String OTHER_VALUE = "another value"; - private static final AbstractOption OPTION = new AbstractOption(RPC_OPTION, VALUE) { - }; - private static final AbstractOption OPTION_EQUALS = new AbstractOption(RPC_OPTION, VALUE) { - }; + private static final AbstractOption OPTION = new AbstractOption(RPC_OPTION, VALUE) {}; + private static final AbstractOption OPTION_EQUALS = new AbstractOption(RPC_OPTION, VALUE) {}; private static final AbstractOption OPTION_NOT_EQUALS1 = - new AbstractOption(RPC_OPTION, OTHER_VALUE) { - }; + new AbstractOption(RPC_OPTION, OTHER_VALUE) {}; private static final AbstractOption OPTION_NOT_EQUALS2 = - new AbstractOption(ANOTHER_RPC_OPTION, VALUE) { - }; + new AbstractOption(ANOTHER_RPC_OPTION, VALUE) {}; @Test public void testEquals() { @@ -58,13 +54,11 @@ public void testConstructor() { assertEquals(RPC_OPTION, OPTION.rpcOption()); assertEquals(VALUE, OPTION.value()); try { - new AbstractOption(null, VALUE) { - }; + new AbstractOption(null, VALUE) {}; fail("Cannot build with empty option."); } catch (NullPointerException e) { // expected } - new AbstractOption(RPC_OPTION, null) { - }; // null value is ok + new AbstractOption(RPC_OPTION, null) {}; // null value is ok } } From a69101a80df1637361b02a93233d0ad3e5d69098 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Mon, 1 Feb 2016 16:18:16 -0800 Subject: [PATCH 057/375] Added Dns methods. Fixes #596. Added Zone and ZoneTest --- .../main/java/com/google/gcloud/dns/Dns.java | 194 ++++- .../main/java/com/google/gcloud/dns/Zone.java | 256 ++++++ .../google/gcloud/dns/AbstractOptionTest.java | 8 +- .../java/com/google/gcloud/dns/ZoneTest.java | 750 ++++++++++++++++++ 4 files changed, 1200 insertions(+), 8 deletions(-) create mode 100644 gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java create mode 100644 gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index 28e79104cf58..b48e4b0a90f2 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -18,14 +18,14 @@ import com.google.common.base.Joiner; import com.google.common.collect.Sets; +import com.google.gcloud.Page; import com.google.gcloud.Service; import com.google.gcloud.spi.DnsRpc; import java.io.Serializable; +import java.math.BigInteger; import java.util.Set; -import static com.google.gcloud.dns.Dns.ZoneField.selector; - /** * An interface for the Google Cloud DNS service. * @@ -285,7 +285,7 @@ class ZoneListOption extends AbstractOption implements Serializable { */ public static ZoneListOption fields(ZoneField... fields) { StringBuilder builder = new StringBuilder(); - builder.append("managedZones(").append(selector(fields)).append(')'); + builder.append("managedZones(").append(ZoneField.selector(fields)).append(')'); return new ZoneListOption(DnsRpc.Option.FIELDS, builder.toString()); } @@ -420,5 +420,191 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) { } } - // TODO(mderka) Add methods. Created issue #596. + /** + * Creates a new zone. + * + * @return ZoneInfo object representing the new zone's metadata. In addition to the name, dns name + * and description (supplied by the user within the {@code zoneInfo} parameter, the returned + * object will include the following read-only fields supplied by the server: creation time, id, + * and list of name servers. + * @throws DnsException upon failure + * @see Cloud DNS Managed Zones: + * create + */ + ZoneInfo create(ZoneInfo zoneInfo); + + /** + * Retrieves the zone by the specified zone name. Returns {@code null} is the zone is not found. + * The returned fields can be optionally restricted by specifying {@code ZoneFieldOptions}. + * + * @throws DnsException upon failure + * @see Cloud DNS Managed Zones: + * get + */ + ZoneInfo getZone(String zoneName, ZoneOption... options); + + /** + * Retrieves the zone by the specified zone name. Returns {@code null} is the zone is not found. + * The returned fields can be optionally restricted by specifying {@code ZoneFieldOptions}. + * + * @throws DnsException upon failure + * @see Cloud DNS Managed Zones: + * get + */ + ZoneInfo getZone(BigInteger zoneId, ZoneOption... options); + + /** + * Lists the zoned inside the project. + * + *

This method returns zone in an unspecified order. New zones do not necessarily appear at the + * end of the list. Use {@link ZoneListOption} to restrict the listing to a domain name, set page + * size, and set page tokens. + * + * @return {@code Page}, a page of zones + * @throws DnsException upon failure + * @see Cloud DNS Managed Zones: + * list + */ + Page listZones(ZoneListOption... options); + + /** + * Deletes an existing zone identified by name. Returns true if the zone was successfully deleted + * and false otherwise. + * + * @return {@code true} if zone was found and deleted and false otherwise + * @throws DnsException upon failure + * @see Cloud DNS Managed Zones: + * delete + */ + boolean delete(String zoneName); // delete does not admit any options + + /** + * Deletes an existing zone identified by id. Returns true if the zone was successfully deleted + * and false otherwise. + * + * @return {@code true} if zone was found and deleted and false otherwise + * @throws DnsException upon failure + * @see Cloud DNS Managed Zones: + * delete + */ + boolean delete(BigInteger zoneId); // delete does not admit any options + + /** + * Lists the DNS records in the zone identified by name. + * + *

The fields to be returned, page size and page tokens can be specified using {@code + * DnsRecordOptions}. Returns null if the zone cannot be found. + * + * @throws DnsException upon failure + * @see Cloud DNS + * ResourceRecordSets: list + */ + Page listDnsRecords(String zoneName, DnsRecordListOption... options); + + /** + * Lists the DNS records in the zone identified by ID. + * + *

The fields to be returned, page size and page tokens can be specified using {@code + * DnsRecordOptions}. Returns null if the zone cannot be found. + * + * @throws DnsException upon failure + * @see Cloud DNS + * ResourceRecordSets: list + */ + Page listDnsRecords(BigInteger zoneId, DnsRecordListOption... options); + + /** + * Retrieves the metadata about the current project. The returned fields can be optionally + * restricted by specifying {@code ProjectOptions}. + * + * @throws DnsException upon failure + * @see Cloud DNS Projects: get + */ + ProjectInfo getProjectInfo(ProjectGetOption... fields); + + /** + * Returns the current project id. + */ + String getProjectId(); + + /** + * Returns the current project number. + */ + BigInteger getProjectNumber(); + + /** + * Submits a change requests for applying to the zone identified by ID to the service. The + * returned object contains the following read-only fields supplied by the server: id, start time + * and status. time, id, and list of name servers. The returned fields can be modified by {@code + * ChangeRequestFieldOptions}. Returns null if the zone is not found. + * + * @return ChangeRequest object representing the new change request or null if zone is not found + * @throws DnsException upon failure + * @see Cloud DNS Changes: create + */ + ChangeRequest applyChangeRequest(ChangeRequest changeRequest, BigInteger zoneId, + ChangeRequestOption... options); + + /** + * Submits a change requests for applying to the zone identified by name to the service. The + * returned object contains the following read-only fields supplied by the server: id, start time + * and status. time, id, and list of name servers. The returned fields can be modified by {@code + * ChangeRequestFieldOptions}. Returns null if the zone is not found. + * + * @return ChangeRequest object representing the new change request or null if zone is not found + * @throws DnsException upon failure + * @see Cloud DNS Changes: create + */ + ChangeRequest applyChangeRequest(ChangeRequest changeRequest, String zoneName, + ChangeRequestOption... options); + + /** + * Retrieves updated information about a change request previously submitted for a zone identified + * by ID. Returns null if the zone or request cannot be found. + * + *

The fields to be returned using {@code ChangeRequestFieldOptions}. + * + * @throws DnsException upon failure + * @see Cloud DNS Chages: get + */ + ChangeRequest getChangeRequest(ChangeRequest changeRequest, BigInteger zoneId, + ChangeRequestOption... options); + + /** + * Retrieves updated information about a change request previously submitted for a zone identified + * by name. Returns null if the zone or request cannot be found. + * + *

The fields to be returned using {@code ChangeRequestFieldOptions}. + * + * @throws DnsException upon failure + * @see Cloud DNS Chages: get + */ + ChangeRequest getChangeRequest(ChangeRequest changeRequest, String zoneName, + ChangeRequestOption... options); + + /** + * Lists the change requests for the zone identified by ID that were submitted to the service. + * + *

The sorting key for changes, fields to be returned, page and page tokens can be specified + * using {@code ChangeRequestListOptions}. Note that the only sorting key currently supported is + * the timestamp of submitting the change request to the service. + * + * @return {@code Page}, a page of change requests + * @throws DnsException upon failure + * @see Cloud DNS Chages: list + */ + Page listChangeRequests(BigInteger zoneId, ChangeRequestListOption... options); + + /** + * Lists the change requests for the zone identified by name that were submitted to the service. + * + *

The sorting key for changes, fields to be returned, page and page tokens can be specified + * using {@code ChangeRequestListOptions}. Note that the only sorting key currently supported is + * the timestamp of submitting the change request to the service. + * + * @return {@code Page}, a page of change requests + * @throws DnsException upon failure + * @see Cloud DNS Chages: list + */ + Page listChangeRequests(String zoneName, ChangeRequestListOption... options); } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java new file mode 100644 index 000000000000..f4d9702ba12f --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java @@ -0,0 +1,256 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.dns; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.gcloud.Page; + +import java.io.Serializable; +import java.math.BigInteger; + +/** + * A Google Cloud DNS Zone object. + * + *

A zone is the container for all of your DNS records that share the same DNS name prefix, for + * example, example.com. Zones are automatically assigned a set of name servers when they are + * created to handle responding to DNS queries for that zone. A zone has quotas for the number of + * resource records that it can include. + * + * @see Google Cloud DNS managed zone + * documentation + */ +public class Zone implements Serializable { + + // TODO(mderka) Zone and zoneInfo to be merged. Opened issue #605. + + private static final long serialVersionUID = -4012581571095484813L; + private final ZoneInfo zoneInfo; + private final Dns dns; + + /** + * Constructs a {@code Zone} object that contains the given {@code zoneInfo}. + */ + public Zone(Dns dns, ZoneInfo zoneInfo) { + this.zoneInfo = checkNotNull(zoneInfo); + this.dns = checkNotNull(dns); + } + + /** + * Constructs a {@code Zone} object that contains meta information received from the Google Cloud + * DNS service for the provided zoneName. + * + * @param zoneName Name of the zone to be searched for + * @param options Optional restriction on what fields should be returned by the service + * @return Zone object containing metadata or null if not not found + * @throws DnsException upon failure + */ + public static Zone get(Dns dnsService, String zoneName, + Dns.ZoneOption... options) { + checkNotNull(zoneName); + checkNotNull(dnsService); + ZoneInfo zoneInfo = dnsService.getZone(zoneName, options); + return zoneInfo == null ? null : new Zone(dnsService, zoneInfo); + } + + /** + * Constructs a {@code Zone} object that contains meta information received from the Google Cloud + * DNS service for the provided zoneName. + * + * @param zoneId ID of the zone to be searched for + * @param options Optional restriction on what fields should be returned by the service + * @return Zone object containing metadata or null if not not found + * @throws DnsException upon failure + */ + public static Zone get(Dns dnsService, BigInteger zoneId, + Dns.ZoneOption... options) { + checkNotNull(zoneId); + checkNotNull(dnsService); + ZoneInfo zoneInfo = dnsService.getZone(zoneId, options); + return zoneInfo == null ? null : new Zone(dnsService, zoneInfo); + } + + /** + * Retrieves the latest information about the zone. The method first attempts to retrieve the zone + * by ID and if not set or zone is not found, it searches by name. + * + * @param options Optional restriction on what fields should be fetched + * @return Zone object containing updated metadata or null if not not found + * @throws DnsException upon failure + * @throws NullPointerException if both zone ID and name are not initialized + */ + public Zone reload(Dns.ZoneOption... options) { + checkNameOrIdNotNull(); + Zone zone = null; + if (zoneInfo.id() != null) { + zone = Zone.get(dns, zoneInfo.id(), options); + } + if (zone == null && zoneInfo.name() != null) { + // zone was not found by id or id is not set at all + zone = Zone.get(dns, zoneInfo.name(), options); + } + return zone; + } + + /** + * Deletes the zone. The method first attempts to delete the zone by ID. If the zone is not found + * or id is not set, it attempts to delete by name. + * + * @return true is zone was found and deleted and false otherwise + * @throws DnsException upon failure + * @throws NullPointerException if both zone ID and name are not initialized + */ + public boolean delete() { + checkNameOrIdNotNull(); + boolean deleted = false; + if (zoneInfo.id() != null) { + deleted = dns.delete(zoneInfo.id()); + } + if (!deleted && zoneInfo.name() != null) { + // zone was not found by id or id is not set at all + deleted = dns.delete(zoneInfo.name()); + } + return deleted; + } + + /** + * Lists all {@link DnsRecord}s associated with this zone. First searches for zone by ID and if + * not found then by name. + * + * @param options Optional restriction on listing and on what fields of {@link DnsRecord} should + * be returned by the service + * @return {@code Page}, a page of DNS records, or null if the zone is not found + * @throws DnsException upon failure + * @throws NullPointerException if both zone ID and name are not initialized + */ + public Page listDnsRecords(Dns.DnsRecordListOption... options) { + checkNameOrIdNotNull(); + Page page = null; + if (zoneInfo.id() != null) { + page = dns.listDnsRecords(zoneInfo.id(), options); + } + if (page == null && zoneInfo.name() != null) { + // zone was not found by id or id is not set at all + page = dns.listDnsRecords(zoneInfo.name(), options); + } + return page; + } + + /** + * Submits {@link ChangeRequest} to the service for it to applied to this zone. First searches for + * the zone by ID and if not found then by name. Returns a {@link ChangeRequest} with + * server-assigned ID or null if the zone was not found. + * + * @param options Optional restriction on what fields of {@link ChangeRequest} should be returned + * by the service + * @return ChangeRequest with server-assigned ID or null if the zone was not found. + * @throws DnsException upon failure + * @throws NullPointerException if both zone ID and name are not initialized + */ + public ChangeRequest applyChangeRequest(ChangeRequest changeRequest, + Dns.ChangeRequestOption... options) { + checkNameOrIdNotNull(); + checkNotNull(changeRequest); + ChangeRequest updated = null; + if (zoneInfo.id() != null) { + updated = dns.applyChangeRequest(changeRequest, zoneInfo.id(), options); + } + if (updated == null && zoneInfo.name() != null) { + // zone was not found by id or id is not set at all + updated = dns.applyChangeRequest(changeRequest, zoneInfo.name(), options); + } + return updated; + } + + /** + * Retrieves an updated information about a change request previously submitted to be applied to + * this zone. First searches for the zone by ID and if not found then by name. Returns a {@link + * ChangeRequest} if found and null is the zone or the change request was not found. + * + * @param options Optional restriction on what fields of {@link ChangeRequest} should be returned + * by the service + * @return ChangeRequest with updated information of null if the change request or zone was not + * found. + * @throws DnsException upon failure + * @throws NullPointerException if both zone ID and name are not initialized + * @throws NullPointerException if the change request does not have initialized id + */ + public ChangeRequest getChangeRequest(ChangeRequest changeRequest, + Dns.ChangeRequestOption... options) { + checkNameOrIdNotNull(); + checkNotNull(changeRequest); + checkNotNull(changeRequest.id()); + ChangeRequest updated = null; + if (zoneInfo.id() != null) { + updated = dns.getChangeRequest(changeRequest, zoneInfo.id(), options); + } + if (updated == null && zoneInfo.name() != null) { + // zone was not found by id or id is not set at all + updated = dns.getChangeRequest(changeRequest, zoneInfo.name(), options); + } + return updated; + } + + /** + * Retrieves all change requests for this zone. First searches for the zone by ID and if not found + * then by name. Returns a page of {@link ChangeRequest}s or null if the zone is not found. + * + * @param options Optional restriction on listing and on what fields of {@link ChangeRequest}s + * should be returned by the service + * @return {@code Page}, a page of change requests, or null if the zone is not + * found + * @throws DnsException upon failure + * @throws NullPointerException if both zone ID and name are not initialized + */ + public Page listChangeRequests(Dns.ChangeRequestListOption... options) { + checkNameOrIdNotNull(); + Page changeRequests = null; + if (zoneInfo.id() != null) { + changeRequests = dns.listChangeRequests(zoneInfo.id(), options); + } + if (changeRequests == null && zoneInfo.name() != null) { + // zone was not found by id or id is not set at all + changeRequests = dns.listChangeRequests(zoneInfo.name(), options); + } + return changeRequests; + } + + /** + * Check that at least one of name and ID are initialized and throw and exception if not. + */ + private void checkNameOrIdNotNull() { + if (zoneInfo != null && zoneInfo.id() == null && zoneInfo.name() == null) { + throw new NullPointerException("Both zoneInfo.id and zoneInfo.name are null. " + + "This is an inconsistent state which should never happen."); + } + } + + /** + * Returns the {@link ZoneInfo} object containing meta information about this managed zone. + */ + public ZoneInfo info() { + return this.zoneInfo; + } + + /** + * Returns the {@link Dns} service object associated with this managed zone. + */ + public Dns dns() { + return this.dns; + } + +} diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/AbstractOptionTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/AbstractOptionTest.java index e3f2896bd10b..09e35527879b 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/AbstractOptionTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/AbstractOptionTest.java @@ -16,14 +16,14 @@ package com.google.gcloud.dns; -import com.google.gcloud.spi.DnsRpc; - -import org.junit.Test; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.fail; +import com.google.gcloud.spi.DnsRpc; + +import org.junit.Test; + public class AbstractOptionTest { private static final DnsRpc.Option RPC_OPTION = DnsRpc.Option.DNS_TYPE; diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java new file mode 100644 index 000000000000..5f9d119e6150 --- /dev/null +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java @@ -0,0 +1,750 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.dns; + +import static org.easymock.EasyMock.createStrictMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.google.gcloud.Page; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.math.BigInteger; + +public class ZoneTest { + + private static final String ZONE_NAME = "dns-zone-name"; + private static final BigInteger ZONE_ID = new BigInteger("123"); + private static final ZoneInfo ZONE_INFO = ZoneInfo.builder(ZONE_NAME, ZONE_ID) + .dnsName("example.com") + .creationTimeMillis(123478946464L) + .build(); + private static final ZoneInfo NO_ID_INFO = ZoneInfo.builder(ZONE_NAME) + .dnsName("anoter-example.com") + .creationTimeMillis(893123464L) + .build(); + private static final ZoneInfo NO_NAME_INFO = ZoneInfo.builder(ZONE_ID) + .dnsName("one-more-example.com") + .creationTimeMillis(875221546464L) + .build(); + private static final Dns.ZoneOption ZONE_FIELD_OPTIONS = + Dns.ZoneOption.fields(Dns.ZoneField.CREATION_TIME); + private static final Dns.DnsRecordListOption DNS_RECORD_OPTIONS = + Dns.DnsRecordListOption.dnsName("some-dns"); + private static final Dns.ChangeRequestOption CHANGE_REQUEST_FIELD_OPTIONS = + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME); + private static final Dns.ChangeRequestListOption CHANGE_REQUEST_LIST_OPTIONS = + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.START_TIME); + private static final ChangeRequest CHANGE_REQUEST = ChangeRequest.builder().id("someid").build(); + private static final ChangeRequest CHANGE_REQUEST_AFTER = CHANGE_REQUEST.toBuilder() + .startTimeMillis(123465L).build(); + private static final ChangeRequest CHANGE_REQUEST_NO_ID = ChangeRequest.builder().build(); + + private Dns dns; + private Zone zone; + private Zone zoneNoName; + private Zone zoneNoId; + + @Before + public void setUp() throws Exception { + dns = createStrictMock(Dns.class); + zone = new Zone(dns, ZONE_INFO); + zoneNoId = new Zone(dns, NO_ID_INFO); + zoneNoName = new Zone(dns, NO_NAME_INFO); + } + + @After + public void tearDown() throws Exception { + verify(dns); + } + + @Test + public void testConstructor() { + replay(dns); + assertNotNull(zone.info()); + assertEquals(ZONE_INFO, zone.info()); + assertNotNull(zone.dns()); + assertEquals(dns, zone.dns()); + } + + @Test + public void testGetById() { + expect(dns.getZone(ZONE_ID)).andReturn(ZONE_INFO); + expect(dns.getZone(ZONE_ID, ZONE_FIELD_OPTIONS)).andReturn(ZONE_INFO); // for options + replay(dns); + Zone retrieved = Zone.get(dns, ZONE_ID); + assertSame(dns, retrieved.dns()); + assertEquals(ZONE_INFO, retrieved.info()); + BigInteger id = null; + try { + Zone.get(dns, id); + fail("Cannot get null zone."); + } catch (NullPointerException e) { + // expected + } + try { + Zone.get(null, id); + fail("Cannot get null zone."); + } catch (NullPointerException e) { + // expected + } + // test passing options + Zone.get(dns, ZONE_ID, ZONE_FIELD_OPTIONS); + } + + @Test + public void testGetByName() { + expect(dns.getZone(ZONE_NAME)).andReturn(ZONE_INFO); + expect(dns.getZone(ZONE_ID, ZONE_FIELD_OPTIONS)).andReturn(ZONE_INFO); // for options + replay(dns); + Zone retrieved = Zone.get(dns, ZONE_NAME); + assertSame(dns, retrieved.dns()); + assertEquals(ZONE_INFO, retrieved.info()); + String name = null; + try { + Zone.get(dns, name); + fail("Cannot get null zone."); + } catch (NullPointerException e) { + // expected + } + try { + Zone.get(null, name); + fail("Cannot get null zone."); + } catch (NullPointerException e) { + // expected + } + // test passing options + Zone.get(dns, ZONE_ID, ZONE_FIELD_OPTIONS); + } + + @Test + public void deleteByIdAndFound() { + expect(dns.delete(ZONE_ID)).andReturn(true); + replay(dns); + boolean result = zone.delete(); + assertTrue(result); + } + + @Test + public void deleteByIdAndNotFoundAndNameSetAndFound() { + expect(dns.delete(ZONE_ID)).andReturn(false); + expect(dns.delete(ZONE_NAME)).andReturn(true); + replay(dns); + boolean result = zone.delete(); + assertTrue(result); + } + + @Test + public void deleteByIdAndNotFoundAndNameSetAndNotFound() { + expect(dns.delete(ZONE_ID)).andReturn(false); + expect(dns.delete(ZONE_NAME)).andReturn(false); + replay(dns); + boolean result = zone.delete(); + assertFalse(result); + } + + @Test + public void deleteByIdAndNotFoundAndNameNotSet() { + expect(dns.delete(ZONE_ID)).andReturn(false); + replay(dns); + boolean result = zoneNoName.delete(); + assertFalse(result); + } + + @Test + public void deleteByNameAndFound() { + expect(dns.delete(ZONE_NAME)).andReturn(true); + replay(dns); + boolean result = zoneNoId.delete(); + assertTrue(result); + } + + @Test + public void deleteByNameAndNotFound() { + expect(dns.delete(ZONE_NAME)).andReturn(true); + replay(dns); + boolean result = zoneNoId.delete(); + assertTrue(result); + } + + @Test + public void listDnsRecordsByIdAndFound() { + Page pageMock = createStrictMock(Page.class); + replay(pageMock); + expect(dns.listDnsRecords(ZONE_ID)).andReturn(pageMock); + // again for options + expect(dns.listDnsRecords(ZONE_ID, DNS_RECORD_OPTIONS)).andReturn(pageMock); + replay(dns); + Page result = zone.listDnsRecords(); + assertSame(pageMock, result); + verify(pageMock); + // verify options + zone.listDnsRecords(DNS_RECORD_OPTIONS); + } + + @Test + public void listDnsRecordsByIdAndNotFoundAndNameSetAndFound() { + Page pageMock = createStrictMock(Page.class); + replay(pageMock); + expect(dns.listDnsRecords(ZONE_ID)).andReturn(null); + expect(dns.listDnsRecords(ZONE_NAME)).andReturn(pageMock); + // again for options + expect(dns.listDnsRecords(ZONE_ID, DNS_RECORD_OPTIONS)).andReturn(null); + expect(dns.listDnsRecords(ZONE_NAME, DNS_RECORD_OPTIONS)).andReturn(pageMock); + replay(dns); + Page result = zone.listDnsRecords(); + assertSame(pageMock, result); + verify(pageMock); + // verify options + zone.listDnsRecords(DNS_RECORD_OPTIONS); + } + + @Test + public void listDnsRecordsByIdAndNotFoundAndNameSetAndNotFound() { + expect(dns.listDnsRecords(ZONE_ID)).andReturn(null); + expect(dns.listDnsRecords(ZONE_NAME)).andReturn(null); + // again for options + expect(dns.listDnsRecords(ZONE_ID, DNS_RECORD_OPTIONS)).andReturn(null); + expect(dns.listDnsRecords(ZONE_NAME, DNS_RECORD_OPTIONS)).andReturn(null); + replay(dns); + Page result = zone.listDnsRecords(); + assertNull(result); + // check options + zone.listDnsRecords(DNS_RECORD_OPTIONS); + } + + @Test + public void listDnsRecordsByIdAndNotFoundAndNameNotSet() { + expect(dns.listDnsRecords(ZONE_ID)).andReturn(null); + expect(dns.listDnsRecords(ZONE_ID, DNS_RECORD_OPTIONS)).andReturn(null); // for options + replay(dns); + Page result = zoneNoName.listDnsRecords(); + assertNull(result); + zoneNoName.listDnsRecords(DNS_RECORD_OPTIONS); // check options + } + + @Test + public void listDnsRecordsByNameAndFound() { + Page pageMock = createStrictMock(Page.class); + replay(pageMock); + expect(dns.listDnsRecords(ZONE_NAME)).andReturn(pageMock); + // again for options + expect(dns.listDnsRecords(ZONE_NAME, DNS_RECORD_OPTIONS)).andReturn(pageMock); + replay(dns); + Page result = zoneNoId.listDnsRecords(); + assertSame(pageMock, result); + verify(pageMock); + zoneNoId.listDnsRecords(DNS_RECORD_OPTIONS); // check options + } + + @Test + public void listDnsRecordsByNameAndNotFound() { + expect(dns.listDnsRecords(ZONE_NAME)).andReturn(null); + // again for options + expect(dns.listDnsRecords(ZONE_NAME, DNS_RECORD_OPTIONS)).andReturn(null); + replay(dns); + Page result = zoneNoId.listDnsRecords(); + assertNull(result); + zoneNoId.listDnsRecords(DNS_RECORD_OPTIONS); // check options + } + + @Test + public void reloadByIdAndFound() { + expect(dns.getZone(ZONE_ID)).andReturn(zone.info()); + expect(dns.getZone(ZONE_ID, ZONE_FIELD_OPTIONS)).andReturn(zone.info()); // for options + replay(dns); + Zone result = zone.reload(); + assertSame(zone.dns(), result.dns()); + assertEquals(zone.info(), result.info()); + zone.reload(ZONE_FIELD_OPTIONS); // for options + } + + @Test + public void reloadByIdAndNotFoundAndNameSetAndFound() { + expect(dns.getZone(ZONE_ID)).andReturn(null); + expect(dns.getZone(ZONE_NAME)).andReturn(zone.info()); + // again for options + expect(dns.getZone(ZONE_ID, ZONE_FIELD_OPTIONS)).andReturn(null); + expect(dns.getZone(ZONE_NAME, ZONE_FIELD_OPTIONS)).andReturn(zone.info()); + replay(dns); + Zone result = zone.reload(); + assertSame(zone.dns(), result.dns()); + assertEquals(zone.info(), result.info()); + zone.reload(ZONE_FIELD_OPTIONS); // for options + } + + @Test + public void reloadByIdAndNotFoundAndNameSetAndNotFound() { + expect(dns.getZone(ZONE_ID)).andReturn(null); + expect(dns.getZone(ZONE_NAME)).andReturn(null); + // again with options + expect(dns.getZone(ZONE_ID, ZONE_FIELD_OPTIONS)).andReturn(null); + expect(dns.getZone(ZONE_NAME, ZONE_FIELD_OPTIONS)).andReturn(null); + replay(dns); + Zone result = zone.reload(); + assertNull(result); + // again for options + zone.reload(ZONE_FIELD_OPTIONS); + } + + @Test + public void reloadByIdAndNotFoundAndNameNotSet() { + expect(dns.getZone(ZONE_ID)).andReturn(null); + expect(dns.getZone(ZONE_ID, ZONE_FIELD_OPTIONS)).andReturn(null); // for options + replay(dns); + Zone result = zoneNoName.reload(); + assertNull(result); + zoneNoName.reload(ZONE_FIELD_OPTIONS); // for options + } + + @Test + public void reloadByNameAndFound() { + expect(dns.getZone(ZONE_NAME)).andReturn(zoneNoId.info()); + // again for options + expect(dns.getZone(ZONE_NAME, ZONE_FIELD_OPTIONS)).andReturn(zoneNoId.info()); + replay(dns); + Zone result = zoneNoId.reload(); + assertSame(zoneNoId.dns(), result.dns()); + assertEquals(zoneNoId.info(), result.info()); + zoneNoId.reload(ZONE_FIELD_OPTIONS); // check options + } + + @Test + public void reloadByNameAndNotFound() { + expect(dns.getZone(ZONE_NAME)).andReturn(null); + // again for options + expect(dns.getZone(ZONE_NAME, ZONE_FIELD_OPTIONS)).andReturn(null); + replay(dns); + Zone result = zoneNoId.reload(); + assertNull(result); + zoneNoId.reload(ZONE_FIELD_OPTIONS); // for options + } + + @Test + public void applyChangeByIdAndFound() { + expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_ID)).andReturn(CHANGE_REQUEST_AFTER); + // again for options + expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) + .andReturn(CHANGE_REQUEST_AFTER); + replay(dns); + ChangeRequest result = zone.applyChangeRequest(CHANGE_REQUEST); + assertNotEquals(CHANGE_REQUEST, result); + assertEquals(CHANGE_REQUEST_AFTER, result); + // for options + result = zone.applyChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); + assertNotEquals(CHANGE_REQUEST, result); + assertEquals(CHANGE_REQUEST_AFTER, result); + } + + @Test + public void applyChangeByIdAndNotFoundAndNameSetAndFound() { + expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_ID)).andReturn(null); + expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_NAME)) + .andReturn(CHANGE_REQUEST_AFTER); + // again for options + expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) + .andReturn(null); + expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) + .andReturn(CHANGE_REQUEST_AFTER); + replay(dns); + ChangeRequest result = zone.applyChangeRequest(CHANGE_REQUEST); + assertNotEquals(CHANGE_REQUEST, result); + assertEquals(CHANGE_REQUEST_AFTER, result); + // for options + result = zone.applyChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); + assertNotEquals(CHANGE_REQUEST, result); + assertEquals(CHANGE_REQUEST_AFTER, result); + } + + @Test + public void applyChangeIdAndNotFoundAndNameSetAndNotFound() { + expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_ID)).andReturn(null); + expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_NAME)).andReturn(null); + // again with options + expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) + .andReturn(null); + expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) + .andReturn(null); + replay(dns); + ChangeRequest result = zone.applyChangeRequest(CHANGE_REQUEST); + assertNull(result); + // again for options + result = zone.applyChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); + assertNull(result); + } + + @Test + public void applyChangeRequestByIdAndNotFoundAndNameNotSet() { + expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_ID)).andReturn(null); + expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) + .andReturn(null); // for options + replay(dns); + ChangeRequest result = zoneNoName.applyChangeRequest(CHANGE_REQUEST); + assertNull(result); + // again for options + result = zoneNoName.applyChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); + assertNull(result); + } + + @Test + public void applyChangeByNameAndFound() { + // ID is not set + expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_NAME)) + .andReturn(CHANGE_REQUEST_AFTER); + // again for options + expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) + .andReturn(CHANGE_REQUEST_AFTER); + replay(dns); + ChangeRequest result = zoneNoId.applyChangeRequest(CHANGE_REQUEST); + assertEquals(CHANGE_REQUEST_AFTER, result); + // check options + result = zoneNoId.applyChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); + assertEquals(CHANGE_REQUEST_AFTER, result); + } + + @Test + public void applyChangeByNameAndNotFound() { + // ID is not set + expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_NAME)).andReturn(null); + // again for options + expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) + .andReturn(null); + replay(dns); + ChangeRequest result = zoneNoId.applyChangeRequest(CHANGE_REQUEST); + assertNull(result); + // check options + result = zoneNoId.applyChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); + assertNull(result); + } + + @Test + public void applyNullChangeRequest() { + replay(dns); // no calls expected + try { + zone.applyChangeRequest(null); + fail("Cannot apply null ChangeRequest."); + } catch (NullPointerException e) { + // expected + } + try { + zone.applyChangeRequest(null, CHANGE_REQUEST_FIELD_OPTIONS); + fail("Cannot apply null ChangeRequest."); + } catch (NullPointerException e) { + // expected + } + try { + zoneNoId.applyChangeRequest(null); + fail("Cannot apply null ChangeRequest."); + } catch (NullPointerException e) { + // expected + } + try { + zoneNoId.applyChangeRequest(null, CHANGE_REQUEST_FIELD_OPTIONS); + fail("Cannot apply null ChangeRequest."); + } catch (NullPointerException e) { + // expected + } + try { + zoneNoName.applyChangeRequest(null); + fail("Cannot apply null ChangeRequest."); + } catch (NullPointerException e) { + // expected + } + try { + zoneNoName.applyChangeRequest(null, CHANGE_REQUEST_FIELD_OPTIONS); + fail("Cannot apply null ChangeRequest."); + } catch (NullPointerException e) { + // expected + } + } + + @Test + public void getChangeByIdAndFound() { + expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_ID)).andReturn(CHANGE_REQUEST_AFTER); + // again for options + expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) + .andReturn(CHANGE_REQUEST_AFTER); + replay(dns); + ChangeRequest result = zone.getChangeRequest(CHANGE_REQUEST); + assertNotEquals(CHANGE_REQUEST, result); + assertEquals(CHANGE_REQUEST_AFTER, result); + // for options + result = zone.getChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); + assertNotEquals(CHANGE_REQUEST, result); + assertEquals(CHANGE_REQUEST_AFTER, result); + // test no id + } + + @Test + public void getChangeByIdAndNotFoundAndNameSetAndFound() { + expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_ID)).andReturn(null); + expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_NAME)) + .andReturn(CHANGE_REQUEST_AFTER); + // again for options + expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) + .andReturn(null); + expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) + .andReturn(CHANGE_REQUEST_AFTER); + replay(dns); + ChangeRequest result = zone.getChangeRequest(CHANGE_REQUEST); + assertNotEquals(CHANGE_REQUEST, result); + assertEquals(CHANGE_REQUEST_AFTER, result); + // for options + result = zone.getChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); + assertNotEquals(CHANGE_REQUEST, result); + assertEquals(CHANGE_REQUEST_AFTER, result); + } + + @Test + public void getChangeIdAndNotFoundAndNameSetAndNotFound() { + expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_ID)).andReturn(null); + expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_NAME)).andReturn(null); + // again with options + expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) + .andReturn(null); + expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) + .andReturn(null); + replay(dns); + ChangeRequest result = zone.getChangeRequest(CHANGE_REQUEST); + assertNull(result); + // again for options + result = zone.getChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); + assertNull(result); + } + + @Test + public void getChangeRequestByIdAndNotFoundAndNameNotSet() { + expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_ID)).andReturn(null); + expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) + .andReturn(null); // for options + replay(dns); + ChangeRequest result = zoneNoName.getChangeRequest(CHANGE_REQUEST); + assertNull(result); + // again for options + result = zoneNoName.getChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); + assertNull(result); + } + + @Test + public void getChangeByNameAndFound() { + // ID is not set + expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_NAME)) + .andReturn(CHANGE_REQUEST_AFTER); + // again for options + expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) + .andReturn(CHANGE_REQUEST_AFTER); + replay(dns); + ChangeRequest result = zoneNoId.getChangeRequest(CHANGE_REQUEST); + assertEquals(CHANGE_REQUEST_AFTER, result); + // check options + result = zoneNoId.getChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); + assertEquals(CHANGE_REQUEST_AFTER, result); + } + + @Test + public void getChangeByNameAndNotFound() { + // ID is not set + expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_NAME)).andReturn(null); + // again for options + expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) + .andReturn(null); + replay(dns); + ChangeRequest result = zoneNoId.getChangeRequest(CHANGE_REQUEST); + assertNull(result); + // check options + result = zoneNoId.getChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); + assertNull(result); + } + + @Test + public void getNullChangeRequest() { + replay(dns); // no calls expected + try { + zone.getChangeRequest(null); + fail("Cannot get null ChangeRequest."); + } catch (NullPointerException e) { + // expected + } + try { + zone.getChangeRequest(null, CHANGE_REQUEST_FIELD_OPTIONS); + fail("Cannot get null ChangeRequest."); + } catch (NullPointerException e) { + // expected + } + try { + zoneNoId.getChangeRequest(null); + fail("Cannot get null ChangeRequest."); + } catch (NullPointerException e) { + // expected + } + try { + zoneNoId.getChangeRequest(null, CHANGE_REQUEST_FIELD_OPTIONS); + fail("Cannot get null ChangeRequest."); + } catch (NullPointerException e) { + // expected + } + try { + zoneNoName.getChangeRequest(null); + fail("Cannot get null ChangeRequest."); + } catch (NullPointerException e) { + // expected + } + try { + zoneNoName.getChangeRequest(null, CHANGE_REQUEST_FIELD_OPTIONS); + fail("Cannot get null ChangeRequest."); + } catch (NullPointerException e) { + // expected + } + } + + @Test + public void getChangeRequestWithNoId() { + replay(dns); // no calls expected + try { + zone.getChangeRequest(CHANGE_REQUEST_NO_ID); + fail("Cannot get ChangeRequest with no id."); + } catch (NullPointerException e) { + // expected + } + try { + zone.getChangeRequest(CHANGE_REQUEST_NO_ID, CHANGE_REQUEST_FIELD_OPTIONS); + fail("Cannot get ChangeRequest with no id."); + } catch (NullPointerException e) { + // expected + } + try { + zoneNoId.getChangeRequest(CHANGE_REQUEST_NO_ID); + fail("Cannot get ChangeRequest with no id."); + } catch (NullPointerException e) { + // expected + } + try { + zoneNoId.getChangeRequest(CHANGE_REQUEST_NO_ID, CHANGE_REQUEST_FIELD_OPTIONS); + fail("Cannot get ChangeRequest with no id."); + } catch (NullPointerException e) { + // expected + } + try { + zoneNoName.getChangeRequest(CHANGE_REQUEST_NO_ID); + fail("Cannot get ChangeRequest with no id."); + } catch (NullPointerException e) { + // expected + } + try { + zoneNoName.getChangeRequest(CHANGE_REQUEST_NO_ID, CHANGE_REQUEST_FIELD_OPTIONS); + fail("Cannot get ChangeRequest with no id."); + } catch (NullPointerException e) { + // expected + } + } + + @Test + public void listChangeRequestsByIdAndFound() { + Page pageMock = createStrictMock(Page.class); + replay(pageMock); + expect(dns.listChangeRequests(ZONE_ID)).andReturn(pageMock); + // again for options + expect(dns.listChangeRequests(ZONE_ID, CHANGE_REQUEST_LIST_OPTIONS)).andReturn(pageMock); + replay(dns); + Page result = zone.listChangeRequests(); + assertSame(pageMock, result); + verify(pageMock); + // verify options + zone.listChangeRequests(CHANGE_REQUEST_LIST_OPTIONS); + } + + @Test + public void listChangeRequestsByIdAndNotFoundAndNameSetAndFound() { + Page pageMock = createStrictMock(Page.class); + replay(pageMock); + expect(dns.listChangeRequests(ZONE_ID)).andReturn(null); + expect(dns.listChangeRequests(ZONE_NAME)).andReturn(pageMock); + // again for options + expect(dns.listChangeRequests(ZONE_ID, CHANGE_REQUEST_LIST_OPTIONS)).andReturn(null); + expect(dns.listChangeRequests(ZONE_NAME, CHANGE_REQUEST_LIST_OPTIONS)) + .andReturn(pageMock); + replay(dns); + Page result = zone.listChangeRequests(); + assertSame(pageMock, result); + verify(pageMock); + // verify options + zone.listChangeRequests(CHANGE_REQUEST_LIST_OPTIONS); + } + + @Test + public void listChangeRequestsByIdAndNotFoundAndNameSetAndNotFound() { + expect(dns.listChangeRequests(ZONE_ID)).andReturn(null); + expect(dns.listChangeRequests(ZONE_NAME)).andReturn(null); + // again for options + expect(dns.listChangeRequests(ZONE_ID, CHANGE_REQUEST_LIST_OPTIONS)).andReturn(null); + expect(dns.listChangeRequests(ZONE_NAME, CHANGE_REQUEST_LIST_OPTIONS)).andReturn(null); + replay(dns); + Page result = zone.listChangeRequests(); + assertNull(result); + // check options + zone.listChangeRequests(CHANGE_REQUEST_LIST_OPTIONS); + } + + @Test + public void listChangeRequestsByIdAndNotFoundAndNameNotSet() { + expect(dns.listChangeRequests(ZONE_ID)).andReturn(null); + // again for options + expect(dns.listChangeRequests(ZONE_ID, CHANGE_REQUEST_LIST_OPTIONS)).andReturn(null); + replay(dns); + Page result = zoneNoName.listChangeRequests(); + assertNull(result); + zoneNoName.listChangeRequests(CHANGE_REQUEST_LIST_OPTIONS); // check options + } + + @Test + public void listChangeRequestsByNameAndFound() { + Page pageMock = createStrictMock(Page.class); + replay(pageMock); + expect(dns.listChangeRequests(ZONE_NAME)).andReturn(pageMock); + // again for options + expect(dns.listChangeRequests(ZONE_NAME, CHANGE_REQUEST_LIST_OPTIONS)) + .andReturn(pageMock); + replay(dns); + Page result = zoneNoId.listChangeRequests(); + assertSame(pageMock, result); + verify(pageMock); + zoneNoId.listChangeRequests(CHANGE_REQUEST_LIST_OPTIONS); // check options + } + + @Test + public void listChangeRequestsByNameAndNotFound() { + expect(dns.listChangeRequests(ZONE_NAME)).andReturn(null); + // again for options + expect(dns.listChangeRequests(ZONE_NAME, CHANGE_REQUEST_LIST_OPTIONS)).andReturn(null); + replay(dns); + Page result = zoneNoId.listChangeRequests(); + assertNull(result); + zoneNoId.listChangeRequests(CHANGE_REQUEST_LIST_OPTIONS); // check options + } +} From d27d567606f198822c5ec2b4a5e8c592e263abec Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 1 Feb 2016 17:35:06 -0800 Subject: [PATCH 058/375] Fix ServiceOptions merge bug, remove unnecessary protected modifier from DateTime, set cursorAfter to endCursor where appropriate, and fix error codes for retries. --- .../com/google/gcloud/ServiceOptions.java | 4 +--- .../gcloud/datastore/DatastoreException.java | 4 +--- .../com/google/gcloud/datastore/DateTime.java | 4 ++-- .../gcloud/datastore/QueryResultsImpl.java | 1 + .../datastore/DatastoreExceptionTest.java | 20 +++++++++---------- .../gcloud/datastore/DatastoreTest.java | 2 +- 6 files changed, 16 insertions(+), 19 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java index 34280dbf92e5..31e543809464 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java @@ -18,7 +18,6 @@ import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; import static java.nio.charset.StandardCharsets.UTF_8; import com.google.api.client.extensions.appengine.http.UrlFetchTransport; @@ -229,8 +228,7 @@ public B clock(Clock clock) { * @return the builder */ public B projectId(String projectId) { - this.projectId = - checkNotNull(projectId, "Project ID cannot be set to null. Leave unset for default."); + this.projectId = projectId; return self(); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreException.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreException.java index ecad69ac635b..a940fe573f93 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreException.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreException.java @@ -34,9 +34,7 @@ public class DatastoreException extends BaseServiceException { // see https://cloud.google.com/datastore/docs/concepts/errors#Error_Codes" private static final Set RETRYABLE_ERRORS = ImmutableSet.of( - new Error(409, "ABORTED"), - new Error(403, "DEADLINE_EXCEEDED"), - new Error(503, "UNAVAILABLE")); + new Error(10, "ABORTED"), new Error(4, "DEADLINE_EXCEEDED"), new Error(14, "UNAVAILABLE")); private static final long serialVersionUID = 2663750991205874435L; public DatastoreException(int code, String message, String reason, Throwable cause) { diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java index 45347ed41dcb..5e8664395802 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java @@ -106,11 +106,11 @@ Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { com.google.protobuf.Timestamp.parseFrom(bytesPb))); } - protected static long timestampPbToMicroseconds(com.google.protobuf.Timestamp timestampPb) { + static long timestampPbToMicroseconds(com.google.protobuf.Timestamp timestampPb) { return timestampPb.getSeconds() * 1000000 + timestampPb.getNanos() / 1000; } - protected static com.google.protobuf.Timestamp microsecondsToTimestampPb(long microseconds) { + static com.google.protobuf.Timestamp microsecondsToTimestampPb(long microseconds) { long seconds = microseconds / 1000000; int nanos = (int) (microseconds % 1000000) * 1000; return com.google.protobuf.Timestamp.newBuilder().setSeconds(seconds).setNanos(nanos).build(); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java index 25dde18a1a1b..ec3a652c6131 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java @@ -93,6 +93,7 @@ protected T computeNext() { sendRequest(); } if (!entityResultPbIter.hasNext()) { + cursor = runQueryResponsePb.getBatch().getEndCursor(); return endOfData(); } com.google.datastore.v1beta3.EntityResult entityResultPb = entityResultPbIter.next(); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreExceptionTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreExceptionTest.java index 4d62224172f9..301a863476b6 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreExceptionTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreExceptionTest.java @@ -38,29 +38,29 @@ public class DatastoreExceptionTest { @Test public void testDatastoreException() throws Exception { - DatastoreException exception = new DatastoreException(409, "message", "ABORTED"); - assertEquals(409, exception.code()); + DatastoreException exception = new DatastoreException(10, "message", "ABORTED"); + assertEquals(10, exception.code()); assertEquals("ABORTED", exception.reason()); assertEquals("message", exception.getMessage()); assertTrue(exception.retryable()); assertTrue(exception.idempotent()); - exception = new DatastoreException(403, "message", "DEADLINE_EXCEEDED"); - assertEquals(403, exception.code()); + exception = new DatastoreException(4, "message", "DEADLINE_EXCEEDED"); + assertEquals(4, exception.code()); assertEquals("DEADLINE_EXCEEDED", exception.reason()); assertEquals("message", exception.getMessage()); assertTrue(exception.retryable()); assertTrue(exception.idempotent()); - exception = new DatastoreException(503, "message", "UNAVAILABLE"); - assertEquals(503, exception.code()); + exception = new DatastoreException(14, "message", "UNAVAILABLE"); + assertEquals(14, exception.code()); assertEquals("UNAVAILABLE", exception.reason()); assertEquals("message", exception.getMessage()); assertTrue(exception.retryable()); assertTrue(exception.idempotent()); - exception = new DatastoreException(500, "message", "INTERNAL"); - assertEquals(500, exception.code()); + exception = new DatastoreException(2, "message", "INTERNAL"); + assertEquals(2, exception.code()); assertEquals("INTERNAL", exception.reason()); assertEquals("message", exception.getMessage()); assertFalse(exception.retryable()); @@ -77,14 +77,14 @@ public void testDatastoreException() throws Exception { @Test public void testTranslateAndThrow() throws Exception { - DatastoreException cause = new DatastoreException(503, "message", "UNAVAILABLE"); + DatastoreException cause = new DatastoreException(14, "message", "UNAVAILABLE"); RetryHelper.RetryHelperException exceptionMock = createMock(RetryHelper.RetryHelperException.class); expect(exceptionMock.getCause()).andReturn(cause).times(2); replay(exceptionMock); try { DatastoreException.translateAndThrow(exceptionMock); } catch (BaseServiceException ex) { - assertEquals(503, ex.code()); + assertEquals(14, ex.code()); assertEquals("message", ex.getMessage()); assertTrue(ex.retryable()); assertTrue(ex.idempotent()); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index a39952c448eb..002e5f6df04f 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -986,7 +986,7 @@ public void testRetryableException() throws Exception { EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) .andReturn(rpcMock); EasyMock.expect(rpcMock.lookup(requestPb)) - .andThrow(new DatastoreException(503, "UNAVAILABLE", "UNAVAILABLE", null)) + .andThrow(new DatastoreException(14, "UNAVAILABLE", "UNAVAILABLE", null)) .andReturn(responsePb); EasyMock.replay(rpcFactoryMock, rpcMock); DatastoreOptions options = this.options.toBuilder() From e083dfd87052a3231067cf0b0535e899d279d5c3 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Tue, 2 Feb 2016 12:39:08 -0800 Subject: [PATCH 059/375] Fixed documentation and some code formatting. Declared exceptions to be thrown when parent objects do not exist. Changed contracts of applyChangeRequest and getChangeRequest methods. Adjusted tests. --- .../main/java/com/google/gcloud/dns/Dns.java | 147 +++++++++--------- .../main/java/com/google/gcloud/dns/Zone.java | 92 +++++------ .../java/com/google/gcloud/dns/DnsTest.java | 2 +- .../java/com/google/gcloud/dns/ZoneTest.java | 112 ++++++------- 4 files changed, 171 insertions(+), 182 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index b48e4b0a90f2..130e8bb99f5e 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -37,7 +37,7 @@ public interface Dns extends Service { * The fields of a project. * *

These values can be used to specify the fields to include in a partial response when calling - * {@code Dns#getProjectInfo(ProjectGetOption...)}. Project ID is always returned, even if not + * {@link Dns#getProjectInfo(ProjectOption...)}. Project ID is always returned, even if not * specified. */ enum ProjectField { @@ -69,7 +69,7 @@ static String selector(ProjectField... fields) { * The fields of a zone. * *

These values can be used to specify the fields to include in a partial response when calling - * {@code Dns#getZone(BigInteger, ZoneOption...)} or {@code Dns#getZone(String, ZoneOption...)}. + * {@link Dns#getZone(BigInteger, ZoneOption...)} or {@link Dns#getZone(String, ZoneOption...)}. * The ID is always returned, even if not specified. */ enum ZoneField { @@ -105,7 +105,7 @@ static String selector(ZoneField... fields) { * The fields of a DNS record. * *

These values can be used to specify the fields to include in a partial response when calling - * {@code Dns#listDnsRecords(BigInteger, DnsRecordListOption...)} or {@code + * {@link Dns#listDnsRecords(BigInteger, DnsRecordListOption...)} or {@link * Dns#listDnsRecords(String, DnsRecordListOption...)}. The name is always returned even if not * selected. */ @@ -139,8 +139,8 @@ static String selector(DnsRecordField... fields) { * The fields of a change request. * *

These values can be used to specify the fields to include in a partial response when calling - * {@code Dns#applyChangeRequest(ChangeRequest, BigInteger, ChangeRequestOption...)} or {@code - * Dns#applyChangeRequest(ChangeRequest, String, ChangeRequestOption...)} The ID is always + * {@link Dns#applyChangeRequest(BigInteger, ChangeRequest, ChangeRequestOption...)} or {@link + * Dns#applyChangeRequest(String, ChangeRequest, ChangeRequestOption...)} The ID is always * returned even if not selected. */ enum ChangeRequestField { @@ -313,11 +313,11 @@ public static ZoneListOption pageSize(int pageSize) { /** * Class for specifying project options. */ - class ProjectGetOption extends AbstractOption implements Serializable { + class ProjectOption extends AbstractOption implements Serializable { private static final long serialVersionUID = 6817937338218847748L; - ProjectGetOption(DnsRpc.Option option, Object value) { + ProjectOption(DnsRpc.Option option, Object value) { super(option, value); } @@ -325,12 +325,12 @@ class ProjectGetOption extends AbstractOption implements Serializable { * Returns an option to specify the project's fields to be returned by the RPC call. * *

If this option is not provided all project fields are returned. {@code - * ProjectGetOption.fields} can be used to specify only the fields of interest. Project ID is + * ProjectOption.fields} can be used to specify only the fields of interest. Project ID is * always returned, even if not specified. {@link ProjectField} provides a list of fields that * can be used. */ - public static ProjectGetOption fields(ProjectField... fields) { - return new ProjectGetOption(DnsRpc.Option.FIELDS, ProjectField.selector(fields)); + public static ProjectOption fields(ProjectField... fields) { + return new ProjectOption(DnsRpc.Option.FIELDS, ProjectField.selector(fields)); } } @@ -423,10 +423,11 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) { /** * Creates a new zone. * - * @return ZoneInfo object representing the new zone's metadata. In addition to the name, dns name - * and description (supplied by the user within the {@code zoneInfo} parameter, the returned - * object will include the following read-only fields supplied by the server: creation time, id, - * and list of name servers. + *

Returns {@link ZoneInfo} object representing the new zone's information. In addition to the + * name, dns name and description (supplied by the user within the {@code zoneInfo} parameter), + * the returned object will include the following read-only fields supplied by the server: + * creation time, id, and list of name servers. + * * @throws DnsException upon failure * @see Cloud DNS Managed Zones: * create @@ -434,8 +435,8 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) { ZoneInfo create(ZoneInfo zoneInfo); /** - * Retrieves the zone by the specified zone name. Returns {@code null} is the zone is not found. - * The returned fields can be optionally restricted by specifying {@code ZoneFieldOptions}. + * Returns the zone by the specified zone name. Returns {@code null} if the zone is not found. The + * returned fields can be optionally restricted by specifying {@link ZoneOption}s. * * @throws DnsException upon failure * @see Cloud DNS Managed Zones: @@ -444,8 +445,8 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) { ZoneInfo getZone(String zoneName, ZoneOption... options); /** - * Retrieves the zone by the specified zone name. Returns {@code null} is the zone is not found. - * The returned fields can be optionally restricted by specifying {@code ZoneFieldOptions}. + * Returns the zone by the specified zone id. Returns {@code null} if the zone is not found. The + * returned fields can be optionally restricted by specifying {@link ZoneOption}s. * * @throws DnsException upon failure * @see Cloud DNS Managed Zones: @@ -454,13 +455,13 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) { ZoneInfo getZone(BigInteger zoneId, ZoneOption... options); /** - * Lists the zoned inside the project. + * Lists the zones inside the project. * - *

This method returns zone in an unspecified order. New zones do not necessarily appear at the - * end of the list. Use {@link ZoneListOption} to restrict the listing to a domain name, set page - * size, and set page tokens. + *

This method returns zones in an unspecified order. New zones do not necessarily appear at + * the end of the list. Use {@link ZoneListOption} to restrict the listing to a domain name, set + * page size, and set page token. * - * @return {@code Page}, a page of zones + * @return a page of zones * @throws DnsException upon failure * @see Cloud DNS Managed Zones: * list @@ -468,10 +469,10 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) { Page listZones(ZoneListOption... options); /** - * Deletes an existing zone identified by name. Returns true if the zone was successfully deleted - * and false otherwise. + * Deletes an existing zone identified by name. Returns {@code true} if the zone was successfully + * deleted and {@code false} otherwise. * - * @return {@code true} if zone was found and deleted and false otherwise + * @return {@code true} if zone was found and deleted and {@code false} otherwise * @throws DnsException upon failure * @see Cloud DNS Managed Zones: * delete @@ -479,10 +480,10 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) { boolean delete(String zoneName); // delete does not admit any options /** - * Deletes an existing zone identified by id. Returns true if the zone was successfully deleted - * and false otherwise. + * Deletes an existing zone identified by id. Returns {@code true} if the zone was successfully + * deleted and {@code false} otherwise. * - * @return {@code true} if zone was found and deleted and false otherwise + * @return {@code true} if zone was found and deleted and {@code false} otherwise * @throws DnsException upon failure * @see Cloud DNS Managed Zones: * delete @@ -492,10 +493,10 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) { /** * Lists the DNS records in the zone identified by name. * - *

The fields to be returned, page size and page tokens can be specified using {@code - * DnsRecordOptions}. Returns null if the zone cannot be found. + *

The fields to be returned, page size and page tokens can be specified using {@link + * DnsRecordListOption}s. * - * @throws DnsException upon failure + * @throws DnsException upon failure or if the zone cannot be found * @see Cloud DNS * ResourceRecordSets: list */ @@ -504,23 +505,23 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) { /** * Lists the DNS records in the zone identified by ID. * - *

The fields to be returned, page size and page tokens can be specified using {@code - * DnsRecordOptions}. Returns null if the zone cannot be found. + *

The fields to be returned, page size and page tokens can be specified using {@link + * DnsRecordListOption}s. * - * @throws DnsException upon failure + * @throws DnsException upon failure or if the zone cannot be found * @see Cloud DNS * ResourceRecordSets: list */ Page listDnsRecords(BigInteger zoneId, DnsRecordListOption... options); /** - * Retrieves the metadata about the current project. The returned fields can be optionally - * restricted by specifying {@code ProjectOptions}. + * Retrieves the information about the current project. The returned fields can be optionally + * restricted by specifying {@link ProjectOption}s. * * @throws DnsException upon failure * @see Cloud DNS Projects: get */ - ProjectInfo getProjectInfo(ProjectGetOption... fields); + ProjectInfo getProjectInfo(ProjectOption... fields); /** * Returns the current project id. @@ -533,64 +534,61 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) { BigInteger getProjectNumber(); /** - * Submits a change requests for applying to the zone identified by ID to the service. The - * returned object contains the following read-only fields supplied by the server: id, start time - * and status. time, id, and list of name servers. The returned fields can be modified by {@code - * ChangeRequestFieldOptions}. Returns null if the zone is not found. + * Submits a change request for the specified zone. The returned object contains the following + * read-only fields supplied by the server: id, start time and status. time, id, and list of name + * servers. The fields to be returned can be selected by {@link ChangeRequestOption}s. * - * @return ChangeRequest object representing the new change request or null if zone is not found + * @return the new {@link ChangeRequest} or {@code null} if zone is not found * @throws DnsException upon failure * @see Cloud DNS Changes: create */ - ChangeRequest applyChangeRequest(ChangeRequest changeRequest, BigInteger zoneId, - ChangeRequestOption... options); + ChangeRequest applyChangeRequest(BigInteger zoneId, ChangeRequest changeRequest, + ChangeRequestOption... options); /** - * Submits a change requests for applying to the zone identified by name to the service. The - * returned object contains the following read-only fields supplied by the server: id, start time - * and status. time, id, and list of name servers. The returned fields can be modified by {@code - * ChangeRequestFieldOptions}. Returns null if the zone is not found. + * Submits a change request for the specified zone. The returned object contains the following + * read-only fields supplied by the server: id, start time and status. time, id, and list of name + * servers. The fields to be returned can be selected by {@link ChangeRequestOption}s. * - * @return ChangeRequest object representing the new change request or null if zone is not found - * @throws DnsException upon failure + * @return the new {@link ChangeRequest} + * @throws DnsException upon failure if zone is not found * @see Cloud DNS Changes: create */ - ChangeRequest applyChangeRequest(ChangeRequest changeRequest, String zoneName, - ChangeRequestOption... options); + ChangeRequest applyChangeRequest(String zoneName, ChangeRequest changeRequest, + ChangeRequestOption... options); /** * Retrieves updated information about a change request previously submitted for a zone identified - * by ID. Returns null if the zone or request cannot be found. - * - *

The fields to be returned using {@code ChangeRequestFieldOptions}. + * by ID. Returns {@code null} if the request cannot be found and throws an exception if the zone + * does not exist. The fields to be returned using can be specified using {@link + * ChangeRequestOption}s. * - * @throws DnsException upon failure + * @throws DnsException upon failure or if the zone cannot be found * @see Cloud DNS Chages: get */ - ChangeRequest getChangeRequest(ChangeRequest changeRequest, BigInteger zoneId, - ChangeRequestOption... options); + ChangeRequest getChangeRequest(String changeRequestId, BigInteger zoneId, + ChangeRequestOption... options); /** * Retrieves updated information about a change request previously submitted for a zone identified - * by name. Returns null if the zone or request cannot be found. - * - *

The fields to be returned using {@code ChangeRequestFieldOptions}. + * by ID. Returns {@code null} if the request cannot be found and throws an exception if the zone + * does not exist. The fields to be returned using can be specified using {@link + * ChangeRequestOption}s. * - * @throws DnsException upon failure + * @throws DnsException upon failure or if the zone cannot be found * @see Cloud DNS Chages: get */ - ChangeRequest getChangeRequest(ChangeRequest changeRequest, String zoneName, - ChangeRequestOption... options); + ChangeRequest getChangeRequest(String changeRequestId, String zoneName, + ChangeRequestOption... options); /** * Lists the change requests for the zone identified by ID that were submitted to the service. * - *

The sorting key for changes, fields to be returned, page and page tokens can be specified - * using {@code ChangeRequestListOptions}. Note that the only sorting key currently supported is - * the timestamp of submitting the change request to the service. + *

The sorting order for changes (based on when they were received by the server), fields to be + * returned, page size and page token can be specified using {@link ChangeRequestListOption}s. * - * @return {@code Page}, a page of change requests - * @throws DnsException upon failure + * @return A page of change requests + * @throws DnsException upon failure or if the zone cannot be found * @see Cloud DNS Chages: list */ Page listChangeRequests(BigInteger zoneId, ChangeRequestListOption... options); @@ -598,12 +596,11 @@ ChangeRequest getChangeRequest(ChangeRequest changeRequest, String zoneName, /** * Lists the change requests for the zone identified by name that were submitted to the service. * - *

The sorting key for changes, fields to be returned, page and page tokens can be specified - * using {@code ChangeRequestListOptions}. Note that the only sorting key currently supported is - * the timestamp of submitting the change request to the service. + *

The sorting order for changes (based on when they were received by the server), fields to be + * returned, page size and page token can be specified using {@link ChangeRequestListOption}s. * - * @return {@code Page}, a page of change requests - * @throws DnsException upon failure + * @return A page of change requests + * @throws DnsException upon failure or if the zone cannot be found * @see Cloud DNS Chages: list */ Page listChangeRequests(String zoneName, ChangeRequestListOption... options); diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java index f4d9702ba12f..dc0be8b94b44 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java @@ -16,6 +16,7 @@ package com.google.gcloud.dns; +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import com.google.gcloud.Page; @@ -52,15 +53,14 @@ public Zone(Dns dns, ZoneInfo zoneInfo) { /** * Constructs a {@code Zone} object that contains meta information received from the Google Cloud - * DNS service for the provided zoneName. + * DNS service for the provided {@code zoneName}. * - * @param zoneName Name of the zone to be searched for - * @param options Optional restriction on what fields should be returned by the service - * @return Zone object containing metadata or null if not not found + * @param zoneName name of the zone to be searched for + * @param options optional restriction on what fields should be returned by the service + * @return zone object containing metadata or {@code null} if not not found * @throws DnsException upon failure */ - public static Zone get(Dns dnsService, String zoneName, - Dns.ZoneOption... options) { + public static Zone get(Dns dnsService, String zoneName, Dns.ZoneOption... options) { checkNotNull(zoneName); checkNotNull(dnsService); ZoneInfo zoneInfo = dnsService.getZone(zoneName, options); @@ -68,16 +68,15 @@ public static Zone get(Dns dnsService, String zoneName, } /** - * Constructs a {@code Zone} object that contains meta information received from the Google Cloud - * DNS service for the provided zoneName. + * Constructs a {@code Zone} object that contains information received from the Google Cloud DNS + * service for the provided {@code zoneId}. * * @param zoneId ID of the zone to be searched for - * @param options Optional restriction on what fields should be returned by the service - * @return Zone object containing metadata or null if not not found + * @param options optional restriction on what fields should be returned by the service + * @return zone object containing zone's information or {@code null} if not not found * @throws DnsException upon failure */ - public static Zone get(Dns dnsService, BigInteger zoneId, - Dns.ZoneOption... options) { + public static Zone get(Dns dnsService, BigInteger zoneId, Dns.ZoneOption... options) { checkNotNull(zoneId); checkNotNull(dnsService); ZoneInfo zoneInfo = dnsService.getZone(zoneId, options); @@ -88,8 +87,8 @@ public static Zone get(Dns dnsService, BigInteger zoneId, * Retrieves the latest information about the zone. The method first attempts to retrieve the zone * by ID and if not set or zone is not found, it searches by name. * - * @param options Optional restriction on what fields should be fetched - * @return Zone object containing updated metadata or null if not not found + * @param options optional restriction on what fields should be fetched + * @return zone object containing updated information or {@code null} if not not found * @throws DnsException upon failure * @throws NullPointerException if both zone ID and name are not initialized */ @@ -110,7 +109,7 @@ public Zone reload(Dns.ZoneOption... options) { * Deletes the zone. The method first attempts to delete the zone by ID. If the zone is not found * or id is not set, it attempts to delete by name. * - * @return true is zone was found and deleted and false otherwise + * @return {@code true} is zone was found and deleted and {@code false} otherwise * @throws DnsException upon failure * @throws NullPointerException if both zone ID and name are not initialized */ @@ -131,10 +130,10 @@ public boolean delete() { * Lists all {@link DnsRecord}s associated with this zone. First searches for zone by ID and if * not found then by name. * - * @param options Optional restriction on listing and on what fields of {@link DnsRecord} should + * @param options optional restriction on listing and on what fields of {@link DnsRecord} should * be returned by the service - * @return {@code Page}, a page of DNS records, or null if the zone is not found - * @throws DnsException upon failure + * @return a page of DNS records + * @throws DnsException upon failure or if the zone is not found * @throws NullPointerException if both zone ID and name are not initialized */ public Page listDnsRecords(Dns.DnsRecordListOption... options) { @@ -153,25 +152,24 @@ public Page listDnsRecords(Dns.DnsRecordListOption... options) { /** * Submits {@link ChangeRequest} to the service for it to applied to this zone. First searches for * the zone by ID and if not found then by name. Returns a {@link ChangeRequest} with - * server-assigned ID or null if the zone was not found. + * server-assigned ID or {@code null} if the zone was not found. * - * @param options Optional restriction on what fields of {@link ChangeRequest} should be returned - * by the service - * @return ChangeRequest with server-assigned ID or null if the zone was not found. - * @throws DnsException upon failure + * @param options optional restriction on what fields of {@link ChangeRequest} should be returned + * @return ChangeRequest with server-assigned ID + * @throws DnsException upon failure or if the zone is not found * @throws NullPointerException if both zone ID and name are not initialized */ public ChangeRequest applyChangeRequest(ChangeRequest changeRequest, - Dns.ChangeRequestOption... options) { + Dns.ChangeRequestOption... options) { checkNameOrIdNotNull(); checkNotNull(changeRequest); ChangeRequest updated = null; if (zoneInfo.id() != null) { - updated = dns.applyChangeRequest(changeRequest, zoneInfo.id(), options); + updated = dns.applyChangeRequest(zoneInfo.id(), changeRequest, options); } if (updated == null && zoneInfo.name() != null) { // zone was not found by id or id is not set at all - updated = dns.applyChangeRequest(changeRequest, zoneInfo.name(), options); + updated = dns.applyChangeRequest(zoneInfo.name(), changeRequest, options); } return updated; } @@ -179,41 +177,38 @@ public ChangeRequest applyChangeRequest(ChangeRequest changeRequest, /** * Retrieves an updated information about a change request previously submitted to be applied to * this zone. First searches for the zone by ID and if not found then by name. Returns a {@link - * ChangeRequest} if found and null is the zone or the change request was not found. + * ChangeRequest} if found and {@code null} is the zone or the change request was not found. * - * @param options Optional restriction on what fields of {@link ChangeRequest} should be returned - * by the service - * @return ChangeRequest with updated information of null if the change request or zone was not - * found. - * @throws DnsException upon failure + * @param options optional restriction on what fields of {@link ChangeRequest} should be returned + * @return updated ChangeRequest + * @throws DnsException upon failure or if the zone is not found * @throws NullPointerException if both zone ID and name are not initialized * @throws NullPointerException if the change request does not have initialized id */ - public ChangeRequest getChangeRequest(ChangeRequest changeRequest, - Dns.ChangeRequestOption... options) { + public ChangeRequest getChangeRequest(String changeRequestId, + Dns.ChangeRequestOption... options) { checkNameOrIdNotNull(); - checkNotNull(changeRequest); - checkNotNull(changeRequest.id()); + checkNotNull(changeRequestId); ChangeRequest updated = null; if (zoneInfo.id() != null) { - updated = dns.getChangeRequest(changeRequest, zoneInfo.id(), options); + updated = dns.getChangeRequest(changeRequestId, zoneInfo.id(), options); } if (updated == null && zoneInfo.name() != null) { // zone was not found by id or id is not set at all - updated = dns.getChangeRequest(changeRequest, zoneInfo.name(), options); + updated = dns.getChangeRequest(changeRequestId, zoneInfo.name(), options); } return updated; } /** * Retrieves all change requests for this zone. First searches for the zone by ID and if not found - * then by name. Returns a page of {@link ChangeRequest}s or null if the zone is not found. + * then by name. Returns a page of {@link ChangeRequest}s or {@code null} if the zone is not + * found. * - * @param options Optional restriction on listing and on what fields of {@link ChangeRequest}s + * @param options optional restriction on listing and on what fields of {@link ChangeRequest}s * should be returned by the service - * @return {@code Page}, a page of change requests, or null if the zone is not - * found - * @throws DnsException upon failure + * @return a page of change requests + * @throws DnsException upon failure or if the zone is not found * @throws NullPointerException if both zone ID and name are not initialized */ public Page listChangeRequests(Dns.ChangeRequestListOption... options) { @@ -233,24 +228,21 @@ public Page listChangeRequests(Dns.ChangeRequestListOption... opt * Check that at least one of name and ID are initialized and throw and exception if not. */ private void checkNameOrIdNotNull() { - if (zoneInfo != null && zoneInfo.id() == null && zoneInfo.name() == null) { - throw new NullPointerException("Both zoneInfo.id and zoneInfo.name are null. " - + "This is an inconsistent state which should never happen."); - } + checkArgument(zoneInfo != null && (zoneInfo.id() != null || zoneInfo.name() != null), + "Both zoneInfo.id and zoneInfo.name are null. This is should never happen."); } /** - * Returns the {@link ZoneInfo} object containing meta information about this managed zone. + * Returns the {@link ZoneInfo} object containing information about this zone. */ public ZoneInfo info() { return this.zoneInfo; } /** - * Returns the {@link Dns} service object associated with this managed zone. + * Returns the {@link Dns} service object associated with this zone. */ public Dns dns() { return this.dns; } - } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java index 2e98dbd46de4..a60cae1d1793 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java @@ -94,7 +94,7 @@ public void testZoneList() { @Test public void testProjectGetOption() { // fields - Dns.ProjectGetOption fields = Dns.ProjectGetOption.fields(Dns.ProjectField.QUOTA); + Dns.ProjectOption fields = Dns.ProjectOption.fields(Dns.ProjectField.QUOTA); assertEquals(DnsRpc.Option.FIELDS, fields.rpcOption()); assertTrue(fields.value() instanceof String); assertTrue(((String) fields.value()).contains(Dns.ProjectField.QUOTA.selector())); diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java index 5f9d119e6150..a87bb969855b 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java @@ -348,9 +348,9 @@ public void reloadByNameAndNotFound() { @Test public void applyChangeByIdAndFound() { - expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_ID)).andReturn(CHANGE_REQUEST_AFTER); + expect(dns.applyChangeRequest(ZONE_ID, CHANGE_REQUEST)).andReturn(CHANGE_REQUEST_AFTER); // again for options - expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.applyChangeRequest(ZONE_ID, CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(CHANGE_REQUEST_AFTER); replay(dns); ChangeRequest result = zone.applyChangeRequest(CHANGE_REQUEST); @@ -364,13 +364,13 @@ public void applyChangeByIdAndFound() { @Test public void applyChangeByIdAndNotFoundAndNameSetAndFound() { - expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_ID)).andReturn(null); - expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_NAME)) + expect(dns.applyChangeRequest(ZONE_ID, CHANGE_REQUEST)).andReturn(null); + expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST)) .andReturn(CHANGE_REQUEST_AFTER); // again for options - expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.applyChangeRequest(ZONE_ID, CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(null); - expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(CHANGE_REQUEST_AFTER); replay(dns); ChangeRequest result = zone.applyChangeRequest(CHANGE_REQUEST); @@ -384,12 +384,12 @@ public void applyChangeByIdAndNotFoundAndNameSetAndFound() { @Test public void applyChangeIdAndNotFoundAndNameSetAndNotFound() { - expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_ID)).andReturn(null); - expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_NAME)).andReturn(null); + expect(dns.applyChangeRequest(ZONE_ID, CHANGE_REQUEST)).andReturn(null); + expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST)).andReturn(null); // again with options - expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.applyChangeRequest(ZONE_ID, CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(null); - expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(null); replay(dns); ChangeRequest result = zone.applyChangeRequest(CHANGE_REQUEST); @@ -401,8 +401,8 @@ public void applyChangeIdAndNotFoundAndNameSetAndNotFound() { @Test public void applyChangeRequestByIdAndNotFoundAndNameNotSet() { - expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_ID)).andReturn(null); - expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.applyChangeRequest(ZONE_ID, CHANGE_REQUEST)).andReturn(null); + expect(dns.applyChangeRequest(ZONE_ID, CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(null); // for options replay(dns); ChangeRequest result = zoneNoName.applyChangeRequest(CHANGE_REQUEST); @@ -415,10 +415,10 @@ public void applyChangeRequestByIdAndNotFoundAndNameNotSet() { @Test public void applyChangeByNameAndFound() { // ID is not set - expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_NAME)) + expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST)) .andReturn(CHANGE_REQUEST_AFTER); // again for options - expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(CHANGE_REQUEST_AFTER); replay(dns); ChangeRequest result = zoneNoId.applyChangeRequest(CHANGE_REQUEST); @@ -431,9 +431,9 @@ public void applyChangeByNameAndFound() { @Test public void applyChangeByNameAndNotFound() { // ID is not set - expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_NAME)).andReturn(null); + expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST)).andReturn(null); // again for options - expect(dns.applyChangeRequest(CHANGE_REQUEST, ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(null); replay(dns); ChangeRequest result = zoneNoId.applyChangeRequest(CHANGE_REQUEST); @@ -486,16 +486,16 @@ public void applyNullChangeRequest() { @Test public void getChangeByIdAndFound() { - expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_ID)).andReturn(CHANGE_REQUEST_AFTER); + expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_ID)).andReturn(CHANGE_REQUEST_AFTER); // again for options - expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(CHANGE_REQUEST_AFTER); replay(dns); - ChangeRequest result = zone.getChangeRequest(CHANGE_REQUEST); + ChangeRequest result = zone.getChangeRequest(CHANGE_REQUEST.id()); assertNotEquals(CHANGE_REQUEST, result); assertEquals(CHANGE_REQUEST_AFTER, result); // for options - result = zone.getChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); + result = zone.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS); assertNotEquals(CHANGE_REQUEST, result); assertEquals(CHANGE_REQUEST_AFTER, result); // test no id @@ -503,82 +503,82 @@ public void getChangeByIdAndFound() { @Test public void getChangeByIdAndNotFoundAndNameSetAndFound() { - expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_ID)).andReturn(null); - expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_NAME)) + expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_ID)).andReturn(null); + expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_NAME)) .andReturn(CHANGE_REQUEST_AFTER); // again for options - expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(null); - expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(CHANGE_REQUEST_AFTER); replay(dns); - ChangeRequest result = zone.getChangeRequest(CHANGE_REQUEST); + ChangeRequest result = zone.getChangeRequest(CHANGE_REQUEST.id()); assertNotEquals(CHANGE_REQUEST, result); assertEquals(CHANGE_REQUEST_AFTER, result); // for options - result = zone.getChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); + result = zone.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS); assertNotEquals(CHANGE_REQUEST, result); assertEquals(CHANGE_REQUEST_AFTER, result); } @Test public void getChangeIdAndNotFoundAndNameSetAndNotFound() { - expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_ID)).andReturn(null); - expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_NAME)).andReturn(null); + expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_ID)).andReturn(null); + expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_NAME)).andReturn(null); // again with options - expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(null); - expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(null); replay(dns); - ChangeRequest result = zone.getChangeRequest(CHANGE_REQUEST); + ChangeRequest result = zone.getChangeRequest(CHANGE_REQUEST.id()); assertNull(result); // again for options - result = zone.getChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); + result = zone.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS); assertNull(result); } @Test public void getChangeRequestByIdAndNotFoundAndNameNotSet() { - expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_ID)).andReturn(null); - expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_ID)).andReturn(null); + expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(null); // for options replay(dns); - ChangeRequest result = zoneNoName.getChangeRequest(CHANGE_REQUEST); + ChangeRequest result = zoneNoName.getChangeRequest(CHANGE_REQUEST.id()); assertNull(result); // again for options - result = zoneNoName.getChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); + result = zoneNoName.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS); assertNull(result); } @Test public void getChangeByNameAndFound() { // ID is not set - expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_NAME)) + expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_NAME)) .andReturn(CHANGE_REQUEST_AFTER); // again for options - expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(CHANGE_REQUEST_AFTER); replay(dns); - ChangeRequest result = zoneNoId.getChangeRequest(CHANGE_REQUEST); + ChangeRequest result = zoneNoId.getChangeRequest(CHANGE_REQUEST.id()); assertEquals(CHANGE_REQUEST_AFTER, result); // check options - result = zoneNoId.getChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); + result = zoneNoId.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS); assertEquals(CHANGE_REQUEST_AFTER, result); } @Test public void getChangeByNameAndNotFound() { // ID is not set - expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_NAME)).andReturn(null); + expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_NAME)).andReturn(null); // again for options - expect(dns.getChangeRequest(CHANGE_REQUEST, ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(null); replay(dns); - ChangeRequest result = zoneNoId.getChangeRequest(CHANGE_REQUEST); + ChangeRequest result = zoneNoId.getChangeRequest(CHANGE_REQUEST.id()); assertNull(result); // check options - result = zoneNoId.getChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); + result = zoneNoId.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS); assertNull(result); } @@ -627,38 +627,38 @@ public void getNullChangeRequest() { public void getChangeRequestWithNoId() { replay(dns); // no calls expected try { - zone.getChangeRequest(CHANGE_REQUEST_NO_ID); - fail("Cannot get ChangeRequest with no id."); + zone.getChangeRequest(CHANGE_REQUEST_NO_ID.id()); + fail("Cannot get ChangeRequest by null id."); } catch (NullPointerException e) { // expected } try { - zone.getChangeRequest(CHANGE_REQUEST_NO_ID, CHANGE_REQUEST_FIELD_OPTIONS); - fail("Cannot get ChangeRequest with no id."); + zone.getChangeRequest(CHANGE_REQUEST_NO_ID.id(), CHANGE_REQUEST_FIELD_OPTIONS); + fail("Cannot get ChangeRequest by null id."); } catch (NullPointerException e) { // expected } try { - zoneNoId.getChangeRequest(CHANGE_REQUEST_NO_ID); - fail("Cannot get ChangeRequest with no id."); + zoneNoId.getChangeRequest(CHANGE_REQUEST_NO_ID.id()); + fail("Cannot get ChangeRequest by null id."); } catch (NullPointerException e) { // expected } try { - zoneNoId.getChangeRequest(CHANGE_REQUEST_NO_ID, CHANGE_REQUEST_FIELD_OPTIONS); - fail("Cannot get ChangeRequest with no id."); + zoneNoId.getChangeRequest(CHANGE_REQUEST_NO_ID.id(), CHANGE_REQUEST_FIELD_OPTIONS); + fail("Cannot get ChangeRequest by null id."); } catch (NullPointerException e) { // expected } try { - zoneNoName.getChangeRequest(CHANGE_REQUEST_NO_ID); - fail("Cannot get ChangeRequest with no id."); + zoneNoName.getChangeRequest(CHANGE_REQUEST_NO_ID.id()); + fail("Cannot get ChangeRequest by null id."); } catch (NullPointerException e) { // expected } try { - zoneNoName.getChangeRequest(CHANGE_REQUEST_NO_ID, CHANGE_REQUEST_FIELD_OPTIONS); - fail("Cannot get ChangeRequest with no id."); + zoneNoName.getChangeRequest(CHANGE_REQUEST_NO_ID.id(), CHANGE_REQUEST_FIELD_OPTIONS); + fail("Cannot get ChangeRequest by null id."); } catch (NullPointerException e) { // expected } From d6daf0956ff0975bed3115f9b09a1381bc1cf137 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Tue, 2 Feb 2016 16:17:31 -0800 Subject: [PATCH 060/375] Adjusted documentation, removed getProjectId and getProjectNumber --- .../main/java/com/google/gcloud/dns/Dns.java | 14 +---- .../main/java/com/google/gcloud/dns/Zone.java | 12 ++-- .../java/com/google/gcloud/dns/ZoneTest.java | 56 ++++++++++--------- 3 files changed, 37 insertions(+), 45 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index 130e8bb99f5e..644814fa201b 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -523,16 +523,6 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) { */ ProjectInfo getProjectInfo(ProjectOption... fields); - /** - * Returns the current project id. - */ - String getProjectId(); - - /** - * Returns the current project number. - */ - BigInteger getProjectNumber(); - /** * Submits a change request for the specified zone. The returned object contains the following * read-only fields supplied by the server: id, start time and status. time, id, and list of name @@ -566,7 +556,7 @@ ChangeRequest applyChangeRequest(String zoneName, ChangeRequest changeRequest, * @throws DnsException upon failure or if the zone cannot be found * @see Cloud DNS Chages: get */ - ChangeRequest getChangeRequest(String changeRequestId, BigInteger zoneId, + ChangeRequest getChangeRequest(BigInteger zoneId, String changeRequestId, ChangeRequestOption... options); /** @@ -578,7 +568,7 @@ ChangeRequest getChangeRequest(String changeRequestId, BigInteger zoneId, * @throws DnsException upon failure or if the zone cannot be found * @see Cloud DNS Chages: get */ - ChangeRequest getChangeRequest(String changeRequestId, String zoneName, + ChangeRequest getChangeRequest(String zoneName, String changeRequestId, ChangeRequestOption... options); /** diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java index dc0be8b94b44..86fc86bc3688 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java @@ -130,8 +130,7 @@ public boolean delete() { * Lists all {@link DnsRecord}s associated with this zone. First searches for zone by ID and if * not found then by name. * - * @param options optional restriction on listing and on what fields of {@link DnsRecord} should - * be returned by the service + * @param options optional restriction on listing and fields of {@link DnsRecord}s returned * @return a page of DNS records * @throws DnsException upon failure or if the zone is not found * @throws NullPointerException if both zone ID and name are not initialized @@ -191,11 +190,11 @@ public ChangeRequest getChangeRequest(String changeRequestId, checkNotNull(changeRequestId); ChangeRequest updated = null; if (zoneInfo.id() != null) { - updated = dns.getChangeRequest(changeRequestId, zoneInfo.id(), options); + updated = dns.getChangeRequest(zoneInfo.id(), changeRequestId, options); } if (updated == null && zoneInfo.name() != null) { // zone was not found by id or id is not set at all - updated = dns.getChangeRequest(changeRequestId, zoneInfo.name(), options); + updated = dns.getChangeRequest(zoneInfo.name(), changeRequestId, options); } return updated; } @@ -205,8 +204,7 @@ public ChangeRequest getChangeRequest(String changeRequestId, * then by name. Returns a page of {@link ChangeRequest}s or {@code null} if the zone is not * found. * - * @param options optional restriction on listing and on what fields of {@link ChangeRequest}s - * should be returned by the service + * @param options optional restriction on listing and fields to be returned * @return a page of change requests * @throws DnsException upon failure or if the zone is not found * @throws NullPointerException if both zone ID and name are not initialized @@ -236,7 +234,7 @@ private void checkNameOrIdNotNull() { * Returns the {@link ZoneInfo} object containing information about this zone. */ public ZoneInfo info() { - return this.zoneInfo; + return zoneInfo; } /** diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java index a87bb969855b..c746140ce599 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java @@ -101,16 +101,15 @@ public void testGetById() { Zone retrieved = Zone.get(dns, ZONE_ID); assertSame(dns, retrieved.dns()); assertEquals(ZONE_INFO, retrieved.info()); - BigInteger id = null; try { - Zone.get(dns, id); - fail("Cannot get null zone."); + Zone.get(dns, (BigInteger) null); + fail("Cannot get by null id."); } catch (NullPointerException e) { // expected } try { - Zone.get(null, id); - fail("Cannot get null zone."); + Zone.get(null, new BigInteger("12")); + fail("Cannot get anything from null service."); } catch (NullPointerException e) { // expected } @@ -126,16 +125,15 @@ public void testGetByName() { Zone retrieved = Zone.get(dns, ZONE_NAME); assertSame(dns, retrieved.dns()); assertEquals(ZONE_INFO, retrieved.info()); - String name = null; try { - Zone.get(dns, name); - fail("Cannot get null zone."); + Zone.get(dns, (String) null); + fail("Cannot get by null name."); } catch (NullPointerException e) { // expected } try { - Zone.get(null, name); - fail("Cannot get null zone."); + Zone.get(null, "Not null"); + fail("Cannot get anything from null service."); } catch (NullPointerException e) { // expected } @@ -195,6 +193,7 @@ public void deleteByNameAndNotFound() { @Test public void listDnsRecordsByIdAndFound() { + @SuppressWarnings("unchecked") Page pageMock = createStrictMock(Page.class); replay(pageMock); expect(dns.listDnsRecords(ZONE_ID)).andReturn(pageMock); @@ -210,6 +209,7 @@ public void listDnsRecordsByIdAndFound() { @Test public void listDnsRecordsByIdAndNotFoundAndNameSetAndFound() { + @SuppressWarnings("unchecked") Page pageMock = createStrictMock(Page.class); replay(pageMock); expect(dns.listDnsRecords(ZONE_ID)).andReturn(null); @@ -251,6 +251,7 @@ public void listDnsRecordsByIdAndNotFoundAndNameNotSet() { @Test public void listDnsRecordsByNameAndFound() { + @SuppressWarnings("unchecked") Page pageMock = createStrictMock(Page.class); replay(pageMock); expect(dns.listDnsRecords(ZONE_NAME)).andReturn(pageMock); @@ -486,9 +487,9 @@ public void applyNullChangeRequest() { @Test public void getChangeByIdAndFound() { - expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_ID)).andReturn(CHANGE_REQUEST_AFTER); + expect(dns.getChangeRequest(ZONE_ID, CHANGE_REQUEST.id())).andReturn(CHANGE_REQUEST_AFTER); // again for options - expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.getChangeRequest(ZONE_ID, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(CHANGE_REQUEST_AFTER); replay(dns); ChangeRequest result = zone.getChangeRequest(CHANGE_REQUEST.id()); @@ -503,13 +504,13 @@ public void getChangeByIdAndFound() { @Test public void getChangeByIdAndNotFoundAndNameSetAndFound() { - expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_ID)).andReturn(null); - expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_NAME)) + expect(dns.getChangeRequest(ZONE_ID, CHANGE_REQUEST.id())).andReturn(null); + expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())) .andReturn(CHANGE_REQUEST_AFTER); // again for options - expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.getChangeRequest(ZONE_ID, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(null); - expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(CHANGE_REQUEST_AFTER); replay(dns); ChangeRequest result = zone.getChangeRequest(CHANGE_REQUEST.id()); @@ -523,12 +524,12 @@ public void getChangeByIdAndNotFoundAndNameSetAndFound() { @Test public void getChangeIdAndNotFoundAndNameSetAndNotFound() { - expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_ID)).andReturn(null); - expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_NAME)).andReturn(null); + expect(dns.getChangeRequest(ZONE_ID, CHANGE_REQUEST.id())).andReturn(null); + expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())).andReturn(null); // again with options - expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.getChangeRequest(ZONE_ID, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(null); - expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(null); replay(dns); ChangeRequest result = zone.getChangeRequest(CHANGE_REQUEST.id()); @@ -540,8 +541,8 @@ public void getChangeIdAndNotFoundAndNameSetAndNotFound() { @Test public void getChangeRequestByIdAndNotFoundAndNameNotSet() { - expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_ID)).andReturn(null); - expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_ID, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.getChangeRequest(ZONE_ID, CHANGE_REQUEST.id())).andReturn(null); + expect(dns.getChangeRequest(ZONE_ID, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(null); // for options replay(dns); ChangeRequest result = zoneNoName.getChangeRequest(CHANGE_REQUEST.id()); @@ -554,10 +555,10 @@ public void getChangeRequestByIdAndNotFoundAndNameNotSet() { @Test public void getChangeByNameAndFound() { // ID is not set - expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_NAME)) + expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())) .andReturn(CHANGE_REQUEST_AFTER); // again for options - expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(CHANGE_REQUEST_AFTER); replay(dns); ChangeRequest result = zoneNoId.getChangeRequest(CHANGE_REQUEST.id()); @@ -570,9 +571,9 @@ public void getChangeByNameAndFound() { @Test public void getChangeByNameAndNotFound() { // ID is not set - expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_NAME)).andReturn(null); + expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())).andReturn(null); // again for options - expect(dns.getChangeRequest(CHANGE_REQUEST.id(), ZONE_NAME, CHANGE_REQUEST_FIELD_OPTIONS)) + expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(null); replay(dns); ChangeRequest result = zoneNoId.getChangeRequest(CHANGE_REQUEST.id()); @@ -666,6 +667,7 @@ public void getChangeRequestWithNoId() { @Test public void listChangeRequestsByIdAndFound() { + @SuppressWarnings("unchecked") Page pageMock = createStrictMock(Page.class); replay(pageMock); expect(dns.listChangeRequests(ZONE_ID)).andReturn(pageMock); @@ -681,6 +683,7 @@ public void listChangeRequestsByIdAndFound() { @Test public void listChangeRequestsByIdAndNotFoundAndNameSetAndFound() { + @SuppressWarnings("unchecked") Page pageMock = createStrictMock(Page.class); replay(pageMock); expect(dns.listChangeRequests(ZONE_ID)).andReturn(null); @@ -724,6 +727,7 @@ public void listChangeRequestsByIdAndNotFoundAndNameNotSet() { @Test public void listChangeRequestsByNameAndFound() { + @SuppressWarnings("unchecked") Page pageMock = createStrictMock(Page.class); replay(pageMock); expect(dns.listChangeRequests(ZONE_NAME)).andReturn(pageMock); From 0338ead2661b9099da81adb11ebb6e18553ef2e4 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Wed, 3 Feb 2016 09:01:39 -0800 Subject: [PATCH 061/375] Completes DnsRpc interface by adding methods and doc. Closes #594. --- .../java/com/google/gcloud/spi/DnsRpc.java | 117 +++++++++++++++++- 1 file changed, 116 insertions(+), 1 deletion(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java index f6a0f330a327..9c0f7f3809df 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java @@ -16,6 +16,12 @@ package com.google.gcloud.spi; +import com.google.api.services.dns.model.Change; +import com.google.api.services.dns.model.ManagedZone; +import com.google.api.services.dns.model.Project; +import com.google.api.services.dns.model.ResourceRecordSet; +import com.google.gcloud.dns.DnsException; + import java.util.Map; public interface DnsRpc { @@ -52,5 +58,114 @@ Integer getInt(Map options) { } } - //TODO(mderka) add supported operations. Created issue #594. + class Tuple { + + private final X x; + private final Y y; + + private Tuple(X x, Y y) { + this.x = x; + this.y = y; + } + + public static Tuple of(X x, Y y) { + return new Tuple<>(x, y); + } + + public X x() { + return x; + } + + public Y y() { + return y; + } + } + + /** + * Creates a new zone. + * + * @param zone a zone to be created + * @return Updated {@link ManagedZone} object + * @throws DnsException upon failure + */ + ManagedZone create(ManagedZone zone) throws DnsException; + + /** + * Retrieves and returns an existing zone. + * + * @param zoneName name of the zone to be returned + * @param options a map of options for the service call + * @return a zone or {@code null} if not found + * @throws DnsException upon failure + */ + ManagedZone getZone(String zoneName, Map options) throws DnsException; + + /** + * Lists the zones that exist within the project. + * + * @param options a map of options for the service call + * @throws DnsException upon failure + */ + Tuple> listZones(Map options) throws DnsException; + + /** + * Deletes the zone identified by the name. + * + * @return {@code true} if the zone was deleted and {@code false} otherwise + * @throws DnsException upon failure + */ + boolean deleteZone(String zoneName) throws DnsException; + + /** + * Lists DNS records for a given zone. + * + * @param zoneName name of the zone to be listed + * @param options a map of options for the service call + * @throws DnsException upon failure or if zone not found + */ + Tuple> listDnsRecords(String zoneName, + Map options) throws DnsException; + + /** + * Returns information about the current project. + * + * @param options a map of options for the service call + * @return up-to-date project information + * @throws DnsException upon failure + */ + Project getProject(Map options) throws DnsException; + + /** + * Applies change request to a zone. + * + * @param zoneName the name of a zone to which the {@link Change} should be applied + * @param changeRequest change to be applied + * @param options a map of options for the service call + * @return updated change object with server-assigned ID + * @throws DnsException upon failure or if zone not found + */ + Change applyChangeRequest(String zoneName, Change changeRequest, Map options) + throws DnsException; + + /** + * Returns an existing change request. + * + * @param zoneName the name of a zone to which the {@link Change} was be applied + * @param changeRequestId the unique id assigned to the change by the server + * @param options a map of options for the service call + * @return up-to-date change object + * @throws DnsException upon failure or if zone not found + */ + Change getChangeRequest(String zoneName, String changeRequestId, Map options) + throws DnsException; + + /** + * List an existing change requests for a zone. + * + * @param zoneName the name of a zone to which the {@link Change}s were be applied + * @param options a map of options for the service call + * @throws DnsException upon failure or if zone not found + */ + Tuple> listChangeRequests(String zoneName, Map options) + throws DnsException; } From bc4b8204093d92782d04319c8efda9aae424b9cc Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Wed, 3 Feb 2016 10:46:44 -0800 Subject: [PATCH 062/375] Implements DefaultDnsRpc. Progress in #595. --- .../com/google/gcloud/dns/DnsException.java | 4 +- .../com/google/gcloud/dns/DnsOptions.java | 6 +- .../com/google/gcloud/spi/DefaultDnsRpc.java | 178 ++++++++++++++++++ 3 files changed, 183 insertions(+), 5 deletions(-) create mode 100644 gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java index d18f6163a881..73c546759260 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java @@ -27,8 +27,8 @@ public class DnsException extends BaseServiceException { private static final long serialVersionUID = 490302380416260252L; - public DnsException(IOException exception, boolean idempotent) { - super(exception, idempotent); + public DnsException(IOException exception) { + super(exception, true); } //TODO(mderka) Add translation and retry functionality. Created issue #593. diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java index 1845467c2537..248fd164a55f 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java @@ -18,6 +18,7 @@ import com.google.common.collect.ImmutableSet; import com.google.gcloud.ServiceOptions; +import com.google.gcloud.spi.DefaultDnsRpc; import com.google.gcloud.spi.DnsRpc; import com.google.gcloud.spi.DnsRpcFactory; @@ -46,8 +47,7 @@ public static class DefaultDnsRpcFactory implements DnsRpcFactory { @Override public DnsRpc create(DnsOptions options) { - // TODO(mderka) Implement when DefaultDnsRpc is available. Created issue #595. - return null; + return new DefaultDnsRpc(options); } } @@ -80,7 +80,7 @@ protected DnsFactory defaultServiceFactory() { @SuppressWarnings("unchecked") @Override protected DnsRpcFactory defaultRpcFactory() { - return null; + return DefaultDnsRpcFactory.INSTANCE; } @Override diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java new file mode 100644 index 000000000000..77eb36e3b5ed --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java @@ -0,0 +1,178 @@ +package com.google.gcloud.spi; + +import static com.google.gcloud.spi.DnsRpc.Option.DNS_NAME; +import static com.google.gcloud.spi.DnsRpc.Option.DNS_TYPE; +import static com.google.gcloud.spi.DnsRpc.Option.FIELDS; +import static com.google.gcloud.spi.DnsRpc.Option.PAGE_SIZE; +import static com.google.gcloud.spi.DnsRpc.Option.PAGE_TOKEN; +import static com.google.gcloud.spi.DnsRpc.Option.SORTING_ORDER; +import static java.net.HttpURLConnection.HTTP_NOT_FOUND; + +import com.google.api.client.http.HttpRequestInitializer; +import com.google.api.client.http.HttpTransport; +import com.google.api.client.json.jackson.JacksonFactory; +import com.google.api.services.dns.Dns; +import com.google.api.services.dns.model.Change; +import com.google.api.services.dns.model.ChangesListResponse; +import com.google.api.services.dns.model.ManagedZone; +import com.google.api.services.dns.model.ManagedZonesListResponse; +import com.google.api.services.dns.model.Project; +import com.google.api.services.dns.model.ResourceRecordSet; +import com.google.api.services.dns.model.ResourceRecordSetsListResponse; +import com.google.gcloud.dns.DnsException; +import com.google.gcloud.dns.DnsOptions; + +import java.io.IOException; +import java.util.Map; + +/** + * A default implementation of the DnsRpc interface. + */ +public class DefaultDnsRpc implements DnsRpc { + + private final Dns dns; + private final DnsOptions options; + + private static DnsException translate(IOException exception) { + return new DnsException(exception); + } + + /** + * Constructs an instance of this rpc client with provided {@link DnsOptions}. + */ + public DefaultDnsRpc(DnsOptions options) { + HttpTransport transport = options.httpTransportFactory().create(); + HttpRequestInitializer initializer = options.httpRequestInitializer(); + this.dns = new Dns.Builder(transport, new JacksonFactory(), initializer) + .setRootUrl(options.host()) + .setApplicationName(options.applicationName()) + .build(); + this.options = options; + } + + @Override + public ManagedZone create(ManagedZone zone) throws DnsException { + try { + return dns.managedZones().create(this.options.projectId(), zone).execute(); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public ManagedZone getZone(String zoneName, Map options) throws DnsException { + // just fields option + try { + return dns.managedZones().get(this.options.projectId(), zoneName) + .setFields(FIELDS.getString(options)).execute(); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Tuple> listZones(Map options) + throws DnsException { + // fields, page token, page size + try { + ManagedZonesListResponse zoneList = dns.managedZones().list(this.options.projectId()) + .setFields(FIELDS.getString(options)) + .setMaxResults(PAGE_SIZE.getInt(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + .execute(); + return Tuple.>of(zoneList.getNextPageToken(), + zoneList.getManagedZones()); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public boolean deleteZone(String zoneName) throws DnsException { + try { + dns.managedZones().delete(this.options.projectId(), zoneName).execute(); + return true; + } catch (IOException ex) { + DnsException serviceException = translate(ex); + if (serviceException.code() == HTTP_NOT_FOUND) { + return false; + } + throw serviceException; + } + } + + @Override + public Tuple> listDnsRecords(String zoneName, + Map options) throws DnsException { + // options are fields, page token, dns name, type + try { + ResourceRecordSetsListResponse response = dns.resourceRecordSets() + .list(this.options.projectId(), zoneName) + .setFields(FIELDS.getString(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + .setMaxResults(PAGE_SIZE.getInt(options)) + .setName(DNS_NAME.getString(options)) + .setType(DNS_TYPE.getString(options)) + .execute(); + return Tuple.>of(response.getNextPageToken(), + response.getRrsets()); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Project getProject(Map options) throws DnsException { + try { + return dns.projects().get(this.options.projectId()) + .setFields(FIELDS.getString(options)).execute(); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Change applyChangeRequest(String zoneName, Change changeRequest, Map options) + throws DnsException { + try { + return dns.changes().create(this.options.projectId(), zoneName, changeRequest) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Change getChangeRequest(String zoneName, String changeRequestId, Map options) + throws DnsException { + try { + return dns.changes().get(this.options.projectId(), zoneName, changeRequestId) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Tuple> listChangeRequests(String zoneName, Map options) + throws DnsException { + // options are fields, page token, page size, sort order + try { + Dns.Changes.List request = dns.changes().list(this.options.projectId(), zoneName) + .setFields(FIELDS.getString(options)) + .setMaxResults(PAGE_SIZE.getInt(options)) + .setPageToken(PAGE_TOKEN.getString(options)); + if (SORTING_ORDER.getString(options) != null) { + // this needs to be checked and changed if more sorting options are implemented, issue #604 + String key = "changeSequence"; + request = request.setSortBy(key).setSortOrder(SORTING_ORDER.getString(options)); + } + ChangesListResponse response = request.execute(); + return Tuple.>of(response.getNextPageToken(), response.getChanges()); + } catch (IOException ex) { + throw translate(ex); + } + } +} From 896de75d1cad86e1b2cc2e82bb20700c240fd4ec Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Wed, 3 Feb 2016 14:34:38 -0800 Subject: [PATCH 063/375] Fixed documentation and null returns from rpc. --- .../com/google/gcloud/spi/DefaultDnsRpc.java | 26 ++++++++++++++----- .../java/com/google/gcloud/spi/DnsRpc.java | 22 ++++++++-------- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java index 77eb36e3b5ed..85783d0fdcb6 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java @@ -30,6 +30,7 @@ */ public class DefaultDnsRpc implements DnsRpc { + private static final String SORTING_KEY = "changeSequence"; private final Dns dns; private final DnsOptions options; @@ -64,9 +65,14 @@ public ManagedZone getZone(String zoneName, Map options) throws DnsEx // just fields option try { return dns.managedZones().get(this.options.projectId(), zoneName) - .setFields(FIELDS.getString(options)).execute(); + .setFields(FIELDS.getString(options)) + .execute(); } catch (IOException ex) { - throw translate(ex); + DnsException serviceException = translate(ex); + if (serviceException.code() == HTTP_NOT_FOUND) { + return null; + } + throw serviceException; } } @@ -151,7 +157,16 @@ public Change getChangeRequest(String zoneName, String changeRequestId, Map> listChangeRequests(String zoneName, Map>of(response.getNextPageToken(), response.getChanges()); diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java index 9c0f7f3809df..bff396dedfab 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java @@ -85,7 +85,7 @@ public Y y() { * Creates a new zone. * * @param zone a zone to be created - * @return Updated {@link ManagedZone} object + * @return Updated {@code ManagedZone} object * @throws DnsException upon failure */ ManagedZone create(ManagedZone zone) throws DnsException; @@ -121,7 +121,7 @@ public Y y() { * * @param zoneName name of the zone to be listed * @param options a map of options for the service call - * @throws DnsException upon failure or if zone not found + * @throws DnsException upon failure or if zone was not found */ Tuple> listDnsRecords(String zoneName, Map options) throws DnsException; @@ -131,18 +131,18 @@ Tuple> listDnsRecords(String zoneName, * * @param options a map of options for the service call * @return up-to-date project information - * @throws DnsException upon failure + * @throws DnsException upon failure or if the project is not found */ Project getProject(Map options) throws DnsException; /** * Applies change request to a zone. * - * @param zoneName the name of a zone to which the {@link Change} should be applied + * @param zoneName the name of a zone to which the {@code Change} should be applied * @param changeRequest change to be applied * @param options a map of options for the service call * @return updated change object with server-assigned ID - * @throws DnsException upon failure or if zone not found + * @throws DnsException upon failure or if zone was not found */ Change applyChangeRequest(String zoneName, Change changeRequest, Map options) throws DnsException; @@ -150,21 +150,21 @@ Change applyChangeRequest(String zoneName, Change changeRequest, Map /** * Returns an existing change request. * - * @param zoneName the name of a zone to which the {@link Change} was be applied + * @param zoneName the name of a zone to which the {@code Change} was be applied * @param changeRequestId the unique id assigned to the change by the server * @param options a map of options for the service call - * @return up-to-date change object - * @throws DnsException upon failure or if zone not found + * @return up-to-date change object or {@code null} if change was not found + * @throws DnsException upon failure or if zone was not found */ Change getChangeRequest(String zoneName, String changeRequestId, Map options) throws DnsException; /** - * List an existing change requests for a zone. + * List existing change requests for a zone. * - * @param zoneName the name of a zone to which the {@link Change}s were be applied + * @param zoneName the name of a zone to which the {@code Change}s were be applied * @param options a map of options for the service call - * @throws DnsException upon failure or if zone not found + * @throws DnsException upon failure or if zone was not found */ Tuple> listChangeRequests(String zoneName, Map options) throws DnsException; From 3ae0f215d990f21b0c95fa1da07bbd8f8594fe1b Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Thu, 4 Feb 2016 09:11:09 -0800 Subject: [PATCH 064/375] Change Tuple into ListResult, added NAME option. --- .../main/java/com/google/gcloud/dns/Dns.java | 2 +- .../com/google/gcloud/spi/DefaultDnsRpc.java | 29 ++++++------ .../java/com/google/gcloud/spi/DnsRpc.java | 44 ++++++++++--------- .../java/com/google/gcloud/dns/DnsTest.java | 2 +- 4 files changed, 39 insertions(+), 38 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index 644814fa201b..1227a9e3b323 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -230,7 +230,7 @@ public static DnsRecordListOption pageSize(int pageSize) { * Restricts the list to only DNS records with this fully qualified domain name. */ public static DnsRecordListOption dnsName(String dnsName) { - return new DnsRecordListOption(DnsRpc.Option.DNS_NAME, dnsName); + return new DnsRecordListOption(DnsRpc.Option.NAME, dnsName); } /** diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java index 85783d0fdcb6..73e6ab4036ec 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java @@ -1,6 +1,8 @@ package com.google.gcloud.spi; +import static com.google.gcloud.spi.DnsRpc.ListResult.of; import static com.google.gcloud.spi.DnsRpc.Option.DNS_NAME; +import static com.google.gcloud.spi.DnsRpc.Option.NAME; import static com.google.gcloud.spi.DnsRpc.Option.DNS_TYPE; import static com.google.gcloud.spi.DnsRpc.Option.FIELDS; import static com.google.gcloud.spi.DnsRpc.Option.PAGE_SIZE; @@ -30,7 +32,7 @@ */ public class DefaultDnsRpc implements DnsRpc { - private static final String SORTING_KEY = "changeSequence"; + private static final String SORT_BY = "changeSequence"; private final Dns dns; private final DnsOptions options; @@ -77,17 +79,16 @@ public ManagedZone getZone(String zoneName, Map options) throws DnsEx } @Override - public Tuple> listZones(Map options) - throws DnsException { + public ListResult listZones(Map options) throws DnsException { // fields, page token, page size try { ManagedZonesListResponse zoneList = dns.managedZones().list(this.options.projectId()) .setFields(FIELDS.getString(options)) .setMaxResults(PAGE_SIZE.getInt(options)) + .setDnsName(DNS_NAME.getString(options)) .setPageToken(PAGE_TOKEN.getString(options)) .execute(); - return Tuple.>of(zoneList.getNextPageToken(), - zoneList.getManagedZones()); + return of(zoneList.getNextPageToken(), zoneList.getManagedZones()); } catch (IOException ex) { throw translate(ex); } @@ -108,8 +109,8 @@ public boolean deleteZone(String zoneName) throws DnsException { } @Override - public Tuple> listDnsRecords(String zoneName, - Map options) throws DnsException { + public ListResult listDnsRecords(String zoneName, Map options) + throws DnsException { // options are fields, page token, dns name, type try { ResourceRecordSetsListResponse response = dns.resourceRecordSets() @@ -117,11 +118,10 @@ public Tuple> listDnsRecords(String zoneName .setFields(FIELDS.getString(options)) .setPageToken(PAGE_TOKEN.getString(options)) .setMaxResults(PAGE_SIZE.getInt(options)) - .setName(DNS_NAME.getString(options)) + .setName(NAME.getString(options)) .setType(DNS_TYPE.getString(options)) .execute(); - return Tuple.>of(response.getNextPageToken(), - response.getRrsets()); + return of(response.getNextPageToken(), response.getRrsets()); } catch (IOException ex) { throw translate(ex); } @@ -159,8 +159,7 @@ public Change getChangeRequest(String zoneName, String changeRequestId, Map> listChangeRequests(String zoneName, Map options) + public ListResult listChangeRequests(String zoneName, Map options) throws DnsException { // options are fields, page token, page size, sort order try { @@ -181,10 +180,10 @@ public Tuple> listChangeRequests(String zoneName, Map>of(response.getNextPageToken(), response.getChanges()); + return ListResult.of(response.getNextPageToken(), response.getChanges()); } catch (IOException ex) { throw translate(ex); } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java index bff396dedfab..c3cd3c690177 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java @@ -20,6 +20,7 @@ import com.google.api.services.dns.model.ManagedZone; import com.google.api.services.dns.model.Project; import com.google.api.services.dns.model.ResourceRecordSet; +import com.google.common.collect.ImmutableList; import com.google.gcloud.dns.DnsException; import java.util.Map; @@ -28,9 +29,10 @@ public interface DnsRpc { enum Option { FIELDS("fields"), - PAGE_SIZE("maxSize"), + PAGE_SIZE("maxResults"), PAGE_TOKEN("pageToken"), DNS_NAME("dnsName"), + NAME("name"), DNS_TYPE("type"), SORTING_ORDER("sortOrder"); @@ -58,26 +60,26 @@ Integer getInt(Map options) { } } - class Tuple { + class ListResult { - private final X x; - private final Y y; + private final Iterable results; + private final String pageToken; - private Tuple(X x, Y y) { - this.x = x; - this.y = y; + public ListResult(String pageToken, Iterable results) { + this.results = ImmutableList.copyOf(results); + this.pageToken = pageToken; } - public static Tuple of(X x, Y y) { - return new Tuple<>(x, y); + public static ListResult of(String pageToken, Iterable list) { + return new ListResult<>(pageToken, list); } - public X x() { - return x; + public Iterable results() { + return results; } - public Y y() { - return y; + public String pageToken() { + return pageToken; } } @@ -106,7 +108,7 @@ public Y y() { * @param options a map of options for the service call * @throws DnsException upon failure */ - Tuple> listZones(Map options) throws DnsException; + ListResult listZones(Map options) throws DnsException; /** * Deletes the zone identified by the name. @@ -123,12 +125,12 @@ public Y y() { * @param options a map of options for the service call * @throws DnsException upon failure or if zone was not found */ - Tuple> listDnsRecords(String zoneName, - Map options) throws DnsException; + ListResult listDnsRecords(String zoneName, Map options) + throws DnsException; /** * Returns information about the current project. - * + * * @param options a map of options for the service call * @return up-to-date project information * @throws DnsException upon failure or if the project is not found @@ -136,7 +138,7 @@ Tuple> listDnsRecords(String zoneName, Project getProject(Map options) throws DnsException; /** - * Applies change request to a zone. + * Applies change request to a zone. * * @param zoneName the name of a zone to which the {@code Change} should be applied * @param changeRequest change to be applied @@ -144,7 +146,7 @@ Tuple> listDnsRecords(String zoneName, * @return updated change object with server-assigned ID * @throws DnsException upon failure or if zone was not found */ - Change applyChangeRequest(String zoneName, Change changeRequest, Map options) + Change applyChangeRequest(String zoneName, Change changeRequest, Map options) throws DnsException; /** @@ -156,7 +158,7 @@ Change applyChangeRequest(String zoneName, Change changeRequest, Map * @return up-to-date change object or {@code null} if change was not found * @throws DnsException upon failure or if zone was not found */ - Change getChangeRequest(String zoneName, String changeRequestId, Map options) + Change getChangeRequest(String zoneName, String changeRequestId, Map options) throws DnsException; /** @@ -166,6 +168,6 @@ Change getChangeRequest(String zoneName, String changeRequestId, Map * @param options a map of options for the service call * @throws DnsException upon failure or if zone was not found */ - Tuple> listChangeRequests(String zoneName, Map options) + ListResult listChangeRequests(String zoneName, Map options) throws DnsException; } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java index a60cae1d1793..c2be251cea9e 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java @@ -34,7 +34,7 @@ public void testDnsRecordListOption() { String dnsName = "some name"; Dns.DnsRecordListOption dnsRecordListOption = Dns.DnsRecordListOption.dnsName(dnsName); assertEquals(dnsName, dnsRecordListOption.value()); - assertEquals(DnsRpc.Option.DNS_NAME, dnsRecordListOption.rpcOption()); + assertEquals(DnsRpc.Option.NAME, dnsRecordListOption.rpcOption()); // page token dnsRecordListOption = Dns.DnsRecordListOption.pageToken(PAGE_TOKEN); assertEquals(PAGE_TOKEN, dnsRecordListOption.value()); From 71f5ae22187569bf20461bcb6021761bc9864856 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Thu, 4 Feb 2016 13:54:44 -0800 Subject: [PATCH 065/375] Makes name of Zone mandatory and removes id-based methods. Also makes id a read-only string instead of BigInteger. Includes rewriting testsfor Zone. --- .../main/java/com/google/gcloud/dns/Dns.java | 81 +-- .../main/java/com/google/gcloud/dns/Zone.java | 127 +--- .../java/com/google/gcloud/dns/ZoneInfo.java | 35 +- .../com/google/gcloud/spi/DefaultDnsRpc.java | 2 +- .../com/google/gcloud/dns/ZoneInfoTest.java | 44 +- .../java/com/google/gcloud/dns/ZoneTest.java | 608 +++++------------- 6 files changed, 223 insertions(+), 674 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index 1227a9e3b323..af0868ec17d6 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -23,7 +23,6 @@ import com.google.gcloud.spi.DnsRpc; import java.io.Serializable; -import java.math.BigInteger; import java.util.Set; /** @@ -69,8 +68,7 @@ static String selector(ProjectField... fields) { * The fields of a zone. * *

These values can be used to specify the fields to include in a partial response when calling - * {@link Dns#getZone(BigInteger, ZoneOption...)} or {@link Dns#getZone(String, ZoneOption...)}. - * The ID is always returned, even if not specified. + * {@link Dns#getZone(String, ZoneOption...)}. The ID is always returned, even if not specified. */ enum ZoneField { CREATION_TIME("creationTime"), @@ -105,9 +103,8 @@ static String selector(ZoneField... fields) { * The fields of a DNS record. * *

These values can be used to specify the fields to include in a partial response when calling - * {@link Dns#listDnsRecords(BigInteger, DnsRecordListOption...)} or {@link - * Dns#listDnsRecords(String, DnsRecordListOption...)}. The name is always returned even if not - * selected. + * {@link Dns#listDnsRecords(String, DnsRecordListOption...)}. The name is always returned even if + * not selected. */ enum DnsRecordField { DNS_RECORDS("rrdatas"), @@ -139,8 +136,7 @@ static String selector(DnsRecordField... fields) { * The fields of a change request. * *

These values can be used to specify the fields to include in a partial response when calling - * {@link Dns#applyChangeRequest(BigInteger, ChangeRequest, ChangeRequestOption...)} or {@link - * Dns#applyChangeRequest(String, ChangeRequest, ChangeRequestOption...)} The ID is always + * {@link Dns#applyChangeRequest(String, ChangeRequest, ChangeRequestOption...)} The ID is always * returned even if not selected. */ enum ChangeRequestField { @@ -444,16 +440,6 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) { */ ZoneInfo getZone(String zoneName, ZoneOption... options); - /** - * Returns the zone by the specified zone id. Returns {@code null} if the zone is not found. The - * returned fields can be optionally restricted by specifying {@link ZoneOption}s. - * - * @throws DnsException upon failure - * @see Cloud DNS Managed Zones: - * get - */ - ZoneInfo getZone(BigInteger zoneId, ZoneOption... options); - /** * Lists the zones inside the project. * @@ -479,17 +465,6 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) { */ boolean delete(String zoneName); // delete does not admit any options - /** - * Deletes an existing zone identified by id. Returns {@code true} if the zone was successfully - * deleted and {@code false} otherwise. - * - * @return {@code true} if zone was found and deleted and {@code false} otherwise - * @throws DnsException upon failure - * @see Cloud DNS Managed Zones: - * delete - */ - boolean delete(BigInteger zoneId); // delete does not admit any options - /** * Lists the DNS records in the zone identified by name. * @@ -502,18 +477,6 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) { */ Page listDnsRecords(String zoneName, DnsRecordListOption... options); - /** - * Lists the DNS records in the zone identified by ID. - * - *

The fields to be returned, page size and page tokens can be specified using {@link - * DnsRecordListOption}s. - * - * @throws DnsException upon failure or if the zone cannot be found - * @see Cloud DNS - * ResourceRecordSets: list - */ - Page listDnsRecords(BigInteger zoneId, DnsRecordListOption... options); - /** * Retrieves the information about the current project. The returned fields can be optionally * restricted by specifying {@link ProjectOption}s. @@ -523,18 +486,6 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) { */ ProjectInfo getProjectInfo(ProjectOption... fields); - /** - * Submits a change request for the specified zone. The returned object contains the following - * read-only fields supplied by the server: id, start time and status. time, id, and list of name - * servers. The fields to be returned can be selected by {@link ChangeRequestOption}s. - * - * @return the new {@link ChangeRequest} or {@code null} if zone is not found - * @throws DnsException upon failure - * @see Cloud DNS Changes: create - */ - ChangeRequest applyChangeRequest(BigInteger zoneId, ChangeRequest changeRequest, - ChangeRequestOption... options); - /** * Submits a change request for the specified zone. The returned object contains the following * read-only fields supplied by the server: id, start time and status. time, id, and list of name @@ -547,18 +498,6 @@ ChangeRequest applyChangeRequest(BigInteger zoneId, ChangeRequest changeRequest, ChangeRequest applyChangeRequest(String zoneName, ChangeRequest changeRequest, ChangeRequestOption... options); - /** - * Retrieves updated information about a change request previously submitted for a zone identified - * by ID. Returns {@code null} if the request cannot be found and throws an exception if the zone - * does not exist. The fields to be returned using can be specified using {@link - * ChangeRequestOption}s. - * - * @throws DnsException upon failure or if the zone cannot be found - * @see Cloud DNS Chages: get - */ - ChangeRequest getChangeRequest(BigInteger zoneId, String changeRequestId, - ChangeRequestOption... options); - /** * Retrieves updated information about a change request previously submitted for a zone identified * by ID. Returns {@code null} if the request cannot be found and throws an exception if the zone @@ -571,18 +510,6 @@ ChangeRequest getChangeRequest(BigInteger zoneId, String changeRequestId, ChangeRequest getChangeRequest(String zoneName, String changeRequestId, ChangeRequestOption... options); - /** - * Lists the change requests for the zone identified by ID that were submitted to the service. - * - *

The sorting order for changes (based on when they were received by the server), fields to be - * returned, page size and page token can be specified using {@link ChangeRequestListOption}s. - * - * @return A page of change requests - * @throws DnsException upon failure or if the zone cannot be found - * @see Cloud DNS Chages: list - */ - Page listChangeRequests(BigInteger zoneId, ChangeRequestListOption... options); - /** * Lists the change requests for the zone identified by name that were submitted to the service. * diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java index 86fc86bc3688..04edf332115d 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java @@ -16,13 +16,11 @@ package com.google.gcloud.dns; -import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import com.google.gcloud.Page; import java.io.Serializable; -import java.math.BigInteger; /** * A Google Cloud DNS Zone object. @@ -39,7 +37,7 @@ public class Zone implements Serializable { // TODO(mderka) Zone and zoneInfo to be merged. Opened issue #605. - private static final long serialVersionUID = -4012581571095484813L; + private static final long serialVersionUID = 6847890192129375500L; private final ZoneInfo zoneInfo; private final Dns dns; @@ -68,166 +66,81 @@ public static Zone get(Dns dnsService, String zoneName, Dns.ZoneOption... option } /** - * Constructs a {@code Zone} object that contains information received from the Google Cloud DNS - * service for the provided {@code zoneId}. - * - * @param zoneId ID of the zone to be searched for - * @param options optional restriction on what fields should be returned by the service - * @return zone object containing zone's information or {@code null} if not not found - * @throws DnsException upon failure - */ - public static Zone get(Dns dnsService, BigInteger zoneId, Dns.ZoneOption... options) { - checkNotNull(zoneId); - checkNotNull(dnsService); - ZoneInfo zoneInfo = dnsService.getZone(zoneId, options); - return zoneInfo == null ? null : new Zone(dnsService, zoneInfo); - } - - /** - * Retrieves the latest information about the zone. The method first attempts to retrieve the zone - * by ID and if not set or zone is not found, it searches by name. + * Retrieves the latest information about the zone. The method retrieves the zone by name which + * must always be initialized. * * @param options optional restriction on what fields should be fetched * @return zone object containing updated information or {@code null} if not not found * @throws DnsException upon failure - * @throws NullPointerException if both zone ID and name are not initialized */ public Zone reload(Dns.ZoneOption... options) { - checkNameOrIdNotNull(); - Zone zone = null; - if (zoneInfo.id() != null) { - zone = Zone.get(dns, zoneInfo.id(), options); - } - if (zone == null && zoneInfo.name() != null) { - // zone was not found by id or id is not set at all - zone = Zone.get(dns, zoneInfo.name(), options); - } - return zone; + return Zone.get(dns, zoneInfo.name(), options); } /** - * Deletes the zone. The method first attempts to delete the zone by ID. If the zone is not found - * or id is not set, it attempts to delete by name. + * Deletes the zone. The method first deletes the zone by name which must always be initialized. * * @return {@code true} is zone was found and deleted and {@code false} otherwise * @throws DnsException upon failure - * @throws NullPointerException if both zone ID and name are not initialized */ public boolean delete() { - checkNameOrIdNotNull(); - boolean deleted = false; - if (zoneInfo.id() != null) { - deleted = dns.delete(zoneInfo.id()); - } - if (!deleted && zoneInfo.name() != null) { - // zone was not found by id or id is not set at all - deleted = dns.delete(zoneInfo.name()); - } - return deleted; + return dns.delete(zoneInfo.name()); } /** - * Lists all {@link DnsRecord}s associated with this zone. First searches for zone by ID and if - * not found then by name. + * Lists all {@link DnsRecord}s associated with this zone. The method searches for zone by name + * which must always be initialized. * * @param options optional restriction on listing and fields of {@link DnsRecord}s returned * @return a page of DNS records * @throws DnsException upon failure or if the zone is not found - * @throws NullPointerException if both zone ID and name are not initialized */ public Page listDnsRecords(Dns.DnsRecordListOption... options) { - checkNameOrIdNotNull(); - Page page = null; - if (zoneInfo.id() != null) { - page = dns.listDnsRecords(zoneInfo.id(), options); - } - if (page == null && zoneInfo.name() != null) { - // zone was not found by id or id is not set at all - page = dns.listDnsRecords(zoneInfo.name(), options); - } - return page; + return dns.listDnsRecords(zoneInfo.name(), options); } /** - * Submits {@link ChangeRequest} to the service for it to applied to this zone. First searches for - * the zone by ID and if not found then by name. Returns a {@link ChangeRequest} with - * server-assigned ID or {@code null} if the zone was not found. + * Submits {@link ChangeRequest} to the service for it to applied to this zone. The method + * searches for zone by name which must always be initialized. * * @param options optional restriction on what fields of {@link ChangeRequest} should be returned * @return ChangeRequest with server-assigned ID * @throws DnsException upon failure or if the zone is not found - * @throws NullPointerException if both zone ID and name are not initialized */ public ChangeRequest applyChangeRequest(ChangeRequest changeRequest, Dns.ChangeRequestOption... options) { - checkNameOrIdNotNull(); checkNotNull(changeRequest); - ChangeRequest updated = null; - if (zoneInfo.id() != null) { - updated = dns.applyChangeRequest(zoneInfo.id(), changeRequest, options); - } - if (updated == null && zoneInfo.name() != null) { - // zone was not found by id or id is not set at all - updated = dns.applyChangeRequest(zoneInfo.name(), changeRequest, options); - } - return updated; + return dns.applyChangeRequest(zoneInfo.name(), changeRequest, options); } /** * Retrieves an updated information about a change request previously submitted to be applied to - * this zone. First searches for the zone by ID and if not found then by name. Returns a {@link - * ChangeRequest} if found and {@code null} is the zone or the change request was not found. + * this zone. The method searches for zone by name which must always be initialized. Returns a + * {@link ChangeRequest} if and {@code null} if the change request was not found. Throws {@link + * DnsException} if the zone is not found. * * @param options optional restriction on what fields of {@link ChangeRequest} should be returned * @return updated ChangeRequest * @throws DnsException upon failure or if the zone is not found - * @throws NullPointerException if both zone ID and name are not initialized * @throws NullPointerException if the change request does not have initialized id */ public ChangeRequest getChangeRequest(String changeRequestId, Dns.ChangeRequestOption... options) { - checkNameOrIdNotNull(); checkNotNull(changeRequestId); - ChangeRequest updated = null; - if (zoneInfo.id() != null) { - updated = dns.getChangeRequest(zoneInfo.id(), changeRequestId, options); - } - if (updated == null && zoneInfo.name() != null) { - // zone was not found by id or id is not set at all - updated = dns.getChangeRequest(zoneInfo.name(), changeRequestId, options); - } - return updated; + return dns.getChangeRequest(zoneInfo.name(), changeRequestId, options); } /** - * Retrieves all change requests for this zone. First searches for the zone by ID and if not found - * then by name. Returns a page of {@link ChangeRequest}s or {@code null} if the zone is not - * found. + * Retrieves all change requests for this zone. The method searches for zone by name which must + * always be initialized. Returns a page of {@link ChangeRequest}s. Throws a {@link DnsException} + * if the zone is not found. * * @param options optional restriction on listing and fields to be returned * @return a page of change requests * @throws DnsException upon failure or if the zone is not found - * @throws NullPointerException if both zone ID and name are not initialized */ public Page listChangeRequests(Dns.ChangeRequestListOption... options) { - checkNameOrIdNotNull(); - Page changeRequests = null; - if (zoneInfo.id() != null) { - changeRequests = dns.listChangeRequests(zoneInfo.id(), options); - } - if (changeRequests == null && zoneInfo.name() != null) { - // zone was not found by id or id is not set at all - changeRequests = dns.listChangeRequests(zoneInfo.name(), options); - } - return changeRequests; - } - - /** - * Check that at least one of name and ID are initialized and throw and exception if not. - */ - private void checkNameOrIdNotNull() { - checkArgument(zoneInfo != null && (zoneInfo.id() != null || zoneInfo.name() != null), - "Both zoneInfo.id and zoneInfo.name are null. This is should never happen."); + return dns.listChangeRequests(zoneInfo.name(), options); } /** diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java index 524309eaa8e9..09945fb72138 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java @@ -41,7 +41,7 @@ public class ZoneInfo implements Serializable { private static final long serialVersionUID = 201601191647L; private final String name; - private final BigInteger id; + private final String id; private final Long creationTimeMillis; private final String dnsName; private final String description; @@ -53,7 +53,7 @@ public class ZoneInfo implements Serializable { */ public static class Builder { private String name; - private BigInteger id; + private String id; private Long creationTimeMillis; private String dnsName; private String description; @@ -66,19 +66,10 @@ public static class Builder { private Builder() { } - private Builder(BigInteger id) { - this.id = checkNotNull(id); - } - private Builder(String name) { this.name = checkNotNull(name); } - private Builder(String name, BigInteger id) { - this.name = checkNotNull(name); - this.id = checkNotNull(id); - } - /** * Creates a builder from an existing ZoneInfo object. */ @@ -103,7 +94,7 @@ public Builder name(String name) { /** * Sets an id for the zone which is assigned to the zone by the server. */ - Builder id(BigInteger id) { + Builder id(String id) { this.id = id; return this; } @@ -178,20 +169,6 @@ public static Builder builder(String name) { return new Builder(name); } - /** - * Returns a builder for {@code ZoneInfo} with an assigned {@code id}. - */ - public static Builder builder(BigInteger id) { - return new Builder(id); - } - - /** - * Returns a builder for {@code ZoneInfo} with an assigned {@code name} and {@code id}. - */ - public static Builder builder(String name, BigInteger id) { - return new Builder(name, id); - } - /** * Returns the user-defined name of the zone. */ @@ -202,7 +179,7 @@ public String name() { /** * Returns the read-only zone id assigned by the server. */ - public BigInteger id() { + public String id() { return id; } @@ -255,7 +232,7 @@ com.google.api.services.dns.model.ManagedZone toPb() { pb.setDescription(this.description()); pb.setDnsName(this.dnsName()); if (this.id() != null) { - pb.setId(this.id()); + pb.setId(new BigInteger(this.id())); } pb.setName(this.name()); pb.setNameServers(this.nameServers()); @@ -277,7 +254,7 @@ static ZoneInfo fromPb(com.google.api.services.dns.model.ManagedZone pb) { builder.dnsName(pb.getDnsName()); } if (pb.getId() != null) { - builder.id(pb.getId()); + builder.id(pb.getId().toString()); } if (pb.getName() != null) { builder.name(pb.getName()); diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java index 73e6ab4036ec..12596da02bf6 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java @@ -2,9 +2,9 @@ import static com.google.gcloud.spi.DnsRpc.ListResult.of; import static com.google.gcloud.spi.DnsRpc.Option.DNS_NAME; -import static com.google.gcloud.spi.DnsRpc.Option.NAME; import static com.google.gcloud.spi.DnsRpc.Option.DNS_TYPE; import static com.google.gcloud.spi.DnsRpc.Option.FIELDS; +import static com.google.gcloud.spi.DnsRpc.Option.NAME; import static com.google.gcloud.spi.DnsRpc.Option.PAGE_SIZE; import static com.google.gcloud.spi.DnsRpc.Option.PAGE_TOKEN; import static com.google.gcloud.spi.DnsRpc.Option.SORTING_ORDER; diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java index 2c9fea8f7bde..227916b46f96 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java @@ -26,14 +26,13 @@ import org.junit.Test; -import java.math.BigInteger; import java.util.LinkedList; import java.util.List; public class ZoneInfoTest { private static final String NAME = "mz-example.com"; - private static final BigInteger ID = BigInteger.valueOf(123L); + private static final String ID = "123456"; private static final Long CREATION_TIME_MILLIS = 1123468321321L; private static final String DNS_NAME = "example.com."; private static final String DESCRIPTION = "description for the zone"; @@ -42,8 +41,9 @@ public class ZoneInfoTest { private static final String NS2 = "name server 2"; private static final String NS3 = "name server 3"; private static final List NAME_SERVERS = ImmutableList.of(NS1, NS2, NS3); - private static final ZoneInfo INFO = ZoneInfo.builder(NAME, ID) + private static final ZoneInfo INFO = ZoneInfo.builder(NAME) .creationTimeMillis(CREATION_TIME_MILLIS) + .id(ID) .dnsName(DNS_NAME) .description(DESCRIPTION) .nameServerSet(NAME_SERVER_SET) @@ -52,30 +52,14 @@ public class ZoneInfoTest { @Test public void testDefaultBuilders() { - ZoneInfo withName = ZoneInfo.builder(NAME).build(); - assertTrue(withName.nameServers().isEmpty()); - assertEquals(NAME, withName.name()); - assertNull(withName.id()); - assertNull(withName.creationTimeMillis()); - assertNull(withName.nameServerSet()); - assertNull(withName.description()); - assertNull(withName.dnsName()); - ZoneInfo withId = ZoneInfo.builder(ID).build(); - assertTrue(withId.nameServers().isEmpty()); - assertEquals(ID, withId.id()); - assertNull(withId.name()); - assertNull(withId.creationTimeMillis()); - assertNull(withId.nameServerSet()); - assertNull(withId.description()); - assertNull(withId.dnsName()); - ZoneInfo withBoth = ZoneInfo.builder(NAME, ID).build(); - assertTrue(withBoth.nameServers().isEmpty()); - assertEquals(ID, withBoth.id()); - assertEquals(NAME, withBoth.name()); - assertNull(withBoth.creationTimeMillis()); - assertNull(withBoth.nameServerSet()); - assertNull(withBoth.description()); - assertNull(withBoth.dnsName()); + ZoneInfo zone = ZoneInfo.builder(NAME).build(); + assertTrue(zone.nameServers().isEmpty()); + assertEquals(NAME, zone.name()); + assertNull(zone.id()); + assertNull(zone.creationTimeMillis()); + assertNull(zone.nameServerSet()); + assertNull(zone.description()); + assertNull(zone.dnsName()); } @Test @@ -109,7 +93,7 @@ public void testEqualsAndNotEquals() { assertNotEquals(INFO, clone); clone = INFO.toBuilder().dnsName(differentName).build(); assertNotEquals(INFO, clone); - clone = INFO.toBuilder().id(INFO.id().add(BigInteger.ONE)).build(); + clone = INFO.toBuilder().id(INFO.id() + "1111").build(); assertNotEquals(INFO, clone); clone = INFO.toBuilder().nameServerSet(INFO.nameServerSet() + "salt").build(); assertNotEquals(INFO, clone); @@ -127,7 +111,7 @@ public void testToBuilder() { assertEquals(INFO, INFO.toBuilder().build()); ZoneInfo partial = ZoneInfo.builder(NAME).build(); assertEquals(partial, partial.toBuilder().build()); - partial = ZoneInfo.builder(ID).build(); + partial = ZoneInfo.builder(NAME).id(ID).build(); assertEquals(partial, partial.toBuilder().build()); partial = ZoneInfo.builder(NAME).description(DESCRIPTION).build(); assertEquals(partial, partial.toBuilder().build()); @@ -148,7 +132,7 @@ public void testToAndFromPb() { assertEquals(INFO, ZoneInfo.fromPb(INFO.toPb())); ZoneInfo partial = ZoneInfo.builder(NAME).build(); assertEquals(partial, ZoneInfo.fromPb(partial.toPb())); - partial = ZoneInfo.builder(ID).build(); + partial = ZoneInfo.builder(NAME).id(ID).build(); assertEquals(partial, ZoneInfo.fromPb(partial.toPb())); partial = ZoneInfo.builder(NAME).description(DESCRIPTION).build(); assertEquals(partial, ZoneInfo.fromPb(partial.toPb())); diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java index c746140ce599..59cb642167ed 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java @@ -22,7 +22,6 @@ import static org.easymock.EasyMock.verify; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; @@ -35,24 +34,19 @@ import org.junit.Before; import org.junit.Test; -import java.math.BigInteger; - public class ZoneTest { private static final String ZONE_NAME = "dns-zone-name"; - private static final BigInteger ZONE_ID = new BigInteger("123"); - private static final ZoneInfo ZONE_INFO = ZoneInfo.builder(ZONE_NAME, ZONE_ID) + private static final String ZONE_ID = "123"; + private static final ZoneInfo ZONE_INFO = ZoneInfo.builder(ZONE_NAME) + .id(ZONE_ID) .dnsName("example.com") .creationTimeMillis(123478946464L) .build(); private static final ZoneInfo NO_ID_INFO = ZoneInfo.builder(ZONE_NAME) - .dnsName("anoter-example.com") + .dnsName("another-example.com") .creationTimeMillis(893123464L) .build(); - private static final ZoneInfo NO_NAME_INFO = ZoneInfo.builder(ZONE_ID) - .dnsName("one-more-example.com") - .creationTimeMillis(875221546464L) - .build(); private static final Dns.ZoneOption ZONE_FIELD_OPTIONS = Dns.ZoneOption.fields(Dns.ZoneField.CREATION_TIME); private static final Dns.DnsRecordListOption DNS_RECORD_OPTIONS = @@ -65,10 +59,10 @@ public class ZoneTest { private static final ChangeRequest CHANGE_REQUEST_AFTER = CHANGE_REQUEST.toBuilder() .startTimeMillis(123465L).build(); private static final ChangeRequest CHANGE_REQUEST_NO_ID = ChangeRequest.builder().build(); + private static final DnsException EXCEPTION = createStrictMock(DnsException.class); private Dns dns; private Zone zone; - private Zone zoneNoName; private Zone zoneNoId; @Before @@ -76,7 +70,6 @@ public void setUp() throws Exception { dns = createStrictMock(Dns.class); zone = new Zone(dns, ZONE_INFO); zoneNoId = new Zone(dns, NO_ID_INFO); - zoneNoName = new Zone(dns, NO_NAME_INFO); } @After @@ -93,40 +86,18 @@ public void testConstructor() { assertEquals(dns, zone.dns()); } - @Test - public void testGetById() { - expect(dns.getZone(ZONE_ID)).andReturn(ZONE_INFO); - expect(dns.getZone(ZONE_ID, ZONE_FIELD_OPTIONS)).andReturn(ZONE_INFO); // for options - replay(dns); - Zone retrieved = Zone.get(dns, ZONE_ID); - assertSame(dns, retrieved.dns()); - assertEquals(ZONE_INFO, retrieved.info()); - try { - Zone.get(dns, (BigInteger) null); - fail("Cannot get by null id."); - } catch (NullPointerException e) { - // expected - } - try { - Zone.get(null, new BigInteger("12")); - fail("Cannot get anything from null service."); - } catch (NullPointerException e) { - // expected - } - // test passing options - Zone.get(dns, ZONE_ID, ZONE_FIELD_OPTIONS); - } - @Test public void testGetByName() { expect(dns.getZone(ZONE_NAME)).andReturn(ZONE_INFO); - expect(dns.getZone(ZONE_ID, ZONE_FIELD_OPTIONS)).andReturn(ZONE_INFO); // for options + expect(dns.getZone(ZONE_NAME, ZONE_FIELD_OPTIONS)).andReturn(ZONE_INFO); // for options replay(dns); Zone retrieved = Zone.get(dns, ZONE_NAME); assertSame(dns, retrieved.dns()); assertEquals(ZONE_INFO, retrieved.info()); + // test passing options + Zone.get(dns, ZONE_NAME, ZONE_FIELD_OPTIONS); try { - Zone.get(dns, (String) null); + Zone.get(dns, null); fail("Cannot get by null name."); } catch (NullPointerException e) { // expected @@ -137,311 +108,177 @@ public void testGetByName() { } catch (NullPointerException e) { // expected } - // test passing options - Zone.get(dns, ZONE_ID, ZONE_FIELD_OPTIONS); } @Test - public void deleteByIdAndFound() { - expect(dns.delete(ZONE_ID)).andReturn(true); - replay(dns); - boolean result = zone.delete(); - assertTrue(result); - } - - @Test - public void deleteByIdAndNotFoundAndNameSetAndFound() { - expect(dns.delete(ZONE_ID)).andReturn(false); + public void deleteByNameAndFound() { + expect(dns.delete(ZONE_NAME)).andReturn(true); expect(dns.delete(ZONE_NAME)).andReturn(true); replay(dns); boolean result = zone.delete(); assertTrue(result); - } - - @Test - public void deleteByIdAndNotFoundAndNameSetAndNotFound() { - expect(dns.delete(ZONE_ID)).andReturn(false); - expect(dns.delete(ZONE_NAME)).andReturn(false); - replay(dns); - boolean result = zone.delete(); - assertFalse(result); - } - - @Test - public void deleteByIdAndNotFoundAndNameNotSet() { - expect(dns.delete(ZONE_ID)).andReturn(false); - replay(dns); - boolean result = zoneNoName.delete(); - assertFalse(result); - } - - @Test - public void deleteByNameAndFound() { - expect(dns.delete(ZONE_NAME)).andReturn(true); - replay(dns); - boolean result = zoneNoId.delete(); + result = zoneNoId.delete(); assertTrue(result); } @Test public void deleteByNameAndNotFound() { - expect(dns.delete(ZONE_NAME)).andReturn(true); + expect(dns.delete(ZONE_NAME)).andReturn(false); + expect(dns.delete(ZONE_NAME)).andReturn(false); replay(dns); boolean result = zoneNoId.delete(); - assertTrue(result); - } - - @Test - public void listDnsRecordsByIdAndFound() { - @SuppressWarnings("unchecked") - Page pageMock = createStrictMock(Page.class); - replay(pageMock); - expect(dns.listDnsRecords(ZONE_ID)).andReturn(pageMock); - // again for options - expect(dns.listDnsRecords(ZONE_ID, DNS_RECORD_OPTIONS)).andReturn(pageMock); - replay(dns); - Page result = zone.listDnsRecords(); - assertSame(pageMock, result); - verify(pageMock); - // verify options - zone.listDnsRecords(DNS_RECORD_OPTIONS); + assertFalse(result); + result = zone.delete(); + assertFalse(result); } @Test - public void listDnsRecordsByIdAndNotFoundAndNameSetAndFound() { + public void listDnsRecordsByNameAndFound() { @SuppressWarnings("unchecked") Page pageMock = createStrictMock(Page.class); replay(pageMock); - expect(dns.listDnsRecords(ZONE_ID)).andReturn(null); + expect(dns.listDnsRecords(ZONE_NAME)).andReturn(pageMock); expect(dns.listDnsRecords(ZONE_NAME)).andReturn(pageMock); // again for options - expect(dns.listDnsRecords(ZONE_ID, DNS_RECORD_OPTIONS)).andReturn(null); + expect(dns.listDnsRecords(ZONE_NAME, DNS_RECORD_OPTIONS)).andReturn(pageMock); expect(dns.listDnsRecords(ZONE_NAME, DNS_RECORD_OPTIONS)).andReturn(pageMock); replay(dns); Page result = zone.listDnsRecords(); assertSame(pageMock, result); - verify(pageMock); - // verify options - zone.listDnsRecords(DNS_RECORD_OPTIONS); - } - - @Test - public void listDnsRecordsByIdAndNotFoundAndNameSetAndNotFound() { - expect(dns.listDnsRecords(ZONE_ID)).andReturn(null); - expect(dns.listDnsRecords(ZONE_NAME)).andReturn(null); - // again for options - expect(dns.listDnsRecords(ZONE_ID, DNS_RECORD_OPTIONS)).andReturn(null); - expect(dns.listDnsRecords(ZONE_NAME, DNS_RECORD_OPTIONS)).andReturn(null); - replay(dns); - Page result = zone.listDnsRecords(); - assertNull(result); - // check options - zone.listDnsRecords(DNS_RECORD_OPTIONS); - } - - @Test - public void listDnsRecordsByIdAndNotFoundAndNameNotSet() { - expect(dns.listDnsRecords(ZONE_ID)).andReturn(null); - expect(dns.listDnsRecords(ZONE_ID, DNS_RECORD_OPTIONS)).andReturn(null); // for options - replay(dns); - Page result = zoneNoName.listDnsRecords(); - assertNull(result); - zoneNoName.listDnsRecords(DNS_RECORD_OPTIONS); // check options - } - - @Test - public void listDnsRecordsByNameAndFound() { - @SuppressWarnings("unchecked") - Page pageMock = createStrictMock(Page.class); - replay(pageMock); - expect(dns.listDnsRecords(ZONE_NAME)).andReturn(pageMock); - // again for options - expect(dns.listDnsRecords(ZONE_NAME, DNS_RECORD_OPTIONS)).andReturn(pageMock); - replay(dns); - Page result = zoneNoId.listDnsRecords(); + result = zoneNoId.listDnsRecords(); assertSame(pageMock, result); verify(pageMock); + zone.listDnsRecords(DNS_RECORD_OPTIONS); // check options zoneNoId.listDnsRecords(DNS_RECORD_OPTIONS); // check options } @Test public void listDnsRecordsByNameAndNotFound() { - expect(dns.listDnsRecords(ZONE_NAME)).andReturn(null); - // again for options - expect(dns.listDnsRecords(ZONE_NAME, DNS_RECORD_OPTIONS)).andReturn(null); - replay(dns); - Page result = zoneNoId.listDnsRecords(); - assertNull(result); - zoneNoId.listDnsRecords(DNS_RECORD_OPTIONS); // check options - } - - @Test - public void reloadByIdAndFound() { - expect(dns.getZone(ZONE_ID)).andReturn(zone.info()); - expect(dns.getZone(ZONE_ID, ZONE_FIELD_OPTIONS)).andReturn(zone.info()); // for options - replay(dns); - Zone result = zone.reload(); - assertSame(zone.dns(), result.dns()); - assertEquals(zone.info(), result.info()); - zone.reload(ZONE_FIELD_OPTIONS); // for options - } - - @Test - public void reloadByIdAndNotFoundAndNameSetAndFound() { - expect(dns.getZone(ZONE_ID)).andReturn(null); - expect(dns.getZone(ZONE_NAME)).andReturn(zone.info()); - // again for options - expect(dns.getZone(ZONE_ID, ZONE_FIELD_OPTIONS)).andReturn(null); - expect(dns.getZone(ZONE_NAME, ZONE_FIELD_OPTIONS)).andReturn(zone.info()); - replay(dns); - Zone result = zone.reload(); - assertSame(zone.dns(), result.dns()); - assertEquals(zone.info(), result.info()); - zone.reload(ZONE_FIELD_OPTIONS); // for options - } - - @Test - public void reloadByIdAndNotFoundAndNameSetAndNotFound() { - expect(dns.getZone(ZONE_ID)).andReturn(null); - expect(dns.getZone(ZONE_NAME)).andReturn(null); - // again with options - expect(dns.getZone(ZONE_ID, ZONE_FIELD_OPTIONS)).andReturn(null); - expect(dns.getZone(ZONE_NAME, ZONE_FIELD_OPTIONS)).andReturn(null); - replay(dns); - Zone result = zone.reload(); - assertNull(result); + expect(dns.listDnsRecords(ZONE_NAME)).andThrow(EXCEPTION); + expect(dns.listDnsRecords(ZONE_NAME)).andThrow(EXCEPTION); // again for options - zone.reload(ZONE_FIELD_OPTIONS); - } - - @Test - public void reloadByIdAndNotFoundAndNameNotSet() { - expect(dns.getZone(ZONE_ID)).andReturn(null); - expect(dns.getZone(ZONE_ID, ZONE_FIELD_OPTIONS)).andReturn(null); // for options + expect(dns.listDnsRecords(ZONE_NAME, DNS_RECORD_OPTIONS)).andThrow(EXCEPTION); + expect(dns.listDnsRecords(ZONE_NAME, DNS_RECORD_OPTIONS)).andThrow(EXCEPTION); replay(dns); - Zone result = zoneNoName.reload(); - assertNull(result); - zoneNoName.reload(ZONE_FIELD_OPTIONS); // for options + try { + zoneNoId.listDnsRecords(); + fail("Parent container not found, should throw an exception."); + } catch (DnsException e) { + // expected + } + try { + zone.listDnsRecords(); + fail("Parent container not found, should throw an exception."); + } catch (DnsException e) { + // expected + } + try { + zoneNoId.listDnsRecords(DNS_RECORD_OPTIONS); // check options + fail("Parent container not found, should throw an exception."); + } catch (DnsException e) { + // expected + } + try { + zone.listDnsRecords(DNS_RECORD_OPTIONS); // check options + fail("Parent container not found, should throw an exception."); + } catch (DnsException e) { + // expected + } } @Test public void reloadByNameAndFound() { expect(dns.getZone(ZONE_NAME)).andReturn(zoneNoId.info()); + expect(dns.getZone(ZONE_NAME)).andReturn(zone.info()); // again for options expect(dns.getZone(ZONE_NAME, ZONE_FIELD_OPTIONS)).andReturn(zoneNoId.info()); + expect(dns.getZone(ZONE_NAME, ZONE_FIELD_OPTIONS)).andReturn(zone.info()); replay(dns); Zone result = zoneNoId.reload(); assertSame(zoneNoId.dns(), result.dns()); assertEquals(zoneNoId.info(), result.info()); + result = zone.reload(); + assertSame(zone.dns(), result.dns()); + assertEquals(zone.info(), result.info()); zoneNoId.reload(ZONE_FIELD_OPTIONS); // check options + zone.reload(ZONE_FIELD_OPTIONS); // check options } @Test public void reloadByNameAndNotFound() { + expect(dns.getZone(ZONE_NAME)).andReturn(null); expect(dns.getZone(ZONE_NAME)).andReturn(null); // again for options expect(dns.getZone(ZONE_NAME, ZONE_FIELD_OPTIONS)).andReturn(null); + expect(dns.getZone(ZONE_NAME, ZONE_FIELD_OPTIONS)).andReturn(null); replay(dns); Zone result = zoneNoId.reload(); assertNull(result); + result = zone.reload(); + assertNull(result); zoneNoId.reload(ZONE_FIELD_OPTIONS); // for options + zone.reload(ZONE_FIELD_OPTIONS); // for options } @Test - public void applyChangeByIdAndFound() { - expect(dns.applyChangeRequest(ZONE_ID, CHANGE_REQUEST)).andReturn(CHANGE_REQUEST_AFTER); - // again for options - expect(dns.applyChangeRequest(ZONE_ID, CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS)) + public void applyChangeByNameAndFound() { + expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST)) .andReturn(CHANGE_REQUEST_AFTER); - replay(dns); - ChangeRequest result = zone.applyChangeRequest(CHANGE_REQUEST); - assertNotEquals(CHANGE_REQUEST, result); - assertEquals(CHANGE_REQUEST_AFTER, result); - // for options - result = zone.applyChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); - assertNotEquals(CHANGE_REQUEST, result); - assertEquals(CHANGE_REQUEST_AFTER, result); - } - - @Test - public void applyChangeByIdAndNotFoundAndNameSetAndFound() { - expect(dns.applyChangeRequest(ZONE_ID, CHANGE_REQUEST)).andReturn(null); expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST)) .andReturn(CHANGE_REQUEST_AFTER); // again for options - expect(dns.applyChangeRequest(ZONE_ID, CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS)) - .andReturn(null); expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(CHANGE_REQUEST_AFTER); - replay(dns); - ChangeRequest result = zone.applyChangeRequest(CHANGE_REQUEST); - assertNotEquals(CHANGE_REQUEST, result); - assertEquals(CHANGE_REQUEST_AFTER, result); - // for options - result = zone.applyChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); - assertNotEquals(CHANGE_REQUEST, result); - assertEquals(CHANGE_REQUEST_AFTER, result); - } - - @Test - public void applyChangeIdAndNotFoundAndNameSetAndNotFound() { - expect(dns.applyChangeRequest(ZONE_ID, CHANGE_REQUEST)).andReturn(null); - expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST)).andReturn(null); - // again with options - expect(dns.applyChangeRequest(ZONE_ID, CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS)) - .andReturn(null); - expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS)) - .andReturn(null); - replay(dns); - ChangeRequest result = zone.applyChangeRequest(CHANGE_REQUEST); - assertNull(result); - // again for options - result = zone.applyChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); - assertNull(result); - } - - @Test - public void applyChangeRequestByIdAndNotFoundAndNameNotSet() { - expect(dns.applyChangeRequest(ZONE_ID, CHANGE_REQUEST)).andReturn(null); - expect(dns.applyChangeRequest(ZONE_ID, CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS)) - .andReturn(null); // for options - replay(dns); - ChangeRequest result = zoneNoName.applyChangeRequest(CHANGE_REQUEST); - assertNull(result); - // again for options - result = zoneNoName.applyChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); - assertNull(result); - } - - @Test - public void applyChangeByNameAndFound() { - // ID is not set - expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST)) - .andReturn(CHANGE_REQUEST_AFTER); - // again for options expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(CHANGE_REQUEST_AFTER); replay(dns); ChangeRequest result = zoneNoId.applyChangeRequest(CHANGE_REQUEST); assertEquals(CHANGE_REQUEST_AFTER, result); + result = zone.applyChangeRequest(CHANGE_REQUEST); + assertEquals(CHANGE_REQUEST_AFTER, result); // check options result = zoneNoId.applyChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); assertEquals(CHANGE_REQUEST_AFTER, result); + result = zone.applyChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); + assertEquals(CHANGE_REQUEST_AFTER, result); } @Test public void applyChangeByNameAndNotFound() { // ID is not set - expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST)).andReturn(null); + expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST)).andThrow(EXCEPTION); + expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST)).andThrow(EXCEPTION); // again for options expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS)) - .andReturn(null); + .andThrow(EXCEPTION); + expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS)) + .andThrow(EXCEPTION); replay(dns); - ChangeRequest result = zoneNoId.applyChangeRequest(CHANGE_REQUEST); - assertNull(result); + try { + zoneNoId.applyChangeRequest(CHANGE_REQUEST); + fail("Parent container not found, should throw an exception."); + } catch (DnsException e) { + // expected + } + try { + zone.applyChangeRequest(CHANGE_REQUEST); + fail("Parent container not found, should throw an exception."); + } catch (DnsException e) { + // expected + } // check options - result = zoneNoId.applyChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); - assertNull(result); + try { + zoneNoId.applyChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); + fail("Parent container not found, should throw an exception."); + } catch (DnsException e) { + // expected + } + try { + zone.applyChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); + fail("Parent container not found, should throw an exception."); + } catch (DnsException e) { + // expected + } } @Test @@ -471,116 +308,82 @@ public void applyNullChangeRequest() { } catch (NullPointerException e) { // expected } - try { - zoneNoName.applyChangeRequest(null); - fail("Cannot apply null ChangeRequest."); - } catch (NullPointerException e) { - // expected - } - try { - zoneNoName.applyChangeRequest(null, CHANGE_REQUEST_FIELD_OPTIONS); - fail("Cannot apply null ChangeRequest."); - } catch (NullPointerException e) { - // expected - } } @Test - public void getChangeByIdAndFound() { - expect(dns.getChangeRequest(ZONE_ID, CHANGE_REQUEST.id())).andReturn(CHANGE_REQUEST_AFTER); - // again for options - expect(dns.getChangeRequest(ZONE_ID, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) + public void getChangeAndZoneFoundByName() { + expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())) .andReturn(CHANGE_REQUEST_AFTER); - replay(dns); - ChangeRequest result = zone.getChangeRequest(CHANGE_REQUEST.id()); - assertNotEquals(CHANGE_REQUEST, result); - assertEquals(CHANGE_REQUEST_AFTER, result); - // for options - result = zone.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS); - assertNotEquals(CHANGE_REQUEST, result); - assertEquals(CHANGE_REQUEST_AFTER, result); - // test no id - } - - @Test - public void getChangeByIdAndNotFoundAndNameSetAndFound() { - expect(dns.getChangeRequest(ZONE_ID, CHANGE_REQUEST.id())).andReturn(null); expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())) .andReturn(CHANGE_REQUEST_AFTER); // again for options - expect(dns.getChangeRequest(ZONE_ID, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) - .andReturn(null); + expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) + .andReturn(CHANGE_REQUEST_AFTER); expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(CHANGE_REQUEST_AFTER); replay(dns); - ChangeRequest result = zone.getChangeRequest(CHANGE_REQUEST.id()); - assertNotEquals(CHANGE_REQUEST, result); + ChangeRequest result = zoneNoId.getChangeRequest(CHANGE_REQUEST.id()); assertEquals(CHANGE_REQUEST_AFTER, result); - // for options - result = zone.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS); - assertNotEquals(CHANGE_REQUEST, result); + result = zone.getChangeRequest(CHANGE_REQUEST.id()); + assertEquals(CHANGE_REQUEST_AFTER, result); + // check options + result = zoneNoId.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS); assertEquals(CHANGE_REQUEST_AFTER, result); - } - - @Test - public void getChangeIdAndNotFoundAndNameSetAndNotFound() { - expect(dns.getChangeRequest(ZONE_ID, CHANGE_REQUEST.id())).andReturn(null); - expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())).andReturn(null); - // again with options - expect(dns.getChangeRequest(ZONE_ID, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) - .andReturn(null); - expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) - .andReturn(null); - replay(dns); - ChangeRequest result = zone.getChangeRequest(CHANGE_REQUEST.id()); - assertNull(result); - // again for options result = zone.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS); - assertNull(result); - } - - @Test - public void getChangeRequestByIdAndNotFoundAndNameNotSet() { - expect(dns.getChangeRequest(ZONE_ID, CHANGE_REQUEST.id())).andReturn(null); - expect(dns.getChangeRequest(ZONE_ID, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) - .andReturn(null); // for options - replay(dns); - ChangeRequest result = zoneNoName.getChangeRequest(CHANGE_REQUEST.id()); - assertNull(result); - // again for options - result = zoneNoName.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS); - assertNull(result); + assertEquals(CHANGE_REQUEST_AFTER, result); } @Test - public void getChangeByNameAndFound() { - // ID is not set - expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())) - .andReturn(CHANGE_REQUEST_AFTER); + public void getChangeAndZoneNotFoundByName() { + expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())).andThrow(EXCEPTION); + expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())).andThrow(EXCEPTION); // again for options expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) - .andReturn(CHANGE_REQUEST_AFTER); + .andThrow(EXCEPTION); + expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) + .andThrow(EXCEPTION); replay(dns); - ChangeRequest result = zoneNoId.getChangeRequest(CHANGE_REQUEST.id()); - assertEquals(CHANGE_REQUEST_AFTER, result); + try { + ChangeRequest result = zoneNoId.getChangeRequest(CHANGE_REQUEST.id()); + fail("Parent container not found, should throw an exception."); + } catch (DnsException e) { + // expected + } + try { + ChangeRequest result = zone.getChangeRequest(CHANGE_REQUEST.id()); + fail("Parent container not found, should throw an exception."); + } catch (DnsException e) { + // expected + } // check options - result = zoneNoId.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS); - assertEquals(CHANGE_REQUEST_AFTER, result); + try { + zoneNoId.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS); + fail("Parent container not found, should throw an exception."); + } catch (DnsException e) { + // expected + } + try { + zone.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS); + fail("Parent container not found, should throw an exception."); + } catch (DnsException e) { + // expected + } } @Test - public void getChangeByNameAndNotFound() { - // ID is not set + public void getChangedWhichDoesNotExistZoneFound() { + expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())).andReturn(null); expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())).andReturn(null); // again for options + expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) + .andReturn(null); expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) .andReturn(null); replay(dns); - ChangeRequest result = zoneNoId.getChangeRequest(CHANGE_REQUEST.id()); - assertNull(result); - // check options - result = zoneNoId.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS); - assertNull(result); + assertNull(zoneNoId.getChangeRequest(CHANGE_REQUEST.id())); + assertNull(zone.getChangeRequest(CHANGE_REQUEST.id())); + assertNull(zoneNoId.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)); + assertNull(zone.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)); } @Test @@ -610,18 +413,6 @@ public void getNullChangeRequest() { } catch (NullPointerException e) { // expected } - try { - zoneNoName.getChangeRequest(null); - fail("Cannot get null ChangeRequest."); - } catch (NullPointerException e) { - // expected - } - try { - zoneNoName.getChangeRequest(null, CHANGE_REQUEST_FIELD_OPTIONS); - fail("Cannot get null ChangeRequest."); - } catch (NullPointerException e) { - // expected - } } @Test @@ -651,104 +442,61 @@ public void getChangeRequestWithNoId() { } catch (NullPointerException e) { // expected } - try { - zoneNoName.getChangeRequest(CHANGE_REQUEST_NO_ID.id()); - fail("Cannot get ChangeRequest by null id."); - } catch (NullPointerException e) { - // expected - } - try { - zoneNoName.getChangeRequest(CHANGE_REQUEST_NO_ID.id(), CHANGE_REQUEST_FIELD_OPTIONS); - fail("Cannot get ChangeRequest by null id."); - } catch (NullPointerException e) { - // expected - } - } - - @Test - public void listChangeRequestsByIdAndFound() { - @SuppressWarnings("unchecked") - Page pageMock = createStrictMock(Page.class); - replay(pageMock); - expect(dns.listChangeRequests(ZONE_ID)).andReturn(pageMock); - // again for options - expect(dns.listChangeRequests(ZONE_ID, CHANGE_REQUEST_LIST_OPTIONS)).andReturn(pageMock); - replay(dns); - Page result = zone.listChangeRequests(); - assertSame(pageMock, result); - verify(pageMock); - // verify options - zone.listChangeRequests(CHANGE_REQUEST_LIST_OPTIONS); } @Test - public void listChangeRequestsByIdAndNotFoundAndNameSetAndFound() { + public void listChangeRequestsAndZoneFound() { @SuppressWarnings("unchecked") Page pageMock = createStrictMock(Page.class); replay(pageMock); - expect(dns.listChangeRequests(ZONE_ID)).andReturn(null); + expect(dns.listChangeRequests(ZONE_NAME)).andReturn(pageMock); expect(dns.listChangeRequests(ZONE_NAME)).andReturn(pageMock); // again for options - expect(dns.listChangeRequests(ZONE_ID, CHANGE_REQUEST_LIST_OPTIONS)).andReturn(null); expect(dns.listChangeRequests(ZONE_NAME, CHANGE_REQUEST_LIST_OPTIONS)) .andReturn(pageMock); - replay(dns); - Page result = zone.listChangeRequests(); - assertSame(pageMock, result); - verify(pageMock); - // verify options - zone.listChangeRequests(CHANGE_REQUEST_LIST_OPTIONS); - } - - @Test - public void listChangeRequestsByIdAndNotFoundAndNameSetAndNotFound() { - expect(dns.listChangeRequests(ZONE_ID)).andReturn(null); - expect(dns.listChangeRequests(ZONE_NAME)).andReturn(null); - // again for options - expect(dns.listChangeRequests(ZONE_ID, CHANGE_REQUEST_LIST_OPTIONS)).andReturn(null); - expect(dns.listChangeRequests(ZONE_NAME, CHANGE_REQUEST_LIST_OPTIONS)).andReturn(null); - replay(dns); - Page result = zone.listChangeRequests(); - assertNull(result); - // check options - zone.listChangeRequests(CHANGE_REQUEST_LIST_OPTIONS); - } - - @Test - public void listChangeRequestsByIdAndNotFoundAndNameNotSet() { - expect(dns.listChangeRequests(ZONE_ID)).andReturn(null); - // again for options - expect(dns.listChangeRequests(ZONE_ID, CHANGE_REQUEST_LIST_OPTIONS)).andReturn(null); - replay(dns); - Page result = zoneNoName.listChangeRequests(); - assertNull(result); - zoneNoName.listChangeRequests(CHANGE_REQUEST_LIST_OPTIONS); // check options - } - - @Test - public void listChangeRequestsByNameAndFound() { - @SuppressWarnings("unchecked") - Page pageMock = createStrictMock(Page.class); - replay(pageMock); - expect(dns.listChangeRequests(ZONE_NAME)).andReturn(pageMock); - // again for options expect(dns.listChangeRequests(ZONE_NAME, CHANGE_REQUEST_LIST_OPTIONS)) .andReturn(pageMock); replay(dns); Page result = zoneNoId.listChangeRequests(); assertSame(pageMock, result); + result = zone.listChangeRequests(); + assertSame(pageMock, result); verify(pageMock); zoneNoId.listChangeRequests(CHANGE_REQUEST_LIST_OPTIONS); // check options + zone.listChangeRequests(CHANGE_REQUEST_LIST_OPTIONS); // check options } @Test - public void listChangeRequestsByNameAndNotFound() { - expect(dns.listChangeRequests(ZONE_NAME)).andReturn(null); + public void listChangeRequestsAndZoneNotFound() { + expect(dns.listChangeRequests(ZONE_NAME)).andThrow(EXCEPTION); + expect(dns.listChangeRequests(ZONE_NAME)).andThrow(EXCEPTION); // again for options - expect(dns.listChangeRequests(ZONE_NAME, CHANGE_REQUEST_LIST_OPTIONS)).andReturn(null); + expect(dns.listChangeRequests(ZONE_NAME, CHANGE_REQUEST_LIST_OPTIONS)).andThrow(EXCEPTION); + expect(dns.listChangeRequests(ZONE_NAME, CHANGE_REQUEST_LIST_OPTIONS)).andThrow(EXCEPTION); replay(dns); - Page result = zoneNoId.listChangeRequests(); - assertNull(result); - zoneNoId.listChangeRequests(CHANGE_REQUEST_LIST_OPTIONS); // check options + try { + zoneNoId.listChangeRequests(); + fail("Parent container not found, should throw an exception."); + } catch (DnsException e) { + // expected + } + try { + zone.listChangeRequests(); + fail("Parent container not found, should throw an exception."); + } catch (DnsException e) { + // expected + } + try { + zoneNoId.listChangeRequests(CHANGE_REQUEST_LIST_OPTIONS); // check options + fail("Parent container not found, should throw an exception."); + } catch (DnsException e) { + // expected + } + try { + zone.listChangeRequests(CHANGE_REQUEST_LIST_OPTIONS); // check options + fail("Parent container not found, should throw an exception."); + } catch (DnsException e) { + // expected + } } } From 3183f4a7445dcb5e8992132ec5463bbced65c07b Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Thu, 4 Feb 2016 14:04:45 -0800 Subject: [PATCH 066/375] Added field options for zone create method. --- .../src/main/java/com/google/gcloud/dns/Dns.java | 7 ++++--- .../src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java | 7 +++++-- .../src/main/java/com/google/gcloud/spi/DnsRpc.java | 3 ++- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index af0868ec17d6..f6649c28680c 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -421,14 +421,15 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) { * *

Returns {@link ZoneInfo} object representing the new zone's information. In addition to the * name, dns name and description (supplied by the user within the {@code zoneInfo} parameter), - * the returned object will include the following read-only fields supplied by the server: - * creation time, id, and list of name servers. + * the returned object can include the following read-only fields supplied by the server: creation + * time, id, and list of name servers. The returned fields can be optionally restricted by + * specifying {@link ZoneOption}s. * * @throws DnsException upon failure * @see Cloud DNS Managed Zones: * create */ - ZoneInfo create(ZoneInfo zoneInfo); + ZoneInfo create(ZoneInfo zoneInfo, ZoneOption... options); /** * Returns the zone by the specified zone name. Returns {@code null} if the zone is not found. The diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java index 12596da02bf6..6ed9c7e0f216 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java @@ -54,9 +54,12 @@ public DefaultDnsRpc(DnsOptions options) { } @Override - public ManagedZone create(ManagedZone zone) throws DnsException { + public ManagedZone create(ManagedZone zone, Map options) throws DnsException { try { - return dns.managedZones().create(this.options.projectId(), zone).execute(); + return dns.managedZones() + .create(this.options.projectId(), zone) + .setFields(FIELDS.getString(options)) + .execute(); } catch (IOException ex) { throw translate(ex); } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java index c3cd3c690177..addb69d24b40 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java @@ -87,10 +87,11 @@ public String pageToken() { * Creates a new zone. * * @param zone a zone to be created + * @param options a map of options for the service call * @return Updated {@code ManagedZone} object * @throws DnsException upon failure */ - ManagedZone create(ManagedZone zone) throws DnsException; + ManagedZone create(ManagedZone zone, Map options) throws DnsException; /** * Retrieves and returns an existing zone. From 4057dcd93d2dee27c0a7f51e51723ca414daa5fd Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Thu, 4 Feb 2016 18:19:27 -0800 Subject: [PATCH 067/375] Fixed doc after refactoring. Made zone name mandatory in fields. --- .../src/main/java/com/google/gcloud/dns/Dns.java | 4 ++-- .../src/main/java/com/google/gcloud/dns/Zone.java | 15 ++++++--------- .../main/java/com/google/gcloud/dns/ZoneInfo.java | 11 +---------- .../test/java/com/google/gcloud/dns/DnsTest.java | 2 +- 4 files changed, 10 insertions(+), 22 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index f6649c28680c..040a97e5b253 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -68,7 +68,7 @@ static String selector(ProjectField... fields) { * The fields of a zone. * *

These values can be used to specify the fields to include in a partial response when calling - * {@link Dns#getZone(String, ZoneOption...)}. The ID is always returned, even if not specified. + * {@link Dns#getZone(String, ZoneOption...)}. The name is always returned, even if not specified. */ enum ZoneField { CREATION_TIME("creationTime"), @@ -91,7 +91,7 @@ String selector() { static String selector(ZoneField... fields) { Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); - fieldStrings.add(ZONE_ID.selector()); + fieldStrings.add(NAME.selector()); for (ZoneField field : fields) { fieldStrings.add(field.selector()); } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java index 04edf332115d..f5e0a8b4a63b 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java @@ -78,7 +78,7 @@ public Zone reload(Dns.ZoneOption... options) { } /** - * Deletes the zone. The method first deletes the zone by name which must always be initialized. + * Deletes the zone. The method deletes the zone by name. * * @return {@code true} is zone was found and deleted and {@code false} otherwise * @throws DnsException upon failure @@ -88,8 +88,7 @@ public boolean delete() { } /** - * Lists all {@link DnsRecord}s associated with this zone. The method searches for zone by name - * which must always be initialized. + * Lists all {@link DnsRecord}s associated with this zone. The method searches for zone by name. * * @param options optional restriction on listing and fields of {@link DnsRecord}s returned * @return a page of DNS records @@ -115,14 +114,13 @@ public ChangeRequest applyChangeRequest(ChangeRequest changeRequest, /** * Retrieves an updated information about a change request previously submitted to be applied to - * this zone. The method searches for zone by name which must always be initialized. Returns a - * {@link ChangeRequest} if and {@code null} if the change request was not found. Throws {@link - * DnsException} if the zone is not found. + * this zone. Returns a {@link ChangeRequest} or {@code null} if the change request was not + * found. Throws {@link DnsException} if the zone is not found. * * @param options optional restriction on what fields of {@link ChangeRequest} should be returned * @return updated ChangeRequest * @throws DnsException upon failure or if the zone is not found - * @throws NullPointerException if the change request does not have initialized id + * @throws NullPointerException if {@code changeRequestId} is null */ public ChangeRequest getChangeRequest(String changeRequestId, Dns.ChangeRequestOption... options) { @@ -132,8 +130,7 @@ public ChangeRequest getChangeRequest(String changeRequestId, /** * Retrieves all change requests for this zone. The method searches for zone by name which must - * always be initialized. Returns a page of {@link ChangeRequest}s. Throws a {@link DnsException} - * if the zone is not found. + * always be initialized. Returns a page of {@link ChangeRequest}s. * * @param options optional restriction on listing and fields to be returned * @return a page of change requests diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java index 09945fb72138..a15518ae166f 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java @@ -60,12 +60,6 @@ public static class Builder { private String nameServerSet; private List nameServers = new LinkedList<>(); - /** - * Returns an empty builder for {@code ZoneInfo}. We use it internally in {@code toPb()}. - */ - private Builder() { - } - private Builder(String name) { this.name = checkNotNull(name); } @@ -246,7 +240,7 @@ com.google.api.services.dns.model.ManagedZone toPb() { } static ZoneInfo fromPb(com.google.api.services.dns.model.ManagedZone pb) { - Builder builder = new Builder(); + Builder builder = new Builder(pb.getName()); if (pb.getDescription() != null) { builder.description(pb.getDescription()); } @@ -256,9 +250,6 @@ static ZoneInfo fromPb(com.google.api.services.dns.model.ManagedZone pb) { if (pb.getId() != null) { builder.id(pb.getId().toString()); } - if (pb.getName() != null) { - builder.name(pb.getName()); - } if (pb.getNameServers() != null) { builder.nameServers(pb.getNameServers()); } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java index c2be251cea9e..74faca329884 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java @@ -80,7 +80,7 @@ public void testZoneList() { assertTrue(fields.value() instanceof String); assertTrue(((String) fields.value()).contains(Dns.ZoneField.CREATION_TIME.selector())); assertTrue(((String) fields.value()).contains(Dns.ZoneField.DESCRIPTION.selector())); - assertTrue(((String) fields.value()).contains(Dns.ZoneField.ZONE_ID.selector())); + assertTrue(((String) fields.value()).contains(Dns.ZoneField.NAME.selector())); // page token Dns.ZoneListOption option = Dns.ZoneListOption.pageToken(PAGE_TOKEN); assertEquals(PAGE_TOKEN, option.value()); From d7226350faa112b2f2e5310e7268ba61176729ee Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Fri, 5 Feb 2016 08:45:53 -0800 Subject: [PATCH 068/375] Javadoc fixed. --- .../src/main/java/com/google/gcloud/dns/Zone.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java index f5e0a8b4a63b..3f4ea8cab3e4 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java @@ -66,8 +66,7 @@ public static Zone get(Dns dnsService, String zoneName, Dns.ZoneOption... option } /** - * Retrieves the latest information about the zone. The method retrieves the zone by name which - * must always be initialized. + * Retrieves the latest information about the zone. The method retrieves the zone by name. * * @param options optional restriction on what fields should be fetched * @return zone object containing updated information or {@code null} if not not found @@ -100,7 +99,7 @@ public Page listDnsRecords(Dns.DnsRecordListOption... options) { /** * Submits {@link ChangeRequest} to the service for it to applied to this zone. The method - * searches for zone by name which must always be initialized. + * searches for zone by name. * * @param options optional restriction on what fields of {@link ChangeRequest} should be returned * @return ChangeRequest with server-assigned ID @@ -114,8 +113,8 @@ public ChangeRequest applyChangeRequest(ChangeRequest changeRequest, /** * Retrieves an updated information about a change request previously submitted to be applied to - * this zone. Returns a {@link ChangeRequest} or {@code null} if the change request was not - * found. Throws {@link DnsException} if the zone is not found. + * this zone. Returns a {@link ChangeRequest} or {@code null} if the change request was not found. + * Throws {@link DnsException} if the zone is not found. * * @param options optional restriction on what fields of {@link ChangeRequest} should be returned * @return updated ChangeRequest @@ -129,8 +128,8 @@ public ChangeRequest getChangeRequest(String changeRequestId, } /** - * Retrieves all change requests for this zone. The method searches for zone by name which must - * always be initialized. Returns a page of {@link ChangeRequest}s. + * Retrieves all change requests for this zone. The method searches for zone by name. Returns a + * page of {@link ChangeRequest}s. * * @param options optional restriction on listing and fields to be returned * @return a page of change requests From 5be58b3e91cade1d349014122484a29e254ba8f3 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Sun, 7 Feb 2016 14:01:52 -0800 Subject: [PATCH 069/375] Makes Zone subclass of ZoneInfo. Fixes #605. --- .../main/java/com/google/gcloud/dns/Dns.java | 2 +- .../main/java/com/google/gcloud/dns/Zone.java | 121 ++++++++++++++---- .../java/com/google/gcloud/dns/ZoneInfo.java | 98 ++++++++------ .../java/com/google/gcloud/dns/ZoneTest.java | 61 +++++++-- 4 files changed, 209 insertions(+), 73 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index 040a97e5b253..3ea505b5e09b 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -439,7 +439,7 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) { * @see Cloud DNS Managed Zones: * get */ - ZoneInfo getZone(String zoneName, ZoneOption... options); + Zone getZone(String zoneName, ZoneOption... options); /** * Lists the zones inside the project. diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java index 3f4ea8cab3e4..2da67a8e9a01 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java @@ -20,7 +20,8 @@ import com.google.gcloud.Page; -import java.io.Serializable; +import java.util.List; +import java.util.Objects; /** * A Google Cloud DNS Zone object. @@ -33,20 +34,87 @@ * @see Google Cloud DNS managed zone * documentation */ -public class Zone implements Serializable { +public class Zone extends ZoneInfo { - // TODO(mderka) Zone and zoneInfo to be merged. Opened issue #605. + private static final long serialVersionUID = 564454483894599281L; + private transient Dns dns; - private static final long serialVersionUID = 6847890192129375500L; - private final ZoneInfo zoneInfo; - private final Dns dns; + /** + * Builder for {@code Zone}. + */ + public static class Builder extends ZoneInfo.Builder { + private final Dns dns; + private final ZoneInfo.BuilderImpl infoBuilder; + + private Builder(Zone zone) { + this.dns = zone.dns; + this.infoBuilder = new ZoneInfo.BuilderImpl(zone); + } + + @Override + public Builder name(String name) { + infoBuilder.name(name); + return this; + } + + @Override + Builder id(String id) { + infoBuilder.id(id); + return this; + } + + @Override + Builder creationTimeMillis(long creationTimeMillis) { + infoBuilder.creationTimeMillis(creationTimeMillis); + return this; + } + + @Override + public Builder dnsName(String dnsName) { + infoBuilder.dnsName(dnsName); + return this; + } + + @Override + public Builder description(String description) { + infoBuilder.description(description); + return this; + } + + @Override + public Builder nameServerSet(String nameServerSet) { + infoBuilder.nameServerSet(nameServerSet); + return this; + } + + @Override + Builder nameServers(List nameServers) { + infoBuilder.nameServers(nameServers); // infoBuilder makes a copy + return this; + } + + @Override + public Zone build() { + return new Zone(dns, infoBuilder); + } + } + + Zone(Dns dns, ZoneInfo.BuilderImpl infoBuilder) { + super(infoBuilder); + this.dns = dns; + } + + @Override + public Builder toBuilder() { + return new Builder(this); + } /** * Constructs a {@code Zone} object that contains the given {@code zoneInfo}. */ public Zone(Dns dns, ZoneInfo zoneInfo) { - this.zoneInfo = checkNotNull(zoneInfo); - this.dns = checkNotNull(dns); + super(new BuilderImpl(zoneInfo)); + this.dns = dns; } /** @@ -61,8 +129,7 @@ public Zone(Dns dns, ZoneInfo zoneInfo) { public static Zone get(Dns dnsService, String zoneName, Dns.ZoneOption... options) { checkNotNull(zoneName); checkNotNull(dnsService); - ZoneInfo zoneInfo = dnsService.getZone(zoneName, options); - return zoneInfo == null ? null : new Zone(dnsService, zoneInfo); + return dnsService.getZone(zoneName, options); } /** @@ -73,7 +140,7 @@ public static Zone get(Dns dnsService, String zoneName, Dns.ZoneOption... option * @throws DnsException upon failure */ public Zone reload(Dns.ZoneOption... options) { - return Zone.get(dns, zoneInfo.name(), options); + return dns.getZone(name(), options); } /** @@ -83,7 +150,7 @@ public Zone reload(Dns.ZoneOption... options) { * @throws DnsException upon failure */ public boolean delete() { - return dns.delete(zoneInfo.name()); + return dns.delete(name()); } /** @@ -94,7 +161,7 @@ public boolean delete() { * @throws DnsException upon failure or if the zone is not found */ public Page listDnsRecords(Dns.DnsRecordListOption... options) { - return dns.listDnsRecords(zoneInfo.name(), options); + return dns.listDnsRecords(name(), options); } /** @@ -108,7 +175,7 @@ public Page listDnsRecords(Dns.DnsRecordListOption... options) { public ChangeRequest applyChangeRequest(ChangeRequest changeRequest, Dns.ChangeRequestOption... options) { checkNotNull(changeRequest); - return dns.applyChangeRequest(zoneInfo.name(), changeRequest, options); + return dns.applyChangeRequest(name(), changeRequest, options); } /** @@ -124,7 +191,7 @@ public ChangeRequest applyChangeRequest(ChangeRequest changeRequest, public ChangeRequest getChangeRequest(String changeRequestId, Dns.ChangeRequestOption... options) { checkNotNull(changeRequestId); - return dns.getChangeRequest(zoneInfo.name(), changeRequestId, options); + return dns.getChangeRequest(name(), changeRequestId, options); } /** @@ -136,14 +203,7 @@ public ChangeRequest getChangeRequest(String changeRequestId, * @throws DnsException upon failure or if the zone is not found */ public Page listChangeRequests(Dns.ChangeRequestListOption... options) { - return dns.listChangeRequests(zoneInfo.name(), options); - } - - /** - * Returns the {@link ZoneInfo} object containing information about this zone. - */ - public ZoneInfo info() { - return zoneInfo; + return dns.listChangeRequests(name(), options); } /** @@ -152,4 +212,19 @@ public ZoneInfo info() { public Dns dns() { return this.dns; } + + @Override + public boolean equals(Object obj) { + return obj instanceof Zone && Objects.equals(toPb(), ((Zone) obj).toPb()); + } + + @Override + public int hashCode() { + return super.hashCode(); + } + + static Zone fromPb(Dns dns, com.google.api.services.dns.model.ManagedZone zone) { + ZoneInfo info = ZoneInfo.fromPb(zone); + return new Zone(dns, info); + } } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java index a15518ae166f..e397e37a7fbf 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java @@ -49,9 +49,55 @@ public class ZoneInfo implements Serializable { private final List nameServers; /** - * A builder for {@code ZoneInfo}. + * Builder for {@code ZoneInfo}. */ - public static class Builder { + public abstract static class Builder { + /** + * Sets a mandatory user-provided name for the zone. It must be unique within the project. + */ + public abstract Builder name(String name); + + /** + * Sets an id for the zone which is assigned to the zone by the server. + */ + abstract Builder id(String id); + + /** + * Sets the time when this zone was created. + */ + abstract Builder creationTimeMillis(long creationTimeMillis); + + /** + * Sets a mandatory DNS name of this zone, for instance "example.com.". + */ + public abstract Builder dnsName(String dnsName); + + /** + * Sets a mandatory description for this zone. The value is a string of at most 1024 characters + * which has no effect on the zone's function. + */ + public abstract Builder description(String description); + + /** + * Optionally specifies the NameServerSet for this zone. A NameServerSet is a set of DNS name + * servers that all host the same zones. Most users will not need to specify this value. + */ + public abstract Builder nameServerSet(String nameServerSet); + // todo(mderka) add more to the doc when questions are answered by the service owner + + /** + * Sets a list of servers that hold the information about the zone. This information is provided + * by Google Cloud DNS and is read only. + */ + abstract Builder nameServers(List nameServers); + + /** + * Builds the instance of {@code ZoneInfo} based on the information set by this builder. + */ + public abstract ZoneInfo build(); + } + + public static class BuilderImpl extends Builder { private String name; private String id; private Long creationTimeMillis; @@ -60,14 +106,14 @@ public static class Builder { private String nameServerSet; private List nameServers = new LinkedList<>(); - private Builder(String name) { + private BuilderImpl(String name) { this.name = checkNotNull(name); } /** * Creates a builder from an existing ZoneInfo object. */ - Builder(ZoneInfo info) { + BuilderImpl(ZoneInfo info) { this.name = info.name; this.id = info.id; this.creationTimeMillis = info.creationTimeMillis; @@ -77,76 +123,56 @@ private Builder(String name) { this.nameServers.addAll(info.nameServers); } - /** - * Sets a mandatory user-provided name for the zone. It must be unique within the project. - */ + @Override public Builder name(String name) { this.name = checkNotNull(name); return this; } - /** - * Sets an id for the zone which is assigned to the zone by the server. - */ + @Override Builder id(String id) { this.id = id; return this; } - /** - * Sets the time when this zone was created. - */ + @Override Builder creationTimeMillis(long creationTimeMillis) { this.creationTimeMillis = creationTimeMillis; return this; } - /** - * Sets a mandatory DNS name of this zone, for instance "example.com.". - */ + @Override public Builder dnsName(String dnsName) { this.dnsName = checkNotNull(dnsName); return this; } - /** - * Sets a mandatory description for this zone. The value is a string of at most 1024 characters - * which has no effect on the zone's function. - */ + @Override public Builder description(String description) { this.description = checkNotNull(description); return this; } - /** - * Optionally specifies the NameServerSet for this zone. A NameServerSet is a set of DNS name - * servers that all host the same zones. Most users will not need to specify this value. - */ + @Override public Builder nameServerSet(String nameServerSet) { - // todo(mderka) add more to the doc when questions are answered by the service owner this.nameServerSet = checkNotNull(nameServerSet); return this; } - /** - * Sets a list of servers that hold the information about the zone. This information is provided - * by Google Cloud DNS and is read only. - */ + @Override Builder nameServers(List nameServers) { checkNotNull(nameServers); this.nameServers = Lists.newLinkedList(nameServers); return this; } - /** - * Builds the instance of {@code ZoneInfo} based on the information set by this builder. - */ + @Override public ZoneInfo build() { return new ZoneInfo(this); } } - private ZoneInfo(Builder builder) { + ZoneInfo(BuilderImpl builder) { this.name = builder.name; this.id = builder.id; this.creationTimeMillis = builder.creationTimeMillis; @@ -160,7 +186,7 @@ private ZoneInfo(Builder builder) { * Returns a builder for {@code ZoneInfo} with an assigned {@code name}. */ public static Builder builder(String name) { - return new Builder(name); + return new BuilderImpl(name); } /** @@ -217,7 +243,7 @@ public List nameServers() { * Returns a builder for {@code ZoneInfo} prepopulated with the metadata of this zone. */ public Builder toBuilder() { - return new Builder(this); + return new BuilderImpl(this); } com.google.api.services.dns.model.ManagedZone toPb() { @@ -240,7 +266,7 @@ com.google.api.services.dns.model.ManagedZone toPb() { } static ZoneInfo fromPb(com.google.api.services.dns.model.ManagedZone pb) { - Builder builder = new Builder(pb.getName()); + Builder builder = new BuilderImpl(pb.getName()); if (pb.getDescription() != null) { builder.description(pb.getDescription()); } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java index 59cb642167ed..1b09dca715a4 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java @@ -22,23 +22,27 @@ import static org.easymock.EasyMock.verify; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.google.common.collect.ImmutableList; import com.google.gcloud.Page; import org.junit.After; import org.junit.Before; import org.junit.Test; +import java.math.BigInteger; + public class ZoneTest { private static final String ZONE_NAME = "dns-zone-name"; private static final String ZONE_ID = "123"; - private static final ZoneInfo ZONE_INFO = ZoneInfo.builder(ZONE_NAME) + private static final ZoneInfo ZONE_INFO = Zone.builder(ZONE_NAME) .id(ZONE_ID) .dnsName("example.com") .creationTimeMillis(123478946464L) @@ -80,20 +84,19 @@ public void tearDown() throws Exception { @Test public void testConstructor() { replay(dns); - assertNotNull(zone.info()); - assertEquals(ZONE_INFO, zone.info()); + assertEquals(ZONE_INFO.toPb(), zone.toPb()); assertNotNull(zone.dns()); assertEquals(dns, zone.dns()); } @Test public void testGetByName() { - expect(dns.getZone(ZONE_NAME)).andReturn(ZONE_INFO); - expect(dns.getZone(ZONE_NAME, ZONE_FIELD_OPTIONS)).andReturn(ZONE_INFO); // for options + expect(dns.getZone(ZONE_NAME)).andReturn(zone); + expect(dns.getZone(ZONE_NAME, ZONE_FIELD_OPTIONS)).andReturn(zone); // for options replay(dns); Zone retrieved = Zone.get(dns, ZONE_NAME); assertSame(dns, retrieved.dns()); - assertEquals(ZONE_INFO, retrieved.info()); + assertEquals(zone, retrieved); // test passing options Zone.get(dns, ZONE_NAME, ZONE_FIELD_OPTIONS); try { @@ -188,18 +191,18 @@ public void listDnsRecordsByNameAndNotFound() { @Test public void reloadByNameAndFound() { - expect(dns.getZone(ZONE_NAME)).andReturn(zoneNoId.info()); - expect(dns.getZone(ZONE_NAME)).andReturn(zone.info()); + expect(dns.getZone(ZONE_NAME)).andReturn(zone); + expect(dns.getZone(ZONE_NAME)).andReturn(zone); // again for options - expect(dns.getZone(ZONE_NAME, ZONE_FIELD_OPTIONS)).andReturn(zoneNoId.info()); - expect(dns.getZone(ZONE_NAME, ZONE_FIELD_OPTIONS)).andReturn(zone.info()); + expect(dns.getZone(ZONE_NAME, ZONE_FIELD_OPTIONS)).andReturn(zoneNoId); + expect(dns.getZone(ZONE_NAME, ZONE_FIELD_OPTIONS)).andReturn(zone); replay(dns); Zone result = zoneNoId.reload(); - assertSame(zoneNoId.dns(), result.dns()); - assertEquals(zoneNoId.info(), result.info()); + assertSame(zone.dns(), result.dns()); + assertEquals(zone, result); result = zone.reload(); assertSame(zone.dns(), result.dns()); - assertEquals(zone.info(), result.info()); + assertEquals(zone, result); zoneNoId.reload(ZONE_FIELD_OPTIONS); // check options zone.reload(ZONE_FIELD_OPTIONS); // check options } @@ -499,4 +502,36 @@ public void listChangeRequestsAndZoneNotFound() { // expected } } + + @Test + public void testFromPb() { + replay(dns); + assertEquals(Zone.fromPb(dns, zone.toPb()), zone); + } + + @Test + public void testEqualsAndToBuilder() { + replay(dns); + assertEquals(zone, zone.toBuilder().build()); + } + + @Test + public void testBuilder() { + replay(dns); + assertNotEquals(zone, zone.toBuilder() + .id((new BigInteger(zone.id())).add(BigInteger.ONE).toString()) + .build()); + assertNotEquals(zone, zone.toBuilder().dnsName(zone.name() + "aaaa").build()); + assertNotEquals(zone, zone.toBuilder().nameServerSet(zone.nameServerSet() + "aaaa").build()); + assertNotEquals(zone, zone.toBuilder().nameServers(ImmutableList.of("nameserverpppp")).build()); + assertNotEquals(zone, zone.toBuilder().dnsName(zone.dnsName() + "aaaa").build()); + assertNotEquals(zone, zone.toBuilder().creationTimeMillis(zone.creationTimeMillis() + 1) + .build()); + Zone.Builder builder = zone.toBuilder(); + builder.id(ZONE_ID) + .dnsName("example.com") + .creationTimeMillis(123478946464L) + .build(); + assertEquals(zone, builder.build()); + } } From d1c45124dffd0a5a3bfdc2a4abe5c6483f32c295 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Sun, 7 Feb 2016 10:32:02 -0800 Subject: [PATCH 070/375] Added implementation of Dns and test. Renamed getProjectInfo. Fixed #619. --- .../main/java/com/google/gcloud/dns/Dns.java | 6 +- .../com/google/gcloud/dns/DnsException.java | 18 + .../java/com/google/gcloud/dns/DnsImpl.java | 335 ++++++++++++++++ .../com/google/gcloud/dns/DnsOptions.java | 2 +- .../com/google/gcloud/dns/DnsImplTest.java | 370 ++++++++++++++++++ 5 files changed, 727 insertions(+), 4 deletions(-) create mode 100644 gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java create mode 100644 gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index 3ea505b5e09b..88e0d7a08591 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -36,7 +36,7 @@ public interface Dns extends Service { * The fields of a project. * *

These values can be used to specify the fields to include in a partial response when calling - * {@link Dns#getProjectInfo(ProjectOption...)}. Project ID is always returned, even if not + * {@link Dns#getProject(ProjectOption...)}. Project ID is always returned, even if not * specified. */ enum ProjectField { @@ -429,7 +429,7 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) { * @see Cloud DNS Managed Zones: * create */ - ZoneInfo create(ZoneInfo zoneInfo, ZoneOption... options); + Zone create(ZoneInfo zoneInfo, ZoneOption... options); /** * Returns the zone by the specified zone name. Returns {@code null} if the zone is not found. The @@ -485,7 +485,7 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) { * @throws DnsException upon failure * @see Cloud DNS Projects: get */ - ProjectInfo getProjectInfo(ProjectOption... fields); + ProjectInfo getProject(ProjectOption... fields); /** * Submits a change request for the specified zone. The returned object contains the following diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java index 73c546759260..2092d5909d37 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java @@ -17,6 +17,8 @@ package com.google.gcloud.dns; import com.google.gcloud.BaseServiceException; +import com.google.gcloud.RetryHelper.RetryHelperException; +import com.google.gcloud.RetryHelper.RetryInterruptedException; import java.io.IOException; @@ -31,5 +33,21 @@ public DnsException(IOException exception) { super(exception, true); } + public DnsException(int code, String message) { + super(code, message, null, true); + } + + /** + * Translate RetryHelperException to the DnsException that caused the error. This method will + * always throw an exception. + * + * @throws DnsException when {@code ex} was caused by a {@code DnsException} + * @throws RetryInterruptedException when {@code ex} is a {@code RetryInterruptedException} + */ + static DnsException translateAndThrow(RetryHelperException ex) { + BaseServiceException.translateAndPropagateIfPossible(ex); + throw new DnsException(UNKNOWN_CODE, ex.getMessage()); + } + //TODO(mderka) Add translation and retry functionality. Created issue #593. } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java new file mode 100644 index 000000000000..b3ae73fd7e93 --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java @@ -0,0 +1,335 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.dns; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.gcloud.RetryHelper.RetryHelperException; +import static com.google.gcloud.RetryHelper.runWithRetries; +import static com.google.gcloud.dns.ChangeRequest.fromPb; + +import com.google.api.services.dns.model.Change; +import com.google.api.services.dns.model.ManagedZone; +import com.google.api.services.dns.model.ResourceRecordSet; +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; +import com.google.common.collect.Maps; +import com.google.gcloud.BaseService; +import com.google.gcloud.Page; +import com.google.gcloud.PageImpl; +import com.google.gcloud.RetryHelper; +import com.google.gcloud.spi.DnsRpc; + +import java.util.Map; +import java.util.concurrent.Callable; + +/** + * A default implementation of Dns. + */ +final class DnsImpl extends BaseService implements Dns { + + private final DnsRpc dnsRpc; + + private static class ZonePageFetcher implements PageImpl.NextPageFetcher { + + private static final long serialVersionUID = 2158209410430566961L; + private final Map requestOptions; + private final DnsOptions serviceOptions; + + ZonePageFetcher(DnsOptions serviceOptions, String cursor, + Map optionMap) { + this.requestOptions = + PageImpl.nextRequestOptions(DnsRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + } + + @Override + public Page nextPage() { + return listZones(serviceOptions, requestOptions); + } + } + + private static class ChangeRequestPageFetcher implements PageImpl.NextPageFetcher { + + private static final Function PB_TO_CHANGE_REQUEST = + new Function() { + @Override + public ChangeRequest apply(com.google.api.services.dns.model.Change changePb) { + return fromPb(changePb); + } + }; + private static final long serialVersionUID = -8737501076674042014L; + private final String zoneName; + private final Map requestOptions; + private final DnsOptions serviceOptions; + + ChangeRequestPageFetcher(String zoneName, DnsOptions serviceOptions, String cursor, + Map optionMap) { + this.zoneName = zoneName; + this.requestOptions = + PageImpl.nextRequestOptions(DnsRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + } + + @Override + public Page nextPage() { + return listChangeRequests(zoneName, serviceOptions, requestOptions, PB_TO_CHANGE_REQUEST); + } + } + + private static class DnsRecordPageFetcher implements PageImpl.NextPageFetcher { + + private static final Function PB_TO_DNS_RECORD = + new Function() { + @Override + public DnsRecord apply(com.google.api.services.dns.model.ResourceRecordSet pb) { + return DnsRecord.fromPb(pb); + } + }; + private static final long serialVersionUID = 670996349097667660L; + private final Map requestOptions; + private final DnsOptions serviceOptions; + private final String zoneName; + + DnsRecordPageFetcher(String zoneName, DnsOptions serviceOptions, String cursor, + Map optionMap) { + this.zoneName = zoneName; + this.requestOptions = + PageImpl.nextRequestOptions(DnsRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + } + + @Override + public Page nextPage() { + return listDnsRecords(zoneName, serviceOptions, requestOptions, PB_TO_DNS_RECORD); + } + } + + private static Page listZones(final DnsOptions serviceOptions, + final Map optionsMap) { + // define transformation function + // this differs from the other list operations since zone is functional and requires dns service + Function pbToZoneFunction = new Function() { + @Override + public Zone apply( + com.google.api.services.dns.model.ManagedZone zonePb) { + return new Zone(serviceOptions.service(), ZoneInfo.fromPb(zonePb)); + } + }; + try { + // get a list of managed zones + DnsRpc.ListResult result = + runWithRetries(new Callable>() { + @Override + public DnsRpc.ListResult call() { + return serviceOptions.rpc().listZones(optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.pageToken(); + // transform that list into zone objects + Iterable zones = result.results() == null + ? ImmutableList.of() : Iterables.transform(result.results(), pbToZoneFunction); + return new PageImpl<>(new ZonePageFetcher(serviceOptions, cursor, optionsMap), + cursor, zones); + } catch (RetryHelperException e) { + throw DnsException.translateAndThrow(e); + } + } + + private static Page listChangeRequests(final String zoneName, + final DnsOptions serviceOptions, final Map optionsMap, + Function TRANSFORM_FUNCTION) { + try { + // get a list of changes + DnsRpc.ListResult result = runWithRetries(new Callable>() { + @Override + public DnsRpc.ListResult call() { + return serviceOptions.rpc().listChangeRequests(zoneName, optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.pageToken(); + // transform that list into change request objects + Iterable changes = result.results() == null + ? ImmutableList.of() + : Iterables.transform(result.results(), TRANSFORM_FUNCTION); + return new PageImpl<>(new ChangeRequestPageFetcher(zoneName, serviceOptions, cursor, + optionsMap), cursor, changes); + } catch (RetryHelperException e) { + throw DnsException.translateAndThrow(e); + } + } + + private static Page listDnsRecords(final String zoneName, + final DnsOptions serviceOptions, final Map optionsMap, + Function TRANSFORM_FUNCTION) { + try { + // get a list of resource record sets + DnsRpc.ListResult result = runWithRetries( + new Callable>() { + @Override + public DnsRpc.ListResult call() { + return serviceOptions.rpc().listDnsRecords(zoneName, optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.pageToken(); + // transform that list into dns records + Iterable records = result.results() == null + ? ImmutableList.of() + : Iterables.transform(result.results(), TRANSFORM_FUNCTION); + return new PageImpl<>(new DnsRecordPageFetcher(zoneName, serviceOptions, cursor, optionsMap), + cursor, records); + } catch (RetryHelperException e) { + throw DnsException.translateAndThrow(e); + } + } + + DnsImpl(DnsOptions options) { + super(options); + dnsRpc = options.rpc(); + } + + @Override + public Page listZones(ZoneListOption... options) { + return listZones(options(), optionMap(options)); + } + + @Override + public Page listChangeRequests(String zoneName, + ChangeRequestListOption... options) { + return listChangeRequests(zoneName, options(), optionMap(options), + ChangeRequestPageFetcher.PB_TO_CHANGE_REQUEST); + } + + @Override + public Page listDnsRecords(String zoneName, DnsRecordListOption... options) { + return listDnsRecords(zoneName, options(), optionMap(options), + DnsRecordPageFetcher.PB_TO_DNS_RECORD); + } + + @Override + public Zone create(final ZoneInfo zoneInfo, Dns.ZoneOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.dns.model.ManagedZone answer = runWithRetries( + new Callable() { + @Override + public com.google.api.services.dns.model.ManagedZone call() { + return dnsRpc.create(zoneInfo.toPb(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Zone.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException ex) { + throw DnsException.translateAndThrow(ex); + } + } + + @Override + public Zone getZone(final String zoneName, Dns.ZoneOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.dns.model.ManagedZone answer = runWithRetries( + new Callable() { + @Override + public com.google.api.services.dns.model.ManagedZone call() { + return dnsRpc.getZone(zoneName, optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Zone.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException ex) { + throw DnsException.translateAndThrow(ex); + } + } + + @Override + public boolean delete(final String zoneName) { + try { + return runWithRetries(new Callable() { + @Override + public Boolean call() { + return dnsRpc.deleteZone(zoneName); + } + }, options().retryParams(), EXCEPTION_HANDLER); + } catch (RetryHelper.RetryHelperException ex) { + throw DnsException.translateAndThrow(ex); + } + } + + @Override + public ProjectInfo getProject(Dns.ProjectOption... fields) { + final Map optionsMap = optionMap(fields); + try { + com.google.api.services.dns.model.Project answer = runWithRetries( + new Callable() { + @Override + public com.google.api.services.dns.model.Project call() { + return dnsRpc.getProject(optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : ProjectInfo.fromPb(answer); // should never be null + } catch (RetryHelper.RetryHelperException ex) { + throw DnsException.translateAndThrow(ex); + } + } + + @Override + public ChangeRequest applyChangeRequest(final String zoneName, final ChangeRequest changeRequest, + Dns.ChangeRequestOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.dns.model.Change answer = + runWithRetries( + new Callable() { + @Override + public com.google.api.services.dns.model.Change call() { + return dnsRpc.applyChangeRequest(zoneName, changeRequest.toPb(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : fromPb(answer); // should never be null + } catch (RetryHelper.RetryHelperException ex) { + throw DnsException.translateAndThrow(ex); + } + } + + @Override + public ChangeRequest getChangeRequest(final String zoneName, final String changeRequestId, + Dns.ChangeRequestOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.dns.model.Change answer = + runWithRetries( + new Callable() { + @Override + public com.google.api.services.dns.model.Change call() { + return dnsRpc.getChangeRequest(zoneName, changeRequestId, optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : fromPb(answer); // should never be null + } catch (RetryHelper.RetryHelperException ex) { + throw DnsException.translateAndThrow(ex); + } + } + + private Map optionMap(AbstractOption... options) { + Map temp = Maps.newEnumMap(DnsRpc.Option.class); + for (AbstractOption option : options) { + Object prev = temp.put(option.rpcOption(), option.value()); + checkArgument(prev == null, "Duplicate option %s", option); + } + return ImmutableMap.copyOf(temp); + } +} diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java index 248fd164a55f..1ce4425366e5 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java @@ -37,7 +37,7 @@ public static class DefaultDnsFactory implements DnsFactory { @Override public Dns create(DnsOptions options) { // TODO(mderka) Implement when DnsImpl is available. Created issue #595. - return null; + return new DnsImpl(options); } } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java new file mode 100644 index 000000000000..8e063c9bb096 --- /dev/null +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java @@ -0,0 +1,370 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.dns; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import com.google.api.services.dns.model.Change; +import com.google.api.services.dns.model.ManagedZone; +import com.google.api.services.dns.model.ResourceRecordSet; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import com.google.gcloud.Page; +import com.google.gcloud.RetryParams; +import com.google.gcloud.ServiceOptions; +import com.google.gcloud.spi.DnsRpc; +import com.google.gcloud.spi.DnsRpcFactory; + +import org.easymock.Capture; +import org.easymock.EasyMock; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.Map; + +public class DnsImplTest { + + // Dns entities + private static final String ZONE_NAME = "some zone name"; + private static final String DNS_NAME = "example.com."; + private static final String CHANGE_ID = "some change id"; + private static final DnsRecord DNS_RECORD1 = DnsRecord.builder("Something", DnsRecord.Type.AAAA) + .build(); + private static final DnsRecord DNS_RECORD2 = DnsRecord.builder("Different", DnsRecord.Type.AAAA) + .build(); + private static final Integer MAX_SIZE = 20; + private static final String PAGE_TOKEN = "some token"; + private static final ZoneInfo ZONE_INFO = ZoneInfo.builder(ZONE_NAME).build(); + private static final ProjectInfo PROJECT_INFO = ProjectInfo.builder().build(); + private static final ChangeRequest CHANGE_REQUEST_PARTIAL = ChangeRequest.builder() + .add(DNS_RECORD1) + .build(); + private static final ChangeRequest CHANGE_REQUEST_COMPLETE = ChangeRequest.builder() + .add(DNS_RECORD1) + .startTimeMillis(123L) + .status(ChangeRequest.Status.PENDING) + .id(CHANGE_ID) + .build(); + + // Result lists + private static final DnsRpc.ListResult LIST_RESULT_OF_PB_CHANGES = + DnsRpc.ListResult.of("cursor", ImmutableList.of(CHANGE_REQUEST_COMPLETE.toPb(), + CHANGE_REQUEST_PARTIAL.toPb())); + private static final DnsRpc.ListResult LIST_RESULT_OF_PB_ZONES = + DnsRpc.ListResult.of("cursor", ImmutableList.of(ZONE_INFO.toPb())); + private static final DnsRpc.ListResult LIST_OF_PB_DNS_RECORDS = + DnsRpc.ListResult.of("cursor", ImmutableList.of(DNS_RECORD1.toPb(), DNS_RECORD2.toPb())); + + // Field options + private static final Dns.ZoneOption ZONE_FIELDS = + Dns.ZoneOption.fields(Dns.ZoneField.CREATION_TIME); + private static final Dns.ProjectOption PROJECT_FIELDS = + Dns.ProjectOption.fields(Dns.ProjectField.QUOTA); + private static final Dns.ChangeRequestOption CHANGE_GET_FIELDS = + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS); + + // Listing options + private static final Dns.ZoneListOption[] ZONE_LIST_OPTIONS = + {Dns.ZoneListOption.pageSize(MAX_SIZE), Dns.ZoneListOption.pageToken(PAGE_TOKEN), + Dns.ZoneListOption.fields(Dns.ZoneField.DESCRIPTION)}; + private static final Dns.ChangeRequestListOption[] CHANGE_LIST_OPTIONS = + {Dns.ChangeRequestListOption.pageSize(MAX_SIZE), + Dns.ChangeRequestListOption.pageToken(PAGE_TOKEN), + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.STATUS), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING)}; + private static final Dns.DnsRecordListOption[] DNS_RECORD_LIST_OPTIONS = + {Dns.DnsRecordListOption.pageSize(MAX_SIZE), + Dns.DnsRecordListOption.pageToken(PAGE_TOKEN), + Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TTL), + Dns.DnsRecordListOption.dnsName(DNS_NAME), + Dns.DnsRecordListOption.type(DnsRecord.Type.AAAA)}; + + // Other + private static final Map EMPTY_RPC_OPTIONS = ImmutableMap.of(); + private static final ServiceOptions.Clock TIME_SOURCE = new ServiceOptions.Clock() { + @Override + public long millis() { + return 42000L; + } + }; + + private DnsOptions options; + private DnsRpcFactory rpcFactoryMock; + private DnsRpc dnsRpcMock; + private Dns dns; + + @Before + public void setUp() { + rpcFactoryMock = EasyMock.createMock(DnsRpcFactory.class); + dnsRpcMock = EasyMock.createMock(DnsRpc.class); + EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DnsOptions.class))) + .andReturn(dnsRpcMock); + EasyMock.replay(rpcFactoryMock); + options = DnsOptions.builder() + .projectId("projectId") + .clock(TIME_SOURCE) + .serviceRpcFactory(rpcFactoryMock) + .retryParams(RetryParams.noRetries()) + .build(); + } + + @After + public void tearDown() throws Exception { + EasyMock.verify(rpcFactoryMock); + } + + @Test + public void testCreateZone() { + EasyMock.expect(dnsRpcMock.create(ZONE_INFO.toPb(), EMPTY_RPC_OPTIONS)) + .andReturn(ZONE_INFO.toPb()); + EasyMock.replay(dnsRpcMock); + dns = options.service(); // creates DnsImpl + ZoneInfo zoneInfo = dns.create(ZONE_INFO); + assertEquals(ZONE_INFO, zoneInfo); + } + + @Test + public void testCreateZoneWithOptions() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(dnsRpcMock.create(EasyMock.eq(ZONE_INFO.toPb()), + EasyMock.capture(capturedOptions))).andReturn(ZONE_INFO.toPb()); + EasyMock.replay(dnsRpcMock); + dns = options.service(); // creates DnsImpl + Zone zone = dns.create(ZONE_INFO, ZONE_FIELDS); + String selector = (String) capturedOptions.getValue().get(ZONE_FIELDS.rpcOption()); + assertEquals(ZONE_INFO, zone); + assertTrue(selector.contains(Dns.ZoneField.CREATION_TIME.selector())); + assertTrue(selector.contains(Dns.ZoneField.NAME.selector())); + } + + @Test + public void testGetZone() { + EasyMock.expect(dnsRpcMock.getZone(ZONE_INFO.name(), EMPTY_RPC_OPTIONS)) + .andReturn(ZONE_INFO.toPb()); + EasyMock.replay(dnsRpcMock); + dns = options.service(); // creates DnsImpl + ZoneInfo zoneInfo = dns.getZone(ZONE_INFO.name()); + assertEquals(ZONE_INFO, zoneInfo); + } + + @Test + public void testGetZoneWithOptions() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(dnsRpcMock.getZone(EasyMock.eq(ZONE_INFO.name()), + EasyMock.capture(capturedOptions))).andReturn(ZONE_INFO.toPb()); + EasyMock.replay(dnsRpcMock); + dns = options.service(); // creates DnsImpl + ZoneInfo zoneInfo = dns.getZone(ZONE_INFO.name(), ZONE_FIELDS); + String selector = (String) capturedOptions.getValue().get(ZONE_FIELDS.rpcOption()); + assertEquals(ZONE_INFO, zoneInfo); + assertTrue(selector.contains(Dns.ZoneField.CREATION_TIME.selector())); + assertTrue(selector.contains(Dns.ZoneField.NAME.selector())); + } + + @Test + public void testDeleteZone() { + EasyMock.expect(dnsRpcMock.deleteZone(ZONE_INFO.name())) + .andReturn(true); + EasyMock.replay(dnsRpcMock); + dns = options.service(); // creates DnsImpl + assertTrue(dns.delete(ZONE_INFO.name())); + } + + @Test + public void testGetProject() { + EasyMock.expect(dnsRpcMock.getProject(EMPTY_RPC_OPTIONS)) + .andReturn(PROJECT_INFO.toPb()); + EasyMock.replay(dnsRpcMock); + dns = options.service(); // creates DnsImpl + ProjectInfo projectInfo = dns.getProject(); + assertEquals(PROJECT_INFO, projectInfo); + } + + @Test + public void testProjectGetWithOptions() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(dnsRpcMock.getProject(EasyMock.capture(capturedOptions))) + .andReturn(PROJECT_INFO.toPb()); + EasyMock.replay(dnsRpcMock); + dns = options.service(); // creates DnsImpl + ProjectInfo projectInfo = dns.getProject(PROJECT_FIELDS); + String selector = (String) capturedOptions.getValue().get(PROJECT_FIELDS.rpcOption()); + assertEquals(PROJECT_INFO, projectInfo); + assertTrue(selector.contains(Dns.ProjectField.QUOTA.selector())); + assertTrue(selector.contains(Dns.ProjectField.PROJECT_ID.selector())); + } + + @Test + public void testGetChangeRequest() { + EasyMock.expect(dnsRpcMock.getChangeRequest(ZONE_INFO.name(), CHANGE_REQUEST_COMPLETE.id(), + EMPTY_RPC_OPTIONS)).andReturn(CHANGE_REQUEST_COMPLETE.toPb()); + EasyMock.replay(dnsRpcMock); + dns = options.service(); // creates DnsImpl + ChangeRequest changeRequest = dns.getChangeRequest(ZONE_INFO.name(), + CHANGE_REQUEST_COMPLETE.id()); + assertEquals(CHANGE_REQUEST_COMPLETE, changeRequest); + } + + @Test + public void testGetChangeRequestWithOptions() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(dnsRpcMock.getChangeRequest(EasyMock.eq(ZONE_INFO.name()), + EasyMock.eq(CHANGE_REQUEST_COMPLETE.id()), EasyMock.capture(capturedOptions))) + .andReturn(CHANGE_REQUEST_COMPLETE.toPb()); + EasyMock.replay(dnsRpcMock); + dns = options.service(); // creates DnsImpl + ChangeRequest changeRequest = dns.getChangeRequest(ZONE_INFO.name(), + CHANGE_REQUEST_COMPLETE.id(), CHANGE_GET_FIELDS); + String selector = (String) capturedOptions.getValue().get(CHANGE_GET_FIELDS.rpcOption()); + assertEquals(CHANGE_REQUEST_COMPLETE, changeRequest); + assertTrue(selector.contains(Dns.ChangeRequestField.STATUS.selector())); + assertTrue(selector.contains(Dns.ChangeRequestField.ID.selector())); + } + + @Test + public void testApplyChangeRequest() { + EasyMock.expect(dnsRpcMock.applyChangeRequest(ZONE_INFO.name(), CHANGE_REQUEST_PARTIAL.toPb(), + EMPTY_RPC_OPTIONS)).andReturn(CHANGE_REQUEST_COMPLETE.toPb()); + EasyMock.replay(dnsRpcMock); + dns = options.service(); // creates DnsImpl + ChangeRequest changeRequest = dns.applyChangeRequest(ZONE_INFO.name(), + CHANGE_REQUEST_PARTIAL); + assertEquals(CHANGE_REQUEST_COMPLETE, changeRequest); + } + + @Test + public void testApplyChangeRequestWithOptions() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(dnsRpcMock.applyChangeRequest(EasyMock.eq(ZONE_INFO.name()), + EasyMock.eq(CHANGE_REQUEST_PARTIAL.toPb()), EasyMock.capture(capturedOptions))) + .andReturn(CHANGE_REQUEST_COMPLETE.toPb()); + EasyMock.replay(dnsRpcMock); + dns = options.service(); // creates DnsImpl + ChangeRequest changeRequest = dns.applyChangeRequest(ZONE_INFO.name(), + CHANGE_REQUEST_PARTIAL, CHANGE_GET_FIELDS); + String selector = (String) capturedOptions.getValue().get(CHANGE_GET_FIELDS.rpcOption()); + assertEquals(CHANGE_REQUEST_COMPLETE, changeRequest); + assertTrue(selector.contains(Dns.ChangeRequestField.STATUS.selector())); + assertTrue(selector.contains(Dns.ChangeRequestField.ID.selector())); + } + + // lists + @Test + public void testListChangeRequests() { + EasyMock.expect(dnsRpcMock.listChangeRequests(ZONE_INFO.name(), EMPTY_RPC_OPTIONS)) + .andReturn(LIST_RESULT_OF_PB_CHANGES); + EasyMock.replay(dnsRpcMock); + dns = options.service(); // creates DnsImpl + Page changeRequestPage = dns.listChangeRequests(ZONE_INFO.name()); + assertTrue(Lists.newArrayList(changeRequestPage.values()).contains(CHANGE_REQUEST_COMPLETE)); + assertTrue(Lists.newArrayList(changeRequestPage.values()).contains(CHANGE_REQUEST_PARTIAL)); + assertEquals(2, Lists.newArrayList(changeRequestPage.values()).size()); + } + + @Test + public void testListChangeRequestsWithOptions() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(dnsRpcMock.listChangeRequests(EasyMock.eq(ZONE_NAME), + EasyMock.capture(capturedOptions))).andReturn(LIST_RESULT_OF_PB_CHANGES); + EasyMock.replay(dnsRpcMock); + dns = options.service(); // creates DnsImpl + Page changeRequestPage = dns.listChangeRequests(ZONE_NAME, CHANGE_LIST_OPTIONS); + assertTrue(Lists.newArrayList(changeRequestPage.values()).contains(CHANGE_REQUEST_COMPLETE)); + assertTrue(Lists.newArrayList(changeRequestPage.values()).contains(CHANGE_REQUEST_PARTIAL)); + assertEquals(2, Lists.newArrayList(changeRequestPage.values()).size()); + Integer size = (Integer) capturedOptions.getValue().get(CHANGE_LIST_OPTIONS[0].rpcOption()); + assertEquals(MAX_SIZE, size); + String selector = (String) capturedOptions.getValue().get(CHANGE_LIST_OPTIONS[1].rpcOption()); + assertEquals(PAGE_TOKEN, selector); + selector = (String) capturedOptions.getValue().get(CHANGE_LIST_OPTIONS[2].rpcOption()); + assertTrue(selector.contains(Dns.ChangeRequestField.STATUS.selector())); + assertTrue(selector.contains(Dns.ChangeRequestField.ID.selector())); + selector = (String) capturedOptions.getValue().get(CHANGE_LIST_OPTIONS[3].rpcOption()); + assertTrue(selector.contains(Dns.SortingOrder.ASCENDING.selector())); + } + + @Test + public void testListZones() { + EasyMock.expect(dnsRpcMock.listZones(EMPTY_RPC_OPTIONS)) + .andReturn(LIST_RESULT_OF_PB_ZONES); + EasyMock.replay(dnsRpcMock); + dns = options.service(); // creates DnsImpl + Page zonePage = dns.listZones(); + assertEquals(1, Lists.newArrayList(zonePage.values()).size()); + assertEquals(ZONE_INFO, Lists.newArrayList(zonePage.values()).get(0)); + } + + @Test + public void testListZonesWithOptions() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(dnsRpcMock.listZones(EasyMock.capture(capturedOptions))) + .andReturn(LIST_RESULT_OF_PB_ZONES); + EasyMock.replay(dnsRpcMock); + dns = options.service(); // creates DnsImpl + Page zonePage = dns.listZones(ZONE_LIST_OPTIONS); + assertEquals(1, Lists.newArrayList(zonePage.values()).size()); + assertEquals(ZONE_INFO, Lists.newArrayList(zonePage.values()).get(0)); + Integer size = (Integer) capturedOptions.getValue().get(ZONE_LIST_OPTIONS[0].rpcOption()); + assertEquals(MAX_SIZE, size); + String selector = (String) capturedOptions.getValue().get(ZONE_LIST_OPTIONS[1].rpcOption()); + assertEquals(PAGE_TOKEN, selector); + selector = (String) capturedOptions.getValue().get(ZONE_LIST_OPTIONS[2].rpcOption()); + assertTrue(selector.contains(Dns.ZoneField.DESCRIPTION.selector())); + assertTrue(selector.contains(Dns.ZoneField.NAME.selector())); + } + + @Test + public void testListDnsRecords() { + EasyMock.expect(dnsRpcMock.listDnsRecords(ZONE_INFO.name(), EMPTY_RPC_OPTIONS)) + .andReturn(LIST_OF_PB_DNS_RECORDS); + EasyMock.replay(dnsRpcMock); + dns = options.service(); // creates DnsImpl + Page dnsPage = dns.listDnsRecords(ZONE_INFO.name()); + assertEquals(2, Lists.newArrayList(dnsPage.values()).size()); + assertTrue(Lists.newArrayList(dnsPage.values()).contains(DNS_RECORD1)); + assertTrue(Lists.newArrayList(dnsPage.values()).contains(DNS_RECORD2)); + } + + @Test + public void testListDnsRecordsWithOptions() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(dnsRpcMock.listDnsRecords(EasyMock.eq(ZONE_NAME), + EasyMock.capture(capturedOptions))).andReturn(LIST_OF_PB_DNS_RECORDS); + EasyMock.replay(dnsRpcMock); + dns = options.service(); // creates DnsImpl + Page dnsPage = dns.listDnsRecords(ZONE_NAME, DNS_RECORD_LIST_OPTIONS); + assertEquals(2, Lists.newArrayList(dnsPage.values()).size()); + assertTrue(Lists.newArrayList(dnsPage.values()).contains(DNS_RECORD1)); + assertTrue(Lists.newArrayList(dnsPage.values()).contains(DNS_RECORD2)); + Integer size = (Integer) capturedOptions.getValue().get(DNS_RECORD_LIST_OPTIONS[0].rpcOption()); + assertEquals(MAX_SIZE, size); + String selector = (String) capturedOptions.getValue() + .get(DNS_RECORD_LIST_OPTIONS[1].rpcOption()); + assertEquals(PAGE_TOKEN, selector); + selector = (String) capturedOptions.getValue().get(DNS_RECORD_LIST_OPTIONS[2].rpcOption()); + assertTrue(selector.contains(Dns.DnsRecordField.NAME.selector())); + assertTrue(selector.contains(Dns.DnsRecordField.TTL.selector())); + selector = (String) capturedOptions.getValue().get(DNS_RECORD_LIST_OPTIONS[3].rpcOption()); + assertEquals(DNS_RECORD_LIST_OPTIONS[3].value(), selector); + DnsRecord.Type type = (DnsRecord.Type) capturedOptions.getValue().get(DNS_RECORD_LIST_OPTIONS[4] + .rpcOption()); + assertEquals(DNS_RECORD_LIST_OPTIONS[4].value(), type); + } +} From c0c5451d286675248e32fdf3a37c7c9293cd3f4a Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Mon, 8 Feb 2016 11:34:41 -0800 Subject: [PATCH 071/375] Included options attribute to Zone. Fixed symmetry of toPb and fromPb. Finished DnsOptions. Fixed #595. --- .../java/com/google/gcloud/dns/DnsImpl.java | 44 +++++++++---------- .../com/google/gcloud/dns/DnsOptions.java | 4 +- .../main/java/com/google/gcloud/dns/Zone.java | 17 +++++-- .../java/com/google/gcloud/dns/ZoneInfo.java | 19 ++++---- .../com/google/gcloud/dns/DnsImplTest.java | 18 ++++---- .../java/com/google/gcloud/dns/ZoneTest.java | 24 +++++++++- 6 files changed, 79 insertions(+), 47 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java index b3ae73fd7e93..c93409554dd8 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java @@ -120,6 +120,11 @@ public Page nextPage() { } } + @Override + public Page listZones(ZoneListOption... options) { + return listZones(options(), optionMap(options)); + } + private static Page listZones(final DnsOptions serviceOptions, final Map optionsMap) { // define transformation function @@ -151,9 +156,16 @@ public DnsRpc.ListResult call() { } } + @Override + public Page listChangeRequests(String zoneName, + ChangeRequestListOption... options) { + return listChangeRequests(zoneName, options(), optionMap(options), + ChangeRequestPageFetcher.PB_TO_CHANGE_REQUEST); + } + private static Page listChangeRequests(final String zoneName, final DnsOptions serviceOptions, final Map optionsMap, - Function TRANSFORM_FUNCTION) { + Function transformFunction) { try { // get a list of changes DnsRpc.ListResult result = runWithRetries(new Callable>() { @@ -166,7 +178,7 @@ public DnsRpc.ListResult call() { // transform that list into change request objects Iterable changes = result.results() == null ? ImmutableList.of() - : Iterables.transform(result.results(), TRANSFORM_FUNCTION); + : Iterables.transform(result.results(), transformFunction); return new PageImpl<>(new ChangeRequestPageFetcher(zoneName, serviceOptions, cursor, optionsMap), cursor, changes); } catch (RetryHelperException e) { @@ -174,9 +186,15 @@ public DnsRpc.ListResult call() { } } + @Override + public Page listDnsRecords(String zoneName, DnsRecordListOption... options) { + return listDnsRecords(zoneName, options(), optionMap(options), + DnsRecordPageFetcher.PB_TO_DNS_RECORD); + } + private static Page listDnsRecords(final String zoneName, final DnsOptions serviceOptions, final Map optionsMap, - Function TRANSFORM_FUNCTION) { + Function transformFunction) { try { // get a list of resource record sets DnsRpc.ListResult result = runWithRetries( @@ -190,7 +208,7 @@ public DnsRpc.ListResult call() { // transform that list into dns records Iterable records = result.results() == null ? ImmutableList.of() - : Iterables.transform(result.results(), TRANSFORM_FUNCTION); + : Iterables.transform(result.results(), transformFunction); return new PageImpl<>(new DnsRecordPageFetcher(zoneName, serviceOptions, cursor, optionsMap), cursor, records); } catch (RetryHelperException e) { @@ -203,24 +221,6 @@ public DnsRpc.ListResult call() { dnsRpc = options.rpc(); } - @Override - public Page listZones(ZoneListOption... options) { - return listZones(options(), optionMap(options)); - } - - @Override - public Page listChangeRequests(String zoneName, - ChangeRequestListOption... options) { - return listChangeRequests(zoneName, options(), optionMap(options), - ChangeRequestPageFetcher.PB_TO_CHANGE_REQUEST); - } - - @Override - public Page listDnsRecords(String zoneName, DnsRecordListOption... options) { - return listDnsRecords(zoneName, options(), optionMap(options), - DnsRecordPageFetcher.PB_TO_DNS_RECORD); - } - @Override public Zone create(final ZoneInfo zoneInfo, Dns.ZoneOption... options) { final Map optionsMap = optionMap(options); diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java index 1ce4425366e5..b47532146b3a 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java @@ -24,8 +24,7 @@ import java.util.Set; -public class DnsOptions - extends ServiceOptions { +public class DnsOptions extends ServiceOptions { private static final long serialVersionUID = -519128051411747771L; private static final String GC_DNS_RW = "https://www.googleapis.com/auth/ndev.clouddns.readwrite"; @@ -36,7 +35,6 @@ public static class DefaultDnsFactory implements DnsFactory { @Override public Dns create(DnsOptions options) { - // TODO(mderka) Implement when DnsImpl is available. Created issue #595. return new DnsImpl(options); } } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java index 2da67a8e9a01..d53909b0f084 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java @@ -20,6 +20,8 @@ import com.google.gcloud.Page; +import java.io.IOException; +import java.io.ObjectInputStream; import java.util.List; import java.util.Objects; @@ -36,7 +38,8 @@ */ public class Zone extends ZoneInfo { - private static final long serialVersionUID = 564454483894599281L; + private static final long serialVersionUID = -5817771337847861598L; + private final DnsOptions options; private transient Dns dns; /** @@ -102,6 +105,7 @@ public Zone build() { Zone(Dns dns, ZoneInfo.BuilderImpl infoBuilder) { super(infoBuilder); this.dns = dns; + this.options = dns.options(); } @Override @@ -115,6 +119,7 @@ public Builder toBuilder() { public Zone(Dns dns, ZoneInfo zoneInfo) { super(new BuilderImpl(zoneInfo)); this.dns = dns; + this.options = dns.options(); } /** @@ -215,12 +220,18 @@ public Dns dns() { @Override public boolean equals(Object obj) { - return obj instanceof Zone && Objects.equals(toPb(), ((Zone) obj).toPb()); + return obj instanceof Zone && Objects.equals(toPb(), ((Zone) obj).toPb()) + && Objects.equals(options, ((Zone) obj).options); } @Override public int hashCode() { - return super.hashCode(); + return Objects.hash(super.hashCode(), options); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + this.dns = options.service(); } static Zone fromPb(Dns dns, com.google.api.services.dns.model.ManagedZone zone) { diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java index e397e37a7fbf..e26dcde70a83 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java @@ -27,7 +27,6 @@ import java.io.Serializable; import java.math.BigInteger; -import java.util.LinkedList; import java.util.List; import java.util.Objects; @@ -97,14 +96,14 @@ public abstract static class Builder { public abstract ZoneInfo build(); } - public static class BuilderImpl extends Builder { + static class BuilderImpl extends Builder { private String name; private String id; private Long creationTimeMillis; private String dnsName; private String description; private String nameServerSet; - private List nameServers = new LinkedList<>(); + private List nameServers; private BuilderImpl(String name) { this.name = checkNotNull(name); @@ -120,7 +119,9 @@ private BuilderImpl(String name) { this.dnsName = info.dnsName; this.description = info.description; this.nameServerSet = info.nameServerSet; - this.nameServers.addAll(info.nameServers); + if (info.nameServers != null) { + this.nameServers = ImmutableList.copyOf(info.nameServers); + } } @Override @@ -179,7 +180,8 @@ public ZoneInfo build() { this.dnsName = builder.dnsName; this.description = builder.description; this.nameServerSet = builder.nameServerSet; - this.nameServers = ImmutableList.copyOf(builder.nameServers); + this.nameServers = builder.nameServers == null + ? null : ImmutableList.copyOf(builder.nameServers); } /** @@ -236,7 +238,7 @@ public String nameServerSet() { * The nameservers that the zone should be delegated to. This is defined by the Google DNS cloud. */ public List nameServers() { - return nameServers; + return nameServers == null ? ImmutableList.of() : nameServers; } /** @@ -255,7 +257,7 @@ com.google.api.services.dns.model.ManagedZone toPb() { pb.setId(new BigInteger(this.id())); } pb.setName(this.name()); - pb.setNameServers(this.nameServers()); + pb.setNameServers(this.nameServers); // do use real attribute value which may be null pb.setNameServerSet(this.nameServerSet()); if (this.creationTimeMillis() != null) { pb.setCreationTime(ISODateTimeFormat.dateTime() @@ -290,7 +292,8 @@ static ZoneInfo fromPb(com.google.api.services.dns.model.ManagedZone pb) { @Override public boolean equals(Object obj) { - return obj instanceof ZoneInfo && Objects.equals(toPb(), ((ZoneInfo) obj).toPb()); + return obj != null && obj.getClass().equals(ZoneInfo.class) + && Objects.equals(toPb(), ((ZoneInfo) obj).toPb()); } @Override diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java index 8e063c9bb096..62e96b05dda5 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java @@ -136,8 +136,8 @@ public void testCreateZone() { .andReturn(ZONE_INFO.toPb()); EasyMock.replay(dnsRpcMock); dns = options.service(); // creates DnsImpl - ZoneInfo zoneInfo = dns.create(ZONE_INFO); - assertEquals(ZONE_INFO, zoneInfo); + Zone zone = dns.create(ZONE_INFO); + assertEquals(new Zone(dns, ZONE_INFO), zone); } @Test @@ -149,7 +149,7 @@ public void testCreateZoneWithOptions() { dns = options.service(); // creates DnsImpl Zone zone = dns.create(ZONE_INFO, ZONE_FIELDS); String selector = (String) capturedOptions.getValue().get(ZONE_FIELDS.rpcOption()); - assertEquals(ZONE_INFO, zone); + assertEquals(new Zone(dns, ZONE_INFO), zone); assertTrue(selector.contains(Dns.ZoneField.CREATION_TIME.selector())); assertTrue(selector.contains(Dns.ZoneField.NAME.selector())); } @@ -160,8 +160,8 @@ public void testGetZone() { .andReturn(ZONE_INFO.toPb()); EasyMock.replay(dnsRpcMock); dns = options.service(); // creates DnsImpl - ZoneInfo zoneInfo = dns.getZone(ZONE_INFO.name()); - assertEquals(ZONE_INFO, zoneInfo); + Zone zone = dns.getZone(ZONE_INFO.name()); + assertEquals(new Zone(dns, ZONE_INFO), zone); } @Test @@ -171,9 +171,9 @@ public void testGetZoneWithOptions() { EasyMock.capture(capturedOptions))).andReturn(ZONE_INFO.toPb()); EasyMock.replay(dnsRpcMock); dns = options.service(); // creates DnsImpl - ZoneInfo zoneInfo = dns.getZone(ZONE_INFO.name(), ZONE_FIELDS); + Zone zone = dns.getZone(ZONE_INFO.name(), ZONE_FIELDS); String selector = (String) capturedOptions.getValue().get(ZONE_FIELDS.rpcOption()); - assertEquals(ZONE_INFO, zoneInfo); + assertEquals(new Zone(dns, ZONE_INFO), zone); assertTrue(selector.contains(Dns.ZoneField.CREATION_TIME.selector())); assertTrue(selector.contains(Dns.ZoneField.NAME.selector())); } @@ -308,7 +308,7 @@ public void testListZones() { dns = options.service(); // creates DnsImpl Page zonePage = dns.listZones(); assertEquals(1, Lists.newArrayList(zonePage.values()).size()); - assertEquals(ZONE_INFO, Lists.newArrayList(zonePage.values()).get(0)); + assertEquals(new Zone(dns, ZONE_INFO), Lists.newArrayList(zonePage.values()).get(0)); } @Test @@ -320,7 +320,7 @@ public void testListZonesWithOptions() { dns = options.service(); // creates DnsImpl Page zonePage = dns.listZones(ZONE_LIST_OPTIONS); assertEquals(1, Lists.newArrayList(zonePage.values()).size()); - assertEquals(ZONE_INFO, Lists.newArrayList(zonePage.values()).get(0)); + assertEquals(new Zone(dns, ZONE_INFO), Lists.newArrayList(zonePage.values()).get(0)); Integer size = (Integer) capturedOptions.getValue().get(ZONE_LIST_OPTIONS[0].rpcOption()); assertEquals(MAX_SIZE, size); String selector = (String) capturedOptions.getValue().get(ZONE_LIST_OPTIONS[1].rpcOption()); diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java index 1b09dca715a4..b28847a4e046 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java @@ -19,6 +19,7 @@ import static org.easymock.EasyMock.createStrictMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.reset; import static org.easymock.EasyMock.verify; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -64,16 +65,22 @@ public class ZoneTest { .startTimeMillis(123465L).build(); private static final ChangeRequest CHANGE_REQUEST_NO_ID = ChangeRequest.builder().build(); private static final DnsException EXCEPTION = createStrictMock(DnsException.class); + private static final DnsOptions OPTIONS = createStrictMock(DnsOptions.class); private Dns dns; private Zone zone; private Zone zoneNoId; + @Before public void setUp() throws Exception { dns = createStrictMock(Dns.class); + expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS); + replay(dns); zone = new Zone(dns, ZONE_INFO); zoneNoId = new Zone(dns, NO_ID_INFO); + reset(dns); } @After @@ -347,13 +354,13 @@ public void getChangeAndZoneNotFoundByName() { .andThrow(EXCEPTION); replay(dns); try { - ChangeRequest result = zoneNoId.getChangeRequest(CHANGE_REQUEST.id()); + zoneNoId.getChangeRequest(CHANGE_REQUEST.id()); fail("Parent container not found, should throw an exception."); } catch (DnsException e) { // expected } try { - ChangeRequest result = zone.getChangeRequest(CHANGE_REQUEST.id()); + zone.getChangeRequest(CHANGE_REQUEST.id()); fail("Parent container not found, should throw an exception."); } catch (DnsException e) { // expected @@ -505,18 +512,31 @@ public void listChangeRequestsAndZoneNotFound() { @Test public void testFromPb() { + expect(dns.options()).andReturn(OPTIONS); replay(dns); assertEquals(Zone.fromPb(dns, zone.toPb()), zone); } @Test public void testEqualsAndToBuilder() { + expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS); replay(dns); assertEquals(zone, zone.toBuilder().build()); + assertEquals(zone.hashCode(), zone.toBuilder().build().hashCode()); } @Test public void testBuilder() { + // one for each build() call because it invokes a constructor + expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS); replay(dns); assertNotEquals(zone, zone.toBuilder() .id((new BigInteger(zone.id())).add(BigInteger.ONE).toString()) From ee5bb8f1db07dd6a3fb125c16acfd27f8e0c7325 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Mon, 8 Feb 2016 16:35:07 -0800 Subject: [PATCH 072/375] Removed zone.get() and optimized retries. --- .../com/google/gcloud/dns/ChangeRequest.java | 27 +++----- .../main/java/com/google/gcloud/dns/Dns.java | 2 +- .../java/com/google/gcloud/dns/DnsImpl.java | 61 +++++++------------ .../java/com/google/gcloud/dns/DnsRecord.java | 18 +++++- .../main/java/com/google/gcloud/dns/Zone.java | 26 +------- .../java/com/google/gcloud/dns/ZoneInfo.java | 2 +- .../com/google/gcloud/dns/DnsImplTest.java | 42 +++++++------ .../java/com/google/gcloud/dns/ZoneTest.java | 28 +-------- 8 files changed, 77 insertions(+), 129 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java index 582dd2b2e05b..76d231b704c4 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java @@ -18,7 +18,7 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.api.services.dns.model.ResourceRecordSet; +import com.google.api.services.dns.model.Change; import com.google.common.base.Function; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; @@ -40,21 +40,14 @@ */ public class ChangeRequest implements Serializable { - private static final Function FROM_PB_FUNCTION = - new Function() { + static final Function FROM_PB_FUNCTION = + new Function() { @Override - public DnsRecord apply(com.google.api.services.dns.model.ResourceRecordSet pb) { - return DnsRecord.fromPb(pb); + public ChangeRequest apply(com.google.api.services.dns.model.Change pb) { + return ChangeRequest.fromPb(pb); } }; - private static final Function TO_PB_FUNCTION = - new Function() { - @Override - public com.google.api.services.dns.model.ResourceRecordSet apply(DnsRecord error) { - return error.toPb(); - } - }; - private static final long serialVersionUID = -8703939628990291682L; + private static final long serialVersionUID = -9027378042756366333L; private final List additions; private final List deletions; private final String id; @@ -274,9 +267,9 @@ com.google.api.services.dns.model.Change toPb() { pb.setStatus(status().name().toLowerCase()); } // set a list of additions - pb.setAdditions(Lists.transform(additions(), TO_PB_FUNCTION)); + pb.setAdditions(Lists.transform(additions(), DnsRecord.TO_PB_FUNCTION)); // set a list of deletions - pb.setDeletions(Lists.transform(deletions(), TO_PB_FUNCTION)); + pb.setDeletions(Lists.transform(deletions(), DnsRecord.TO_PB_FUNCTION)); return pb; } @@ -293,10 +286,10 @@ static ChangeRequest fromPb(com.google.api.services.dns.model.Change pb) { builder.status(ChangeRequest.Status.valueOf(pb.getStatus().toUpperCase())); } if (pb.getDeletions() != null) { - builder.deletions(Lists.transform(pb.getDeletions(), FROM_PB_FUNCTION)); + builder.deletions(Lists.transform(pb.getDeletions(), DnsRecord.FROM_PB_FUNCTION)); } if (pb.getAdditions() != null) { - builder.additions(Lists.transform(pb.getAdditions(), FROM_PB_FUNCTION)); + builder.additions(Lists.transform(pb.getAdditions(), DnsRecord.FROM_PB_FUNCTION)); } return builder.build(); } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index 88e0d7a08591..e724e1cbf1ad 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -419,7 +419,7 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) { /** * Creates a new zone. * - *

Returns {@link ZoneInfo} object representing the new zone's information. In addition to the + *

Returns {@link Zone} object representing the new zone's information. In addition to the * name, dns name and description (supplied by the user within the {@code zoneInfo} parameter), * the returned object can include the following read-only fields supplied by the server: creation * time, id, and list of name servers. The returned fields can be optionally restricted by diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java index c93409554dd8..17521c13c625 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java @@ -66,14 +66,7 @@ public Page nextPage() { private static class ChangeRequestPageFetcher implements PageImpl.NextPageFetcher { - private static final Function PB_TO_CHANGE_REQUEST = - new Function() { - @Override - public ChangeRequest apply(com.google.api.services.dns.model.Change changePb) { - return fromPb(changePb); - } - }; - private static final long serialVersionUID = -8737501076674042014L; + private static final long serialVersionUID = 4473265130673029139L; private final String zoneName; private final Map requestOptions; private final DnsOptions serviceOptions; @@ -88,20 +81,13 @@ public ChangeRequest apply(com.google.api.services.dns.model.Change changePb) { @Override public Page nextPage() { - return listChangeRequests(zoneName, serviceOptions, requestOptions, PB_TO_CHANGE_REQUEST); + return listChangeRequests(zoneName, serviceOptions, requestOptions); } } private static class DnsRecordPageFetcher implements PageImpl.NextPageFetcher { - private static final Function PB_TO_DNS_RECORD = - new Function() { - @Override - public DnsRecord apply(com.google.api.services.dns.model.ResourceRecordSet pb) { - return DnsRecord.fromPb(pb); - } - }; - private static final long serialVersionUID = 670996349097667660L; + private static final long serialVersionUID = -6039369212511530846L; private final Map requestOptions; private final DnsOptions serviceOptions; private final String zoneName; @@ -116,10 +102,15 @@ public DnsRecord apply(com.google.api.services.dns.model.ResourceRecordSet pb) { @Override public Page nextPage() { - return listDnsRecords(zoneName, serviceOptions, requestOptions, PB_TO_DNS_RECORD); + return listDnsRecords(zoneName, serviceOptions, requestOptions); } } + DnsImpl(DnsOptions options) { + super(options); + dnsRpc = options.rpc(); + } + @Override public Page listZones(ZoneListOption... options) { return listZones(options(), optionMap(options)); @@ -133,16 +124,17 @@ private static Page listZones(final DnsOptions serviceOptions, @Override public Zone apply( com.google.api.services.dns.model.ManagedZone zonePb) { - return new Zone(serviceOptions.service(), ZoneInfo.fromPb(zonePb)); + return Zone.fromPb(serviceOptions.service(), zonePb); } }; try { // get a list of managed zones + final DnsRpc rpc = serviceOptions.rpc(); DnsRpc.ListResult result = runWithRetries(new Callable>() { @Override public DnsRpc.ListResult call() { - return serviceOptions.rpc().listZones(optionsMap); + return rpc.listZones(optionsMap); } }, serviceOptions.retryParams(), EXCEPTION_HANDLER); String cursor = result.pageToken(); @@ -159,26 +151,25 @@ public DnsRpc.ListResult call() { @Override public Page listChangeRequests(String zoneName, ChangeRequestListOption... options) { - return listChangeRequests(zoneName, options(), optionMap(options), - ChangeRequestPageFetcher.PB_TO_CHANGE_REQUEST); + return listChangeRequests(zoneName, options(), optionMap(options)); } private static Page listChangeRequests(final String zoneName, - final DnsOptions serviceOptions, final Map optionsMap, - Function transformFunction) { + final DnsOptions serviceOptions, final Map optionsMap) { try { // get a list of changes + final DnsRpc rpc = serviceOptions.rpc(); DnsRpc.ListResult result = runWithRetries(new Callable>() { @Override public DnsRpc.ListResult call() { - return serviceOptions.rpc().listChangeRequests(zoneName, optionsMap); + return rpc.listChangeRequests(zoneName, optionsMap); } }, serviceOptions.retryParams(), EXCEPTION_HANDLER); String cursor = result.pageToken(); // transform that list into change request objects Iterable changes = result.results() == null ? ImmutableList.of() - : Iterables.transform(result.results(), transformFunction); + : Iterables.transform(result.results(), ChangeRequest.FROM_PB_FUNCTION); return new PageImpl<>(new ChangeRequestPageFetcher(zoneName, serviceOptions, cursor, optionsMap), cursor, changes); } catch (RetryHelperException e) { @@ -188,27 +179,26 @@ public DnsRpc.ListResult call() { @Override public Page listDnsRecords(String zoneName, DnsRecordListOption... options) { - return listDnsRecords(zoneName, options(), optionMap(options), - DnsRecordPageFetcher.PB_TO_DNS_RECORD); + return listDnsRecords(zoneName, options(), optionMap(options)); } private static Page listDnsRecords(final String zoneName, - final DnsOptions serviceOptions, final Map optionsMap, - Function transformFunction) { + final DnsOptions serviceOptions, final Map optionsMap) { try { // get a list of resource record sets + final DnsRpc rpc = serviceOptions.rpc(); DnsRpc.ListResult result = runWithRetries( new Callable>() { @Override public DnsRpc.ListResult call() { - return serviceOptions.rpc().listDnsRecords(zoneName, optionsMap); + return rpc.listDnsRecords(zoneName, optionsMap); } }, serviceOptions.retryParams(), EXCEPTION_HANDLER); String cursor = result.pageToken(); // transform that list into dns records Iterable records = result.results() == null ? ImmutableList.of() - : Iterables.transform(result.results(), transformFunction); + : Iterables.transform(result.results(), DnsRecord.FROM_PB_FUNCTION); return new PageImpl<>(new DnsRecordPageFetcher(zoneName, serviceOptions, cursor, optionsMap), cursor, records); } catch (RetryHelperException e) { @@ -216,11 +206,6 @@ public DnsRpc.ListResult call() { } } - DnsImpl(DnsOptions options) { - super(options); - dnsRpc = options.rpc(); - } - @Override public Zone create(final ZoneInfo zoneInfo, Dns.ZoneOption... options) { final Map optionsMap = optionMap(options); @@ -318,7 +303,7 @@ public com.google.api.services.dns.model.Change call() { return dnsRpc.getChangeRequest(zoneName, changeRequestId, optionsMap); } }, options().retryParams(), EXCEPTION_HANDLER); - return answer == null ? null : fromPb(answer); // should never be null + return answer == null ? null : fromPb(answer); } catch (RetryHelper.RetryHelperException ex) { throw DnsException.translateAndThrow(ex); } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java index 99ca20386419..c4e710bd0365 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java @@ -19,6 +19,8 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; +import com.google.api.services.dns.model.ResourceRecordSet; +import com.google.common.base.Function; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; @@ -43,7 +45,21 @@ */ public class DnsRecord implements Serializable { - private static final long serialVersionUID = 2016011914302204L; + static final Function FROM_PB_FUNCTION = + new Function() { + @Override + public DnsRecord apply(com.google.api.services.dns.model.ResourceRecordSet pb) { + return DnsRecord.fromPb(pb); + } + }; + static final Function TO_PB_FUNCTION = + new Function() { + @Override + public com.google.api.services.dns.model.ResourceRecordSet apply(DnsRecord error) { + return error.toPb(); + } + }; + private static final long serialVersionUID = 8148009870800115261L; private final String name; private final List rrdatas; private final Integer ttl; // this is in seconds diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java index d53909b0f084..323b0eb8c439 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java @@ -113,30 +113,6 @@ public Builder toBuilder() { return new Builder(this); } - /** - * Constructs a {@code Zone} object that contains the given {@code zoneInfo}. - */ - public Zone(Dns dns, ZoneInfo zoneInfo) { - super(new BuilderImpl(zoneInfo)); - this.dns = dns; - this.options = dns.options(); - } - - /** - * Constructs a {@code Zone} object that contains meta information received from the Google Cloud - * DNS service for the provided {@code zoneName}. - * - * @param zoneName name of the zone to be searched for - * @param options optional restriction on what fields should be returned by the service - * @return zone object containing metadata or {@code null} if not not found - * @throws DnsException upon failure - */ - public static Zone get(Dns dnsService, String zoneName, Dns.ZoneOption... options) { - checkNotNull(zoneName); - checkNotNull(dnsService); - return dnsService.getZone(zoneName, options); - } - /** * Retrieves the latest information about the zone. The method retrieves the zone by name. * @@ -236,6 +212,6 @@ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundE static Zone fromPb(Dns dns, com.google.api.services.dns.model.ManagedZone zone) { ZoneInfo info = ZoneInfo.fromPb(zone); - return new Zone(dns, info); + return new Zone(dns, new ZoneInfo.BuilderImpl(info)); } } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java index e26dcde70a83..f02f9f2c5226 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java @@ -81,7 +81,7 @@ public abstract static class Builder { * Optionally specifies the NameServerSet for this zone. A NameServerSet is a set of DNS name * servers that all host the same zones. Most users will not need to specify this value. */ - public abstract Builder nameServerSet(String nameServerSet); + abstract Builder nameServerSet(String nameServerSet); // todo(mderka) add more to the doc when questions are answered by the service owner /** diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java index 62e96b05dda5..726a455418d8 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java @@ -81,20 +81,20 @@ public class DnsImplTest { Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS); // Listing options - private static final Dns.ZoneListOption[] ZONE_LIST_OPTIONS = - {Dns.ZoneListOption.pageSize(MAX_SIZE), Dns.ZoneListOption.pageToken(PAGE_TOKEN), - Dns.ZoneListOption.fields(Dns.ZoneField.DESCRIPTION)}; - private static final Dns.ChangeRequestListOption[] CHANGE_LIST_OPTIONS = - {Dns.ChangeRequestListOption.pageSize(MAX_SIZE), - Dns.ChangeRequestListOption.pageToken(PAGE_TOKEN), - Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.STATUS), - Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING)}; - private static final Dns.DnsRecordListOption[] DNS_RECORD_LIST_OPTIONS = - {Dns.DnsRecordListOption.pageSize(MAX_SIZE), - Dns.DnsRecordListOption.pageToken(PAGE_TOKEN), - Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TTL), - Dns.DnsRecordListOption.dnsName(DNS_NAME), - Dns.DnsRecordListOption.type(DnsRecord.Type.AAAA)}; + private static final Dns.ZoneListOption[] ZONE_LIST_OPTIONS = { + Dns.ZoneListOption.pageSize(MAX_SIZE), Dns.ZoneListOption.pageToken(PAGE_TOKEN), + Dns.ZoneListOption.fields(Dns.ZoneField.DESCRIPTION)}; + private static final Dns.ChangeRequestListOption[] CHANGE_LIST_OPTIONS = { + Dns.ChangeRequestListOption.pageSize(MAX_SIZE), + Dns.ChangeRequestListOption.pageToken(PAGE_TOKEN), + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.STATUS), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING)}; + private static final Dns.DnsRecordListOption[] DNS_RECORD_LIST_OPTIONS = { + Dns.DnsRecordListOption.pageSize(MAX_SIZE), + Dns.DnsRecordListOption.pageToken(PAGE_TOKEN), + Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TTL), + Dns.DnsRecordListOption.dnsName(DNS_NAME), + Dns.DnsRecordListOption.type(DnsRecord.Type.AAAA)}; // Other private static final Map EMPTY_RPC_OPTIONS = ImmutableMap.of(); @@ -137,7 +137,7 @@ public void testCreateZone() { EasyMock.replay(dnsRpcMock); dns = options.service(); // creates DnsImpl Zone zone = dns.create(ZONE_INFO); - assertEquals(new Zone(dns, ZONE_INFO), zone); + assertEquals(new Zone(dns, new ZoneInfo.BuilderImpl(ZONE_INFO)), zone); } @Test @@ -149,7 +149,7 @@ public void testCreateZoneWithOptions() { dns = options.service(); // creates DnsImpl Zone zone = dns.create(ZONE_INFO, ZONE_FIELDS); String selector = (String) capturedOptions.getValue().get(ZONE_FIELDS.rpcOption()); - assertEquals(new Zone(dns, ZONE_INFO), zone); + assertEquals(new Zone(dns, new ZoneInfo.BuilderImpl(ZONE_INFO)), zone); assertTrue(selector.contains(Dns.ZoneField.CREATION_TIME.selector())); assertTrue(selector.contains(Dns.ZoneField.NAME.selector())); } @@ -161,7 +161,7 @@ public void testGetZone() { EasyMock.replay(dnsRpcMock); dns = options.service(); // creates DnsImpl Zone zone = dns.getZone(ZONE_INFO.name()); - assertEquals(new Zone(dns, ZONE_INFO), zone); + assertEquals(new Zone(dns, new ZoneInfo.BuilderImpl(ZONE_INFO)), zone); } @Test @@ -173,7 +173,7 @@ public void testGetZoneWithOptions() { dns = options.service(); // creates DnsImpl Zone zone = dns.getZone(ZONE_INFO.name(), ZONE_FIELDS); String selector = (String) capturedOptions.getValue().get(ZONE_FIELDS.rpcOption()); - assertEquals(new Zone(dns, ZONE_INFO), zone); + assertEquals(new Zone(dns, new ZoneInfo.BuilderImpl(ZONE_INFO)), zone); assertTrue(selector.contains(Dns.ZoneField.CREATION_TIME.selector())); assertTrue(selector.contains(Dns.ZoneField.NAME.selector())); } @@ -308,7 +308,8 @@ public void testListZones() { dns = options.service(); // creates DnsImpl Page zonePage = dns.listZones(); assertEquals(1, Lists.newArrayList(zonePage.values()).size()); - assertEquals(new Zone(dns, ZONE_INFO), Lists.newArrayList(zonePage.values()).get(0)); + assertEquals(new Zone(dns, new ZoneInfo.BuilderImpl(ZONE_INFO)), + Lists.newArrayList(zonePage.values()).get(0)); } @Test @@ -320,7 +321,8 @@ public void testListZonesWithOptions() { dns = options.service(); // creates DnsImpl Page zonePage = dns.listZones(ZONE_LIST_OPTIONS); assertEquals(1, Lists.newArrayList(zonePage.values()).size()); - assertEquals(new Zone(dns, ZONE_INFO), Lists.newArrayList(zonePage.values()).get(0)); + assertEquals(new Zone(dns, new ZoneInfo.BuilderImpl(ZONE_INFO)), + Lists.newArrayList(zonePage.values()).get(0)); Integer size = (Integer) capturedOptions.getValue().get(ZONE_LIST_OPTIONS[0].rpcOption()); assertEquals(MAX_SIZE, size); String selector = (String) capturedOptions.getValue().get(ZONE_LIST_OPTIONS[1].rpcOption()); diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java index b28847a4e046..5164dfb6001c 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java @@ -78,8 +78,8 @@ public void setUp() throws Exception { expect(dns.options()).andReturn(OPTIONS); expect(dns.options()).andReturn(OPTIONS); replay(dns); - zone = new Zone(dns, ZONE_INFO); - zoneNoId = new Zone(dns, NO_ID_INFO); + zone = new Zone(dns, new ZoneInfo.BuilderImpl(ZONE_INFO)); + zoneNoId = new Zone(dns, new ZoneInfo.BuilderImpl(NO_ID_INFO)); reset(dns); } @@ -96,30 +96,6 @@ public void testConstructor() { assertEquals(dns, zone.dns()); } - @Test - public void testGetByName() { - expect(dns.getZone(ZONE_NAME)).andReturn(zone); - expect(dns.getZone(ZONE_NAME, ZONE_FIELD_OPTIONS)).andReturn(zone); // for options - replay(dns); - Zone retrieved = Zone.get(dns, ZONE_NAME); - assertSame(dns, retrieved.dns()); - assertEquals(zone, retrieved); - // test passing options - Zone.get(dns, ZONE_NAME, ZONE_FIELD_OPTIONS); - try { - Zone.get(dns, null); - fail("Cannot get by null name."); - } catch (NullPointerException e) { - // expected - } - try { - Zone.get(null, "Not null"); - fail("Cannot get anything from null service."); - } catch (NullPointerException e) { - // expected - } - } - @Test public void deleteByNameAndFound() { expect(dns.delete(ZONE_NAME)).andReturn(true); From db52e09aaae1101fb80e9e6abcfb55233b1ed57b Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Tue, 9 Feb 2016 08:37:41 -0800 Subject: [PATCH 073/375] Made nameServerSet read only and setters package private. Adds dnsName filter for Zone listing and tests. Adds serialization test. Fixes #630, #602 and #631. --- .../main/java/com/google/gcloud/dns/Dns.java | 8 ++ .../com/google/gcloud/dns/DnsOptions.java | 10 ++ .../main/java/com/google/gcloud/dns/Zone.java | 2 +- .../java/com/google/gcloud/dns/ZoneInfo.java | 8 +- .../com/google/gcloud/dns/DnsImplTest.java | 5 +- .../java/com/google/gcloud/dns/DnsTest.java | 5 + .../google/gcloud/dns/SerializationTest.java | 118 ++++++++++++++++++ 7 files changed, 150 insertions(+), 6 deletions(-) create mode 100644 gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index e724e1cbf1ad..3ad2094ec2e3 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -295,6 +295,14 @@ public static ZoneListOption pageToken(String pageToken) { return new ZoneListOption(DnsRpc.Option.PAGE_TOKEN, pageToken); } + /** + * Restricts the list to only zone with this fully qualified domain name. + */ + public static ZoneListOption dnsName(String dnsName) { + StringBuilder builder = new StringBuilder(); + return new ZoneListOption(DnsRpc.Option.DNS_NAME, dnsName); + } + /** * The maximum number of zones to return per RPC. * diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java index b47532146b3a..d9317546cea0 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java @@ -95,4 +95,14 @@ public Builder toBuilder() { public static Builder builder() { return new Builder(); } + + @Override + public boolean equals(Object obj) { + return obj instanceof DnsOptions && baseEquals((DnsOptions) obj); + } + + @Override + public int hashCode() { + return baseHashCode(); + } } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java index 323b0eb8c439..41507647543a 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java @@ -85,7 +85,7 @@ public Builder description(String description) { } @Override - public Builder nameServerSet(String nameServerSet) { + Builder nameServerSet(String nameServerSet) { infoBuilder.nameServerSet(nameServerSet); return this; } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java index f02f9f2c5226..7dffbcdd365c 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java @@ -82,7 +82,7 @@ public abstract static class Builder { * servers that all host the same zones. Most users will not need to specify this value. */ abstract Builder nameServerSet(String nameServerSet); - // todo(mderka) add more to the doc when questions are answered by the service owner + // this should not be included in tooling as per the service owners /** * Sets a list of servers that hold the information about the zone. This information is provided @@ -155,7 +155,7 @@ public Builder description(String description) { } @Override - public Builder nameServerSet(String nameServerSet) { + Builder nameServerSet(String nameServerSet) { this.nameServerSet = checkNotNull(nameServerSet); return this; } @@ -227,10 +227,10 @@ public String description() { } /** - * Returns the optionally specified set of DNS name servers that all host this zone. + * Returns the optionally specified set of DNS name servers that all host this zone. This value is + * set only for specific use cases and is left empty for vast majority of users. */ public String nameServerSet() { - // todo(mderka) update this doc after finding out more about this from the service owners return nameServerSet; } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java index 726a455418d8..89ad90f27654 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java @@ -83,7 +83,8 @@ public class DnsImplTest { // Listing options private static final Dns.ZoneListOption[] ZONE_LIST_OPTIONS = { Dns.ZoneListOption.pageSize(MAX_SIZE), Dns.ZoneListOption.pageToken(PAGE_TOKEN), - Dns.ZoneListOption.fields(Dns.ZoneField.DESCRIPTION)}; + Dns.ZoneListOption.fields(Dns.ZoneField.DESCRIPTION), + Dns.ZoneListOption.dnsName(DNS_NAME)}; private static final Dns.ChangeRequestListOption[] CHANGE_LIST_OPTIONS = { Dns.ChangeRequestListOption.pageSize(MAX_SIZE), Dns.ChangeRequestListOption.pageToken(PAGE_TOKEN), @@ -330,6 +331,8 @@ public void testListZonesWithOptions() { selector = (String) capturedOptions.getValue().get(ZONE_LIST_OPTIONS[2].rpcOption()); assertTrue(selector.contains(Dns.ZoneField.DESCRIPTION.selector())); assertTrue(selector.contains(Dns.ZoneField.NAME.selector())); + selector = (String) capturedOptions.getValue().get(ZONE_LIST_OPTIONS[3].rpcOption()); + assertEquals(DNS_NAME, selector); } @Test diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java index 74faca329884..92a18ad9c1e7 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java @@ -27,6 +27,7 @@ public class DnsTest { private static final Integer PAGE_SIZE = 20; private static final String PAGE_TOKEN = "page token"; + private static final String DNS_NAME = "www.example.com."; @Test public void testDnsRecordListOption() { @@ -89,6 +90,10 @@ public void testZoneList() { option = Dns.ZoneListOption.pageSize(PAGE_SIZE); assertEquals(PAGE_SIZE, option.value()); assertEquals(DnsRpc.Option.PAGE_SIZE, option.rpcOption()); + // dnsName filter + option = Dns.ZoneListOption.dnsName(DNS_NAME); + assertEquals(DNS_NAME, option.value()); + assertEquals(DnsRpc.Option.DNS_NAME, option.rpcOption()); } @Test diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java new file mode 100644 index 000000000000..adf5744d854e --- /dev/null +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java @@ -0,0 +1,118 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.dns; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotSame; + +import com.google.common.collect.ImmutableList; +import com.google.gcloud.RetryParams; + +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.math.BigInteger; +import java.util.concurrent.TimeUnit; + +public class SerializationTest { + + private static final ZoneInfo FULL_ZONE_INFO = Zone.builder("some zone name") + .creationTimeMillis(132L) + .description("some descriptions") + .dnsName("www.example.com") + .id("123333") + .nameServers(ImmutableList.of("server 1", "server 2")) + .nameServerSet("specificationstring") + .build(); + private static final ZoneInfo PARTIAL_ZONE_INFO = Zone.builder("some zone name") + .build(); + private static final ProjectInfo PARTIAL_PROJECT_INFO = ProjectInfo.builder().id("13").build(); + private static final ProjectInfo FULL_PROJECT_INFO = ProjectInfo.builder() + .id("342") + .number(new BigInteger("2343245")) + .quota(new ProjectInfo.Quota(12, 13, 14, 15, 16, 17)) + .build(); + private static final Dns.ZoneListOption ZONE_LIST_OPTION = + Dns.ZoneListOption.dnsName("www.example.com."); + private static final Dns.DnsRecordListOption DNS_REOCRD_LIST_OPTION = + Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TTL); + private static final Dns.ChangeRequestListOption CHANGE_REQUEST_LIST_OPTION = + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.STATUS); + private static final Dns.ZoneOption ZONE_OPTION = + Dns.ZoneOption.fields(Dns.ZoneField.CREATION_TIME); + private static final Dns.ChangeRequestOption CHANGE_REQUEST_OPTION = + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS); + private static final Dns.ProjectOption PROJECT_OPTION = + Dns.ProjectOption.fields(Dns.ProjectField.QUOTA); + private static final DnsOptions OPTIONS = DnsOptions.builder() + .projectId("some-unnecessary-project-ID") + .retryParams(RetryParams.defaultInstance()) + .build(); + private static final Dns DNS = OPTIONS.service(); + private static final Zone FULL_ZONE = new Zone(DNS, new ZoneInfo.BuilderImpl(FULL_ZONE_INFO)); + private static final Zone PARTIAL_ZONE = + new Zone(DNS, new ZoneInfo.BuilderImpl(PARTIAL_ZONE_INFO)); + private static final ChangeRequest CHANGE_REQUEST_PARTIAL = ChangeRequest.builder().build(); + private static final DnsRecord DNS_RECORD_PARTIAL = + DnsRecord.builder("www.www.com", DnsRecord.Type.AAAA).build(); + private static final DnsRecord DNS_RECORD_COMPLETE = + DnsRecord.builder("www.sadfa.com", DnsRecord.Type.A) + .ttl(12, TimeUnit.HOURS) + .addRecord("record") + .build(); + private static final ChangeRequest CHANGE_REQUEST_COMPLETE = ChangeRequest.builder() + .add(DNS_RECORD_COMPLETE) + .delete(DNS_RECORD_PARTIAL) + .status(ChangeRequest.Status.PENDING) + .id("some id") + .startTimeMillis(132L) + .build(); + + + @Test + public void testModelAndRequests() throws Exception { + Serializable[] objects = {FULL_ZONE_INFO, PARTIAL_ZONE_INFO, ZONE_LIST_OPTION, + DNS_REOCRD_LIST_OPTION, CHANGE_REQUEST_LIST_OPTION, ZONE_OPTION, CHANGE_REQUEST_OPTION, + PROJECT_OPTION, PARTIAL_PROJECT_INFO, FULL_PROJECT_INFO, OPTIONS, FULL_ZONE, PARTIAL_ZONE, + OPTIONS, CHANGE_REQUEST_PARTIAL, DNS_RECORD_PARTIAL, DNS_RECORD_COMPLETE, + CHANGE_REQUEST_COMPLETE}; + for (Serializable obj : objects) { + Object copy = serializeAndDeserialize(obj); + assertEquals(obj, obj); + assertEquals(obj, copy); + assertNotSame(obj, copy); + assertEquals(copy, copy); + } + } + + @SuppressWarnings("unchecked") + private T serializeAndDeserialize(T obj) throws IOException, ClassNotFoundException { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + try (ObjectOutputStream output = new ObjectOutputStream(bytes)) { + output.writeObject(obj); + } + try (ObjectInputStream input = + new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray()))) { + return (T) input.readObject(); + } + } +} From d1765c7c5ba2cefe99203f22b06bee1d2dd60751 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Wed, 10 Feb 2016 10:38:24 -0800 Subject: [PATCH 074/375] Fix indentation issues in javadoc code samples --- .../gcloud/bigquery/InsertAllRequest.java | 4 +- .../google/gcloud/bigquery/QueryRequest.java | 2 +- .../google/gcloud/bigquery/QueryResponse.java | 2 +- .../java/com/google/gcloud/Restorable.java | 4 +- .../com/google/gcloud/datastore/Batch.java | 16 +++---- .../com/google/gcloud/datastore/GqlQuery.java | 34 +++++++------- .../gcloud/datastore/StructuredQuery.java | 44 +++++++++---------- .../google/gcloud/datastore/Transaction.java | 28 ++++++------ .../com/google/gcloud/storage/CopyWriter.java | 2 +- .../com/google/gcloud/storage/Storage.java | 2 +- 10 files changed, 69 insertions(+), 69 deletions(-) diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/InsertAllRequest.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/InsertAllRequest.java index 6f39f20e498d..e8828036cddc 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/InsertAllRequest.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/InsertAllRequest.java @@ -177,7 +177,7 @@ public Builder addRow(RowToInsert rowToInsert) { * Adds a row to be inserted with associated id. * *

Example usage of adding a row with associated id: - *

    {@code
+     * 
   {@code
      *   InsertAllRequest.Builder builder = InsertAllRequest.builder(tableId);
      *   List repeatedFieldValue = Arrays.asList(1L, 2L);
      *   Map recordContent = new HashMap();
@@ -198,7 +198,7 @@ public Builder addRow(String id, Map content) {
      * Adds a row to be inserted without an associated id.
      *
      * 

Example usage of adding a row without an associated id: - *

    {@code
+     * 
   {@code
      *   InsertAllRequest.Builder builder = InsertAllRequest.builder(tableId);
      *   List repeatedFieldValue = Arrays.asList(1L, 2L);
      *   Map recordContent = new HashMap();
diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryRequest.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryRequest.java
index 0bcfb3d4a9ae..8f2a89484ca4 100644
--- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryRequest.java
+++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryRequest.java
@@ -35,7 +35,7 @@
  * {@link QueryResponse#jobCompleted()} returns {@code true}.
  *
  * 

Example usage of a query request: - *

    {@code
+ * 
     {@code
  *    // Substitute "field", "table" and "dataset" with real field, table and dataset identifiers
  *    QueryRequest request = QueryRequest.builder("SELECT field FROM table")
  *      .defaultDataset(DatasetId.of("dataset"))
diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryResponse.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryResponse.java
index 77386747754f..d9b61e9b1466 100644
--- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryResponse.java
+++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryResponse.java
@@ -29,7 +29,7 @@
  * Query Request ({@link BigQuery#query(QueryRequest)}).
  *
  * 

Example usage of a query response: - *

    {@code
+ * 
     {@code
  *    QueryResponse response = bigquery.query(request);
  *    while (!response.jobCompleted()) {
  *      Thread.sleep(1000);
diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/Restorable.java b/gcloud-java-core/src/main/java/com/google/gcloud/Restorable.java
index 90633c70046f..0b573522e370 100644
--- a/gcloud-java-core/src/main/java/com/google/gcloud/Restorable.java
+++ b/gcloud-java-core/src/main/java/com/google/gcloud/Restorable.java
@@ -21,14 +21,14 @@
  *
  * 

* A typical capture usage: - *

  {@code
+ * 
 {@code
  * X restorableObj; // X instanceof Restorable
  * RestorableState state = restorableObj.capture();
  * .. persist state
  * }
* * A typical restore usage: - *
  {@code
+ * 
 {@code
  * RestorableState state = ... // read from persistence
  * X restorableObj = state.restore();
  * ...
diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Batch.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Batch.java
index 75a5d1381403..5306a685195a 100644
--- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Batch.java
+++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Batch.java
@@ -24,14 +24,14 @@
  * to the Datastore upon {@link #submit}.
  * A usage example:
  * 
 {@code
- *   Entity entity1 = datastore.get(key1);
- *   Batch batch = datastore.newBatch();
- *   Entity entity2 = Entity.builder(key2).set("name", "John").build();
- *   entity1 = Entity.builder(entity1).clear().setNull("bla").build();
- *   Entity entity3 = Entity.builder(key3).set("title", "title").build();
- *   batch.update(entity1);
- *   batch.add(entity2, entity3);
- *   batch.submit();
+ * Entity entity1 = datastore.get(key1);
+ * Batch batch = datastore.newBatch();
+ * Entity entity2 = Entity.builder(key2).set("name", "John").build();
+ * entity1 = Entity.builder(entity1).clear().setNull("bla").build();
+ * Entity entity3 = Entity.builder(key3).set("title", "title").build();
+ * batch.update(entity1);
+ * batch.add(entity2, entity3);
+ * batch.submit();
  * } 
*/ public interface Batch extends DatastoreBatchWriter { diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java index e6ae166dbf07..7c03b69d9f39 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java @@ -43,27 +43,27 @@ *

A usage example:

* *

When the type of the results is known the preferred usage would be: - *

{@code
- *   Query query =
- *       Query.gqlQueryBuilder(Query.ResultType.ENTITY, "select * from kind").build();
- *   QueryResults results = datastore.run(query);
- *   while (results.hasNext()) {
- *     Entity entity = results.next();
- *     ...
- *   }
+ * 
 {@code
+ * Query query =
+ *     Query.gqlQueryBuilder(Query.ResultType.ENTITY, "select * from kind").build();
+ * QueryResults results = datastore.run(query);
+ * while (results.hasNext()) {
+ *   Entity entity = results.next();
+ *   ...
+ * }
  * } 
* *

When the type of the results is unknown you can use this approach: - *

{@code
- *   Query query = Query.gqlQueryBuilder("select __key__ from kind").build();
- *   QueryResults results = datastore.run(query);
- *   if (Key.class.isAssignableFrom(results.resultClass())) {
- *     QueryResults keys = (QueryResults) results;
- *     while (keys.hasNext()) {
- *       Key key = keys.next();
- *       ...
- *     }
+ * 
 {@code
+ * Query query = Query.gqlQueryBuilder("select __key__ from kind").build();
+ * QueryResults results = datastore.run(query);
+ * if (Key.class.isAssignableFrom(results.resultClass())) {
+ *   QueryResults keys = (QueryResults) results;
+ *   while (keys.hasNext()) {
+ *     Key key = keys.next();
+ *     ...
  *   }
+ * }
  * } 
* * @param the type of the result values this query will produce diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java index 15cca241e250..5892268f859c 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java @@ -46,35 +46,35 @@ *

A usage example:

* *

A simple query that returns all entities for a specific kind - *

{@code
- *   Query query = Query.entityQueryBuilder().kind(kind).build();
- *   QueryResults results = datastore.run(query);
- *   while (results.hasNext()) {
- *     Entity entity = results.next();
- *     ...
- *   }
+ * 
 {@code
+ * Query query = Query.entityQueryBuilder().kind(kind).build();
+ * QueryResults results = datastore.run(query);
+ * while (results.hasNext()) {
+ *   Entity entity = results.next();
+ *   ...
+ * }
  * } 
* *

A simple key-only query of all entities for a specific kind - *

{@code
- *   Query keyOnlyQuery =  Query.keyQueryBuilder().kind(KIND1).build();
- *   QueryResults results = datastore.run(keyOnlyQuery);
- *   ...
+ * 
 {@code
+ * Query keyOnlyQuery =  Query.keyQueryBuilder().kind(KIND1).build();
+ * QueryResults results = datastore.run(keyOnlyQuery);
+ * ...
  * } 
* *

A less trivial example of a projection query that returns the first 10 results * of "age" and "name" properties (sorted and grouped by "age") with an age greater than 18 - *

{@code
- *   Query query = Query.projectionEntityQueryBuilder()
- *       .kind(kind)
- *       .projection(Projection.property("age"), Projection.first("name"))
- *       .filter(PropertyFilter.gt("age", 18))
- *       .groupBy("age")
- *       .orderBy(OrderBy.asc("age"))
- *       .limit(10)
- *       .build();
- *   QueryResults results = datastore.run(query);
- *   ...
+ * 
 {@code
+ * Query query = Query.projectionEntityQueryBuilder()
+ *     .kind(kind)
+ *     .projection(Projection.property("age"), Projection.first("name"))
+ *     .filter(PropertyFilter.gt("age", 18))
+ *     .groupBy("age")
+ *     .orderBy(OrderBy.asc("age"))
+ *     .limit(10)
+ *     .build();
+ * QueryResults results = datastore.run(query);
+ * ...
  * } 
* * @param the type of the result values this query will produce diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Transaction.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Transaction.java index 8089c0130f5d..78ee217f31e7 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Transaction.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Transaction.java @@ -30,21 +30,21 @@ * the Datastore upon {@code commit}. * A usage example: *
 {@code
- *   Transaction transaction = datastore.newTransaction();
- *   try {
- *     Entity entity = transaction.get(key);
- *     if (!entity.contains("last_name") || entity.isNull("last_name")) {
- *       String[] name = entity.getString("name").split(" ");
- *       entity = Entity.builder(entity).remove("name").set("first_name", name[0])
- *           .set("last_name", name[1]).build();
- *       transaction.update(entity);
- *       transaction.commit();
- *     }
- *   } finally {
- *     if (transaction.active()) {
- *       transaction.rollback();
- *     }
+ * Transaction transaction = datastore.newTransaction();
+ * try {
+ *   Entity entity = transaction.get(key);
+ *   if (!entity.contains("last_name") || entity.isNull("last_name")) {
+ *     String[] name = entity.getString("name").split(" ");
+ *     entity = Entity.builder(entity).remove("name").set("first_name", name[0])
+ *         .set("last_name", name[1]).build();
+ *     transaction.update(entity);
+ *     transaction.commit();
  *   }
+ * } finally {
+ *   if (transaction.active()) {
+ *     transaction.rollback();
+ *   }
+ * }
  * } 
* * @see diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java index 1e5427a847d4..ee70df1e4cc7 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java @@ -57,7 +57,7 @@ public class CopyWriter implements Restorable { * is {@code false} will block until all pending chunks are copied. * *

This method has the same effect of doing: - *

    {@code while (!copyWriter.isDone()) {
+   * 
     {@code while (!copyWriter.isDone()) {
    *        copyWriter.copyChunk();
    *    }}
    * 
diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index d1799daede3e..38795bea5e5b 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -1376,7 +1376,7 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx *
    {@code BlobInfo blob = service.copy(copyRequest).result();}
    * 
* To explicitly issue chunk copy requests use {@link CopyWriter#copyChunk()} instead: - *
    {@code CopyWriter copyWriter = service.copy(copyRequest);
+   * 
     {@code CopyWriter copyWriter = service.copy(copyRequest);
    *    while (!copyWriter.isDone()) {
    *        copyWriter.copyChunk();
    *    }

From 257e764c002f638c81cf9e3902ca0a5f167a896c Mon Sep 17 00:00:00 2001
From: Ajay Kannan 
Date: Wed, 10 Feb 2016 10:40:32 -0800
Subject: [PATCH 075/375] fix lint errors

---
 .../com/google/gcloud/datastore/DatastoreExceptionTest.java    | 3 ++-
 .../java/com/google/gcloud/datastore/StructuredQueryTest.java  | 3 ++-
 .../com/google/gcloud/resourcemanager/ResourceManagerImpl.java | 3 ++-
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreExceptionTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreExceptionTest.java
index 4d62224172f9..f7bdcb89bcec 100644
--- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreExceptionTest.java
+++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreExceptionTest.java
@@ -78,7 +78,8 @@ public void testDatastoreException() throws Exception {
   @Test
   public void testTranslateAndThrow() throws Exception {
     DatastoreException cause = new DatastoreException(503, "message", "UNAVAILABLE");
-    RetryHelper.RetryHelperException exceptionMock = createMock(RetryHelper.RetryHelperException.class);
+    RetryHelper.RetryHelperException exceptionMock =
+        createMock(RetryHelper.RetryHelperException.class);
     expect(exceptionMock.getCause()).andReturn(cause).times(2);
     replay(exceptionMock);
     try {
diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/StructuredQueryTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/StructuredQueryTest.java
index b0d188cae16e..4b6589efd723 100644
--- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/StructuredQueryTest.java
+++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/StructuredQueryTest.java
@@ -40,7 +40,8 @@ public class StructuredQueryTest {
   private static final Cursor END_CURSOR = Cursor.copyFrom(new byte[] {10});
   private static final int OFFSET = 42;
   private static final Integer LIMIT = 43;
-  private static final Filter FILTER = CompositeFilter.and(PropertyFilter.gt("p1", 10), PropertyFilter.eq("a", "v"));
+  private static final Filter FILTER =
+      CompositeFilter.and(PropertyFilter.gt("p1", 10), PropertyFilter.eq("a", "v"));
   private static final OrderBy ORDER_BY_1 = OrderBy.asc("p2");
   private static final OrderBy ORDER_BY_2 = OrderBy.desc("p3");
   private static final List ORDER_BY = ImmutableList.of(ORDER_BY_1, ORDER_BY_2);
diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java
index e087caab5966..4176b4e610ba 100644
--- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java
+++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java
@@ -140,7 +140,8 @@ Iterable> call() {
                     public Project apply(
                         com.google.api.services.cloudresourcemanager.model.Project projectPb) {
                       return new Project(
-                          serviceOptions.service(), new ProjectInfo.BuilderImpl(ProjectInfo.fromPb(projectPb)));
+                          serviceOptions.service(),
+                          new ProjectInfo.BuilderImpl(ProjectInfo.fromPb(projectPb)));
                     }
                   });
       return new PageImpl<>(

From 71ac555a9f0160c6295c1508c91f68a4159317c6 Mon Sep 17 00:00:00 2001
From: Ajay Kannan 
Date: Wed, 10 Feb 2016 10:51:04 -0800
Subject: [PATCH 076/375] Move integration tests to separate package

---
 .../bigquery/{ => it}/ITBigQueryTest.java     | 58 ++++++++++++++-----
 .../storage/{ => it}/ITStorageTest.java       | 13 ++++-
 2 files changed, 55 insertions(+), 16 deletions(-)
 rename gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/{ => it}/ITBigQueryTest.java (95%)
 rename gcloud-java-storage/src/test/java/com/google/gcloud/storage/{ => it}/ITStorageTest.java (98%)

diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/ITBigQueryTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java
similarity index 95%
rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/ITBigQueryTest.java
rename to gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java
index 8021809be6b2..0befeecd4b99 100644
--- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/ITBigQueryTest.java
+++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java
@@ -14,14 +14,8 @@
  * limitations under the License.
  */
 
-package com.google.gcloud.bigquery;
-
-import static com.google.gcloud.bigquery.BigQuery.DatasetField;
-import static com.google.gcloud.bigquery.BigQuery.JobField;
-import static com.google.gcloud.bigquery.BigQuery.JobListOption;
-import static com.google.gcloud.bigquery.BigQuery.JobOption;
-import static com.google.gcloud.bigquery.BigQuery.TableField;
-import static com.google.gcloud.bigquery.BigQuery.TableOption;
+package com.google.gcloud.bigquery.it;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
@@ -32,7 +26,42 @@
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.gcloud.Page;
+import com.google.gcloud.WriteChannel;
+import com.google.gcloud.bigquery.BigQuery;
+import com.google.gcloud.bigquery.BigQuery.DatasetField;
 import com.google.gcloud.bigquery.BigQuery.DatasetOption;
+import com.google.gcloud.bigquery.BigQuery.JobField;
+import com.google.gcloud.bigquery.BigQuery.JobListOption;
+import com.google.gcloud.bigquery.BigQuery.JobOption;
+import com.google.gcloud.bigquery.BigQuery.TableField;
+import com.google.gcloud.bigquery.BigQuery.TableOption;
+import com.google.gcloud.bigquery.BigQueryError;
+import com.google.gcloud.bigquery.BigQueryException;
+import com.google.gcloud.bigquery.CopyJobConfiguration;
+import com.google.gcloud.bigquery.Dataset;
+import com.google.gcloud.bigquery.DatasetId;
+import com.google.gcloud.bigquery.DatasetInfo;
+import com.google.gcloud.bigquery.ExternalTableDefinition;
+import com.google.gcloud.bigquery.ExtractJobConfiguration;
+import com.google.gcloud.bigquery.Field;
+import com.google.gcloud.bigquery.FieldValue;
+import com.google.gcloud.bigquery.FormatOptions;
+import com.google.gcloud.bigquery.InsertAllRequest;
+import com.google.gcloud.bigquery.InsertAllResponse;
+import com.google.gcloud.bigquery.Job;
+import com.google.gcloud.bigquery.JobInfo;
+import com.google.gcloud.bigquery.LoadJobConfiguration;
+import com.google.gcloud.bigquery.QueryJobConfiguration;
+import com.google.gcloud.bigquery.QueryRequest;
+import com.google.gcloud.bigquery.QueryResponse;
+import com.google.gcloud.bigquery.Schema;
+import com.google.gcloud.bigquery.StandardTableDefinition;
+import com.google.gcloud.bigquery.Table;
+import com.google.gcloud.bigquery.TableDefinition;
+import com.google.gcloud.bigquery.TableId;
+import com.google.gcloud.bigquery.TableInfo;
+import com.google.gcloud.bigquery.ViewDefinition;
+import com.google.gcloud.bigquery.WriteChannelConfiguration;
 import com.google.gcloud.bigquery.testing.RemoteBigQueryHelper;
 import com.google.gcloud.storage.BlobInfo;
 import com.google.gcloud.storage.BucketInfo;
@@ -45,7 +74,6 @@
 import org.junit.Test;
 import org.junit.rules.Timeout;
 
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.charset.StandardCharsets;
@@ -140,7 +168,7 @@ public class ITBigQueryTest {
   public Timeout globalTimeout = Timeout.seconds(300);
 
   @BeforeClass
-  public static void beforeClass() throws IOException, InterruptedException {
+  public static void beforeClass() throws InterruptedException {
     RemoteBigQueryHelper bigqueryHelper = RemoteBigQueryHelper.create();
     RemoteGcsHelper gcsHelper = RemoteGcsHelper.create();
     bigquery = bigqueryHelper.options().service();
@@ -685,7 +713,7 @@ public void testListJobsWithSelectedFields() {
   }
 
   @Test
-  public void testCreateAndGetJob() throws InterruptedException {
+  public void testCreateAndGetJob() {
     String sourceTableName = "test_create_and_get_job_source_table";
     String destinationTableName = "test_create_and_get_job_destination_table";
     TableId sourceTable = TableId.of(DATASET, sourceTableName);
@@ -717,7 +745,7 @@ public void testCreateAndGetJob() throws InterruptedException {
   }
 
   @Test
-  public void testCreateAndGetJobWithSelectedFields() throws InterruptedException {
+  public void testCreateAndGetJobWithSelectedFields() {
     String sourceTableName = "test_create_and_get_job_with_selected_fields_source_table";
     String destinationTableName = "test_create_and_get_job_with_selected_fields_destination_table";
     TableId sourceTable = TableId.of(DATASET, sourceTableName);
@@ -874,12 +902,12 @@ public void testCancelJob() throws InterruptedException {
   }
 
   @Test
-  public void testCancelNonExistingJob() throws InterruptedException {
+  public void testCancelNonExistingJob() {
     assertFalse(bigquery.cancel("test_cancel_non_existing_job"));
   }
 
   @Test
-  public void testInsertFromFile() throws InterruptedException, FileNotFoundException {
+  public void testInsertFromFile() throws InterruptedException {
     String destinationTableName = "test_insert_from_file_table";
     TableId tableId = TableId.of(DATASET, destinationTableName);
     WriteChannelConfiguration configuration = WriteChannelConfiguration.builder(tableId)
@@ -887,7 +915,7 @@ public void testInsertFromFile() throws InterruptedException, FileNotFoundExcept
         .createDisposition(JobInfo.CreateDisposition.CREATE_IF_NEEDED)
         .schema(TABLE_SCHEMA)
         .build();
-    try (TableDataWriteChannel channel = bigquery.writer(configuration)) {
+    try (WriteChannel channel = bigquery.writer(configuration)) {
       channel.write(ByteBuffer.wrap(JSON_CONTENT.getBytes(StandardCharsets.UTF_8)));
     } catch (IOException e) {
       fail("IOException was not expected");
diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/ITStorageTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java
similarity index 98%
rename from gcloud-java-storage/src/test/java/com/google/gcloud/storage/ITStorageTest.java
rename to gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java
index dffcc366036a..f185bdf8343e 100644
--- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/ITStorageTest.java
+++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.google.gcloud.storage;
+package com.google.gcloud.storage.it;
 
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.junit.Assert.assertArrayEquals;
@@ -32,8 +32,19 @@
 import com.google.gcloud.ReadChannel;
 import com.google.gcloud.RestorableState;
 import com.google.gcloud.WriteChannel;
+import com.google.gcloud.storage.BatchRequest;
+import com.google.gcloud.storage.BatchResponse;
+import com.google.gcloud.storage.Blob;
+import com.google.gcloud.storage.BlobId;
+import com.google.gcloud.storage.BlobInfo;
+import com.google.gcloud.storage.Bucket;
+import com.google.gcloud.storage.BucketInfo;
+import com.google.gcloud.storage.CopyWriter;
+import com.google.gcloud.storage.HttpMethod;
+import com.google.gcloud.storage.Storage;
 import com.google.gcloud.storage.Storage.BlobField;
 import com.google.gcloud.storage.Storage.BucketField;
+import com.google.gcloud.storage.StorageException;
 import com.google.gcloud.storage.testing.RemoteGcsHelper;
 
 import org.junit.AfterClass;

From 4d8d986b2ad0455914f8c95cac72d0900d290378 Mon Sep 17 00:00:00 2001
From: Ajay Kannan 
Date: Wed, 10 Feb 2016 12:49:20 -0800
Subject: [PATCH 077/375] Avoid reading extra output during local gcd shutdown.

---
 .../com/google/gcloud/datastore/testing/LocalGcdHelper.java  | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java
index 7c60da50b0b0..c60035de087f 100644
--- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java
+++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java
@@ -526,6 +526,7 @@ private static void extractFile(ZipInputStream zipIn, File filePath) throws IOEx
 
   public static boolean sendQuitRequest(int port) {
     StringBuilder result = new StringBuilder();
+    String shutdownMsg = "Shutting down local server";
     try {
       URL url = new URL("http", "localhost", port, "/_ah/admin/quit");
       HttpURLConnection con = (HttpURLConnection) url.openConnection();
@@ -537,13 +538,13 @@ public static boolean sendQuitRequest(int port) {
       out.flush();
       InputStream in = con.getInputStream();
       int currByte = 0;
-      while ((currByte = in.read()) != -1) {
+      while ((currByte = in.read()) != -1 && result.length() < shutdownMsg.length()) {
         result.append(((char) currByte));
       }
     } catch (IOException ignore) {
       // ignore
     }
-    return result.toString().startsWith("Shutting down local server");
+    return result.toString().startsWith(shutdownMsg);
   }
 
   public void stop() throws IOException, InterruptedException {

From 9d201a05bcbb7e9f0270ddf8d4cc78bba3f80b1e Mon Sep 17 00:00:00 2001
From: Ajay Kannan 
Date: Wed, 10 Feb 2016 15:28:03 -0800
Subject: [PATCH 078/375] Fix codacy and spacing bugs

---
 .../gcloud/bigquery/InsertAllRequest.java     | 58 +++++++++----------
 .../google/gcloud/bigquery/QueryRequest.java  | 40 ++++++-------
 .../google/gcloud/bigquery/QueryResponse.java | 28 ++++-----
 .../gcloud/bigquery/it/ITBigQueryTest.java    |  7 +--
 .../java/com/google/gcloud/storage/Blob.java  |  4 +-
 .../com/google/gcloud/storage/CopyWriter.java |  7 ++-
 .../com/google/gcloud/storage/Storage.java    | 25 ++++----
 .../gcloud/storage/it/ITStorageTest.java      | 13 ++---
 8 files changed, 91 insertions(+), 91 deletions(-)

diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/InsertAllRequest.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/InsertAllRequest.java
index e8828036cddc..f0d61583f83f 100644
--- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/InsertAllRequest.java
+++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/InsertAllRequest.java
@@ -52,15 +52,15 @@ public class InsertAllRequest implements Serializable {
    * id used by BigQuery to detect duplicate insertion requests on a best-effort basis.
    *
    * 

Example usage of creating a row to insert: - *

    {@code
-   *   List repeatedFieldValue = Arrays.asList(1L, 2L);
-   *   Map recordContent = new HashMap();
-   *   recordContent.put("subfieldName1", "value");
-   *   recordContent.put("subfieldName2", repeatedFieldValue);
-   *   Map rowContent = new HashMap();
-   *   rowContent.put("fieldName1", true);
-   *   rowContent.put("fieldName2", recordContent);
-   *   RowToInsert row = new RowToInsert("rowId", rowContent);
+   * 
 {@code
+   * List repeatedFieldValue = Arrays.asList(1L, 2L);
+   * Map recordContent = new HashMap();
+   * recordContent.put("subfieldName1", "value");
+   * recordContent.put("subfieldName2", repeatedFieldValue);
+   * Map rowContent = new HashMap();
+   * rowContent.put("fieldName1", true);
+   * rowContent.put("fieldName2", recordContent);
+   * RowToInsert row = new RowToInsert("rowId", rowContent);
    * }
* * @see
@@ -177,16 +177,16 @@ public Builder addRow(RowToInsert rowToInsert) { * Adds a row to be inserted with associated id. * *

Example usage of adding a row with associated id: - *

   {@code
-     *   InsertAllRequest.Builder builder = InsertAllRequest.builder(tableId);
-     *   List repeatedFieldValue = Arrays.asList(1L, 2L);
-     *   Map recordContent = new HashMap();
-     *   recordContent.put("subfieldName1", "value");
-     *   recordContent.put("subfieldName2", repeatedFieldValue);
-     *   Map rowContent = new HashMap();
-     *   rowContent.put("fieldName1", true);
-     *   rowContent.put("fieldName2", recordContent);
-     *   builder.addRow("rowId", rowContent);
+     * 
 {@code
+     * InsertAllRequest.Builder builder = InsertAllRequest.builder(tableId);
+     * List repeatedFieldValue = Arrays.asList(1L, 2L);
+     * Map recordContent = new HashMap();
+     * recordContent.put("subfieldName1", "value");
+     * recordContent.put("subfieldName2", repeatedFieldValue);
+     * Map rowContent = new HashMap();
+     * rowContent.put("fieldName1", true);
+     * rowContent.put("fieldName2", recordContent);
+     * builder.addRow("rowId", rowContent);
      * }
*/ public Builder addRow(String id, Map content) { @@ -198,16 +198,16 @@ public Builder addRow(String id, Map content) { * Adds a row to be inserted without an associated id. * *

Example usage of adding a row without an associated id: - *

   {@code
-     *   InsertAllRequest.Builder builder = InsertAllRequest.builder(tableId);
-     *   List repeatedFieldValue = Arrays.asList(1L, 2L);
-     *   Map recordContent = new HashMap();
-     *   recordContent.put("subfieldName1", "value");
-     *   recordContent.put("subfieldName2", repeatedFieldValue);
-     *   Map rowContent = new HashMap();
-     *   rowContent.put("fieldName1", true);
-     *   rowContent.put("fieldName2", recordContent);
-     *   builder.addRow(rowContent);
+     * 
 {@code
+     * InsertAllRequest.Builder builder = InsertAllRequest.builder(tableId);
+     * List repeatedFieldValue = Arrays.asList(1L, 2L);
+     * Map recordContent = new HashMap();
+     * recordContent.put("subfieldName1", "value");
+     * recordContent.put("subfieldName2", repeatedFieldValue);
+     * Map rowContent = new HashMap();
+     * rowContent.put("fieldName1", true);
+     * rowContent.put("fieldName2", recordContent);
+     * builder.addRow(rowContent);
      * }
*/ public Builder addRow(Map content) { diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryRequest.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryRequest.java index 8f2a89484ca4..5f99f3c5b4ee 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryRequest.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryRequest.java @@ -35,26 +35,26 @@ * {@link QueryResponse#jobCompleted()} returns {@code true}. * *

Example usage of a query request: - *

     {@code
- *    // Substitute "field", "table" and "dataset" with real field, table and dataset identifiers
- *    QueryRequest request = QueryRequest.builder("SELECT field FROM table")
- *      .defaultDataset(DatasetId.of("dataset"))
- *      .maxWaitTime(60000L)
- *      .maxResults(1000L)
- *      .build();
- *    QueryResponse response = bigquery.query(request);
- *    while (!response.jobCompleted()) {
- *      Thread.sleep(1000);
- *      response = bigquery.getQueryResults(response.jobId());
- *    }
- *    List executionErrors = response.executionErrors();
- *    // look for errors in executionErrors
- *    QueryResult result = response.result();
- *    Iterator> rowIterator = result.iterateAll();
- *    while(rowIterator.hasNext()) {
- *      List row = rowIterator.next();
- *      // do something with row
- *    }
+ * 
 {@code
+ * // Substitute "field", "table" and "dataset" with real field, table and dataset identifiers
+ * QueryRequest request = QueryRequest.builder("SELECT field FROM table")
+ *     .defaultDataset(DatasetId.of("dataset"))
+ *     .maxWaitTime(60000L)
+ *     .maxResults(1000L)
+ *     .build();
+ * QueryResponse response = bigquery.query(request);
+ * while (!response.jobCompleted()) {
+ *   Thread.sleep(1000);
+ *   response = bigquery.getQueryResults(response.jobId());
+ * }
+ * List executionErrors = response.executionErrors();
+ * // look for errors in executionErrors
+ * QueryResult result = response.result();
+ * Iterator> rowIterator = result.iterateAll();
+ * while(rowIterator.hasNext()) {
+ *   List row = rowIterator.next();
+ *   // do something with row
+ * }
  * }
* * @see
Query diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryResponse.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryResponse.java index d9b61e9b1466..12000cc1cbd2 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryResponse.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryResponse.java @@ -29,20 +29,20 @@ * Query Request ({@link BigQuery#query(QueryRequest)}). * *

Example usage of a query response: - *

     {@code
- *    QueryResponse response = bigquery.query(request);
- *    while (!response.jobCompleted()) {
- *      Thread.sleep(1000);
- *      response = bigquery.getQueryResults(response.jobId());
- *    }
- *    List executionErrors = response.executionErrors();
- *    // look for errors in executionErrors
- *    QueryResult result = response.result();
- *    Iterator> rowIterator = result.iterateAll();
- *    while(rowIterator.hasNext()) {
- *      List row = rowIterator.next();
- *      // do something with row
- *    }
+ * 
 {@code
+ * QueryResponse response = bigquery.query(request);
+ * while (!response.jobCompleted()) {
+ *   Thread.sleep(1000);
+ *   response = bigquery.getQueryResults(response.jobId());
+ * }
+ * List executionErrors = response.executionErrors();
+ * // look for errors in executionErrors
+ * QueryResult result = response.result();
+ * Iterator> rowIterator = result.iterateAll();
+ * while(rowIterator.hasNext()) {
+ *   List row = rowIterator.next();
+ *   // do something with row
+ * }
  * }
* * @see Get Query diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java index 0befeecd4b99..a91a7e0abc07 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java @@ -197,10 +197,9 @@ public static void afterClass() throws ExecutionException, InterruptedException if (bigquery != null) { RemoteBigQueryHelper.forceDelete(bigquery, DATASET); } - if (storage != null && !RemoteGcsHelper.forceDelete(storage, BUCKET, 10, TimeUnit.SECONDS)) { - if (LOG.isLoggable(Level.WARNING)) { - LOG.log(Level.WARNING, "Deletion of bucket {0} timed out, bucket is not empty", BUCKET); - } + if (storage != null && !RemoteGcsHelper.forceDelete(storage, BUCKET, 10, TimeUnit.SECONDS) + && LOG.isLoggable(Level.WARNING)) { + LOG.log(Level.WARNING, "Deletion of bucket {0} timed out, bucket is not empty", BUCKET); } } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java index ec8ab361328e..d89f80f1def3 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java @@ -351,8 +351,8 @@ public Blob reload(BlobSourceOption... options) { *

* *

Example usage of replacing blob's metadata: - *

    {@code blob.toBuilder().metadata(null).build().update();}
-   *    {@code blob.toBuilder().metadata(newMetadata).build().update();}
+   * 
 {@code blob.toBuilder().metadata(null).build().update();}
+   * {@code blob.toBuilder().metadata(newMetadata).build().update();}
    * 
* * @param options update options diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java index ee70df1e4cc7..7eb91d0910a2 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java @@ -57,9 +57,10 @@ public class CopyWriter implements Restorable { * is {@code false} will block until all pending chunks are copied. * *

This method has the same effect of doing: - *

     {@code while (!copyWriter.isDone()) {
-   *        copyWriter.copyChunk();
-   *    }}
+   * 
 {@code
+   * while (!copyWriter.isDone()) {
+   *    copyWriter.copyChunk();
+   * }}
    * 
* * @throws StorageException upon failure diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index 38795bea5e5b..b43d35da6f5f 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -1300,8 +1300,8 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx * can be done by setting the provided {@code blobInfo}'s metadata to {@code null}. * *

Example usage of replacing blob's metadata: - *

    {@code service.update(BlobInfo.builder("bucket", "name").metadata(null).build());}
-   *    {@code service.update(BlobInfo.builder("bucket", "name").metadata(newMetadata).build());}
+   * 
 {@code service.update(BlobInfo.builder("bucket", "name").metadata(null).build());}
+   * {@code service.update(BlobInfo.builder("bucket", "name").metadata(newMetadata).build());}
    * 
* * @return the updated blob @@ -1315,8 +1315,8 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx * can be done by setting the provided {@code blobInfo}'s metadata to {@code null}. * *

Example usage of replacing blob's metadata: - *

    {@code service.update(BlobInfo.builder("bucket", "name").metadata(null).build());}
-   *    {@code service.update(BlobInfo.builder("bucket", "name").metadata(newMetadata).build());}
+   * 
 {@code service.update(BlobInfo.builder("bucket", "name").metadata(null).build());}
+   * {@code service.update(BlobInfo.builder("bucket", "name").metadata(newMetadata).build());}
    * 
* * @return the updated blob @@ -1373,14 +1373,15 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx * might issue multiple RPC calls depending on blob's size. * *

Example usage of copy: - *

    {@code BlobInfo blob = service.copy(copyRequest).result();}
+   * 
 {@code BlobInfo blob = service.copy(copyRequest).result();}
    * 
* To explicitly issue chunk copy requests use {@link CopyWriter#copyChunk()} instead: - *
     {@code CopyWriter copyWriter = service.copy(copyRequest);
-   *    while (!copyWriter.isDone()) {
-   *        copyWriter.copyChunk();
-   *    }
-   *    BlobInfo blob = copyWriter.result();
+   * 
 {@code
+   * CopyWriter copyWriter = service.copy(copyRequest);
+   * while (!copyWriter.isDone()) {
+   *     copyWriter.copyChunk();
+   * }
+   * BlobInfo blob = copyWriter.result();
    * }
    * 
* @@ -1462,8 +1463,8 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx * accessible blobs, but don't want to require users to explicitly log in. * *

Example usage of creating a signed URL that is valid for 2 weeks: - *

   {@code
-   *     service.signUrl(BlobInfo.builder("bucket", "name").build(), 14, TimeUnit.DAYS);
+   * 
 {@code
+   * service.signUrl(BlobInfo.builder("bucket", "name").build(), 14, TimeUnit.DAYS);
    * }
* * @param blobInfo the blob associated with the signed URL diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java index f185bdf8343e..0f560cbe173a 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java @@ -88,10 +88,9 @@ public static void beforeClass() { @AfterClass public static void afterClass() throws ExecutionException, InterruptedException { - if (storage != null && !RemoteGcsHelper.forceDelete(storage, BUCKET, 5, TimeUnit.SECONDS)) { - if (log.isLoggable(Level.WARNING)) { - log.log(Level.WARNING, "Deletion of bucket {0} timed out, bucket is not empty", BUCKET); - } + if (storage != null && !RemoteGcsHelper.forceDelete(storage, BUCKET, 5, TimeUnit.SECONDS) + && log.isLoggable(Level.WARNING)) { + log.log(Level.WARNING, "Deletion of bucket {0} timed out, bucket is not empty", BUCKET); } } @@ -442,7 +441,7 @@ public void testUpdateBlobFail() { @Test public void testDeleteNonExistingBlob() { String blobName = "test-delete-non-existing-blob"; - assertTrue(!storage.delete(BUCKET, blobName)); + assertFalse(storage.delete(BUCKET, blobName)); } @Test @@ -450,7 +449,7 @@ public void testDeleteBlobNonExistingGeneration() { String blobName = "test-delete-blob-non-existing-generation"; BlobInfo blob = BlobInfo.builder(BUCKET, blobName).build(); assertNotNull(storage.create(blob)); - assertTrue(!storage.delete(BlobId.of(BUCKET, blobName, -1L))); + assertFalse(storage.delete(BlobId.of(BUCKET, blobName, -1L))); } @Test @@ -966,7 +965,7 @@ public void testDeleteBlobsFail() { assertNotNull(storage.create(sourceBlob1)); List deleteStatus = storage.delete(sourceBlob1.blobId(), sourceBlob2.blobId()); assertTrue(deleteStatus.get(0)); - assertTrue(!deleteStatus.get(1)); + assertFalse(deleteStatus.get(1)); } @Test From bc66860a5283ae6e596245907739af56d904b590 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Thu, 11 Feb 2016 09:22:02 -0800 Subject: [PATCH 079/375] Minor fix in ITs --- .../com/google/gcloud/bigquery/it/ITBigQueryTest.java | 8 +++++--- .../java/com/google/gcloud/storage/it/ITStorageTest.java | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java index a91a7e0abc07..aa89ed89123e 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java @@ -197,9 +197,11 @@ public static void afterClass() throws ExecutionException, InterruptedException if (bigquery != null) { RemoteBigQueryHelper.forceDelete(bigquery, DATASET); } - if (storage != null && !RemoteGcsHelper.forceDelete(storage, BUCKET, 10, TimeUnit.SECONDS) - && LOG.isLoggable(Level.WARNING)) { - LOG.log(Level.WARNING, "Deletion of bucket {0} timed out, bucket is not empty", BUCKET); + if (storage != null) { + boolean wasDeleted = RemoteGcsHelper.forceDelete(storage, BUCKET, 10, TimeUnit.SECONDS); + if (!wasDeleted && LOG.isLoggable(Level.WARNING)) { + LOG.log(Level.WARNING, "Deletion of bucket {0} timed out, bucket is not empty", BUCKET); + } } } diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java index 0f560cbe173a..43c2cf6d372b 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java @@ -88,9 +88,11 @@ public static void beforeClass() { @AfterClass public static void afterClass() throws ExecutionException, InterruptedException { - if (storage != null && !RemoteGcsHelper.forceDelete(storage, BUCKET, 5, TimeUnit.SECONDS) - && log.isLoggable(Level.WARNING)) { - log.log(Level.WARNING, "Deletion of bucket {0} timed out, bucket is not empty", BUCKET); + if (storage != null) { + boolean wasDeleted = RemoteGcsHelper.forceDelete(storage, BUCKET, 5, TimeUnit.SECONDS); + if (!wasDeleted && log.isLoggable(Level.WARNING)) { + log.log(Level.WARNING, "Deletion of bucket {0} timed out, bucket is not empty", BUCKET); + } } } From deb228f0ae407b81b1bf5257755fd2b24da9777c Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Thu, 11 Feb 2016 17:08:46 -0800 Subject: [PATCH 080/375] Fix double code tags --- .../main/java/com/google/gcloud/storage/Blob.java | 6 ++++-- .../main/java/com/google/gcloud/storage/Storage.java | 12 ++++++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java index d89f80f1def3..aea424ca4063 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java @@ -351,8 +351,10 @@ public Blob reload(BlobSourceOption... options) { *

* *

Example usage of replacing blob's metadata: - *

 {@code blob.toBuilder().metadata(null).build().update();}
-   * {@code blob.toBuilder().metadata(newMetadata).build().update();}
+   * 
 {@code
+   * blob.toBuilder().metadata(null).build().update();
+   * blob.toBuilder().metadata(newMetadata).build().update();
+   * }
    * 
* * @param options update options diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index b43d35da6f5f..0ebe013202b0 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -1300,8 +1300,10 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx * can be done by setting the provided {@code blobInfo}'s metadata to {@code null}. * *

Example usage of replacing blob's metadata: - *

 {@code service.update(BlobInfo.builder("bucket", "name").metadata(null).build());}
-   * {@code service.update(BlobInfo.builder("bucket", "name").metadata(newMetadata).build());}
+   * 
 {@code
+   * service.update(BlobInfo.builder("bucket", "name").metadata(null).build());
+   * service.update(BlobInfo.builder("bucket", "name").metadata(newMetadata).build());
+   * }
    * 
* * @return the updated blob @@ -1315,8 +1317,10 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx * can be done by setting the provided {@code blobInfo}'s metadata to {@code null}. * *

Example usage of replacing blob's metadata: - *

 {@code service.update(BlobInfo.builder("bucket", "name").metadata(null).build());}
-   * {@code service.update(BlobInfo.builder("bucket", "name").metadata(newMetadata).build());}
+   * 
 {@code
+   * service.update(BlobInfo.builder("bucket", "name").metadata(null).build());
+   * service.update(BlobInfo.builder("bucket", "name").metadata(newMetadata).build());
+   * }
    * 
* * @return the updated blob From a68a0b60c09f990073b0d5103b11dcd9596e73ea Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Thu, 11 Feb 2016 17:30:35 -0800 Subject: [PATCH 081/375] Add set methods for lists of same type --- .../google/gcloud/datastore/BaseEntity.java | 93 ++++++++++++++++++- .../google/gcloud/datastore/ListValue.java | 11 ++- .../gcloud/datastore/BaseEntityTest.java | 14 ++- 3 files changed, 110 insertions(+), 8 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java index d674a5e242ad..d2b0748b4a85 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java @@ -33,6 +33,7 @@ import com.google.protobuf.InvalidProtocolBufferException; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Objects; @@ -138,43 +139,120 @@ public B set(String name, String value) { return self(); } + public B set(String name, String first, String second, String... others) { + List values = new LinkedList<>(); + values.add(of(first)); + values.add(of(second)); + for (String other : others) { + values.add(of(other)); + } + properties.put(name, of(values)); + return self(); + } + public B set(String name, long value) { properties.put(name, of(value)); return self(); } + public B set(String name, long first, long second, long... others) { + List values = new LinkedList<>(); + values.add(of(first)); + values.add(of(second)); + for (long other : others) { + values.add(of(other)); + } + properties.put(name, of(values)); + return self(); + } + public B set(String name, double value) { properties.put(name, of(value)); return self(); } + public B set(String name, double first, double second, double... others) { + List values = new LinkedList<>(); + values.add(of(first)); + values.add(of(second)); + for (double other : others) { + values.add(of(other)); + } + properties.put(name, of(values)); + return self(); + } + public B set(String name, boolean value) { properties.put(name, of(value)); return self(); } + public B set(String name, boolean first, boolean second, boolean... others) { + List values = new LinkedList<>(); + values.add(of(first)); + values.add(of(second)); + for (boolean other : others) { + values.add(of(other)); + } + properties.put(name, of(values)); + return self(); + } + public B set(String name, DateTime value) { properties.put(name, of(value)); return self(); } + public B set(String name, DateTime first, DateTime second, DateTime... others) { + List values = new LinkedList<>(); + values.add(of(first)); + values.add(of(second)); + for (DateTime other : others) { + values.add(of(other)); + } + properties.put(name, of(values)); + return self(); + } + public B set(String name, Key value) { properties.put(name, of(value)); return self(); } + public B set(String name, Key first, Key second, Key... others) { + List values = new LinkedList<>(); + values.add(of(first)); + values.add(of(second)); + for (Key other : others) { + values.add(of(other)); + } + properties.put(name, of(values)); + return self(); + } + public B set(String name, FullEntity value) { properties.put(name, of(value)); return self(); } + public B set(String name, FullEntity first, FullEntity second, FullEntity... others) { + List values = new LinkedList<>(); + values.add(of(first)); + values.add(of(second)); + for (FullEntity other : others) { + values.add(of(other)); + } + properties.put(name, of(values)); + return self(); + } + public B set(String name, List> values) { properties.put(name, of(values)); return self(); } - public B set(String name, Value value, Value... other) { - properties.put(name, of(value, other)); + public B set(String name, Value first, Value second, Value... other) { + properties.put(name, of(first, second, other)); return self(); } @@ -183,6 +261,17 @@ public B set(String name, Blob value) { return self(); } + public B set(String name, Blob first, Blob second, Blob... others) { + List values = new LinkedList<>(); + values.add(of(first)); + values.add(of(second)); + for (Blob other : others) { + values.add(of(other)); + } + properties.put(name, of(values)); + return self(); + } + public B setNull(String name) { properties.put(name, of()); return self(); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java index 41c7e82788b5..494d8daedfff 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java @@ -77,8 +77,9 @@ public Builder addValue(Value value) { return this; } - public Builder addValue(Value first, Value... other) { + public Builder addValue(Value first, Value second, Value... other) { addValue(first); + addValue(second); for (Value value : other) { addValue(value); } @@ -121,8 +122,8 @@ public ListValue(List> values) { this(builder().set(values)); } - public ListValue(Value first, Value... other) { - this(new Builder().addValue(first, other)); + public ListValue(Value first, Value second, Value... other) { + this(new Builder().addValue(first, second, other)); } private ListValue(Builder builder) { @@ -138,8 +139,8 @@ public static ListValue of(List> values) { return new ListValue(values); } - public static ListValue of(Value first, Value... other) { - return new ListValue(first, other); + public static ListValue of(Value first, Value second, Value... other) { + return new ListValue(first, second, other); } public static Builder builder() { diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java index 5ece01508d3a..691edb70f493 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java @@ -67,6 +67,16 @@ public void setUp() { builder.set("list1", NullValue.of(), StringValue.of("foo")); builder.set("list2", ImmutableList.of(LongValue.of(10), DoubleValue.of(2))); builder.set("list3", Collections.singletonList(BooleanValue.of(true))); + builder.set( + "blobList", BLOB, Blob.copyFrom(new byte[] {3, 4}), Blob.copyFrom(new byte[] {5, 6})); + builder.set("booleanList", true, false, true); + builder.set("dateTimeList", DateTime.now(), DateTime.now(), DateTime.now()); + builder.set("doubleList", 12.3, 4.56, .789); + builder.set("keyList", KEY, Key.builder("ds2", "k2", "n2").build(), + Key.builder("ds3", "k3", "n3").build()); + builder.set("entityList", ENTITY, PARTIAL_ENTITY, ENTITY); + builder.set("stringList", "s1", "s2", "s3"); + builder.set("longList", 1, 23, 456); } @Test @@ -198,7 +208,9 @@ public void testGetBlob() throws Exception { public void testNames() throws Exception { Set names = ImmutableSet.builder() .add("string", "stringValue", "boolean", "double", "long", "list1", "list2", "list3") - .add("entity", "partialEntity", "null", "dateTime", "blob", "key") + .add("entity", "partialEntity", "null", "dateTime", "blob", "key", "blobList") + .add("booleanList", "dateTimeList", "doubleList", "keyList", "entityList", "stringList") + .add("longList") .build(); BaseEntity entity = builder.build(); assertEquals(names, entity.names()); From 8050cca81afee5f6a952cc7c544e3ae5aa616633 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Thu, 11 Feb 2016 18:15:24 -0800 Subject: [PATCH 082/375] Cleaner getList return value --- .../com/google/gcloud/datastore/BaseEntity.java | 4 ++-- .../com/google/gcloud/datastore/BaseEntityTest.java | 13 ++++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java index d2b0748b4a85..af05cb42c315 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java @@ -437,8 +437,8 @@ public FullEntity getEntity(String name) { * @throws ClassCastException if value is not a list of values */ @SuppressWarnings("unchecked") - public List> getList(String name) { - return ((Value>>) getValue(name)).get(); + public > List getList(String name) { + return (List) getValue(name).get(); } /** diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java index 691edb70f493..a69ea5e20e3b 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java @@ -74,7 +74,7 @@ public void setUp() { builder.set("doubleList", 12.3, 4.56, .789); builder.set("keyList", KEY, Key.builder("ds2", "k2", "n2").build(), Key.builder("ds3", "k3", "n3").build()); - builder.set("entityList", ENTITY, PARTIAL_ENTITY, ENTITY); + builder.set("entityList", ENTITY, PARTIAL_ENTITY); builder.set("stringList", "s1", "s2", "s3"); builder.set("longList", 1, 23, 456); } @@ -193,6 +193,17 @@ public void testGetList() throws Exception { assertEquals(Boolean.TRUE, list.get(0).get()); entity = builder.set("list1", ListValue.of(list)).build(); assertEquals(list, entity.getList("list1")); + List> stringList = entity.getList("stringList"); + assertEquals( + ImmutableList.of(StringValue.of("s1"), StringValue.of("s2"), StringValue.of("s3")), + stringList); + List> doubleList = entity.getList("doubleList"); + assertEquals( + ImmutableList.of(DoubleValue.of(12.3), DoubleValue.of(4.56), DoubleValue.of(.789)), + doubleList); + List entityList = entity.getList("entityList"); + assertEquals( + ImmutableList.of(EntityValue.of(ENTITY), EntityValue.of(PARTIAL_ENTITY)), entityList); } @Test From f9209861f644541c5e8c88a575b37f20da727324 Mon Sep 17 00:00:00 2001 From: Arie Ozarov Date: Thu, 11 Feb 2016 19:56:14 -0800 Subject: [PATCH 083/375] Revert #625 and Fixes ##624 --- .../google/gcloud/bigquery/it/ITBigQueryTest.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java index aa89ed89123e..63a0551ece33 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java @@ -50,6 +50,7 @@ import com.google.gcloud.bigquery.InsertAllResponse; import com.google.gcloud.bigquery.Job; import com.google.gcloud.bigquery.JobInfo; +import com.google.gcloud.bigquery.JobStatistics; import com.google.gcloud.bigquery.LoadJobConfiguration; import com.google.gcloud.bigquery.QueryJobConfiguration; import com.google.gcloud.bigquery.QueryRequest; @@ -683,10 +684,9 @@ public void testQuery() throws InterruptedException { rowCount++; } assertEquals(2, rowCount); - // todo(mziccard) uncomment as soon as #624 is closed - // Job queryJob = bigquery.getJob(response.jobId()); - // JobStatistics.QueryStatistics statistics = queryJob.statistics(); - // assertNotNull(statistics.queryPlan()); + Job queryJob = bigquery.getJob(response.jobId()); + JobStatistics.QueryStatistics statistics = queryJob.statistics(); + assertNotNull(statistics.queryPlan()); } @Test @@ -851,10 +851,9 @@ public void testQueryJob() throws InterruptedException { } assertEquals(2, rowCount); assertTrue(bigquery.delete(DATASET, tableName)); - // todo(mziccard) uncomment as soon as #624 is closed - // Job queryJob = bigquery.getJob(remoteJob.jobId()); - // JobStatistics.QueryStatistics statistics = queryJob.statistics(); - // assertNotNull(statistics.queryPlan()); + Job queryJob = bigquery.getJob(remoteJob.jobId()); + JobStatistics.QueryStatistics statistics = queryJob.statistics(); + assertNotNull(statistics.queryPlan()); } @Test From 4476dcf51507a6cb1dff01736568ac507a1a2adb Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 12 Feb 2016 12:18:02 +0100 Subject: [PATCH 084/375] Update dependencies when possible --- gcloud-java-bigquery/pom.xml | 4 ++-- gcloud-java-core/pom.xml | 16 ++++++++-------- gcloud-java-datastore/pom.xml | 2 +- gcloud-java-resourcemanager/pom.xml | 4 ++-- gcloud-java-storage/pom.xml | 4 ++-- pom.xml | 22 +++++++++++----------- 6 files changed, 26 insertions(+), 26 deletions(-) diff --git a/gcloud-java-bigquery/pom.xml b/gcloud-java-bigquery/pom.xml index 41a51722b7c6..b1e516a2268b 100644 --- a/gcloud-java-bigquery/pom.xml +++ b/gcloud-java-bigquery/pom.xml @@ -30,7 +30,7 @@ com.google.apis google-api-services-bigquery - v2-rev254-1.21.0 + v2-rev261-1.21.0 compile @@ -48,7 +48,7 @@ org.easymock easymock - 3.3 + 3.4 test diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml index bd7f26e0bc3b..3463f40b52bd 100644 --- a/gcloud-java-core/pom.xml +++ b/gcloud-java-core/pom.xml @@ -35,24 +35,24 @@ com.google.http-client google-http-client - 1.20.0 + 1.21.0 compile com.google.oauth-client google-oauth-client - 1.20.0 + 1.21.0 compile com.google.guava guava - 18.0 + 19.0 com.google.api-client google-api-client-appengine - 1.20.0 + 1.21.0 compile @@ -64,7 +64,7 @@ com.google.http-client google-http-client-jackson - 1.20.0 + 1.21.0 compile @@ -82,19 +82,19 @@ joda-time joda-time - 2.8.2 + 2.9.2 compile org.json json - 20090211 + 20151123 compile org.easymock easymock - 3.3 + 3.4 test diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index a76e4f9d9cbd..1b74b4b39dbd 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -42,7 +42,7 @@ org.easymock easymock - 3.3 + 3.4 test diff --git a/gcloud-java-resourcemanager/pom.xml b/gcloud-java-resourcemanager/pom.xml index 0e07d5afbee6..1311e4dc1bb5 100644 --- a/gcloud-java-resourcemanager/pom.xml +++ b/gcloud-java-resourcemanager/pom.xml @@ -24,7 +24,7 @@ com.google.apis google-api-services-cloudresourcemanager - v1beta1-rev6-1.19.0 + v1beta1-rev10-1.21.0 compile @@ -42,7 +42,7 @@ org.easymock easymock - 3.3 + 3.4 test diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml index 6b4755d90041..09487467a827 100644 --- a/gcloud-java-storage/pom.xml +++ b/gcloud-java-storage/pom.xml @@ -24,7 +24,7 @@ com.google.apis google-api-services-storage - v1-rev33-1.20.0 + v1-rev60-1.21.0 compile @@ -46,7 +46,7 @@ org.easymock easymock - 3.3 + 3.4 test diff --git a/pom.xml b/pom.xml index 0084fd53d74f..c3c3554d976a 100644 --- a/pom.xml +++ b/pom.xml @@ -133,7 +133,7 @@ org.apache.maven.plugins maven-surefire-plugin - 2.18 + 2.19.1 @@ -144,7 +144,7 @@ org.apache.maven.plugins maven-enforcer-plugin - 1.4 + 1.4.1 enforce-maven @@ -186,7 +186,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 2.18.1 + 2.19.1 @@ -218,7 +218,7 @@ maven-compiler-plugin - 3.2 + 3.5.1 1.7 1.7 @@ -269,7 +269,7 @@ org.sonatype.plugins nexus-staging-maven-plugin - 1.6.5 + 1.6.6 true sonatype-nexus-staging @@ -280,7 +280,7 @@ org.eluder.coveralls coveralls-maven-plugin - 3.1.0 + 4.1.0 ${basedir}/target/coverage.xml @@ -313,12 +313,12 @@ org.apache.maven.plugins maven-checkstyle-plugin - 2.16 + 2.17 com.puppycrawl.tools checkstyle - 6.8.1 + 6.15 @@ -337,7 +337,7 @@ org.apache.maven.plugins maven-project-info-reports-plugin - 2.8 + 2.8.1 @@ -394,12 +394,12 @@ org.apache.maven.plugins maven-surefire-report-plugin - 2.18.1 + 2.19.1 org.apache.maven.plugins maven-checkstyle-plugin - 2.16 + 2.17 checkstyle.xml false From 2f77f2d648abda3d85eac8fccb1f2b05d11d780d Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 12 Feb 2016 12:19:04 +0100 Subject: [PATCH 085/375] Add versioneye badge to READMEs --- README.md | 1 + gcloud-java-bigquery/README.md | 1 + gcloud-java-contrib/README.md | 6 ++++++ gcloud-java-core/README.md | 1 + gcloud-java-datastore/README.md | 1 + gcloud-java-examples/README.md | 1 + gcloud-java-resourcemanager/README.md | 1 + gcloud-java-storage/README.md | 1 + gcloud-java/README.md | 1 + 9 files changed, 14 insertions(+) diff --git a/README.md b/README.md index 207009ee6475..d465105dfd41 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ Java idiomatic client for [Google Cloud Platform][cloud-platform] services. [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) [![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java.svg) [![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) +[![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969) - [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) - [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs) diff --git a/gcloud-java-bigquery/README.md b/gcloud-java-bigquery/README.md index df1058dec024..ba6caa87783a 100644 --- a/gcloud-java-bigquery/README.md +++ b/gcloud-java-bigquery/README.md @@ -7,6 +7,7 @@ Java idiomatic client for [Google Cloud BigQuery] (https://cloud.google.com/bigq [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) [![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-bigquery.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-bigquery.svg) [![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) +[![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969) - [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) - [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/bigquery/package-summary.html) diff --git a/gcloud-java-contrib/README.md b/gcloud-java-contrib/README.md index 23713f7450a3..01f455e3a43c 100644 --- a/gcloud-java-contrib/README.md +++ b/gcloud-java-contrib/README.md @@ -3,6 +3,12 @@ Google Cloud Java Contributions Packages that provide higher-level abstraction/functionality for common gcloud-java use cases. +[![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java) +[![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) +[![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-bigquery.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-bigquery.svg) +[![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) +[![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969) + Quickstart ---------- If you are using Maven, add this to your pom.xml file diff --git a/gcloud-java-core/README.md b/gcloud-java-core/README.md index 8b91e49f3860..b7e5e05b6ad3 100644 --- a/gcloud-java-core/README.md +++ b/gcloud-java-core/README.md @@ -7,6 +7,7 @@ This module provides common functionality required by service-specific modules o [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) [![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-core.svg)](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-core.svg) [![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) +[![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969) - [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) - [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/package-summary.html) diff --git a/gcloud-java-datastore/README.md b/gcloud-java-datastore/README.md index 8c0ae1950e77..7d985e882a44 100644 --- a/gcloud-java-datastore/README.md +++ b/gcloud-java-datastore/README.md @@ -7,6 +7,7 @@ Java idiomatic client for [Google Cloud Datastore] (https://cloud.google.com/dat [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) [![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-datastore.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-datastore.svg) [![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) +[![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969) - [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) - [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/datastore/package-summary.html) diff --git a/gcloud-java-examples/README.md b/gcloud-java-examples/README.md index 7d24febeac80..0ab9b3ca6924 100644 --- a/gcloud-java-examples/README.md +++ b/gcloud-java-examples/README.md @@ -7,6 +7,7 @@ Examples for gcloud-java (Java idiomatic client for [Google Cloud Platform][clou [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) [![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-examples.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-examples.svg) [![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) +[![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969) - [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) - [Examples] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/examples/package-summary.html) diff --git a/gcloud-java-resourcemanager/README.md b/gcloud-java-resourcemanager/README.md index 6f7d52386fc0..fc80190ebd05 100644 --- a/gcloud-java-resourcemanager/README.md +++ b/gcloud-java-resourcemanager/README.md @@ -7,6 +7,7 @@ Java idiomatic client for [Google Cloud Resource Manager] (https://cloud.google. [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) [![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-resourcemanager.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-resourcemanager.svg) [![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) +[![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969) - [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) - [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/resourcemanager/package-summary.html) diff --git a/gcloud-java-storage/README.md b/gcloud-java-storage/README.md index 554f22b38e7f..80b2ffd0cd67 100644 --- a/gcloud-java-storage/README.md +++ b/gcloud-java-storage/README.md @@ -7,6 +7,7 @@ Java idiomatic client for [Google Cloud Storage] (https://cloud.google.com/stora [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) [![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-storage.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-storage.svg) [![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) +[![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969) - [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) - [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/storage/package-summary.html) diff --git a/gcloud-java/README.md b/gcloud-java/README.md index 4a581d56f991..7443bf5e3392 100644 --- a/gcloud-java/README.md +++ b/gcloud-java/README.md @@ -7,6 +7,7 @@ Java idiomatic client for [Google Cloud Platform][cloud-platform] services. [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) [![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java.svg) [![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) +[![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969) - [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) - [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs) From e08896cd79eeda392f65205ad16b473e2a61ba3b Mon Sep 17 00:00:00 2001 From: aozarov Date: Fri, 12 Feb 2016 10:00:42 -0800 Subject: [PATCH 086/375] upgrade google-api-services-datastore-protobuf to v1beta2-rev1-4.0.0 and fix test --- gcloud-java-datastore/pom.xml | 2 +- .../gcloud/datastore/DatastoreTest.java | 26 +++++++++++++------ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index a76e4f9d9cbd..5866500ba0d6 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -24,7 +24,7 @@ com.google.apis google-api-services-datastore-protobuf - v1beta2-rev1-2.1.2 + v1beta2-rev1-4.0.0 compile diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index e9eed027e8e0..19f53f525b1a 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -31,6 +31,7 @@ import com.google.api.services.datastore.DatastoreV1.RunQueryRequest; import com.google.api.services.datastore.DatastoreV1.RunQueryResponse; import com.google.common.collect.Iterators; +import com.google.common.collect.Lists; import com.google.gcloud.RetryParams; import com.google.gcloud.datastore.Query.ResultType; import com.google.gcloud.datastore.StructuredQuery.OrderBy; @@ -89,8 +90,8 @@ public class DatastoreTest { FullEntity.builder(INCOMPLETE_KEY2).set("str", STR_VALUE).set("bool", BOOL_VALUE) .set("list", LIST_VALUE1).build(); private static final FullEntity PARTIAL_ENTITY2 = - FullEntity.builder(PARTIAL_ENTITY1).remove("str").set("bool", true). - set("list", LIST_VALUE1.get()).build(); + FullEntity.builder(PARTIAL_ENTITY1).remove("str").set("bool", true) + .set("list", LIST_VALUE1.get()).build(); private static final FullEntity PARTIAL_ENTITY3 = FullEntity.builder(PARTIAL_ENTITY1).key(IncompleteKey.builder(PROJECT_ID, KIND3).build()) .build(); @@ -471,9 +472,13 @@ public void testQueryPaginationWithLimit() throws DatastoreException { EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) .andReturn(rpcMock); List responses = buildResponsesForQueryPaginationWithLimit(); - for (int i = 0; i < responses.size(); i++) { + List endCursors = Lists.newArrayListWithCapacity(responses.size()); + for (RunQueryResponse response: responses) { EasyMock.expect(rpcMock.runQuery(EasyMock.anyObject(RunQueryRequest.class))) - .andReturn(responses.get(i)); + .andReturn(response); + if (response.getBatch().getMoreResults() != QueryResultBatch.MoreResultsType.NOT_FINISHED) { + endCursors.add(response.getBatch().getEndCursor()); + } } EasyMock.replay(rpcFactoryMock, rpcMock); Datastore mockDatastore = options.toBuilder() @@ -483,6 +488,7 @@ public void testQueryPaginationWithLimit() throws DatastoreException { .service(); int limit = 2; int totalCount = 0; + Iterator cursorIter = endCursors.iterator(); StructuredQuery query = Query.entityQueryBuilder().limit(limit).build(); while (true) { QueryResults results = mockDatastore.run(query); @@ -492,6 +498,9 @@ public void testQueryPaginationWithLimit() throws DatastoreException { resultCount++; totalCount++; } + assertTrue(cursorIter.hasNext()); + Cursor expectedEndCursor = Cursor.copyFrom(cursorIter.next().toByteArray()); + assertEquals(expectedEndCursor, results.cursorAfter()); if (resultCount < limit) { break; } @@ -505,19 +514,20 @@ private List buildResponsesForQueryPaginationWithLimit() { Entity entity4 = Entity.builder(KEY4).set("value", StringValue.of("value")).build(); Entity entity5 = Entity.builder(KEY5).set("value", "value").build(); datastore.add(ENTITY3, entity4, entity5); + DatastoreRpc datastoreRpc = datastore.options().rpc(); List responses = new ArrayList<>(); Query query = Query.entityQueryBuilder().build(); RunQueryRequest.Builder requestPb = RunQueryRequest.newBuilder(); query.populatePb(requestPb); QueryResultBatch queryResultBatchPb = RunQueryResponse.newBuilder() - .mergeFrom(((DatastoreImpl) datastore).runQuery(requestPb.build())) + .mergeFrom(datastoreRpc.runQuery(requestPb.build())) .getBatch(); QueryResultBatch queryResultBatchPb1 = QueryResultBatch.newBuilder() .mergeFrom(queryResultBatchPb) .setMoreResults(QueryResultBatch.MoreResultsType.NOT_FINISHED) .clearEntityResult() .addAllEntityResult(queryResultBatchPb.getEntityResultList().subList(0, 1)) - .setEndCursor(queryResultBatchPb.getEntityResultList().get(0).getCursor()) + .setEndCursor(ByteString.copyFromUtf8("a")) .build(); responses.add(RunQueryResponse.newBuilder().setBatch(queryResultBatchPb1).build()); QueryResultBatch queryResultBatchPb2 = QueryResultBatch.newBuilder() @@ -534,7 +544,7 @@ private List buildResponsesForQueryPaginationWithLimit() { .setMoreResults(QueryResultBatch.MoreResultsType.MORE_RESULTS_AFTER_LIMIT) .clearEntityResult() .addAllEntityResult(queryResultBatchPb.getEntityResultList().subList(2, 4)) - .setEndCursor(queryResultBatchPb.getEntityResultList().get(3).getCursor()) + .setEndCursor(ByteString.copyFromUtf8("b")) .build(); responses.add(RunQueryResponse.newBuilder().setBatch(queryResultBatchPb3).build()); QueryResultBatch queryResultBatchPb4 = QueryResultBatch.newBuilder() @@ -542,7 +552,7 @@ private List buildResponsesForQueryPaginationWithLimit() { .setMoreResults(QueryResultBatch.MoreResultsType.NO_MORE_RESULTS) .clearEntityResult() .addAllEntityResult(queryResultBatchPb.getEntityResultList().subList(4, 5)) - .setEndCursor(queryResultBatchPb.getEntityResultList().get(4).getCursor()) + .setEndCursor(ByteString.copyFromUtf8("c")) .build(); responses.add(RunQueryResponse.newBuilder().setBatch(queryResultBatchPb4).build()); return responses; From 2314eeec1bff03fea3719063725cac58f23a464b Mon Sep 17 00:00:00 2001 From: aozarov Date: Fri, 12 Feb 2016 17:36:56 -0800 Subject: [PATCH 087/375] update codacy config --- codacy-conf.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codacy-conf.json b/codacy-conf.json index 61328436cba3..e8c819684c9c 100644 --- a/codacy-conf.json +++ b/codacy-conf.json @@ -1 +1 @@ -{"patterns":[{"patternId":"Custom_Javascript_Scopes","enabled":true},{"patternId":"Custom_Javascript_EvalWith","enabled":true},{"patternId":"Custom_Javascript_TryCatch","enabled":true},{"patternId":"Custom_Scala_NonFatal","enabled":true},{"patternId":"bitwise","enabled":true},{"patternId":"maxparams","enabled":true},{"patternId":"CSSLint_universal_selector","enabled":true},{"patternId":"CSSLint_unqualified_attributes","enabled":true},{"patternId":"CSSLint_zero_units","enabled":true},{"patternId":"CSSLint_overqualified_elements","enabled":true},{"patternId":"CSSLint_shorthand","enabled":true},{"patternId":"CSSLint_duplicate_background_images","enabled":true},{"patternId":"CSSLint_box_model","enabled":true},{"patternId":"CSSLint_compatible_vendor_prefixes","enabled":true},{"patternId":"CSSLint_display_property_grouping","enabled":true},{"patternId":"CSSLint_duplicate_properties","enabled":true},{"patternId":"CSSLint_empty_rules","enabled":true},{"patternId":"CSSLint_errors","enabled":true},{"patternId":"CSSLint_gradients","enabled":true},{"patternId":"CSSLint_important","enabled":true},{"patternId":"CSSLint_known_properties","enabled":true},{"patternId":"CSSLint_text_indent","enabled":true},{"patternId":"CSSLint_unique_headings","enabled":true},{"patternId":"PyLint_E0100","enabled":true},{"patternId":"PyLint_E0101","enabled":true},{"patternId":"PyLint_E0102","enabled":true},{"patternId":"PyLint_E0103","enabled":true},{"patternId":"PyLint_E0104","enabled":true},{"patternId":"PyLint_E0105","enabled":true},{"patternId":"PyLint_E0106","enabled":true},{"patternId":"PyLint_E0107","enabled":true},{"patternId":"PyLint_E0108","enabled":true},{"patternId":"PyLint_E0202","enabled":true},{"patternId":"PyLint_E0203","enabled":true},{"patternId":"PyLint_E0211","enabled":true},{"patternId":"PyLint_E0601","enabled":true},{"patternId":"PyLint_E0603","enabled":true},{"patternId":"PyLint_E0604","enabled":true},{"patternId":"PyLint_E0701","enabled":true},{"patternId":"PyLint_E0702","enabled":true},{"patternId":"PyLint_E0710","enabled":true},{"patternId":"PyLint_E0711","enabled":true},{"patternId":"PyLint_E0712","enabled":true},{"patternId":"PyLint_E1003","enabled":true},{"patternId":"PyLint_E1102","enabled":true},{"patternId":"PyLint_E1111","enabled":true},{"patternId":"PyLint_E1120","enabled":true},{"patternId":"PyLint_E1121","enabled":true},{"patternId":"PyLint_E1123","enabled":true},{"patternId":"PyLint_E1124","enabled":true},{"patternId":"PyLint_E1200","enabled":true},{"patternId":"PyLint_E1201","enabled":true},{"patternId":"PyLint_E1205","enabled":true},{"patternId":"PyLint_E1206","enabled":true},{"patternId":"PyLint_E1300","enabled":true},{"patternId":"PyLint_E1301","enabled":true},{"patternId":"PyLint_E1302","enabled":true},{"patternId":"PyLint_E1303","enabled":true},{"patternId":"PyLint_E1304","enabled":true},{"patternId":"PyLint_E1305","enabled":true},{"patternId":"PyLint_E1306","enabled":true},{"patternId":"rulesets-codesize.xml-CyclomaticComplexity","enabled":true},{"patternId":"rulesets-codesize.xml-NPathComplexity","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessiveMethodLength","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessiveClassLength","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessiveParameterList","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessivePublicCount","enabled":true},{"patternId":"rulesets-codesize.xml-TooManyFields","enabled":true},{"patternId":"rulesets-codesize.xml-TooManyMethods","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessiveClassComplexity","enabled":true},{"patternId":"rulesets-controversial.xml-Superglobals","enabled":true},{"patternId":"rulesets-design.xml-ExitExpression","enabled":true},{"patternId":"rulesets-design.xml-EvalExpression","enabled":true},{"patternId":"rulesets-design.xml-GotoStatement","enabled":true},{"patternId":"rulesets-design.xml-NumberOfChildren","enabled":true},{"patternId":"rulesets-design.xml-DepthOfInheritance","enabled":true},{"patternId":"rulesets-unusedcode.xml-UnusedPrivateField","enabled":true},{"patternId":"rulesets-unusedcode.xml-UnusedLocalVariable","enabled":true},{"patternId":"rulesets-unusedcode.xml-UnusedPrivateMethod","enabled":true},{"patternId":"rulesets-unusedcode.xml-UnusedFormalParameter","enabled":true},{"patternId":"PyLint_C0303","enabled":true},{"patternId":"PyLint_C1001","enabled":true},{"patternId":"rulesets-naming.xml-ShortVariable","enabled":true},{"patternId":"rulesets-naming.xml-LongVariable","enabled":true},{"patternId":"rulesets-naming.xml-ShortMethodName","enabled":true},{"patternId":"rulesets-naming.xml-ConstantNamingConventions","enabled":true},{"patternId":"rulesets-naming.xml-BooleanGetMethodName","enabled":true},{"patternId":"PyLint_W0101","enabled":true},{"patternId":"PyLint_W0102","enabled":true},{"patternId":"PyLint_W0104","enabled":true},{"patternId":"PyLint_W0105","enabled":true},{"patternId":"Custom_Scala_GetCalls","enabled":true},{"patternId":"ScalaStyle_EqualsHashCodeChecker","enabled":true},{"patternId":"ScalaStyle_ParameterNumberChecker","enabled":true},{"patternId":"ScalaStyle_ReturnChecker","enabled":true},{"patternId":"ScalaStyle_NullChecker","enabled":true},{"patternId":"ScalaStyle_NoCloneChecker","enabled":true},{"patternId":"ScalaStyle_NoFinalizeChecker","enabled":true},{"patternId":"ScalaStyle_CovariantEqualsChecker","enabled":true},{"patternId":"ScalaStyle_StructuralTypeChecker","enabled":true},{"patternId":"ScalaStyle_MethodLengthChecker","enabled":true},{"patternId":"ScalaStyle_NumberOfMethodsInTypeChecker","enabled":true},{"patternId":"ScalaStyle_WhileChecker","enabled":true},{"patternId":"ScalaStyle_VarFieldChecker","enabled":true},{"patternId":"ScalaStyle_VarLocalChecker","enabled":true},{"patternId":"ScalaStyle_RedundantIfChecker","enabled":true},{"patternId":"ScalaStyle_DeprecatedJavaChecker","enabled":true},{"patternId":"ScalaStyle_EmptyClassChecker","enabled":true},{"patternId":"ScalaStyle_NotImplementedErrorUsage","enabled":true},{"patternId":"Custom_Scala_GroupImports","enabled":true},{"patternId":"Custom_Scala_ReservedKeywords","enabled":true},{"patternId":"Custom_Scala_ElseIf","enabled":true},{"patternId":"Custom_Scala_CallByNameAsLastArguments","enabled":true},{"patternId":"Custom_Scala_WildcardImportOnMany","enabled":true},{"patternId":"Custom_Scala_UtilTryForTryCatch","enabled":true},{"patternId":"Custom_Scala_ProhibitObjectName","enabled":true},{"patternId":"Custom_Scala_ImportsAtBeginningOfPackage","enabled":true},{"patternId":"Custom_Scala_NameResultsAndParameters","enabled":true},{"patternId":"Custom_Scala_IncompletePatternMatching","enabled":true},{"patternId":"Custom_Scala_UsefulTypeAlias","enabled":true},{"patternId":"Custom_Scala_JavaThreads","enabled":true},{"patternId":"Custom_Scala_DirectPromiseCreation","enabled":true},{"patternId":"Custom_Scala_StructuralTypes","enabled":true},{"patternId":"Custom_Scala_CollectionLastHead","enabled":true},{"patternId":"PyLint_W0106","enabled":true},{"patternId":"PyLint_W0107","enabled":true},{"patternId":"PyLint_W0108","enabled":true},{"patternId":"PyLint_W0109","enabled":true},{"patternId":"PyLint_W0110","enabled":true},{"patternId":"PyLint_W0120","enabled":true},{"patternId":"PyLint_W0122","enabled":true},{"patternId":"PyLint_W0150","enabled":true},{"patternId":"PyLint_W0199","enabled":true},{"patternId":"rulesets-cleancode.xml-ElseExpression","enabled":true},{"patternId":"rulesets-cleancode.xml-StaticAccess","enabled":true},{"patternId":"ScalaStyle_NonASCIICharacterChecker","enabled":true},{"patternId":"ScalaStyle_FieldNamesChecker","enabled":true},{"patternId":"Custom_Scala_WithNameCalls","enabled":true},{"patternId":"braces_IfElseStmtsMustUseBraces","enabled":true},{"patternId":"basic_AvoidDecimalLiteralsInBigDecimalConstructor","enabled":true},{"patternId":"basic_CheckSkipResult","enabled":true},{"patternId":"design_AvoidInstanceofChecksInCatchClause","enabled":true},{"patternId":"j2ee_DoNotCallSystemExit","enabled":true},{"patternId":"unusedcode_UnusedLocalVariable","enabled":true},{"patternId":"basic_DontUseFloatTypeForLoopIndices","enabled":true},{"patternId":"basic_AvoidBranchingStatementAsLastInLoop","enabled":true},{"patternId":"empty_EmptyFinallyBlock","enabled":true},{"patternId":"design_CompareObjectsWithEquals","enabled":true},{"patternId":"junit_UnnecessaryBooleanAssertion","enabled":true},{"patternId":"design_SimplifyBooleanExpressions","enabled":true},{"patternId":"basic_JumbledIncrementer","enabled":true},{"patternId":"design_SwitchStmtsShouldHaveDefault","enabled":true},{"patternId":"strictexception_AvoidThrowingRawExceptionTypes","enabled":true},{"patternId":"design_SimplifyBooleanReturns","enabled":true},{"patternId":"empty_EmptyInitializer","enabled":true},{"patternId":"design_FieldDeclarationsShouldBeAtStartOfClass","enabled":true},{"patternId":"naming_PackageCase","enabled":true},{"patternId":"controversial_UnnecessaryConstructor","enabled":true},{"patternId":"naming_MethodNamingConventions","enabled":true},{"patternId":"basic_UnconditionalIfStatement","enabled":true},{"patternId":"design_SingularField","enabled":true},{"patternId":"design_AssignmentToNonFinalStatic","enabled":true},{"patternId":"strings_UseStringBufferLength","enabled":true},{"patternId":"finalizers_AvoidCallingFinalize","enabled":true},{"patternId":"naming_ClassNamingConventions","enabled":true},{"patternId":"imports_UnnecessaryFullyQualifiedName","enabled":true},{"patternId":"unusedcode_UnusedPrivateField","enabled":true},{"patternId":"strings_UnnecessaryCaseChange","enabled":true},{"patternId":"design_NonStaticInitializer","enabled":true},{"patternId":"design_MissingBreakInSwitch","enabled":true},{"patternId":"design_AvoidReassigningParameters","enabled":true},{"patternId":"basic_AvoidThreadGroup","enabled":true},{"patternId":"codesize_ExcessiveParameterList","parameters":{"minimum":"8","violationSuppressRegex":"\"\"","violationSuppressXPath":"\"\""},"enabled":true},{"patternId":"design_UncommentedEmptyMethodBody","enabled":true},{"patternId":"basic_BrokenNullCheck","enabled":true},{"patternId":"strings_StringInstantiation","enabled":true},{"patternId":"design_EqualsNull","enabled":true},{"patternId":"basic_OverrideBothEqualsAndHashcode","enabled":true},{"patternId":"basic_BooleanInstantiation","enabled":true},{"patternId":"basic_ReturnFromFinallyBlock","enabled":true},{"patternId":"empty_EmptyTryBlock","enabled":true},{"patternId":"basic_ExtendsObject","enabled":true},{"patternId":"strictexception_AvoidThrowingNullPointerException","enabled":true},{"patternId":"empty_EmptySwitchStatements","enabled":true},{"patternId":"basic_MisplacedNullCheck","enabled":true},{"patternId":"strings_StringToString","enabled":true},{"patternId":"naming_MethodWithSameNameAsEnclosingClass","enabled":true},{"patternId":"imports_UnusedImports","enabled":true},{"patternId":"basic_AvoidMultipleUnaryOperators","enabled":true},{"patternId":"junit_SimplifyBooleanAssertion","enabled":true},{"patternId":"braces_IfStmtsMustUseBraces","enabled":true},{"patternId":"naming_NoPackage","enabled":true},{"patternId":"unusedcode_UnusedFormalParameter","enabled":true},{"patternId":"empty_EmptyStatementNotInLoop","enabled":true},{"patternId":"naming_GenericsNaming","enabled":true},{"patternId":"strings_UseEqualsToCompareStrings","enabled":true},{"patternId":"empty_EmptyStaticInitializer","enabled":true},{"patternId":"empty_EmptyStatementBlock","enabled":true},{"patternId":"basic_CollapsibleIfStatements","enabled":true},{"patternId":"design_ImmutableField","enabled":true},{"patternId":"controversial_OneDeclarationPerLine","enabled":true},{"patternId":"unnecessary_UnnecessaryReturn","enabled":true},{"patternId":"codesize_NPathComplexity","enabled":true},{"patternId":"imports_DontImportJavaLang","enabled":true},{"patternId":"empty_EmptySynchronizedBlock","enabled":true},{"patternId":"unnecessary_UselessOperationOnImmutable","enabled":true},{"patternId":"design_PositionLiteralsFirstInComparisons","enabled":true},{"patternId":"junit_JUnitSpelling","enabled":true},{"patternId":"finalizers_EmptyFinalizer","enabled":true},{"patternId":"design_NonCaseLabelInSwitchStatement","enabled":true},{"patternId":"android_DoNotHardCodeSDCard","enabled":true},{"patternId":"design_LogicInversion","enabled":true},{"patternId":"unusedcode_UnusedPrivateMethod","enabled":true},{"patternId":"basic_CheckResultSet","enabled":true},{"patternId":"controversial_AvoidPrefixingMethodParameters","enabled":true},{"patternId":"empty_EmptyIfStmt","enabled":true},{"patternId":"basic_DontCallThreadRun","enabled":true},{"patternId":"junit_JUnitStaticSuite","enabled":true},{"patternId":"codesize_ExcessiveMethodLength","enabled":true},{"patternId":"design_MissingStaticMethodInNonInstantiatableClass","enabled":true},{"patternId":"Style_MethodName","enabled":true},{"patternId":"Metrics_CyclomaticComplexity","enabled":true},{"patternId":"Lint_DuplicateMethods","enabled":true},{"patternId":"Style_Lambda","enabled":true},{"patternId":"Lint_UselessSetterCall","enabled":true},{"patternId":"Style_VariableName","enabled":true},{"patternId":"Lint_AmbiguousOperator","enabled":true},{"patternId":"Style_LeadingCommentSpace","enabled":true},{"patternId":"Style_CaseEquality","enabled":true},{"patternId":"Lint_StringConversionInInterpolation","enabled":true},{"patternId":"Performance_ReverseEach","enabled":true},{"patternId":"Lint_LiteralInCondition","enabled":true},{"patternId":"Performance_Sample","enabled":true},{"patternId":"Style_NonNilCheck","enabled":true},{"patternId":"Lint_RescueException","enabled":true},{"patternId":"Lint_UselessElseWithoutRescue","enabled":true},{"patternId":"Style_ConstantName","enabled":true},{"patternId":"Lint_LiteralInInterpolation","enabled":true},{"patternId":"Lint_NestedMethodDefinition","enabled":true},{"patternId":"Style_DoubleNegation","enabled":true},{"patternId":"Lint_SpaceBeforeFirstArg","enabled":true},{"patternId":"Lint_Debugger","enabled":true},{"patternId":"Style_ClassVars","enabled":true},{"patternId":"Lint_EmptyEnsure","enabled":true},{"patternId":"Style_MultilineBlockLayout","enabled":true},{"patternId":"Lint_UnusedBlockArgument","enabled":true},{"patternId":"Lint_UselessAccessModifier","enabled":true},{"patternId":"Performance_Size","enabled":true},{"patternId":"Lint_EachWithObjectArgument","enabled":true},{"patternId":"Style_Alias","enabled":true},{"patternId":"Lint_Loop","enabled":true},{"patternId":"Style_NegatedWhile","enabled":true},{"patternId":"Style_ColonMethodCall","enabled":true},{"patternId":"Lint_AmbiguousRegexpLiteral","enabled":true},{"patternId":"Lint_UnusedMethodArgument","enabled":true},{"patternId":"Style_MultilineIfThen","enabled":true},{"patternId":"Lint_EnsureReturn","enabled":true},{"patternId":"Style_NegatedIf","enabled":true},{"patternId":"Lint_Eval","enabled":true},{"patternId":"Style_NilComparison","enabled":true},{"patternId":"Style_ArrayJoin","enabled":true},{"patternId":"Lint_ConditionPosition","enabled":true},{"patternId":"Lint_UnreachableCode","enabled":true},{"patternId":"Performance_Count","enabled":true},{"patternId":"Lint_EmptyInterpolation","enabled":true},{"patternId":"Style_LambdaCall","enabled":true},{"patternId":"Lint_HandleExceptions","enabled":true},{"patternId":"Lint_ShadowingOuterLocalVariable","enabled":true},{"patternId":"Lint_EndAlignment","enabled":true},{"patternId":"Style_MultilineTernaryOperator","enabled":true},{"patternId":"Style_AutoResourceCleanup","enabled":true},{"patternId":"Lint_ElseLayout","enabled":true},{"patternId":"Style_NestedTernaryOperator","enabled":true},{"patternId":"Style_OneLineConditional","enabled":true},{"patternId":"Style_EmptyElse","enabled":true},{"patternId":"Lint_UselessComparison","enabled":true},{"patternId":"Metrics_PerceivedComplexity","enabled":true},{"patternId":"Style_InfiniteLoop","enabled":true},{"patternId":"Rails_Date","enabled":true},{"patternId":"Style_EvenOdd","enabled":true},{"patternId":"Style_IndentationConsistency","enabled":true},{"patternId":"Style_ModuleFunction","enabled":true},{"patternId":"Lint_UselessAssignment","enabled":true},{"patternId":"Style_EachWithObject","enabled":true},{"patternId":"Performance_Detect","enabled":true},{"patternId":"duplicate_key","enabled":true},{"patternId":"no_interpolation_in_single_quotes","enabled":true},{"patternId":"no_backticks","enabled":true},{"patternId":"no_unnecessary_fat_arrows","enabled":true},{"patternId":"indentation","enabled":true},{"patternId":"ensure_comprehensions","enabled":true},{"patternId":"no_stand_alone_at","enabled":true},{"patternId":"cyclomatic_complexity","enabled":true},{"patternId":"Deserialize","enabled":true},{"patternId":"SymbolDoS","enabled":true},{"patternId":"SkipBeforeFilter","enabled":true},{"patternId":"SanitizeMethods","enabled":true},{"patternId":"SelectTag","enabled":true},{"patternId":"XMLDoS","enabled":true},{"patternId":"SimpleFormat","enabled":true},{"patternId":"Evaluation","enabled":true},{"patternId":"BasicAuth","enabled":true},{"patternId":"JRubyXML","enabled":true},{"patternId":"RenderInline","enabled":true},{"patternId":"YAMLParsing","enabled":true},{"patternId":"Redirect","enabled":true},{"patternId":"UnsafeReflection","enabled":true},{"patternId":"SSLVerify","enabled":true},{"patternId":"HeaderDoS","enabled":true},{"patternId":"TranslateBug","enabled":true},{"patternId":"Execute","enabled":true},{"patternId":"JSONParsing","enabled":true},{"patternId":"LinkTo","enabled":true},{"patternId":"FileDisclosure","enabled":true},{"patternId":"SafeBufferManipulation","enabled":true},{"patternId":"ModelAttributes","enabled":true},{"patternId":"ResponseSplitting","enabled":true},{"patternId":"DigestDoS","enabled":true},{"patternId":"Send","enabled":true},{"patternId":"MailTo","enabled":true},{"patternId":"SymbolDoSCVE","enabled":true},{"patternId":"StripTags","enabled":true},{"patternId":"MassAssignment","enabled":true},{"patternId":"RegexDoS","enabled":true},{"patternId":"SelectVulnerability","enabled":true},{"patternId":"FileAccess","enabled":true},{"patternId":"ContentTag","enabled":true},{"patternId":"SessionSettings","enabled":true},{"patternId":"FilterSkipping","enabled":true},{"patternId":"CreateWith","enabled":true},{"patternId":"JSONEncoding","enabled":true},{"patternId":"SQLCVEs","enabled":true},{"patternId":"ForgerySetting","enabled":true},{"patternId":"QuoteTableName","enabled":true},{"patternId":"I18nXSS","enabled":true},{"patternId":"WithoutProtection","enabled":true},{"patternId":"CrossSiteScripting","enabled":true},{"patternId":"SingleQuotes","enabled":true},{"patternId":"NestedAttributes","enabled":true},{"patternId":"DetailedExceptions","enabled":true},{"patternId":"LinkToHref","enabled":true},{"patternId":"RenderDoS","enabled":true},{"patternId":"ModelSerialize","enabled":true},{"patternId":"SQL","enabled":true},{"patternId":"Render","enabled":true},{"patternId":"UnscopedFind","enabled":true},{"patternId":"ValidationRegex","enabled":true},{"patternId":"EscapeFunction","enabled":true},{"patternId":"Custom_Scala_FieldNamesChecker","enabled":true},{"patternId":"Custom_Scala_ObjDeserialization","enabled":true},{"patternId":"Custom_Scala_RSAPadding","enabled":true},{"patternId":"ESLint_no-extra-boolean-cast","enabled":true},{"patternId":"ESLint_no-iterator","enabled":true},{"patternId":"ESLint_no-invalid-regexp","enabled":true},{"patternId":"ESLint_no-obj-calls","enabled":true},{"patternId":"ESLint_no-sparse-arrays","enabled":true},{"patternId":"ESLint_no-unreachable","enabled":true},{"patternId":"ESLint_no-dupe-keys","enabled":true},{"patternId":"ESLint_no-multi-str","enabled":true},{"patternId":"ESLint_no-extend-native","enabled":true},{"patternId":"ESLint_guard-for-in","enabled":true},{"patternId":"ESLint_no-func-assign","enabled":true},{"patternId":"ESLint_no-extra-semi","enabled":true},{"patternId":"ESLint_camelcase","enabled":true},{"patternId":"ESLint_no-mixed-spaces-and-tabs","enabled":true},{"patternId":"ESLint_no-undef","enabled":true},{"patternId":"ESLint_semi","enabled":true},{"patternId":"ESLint_no-empty-character-class","enabled":true},{"patternId":"ESLint_complexity","enabled":true},{"patternId":"ESLint_no-dupe-class-members","enabled":true},{"patternId":"ESLint_no-debugger","enabled":true},{"patternId":"ESLint_block-scoped-var","enabled":true},{"patternId":"ESLint_no-loop-func","enabled":true},{"patternId":"ESLint_no-use-before-define","enabled":true},{"patternId":"ESLint_no-console","enabled":true},{"patternId":"ESLint_require-yield","enabled":true},{"patternId":"ESLint_no-redeclare","enabled":true},{"patternId":"ESLint_no-undefined","enabled":true},{"patternId":"ESLint_use-isnan","enabled":true},{"patternId":"ESLint_no-control-regex","enabled":true},{"patternId":"ESLint_no-const-assign","enabled":true},{"patternId":"ESLint_no-new","enabled":true},{"patternId":"ESLint_new-cap","enabled":true},{"patternId":"ESLint_no-irregular-whitespace","enabled":true},{"patternId":"ESLint_object-shorthand","enabled":true},{"patternId":"ESLint_no-ex-assign","enabled":true},{"patternId":"ESLint_wrap-iife","enabled":true},{"patternId":"ESLint_arrow-parens","enabled":true},{"patternId":"ESLint_no-constant-condition","enabled":true},{"patternId":"ESLint_no-octal","enabled":true},{"patternId":"ESLint_no-dupe-args","enabled":true},{"patternId":"ESLint_quotes","enabled":true},{"patternId":"ESLint_no-fallthrough","enabled":true},{"patternId":"ESLint_no-delete-var","enabled":true},{"patternId":"ESLint_no-caller","enabled":true},{"patternId":"ESLint_no-cond-assign","enabled":true},{"patternId":"ESLint_no-this-before-super","enabled":true},{"patternId":"ESLint_no-negated-in-lhs","enabled":true},{"patternId":"ESLint_no-inner-declarations","enabled":true},{"patternId":"ESLint_eqeqeq","enabled":true},{"patternId":"ESLint_curly","enabled":true},{"patternId":"ESLint_arrow-spacing","enabled":true},{"patternId":"ESLint_no-empty","enabled":true},{"patternId":"ESLint_no-unused-vars","enabled":true},{"patternId":"ESLint_generator-star-spacing","enabled":true},{"patternId":"ESLint_no-duplicate-case","enabled":true},{"patternId":"ESLint_valid-typeof","enabled":true},{"patternId":"ESLint_no-regex-spaces","enabled":true},{"patternId":"ESLint_no-class-assign","enabled":true},{"patternId":"PyLint_W0221","enabled":true},{"patternId":"PyLint_E0117","enabled":true},{"patternId":"PyLint_E0001","enabled":true},{"patternId":"PyLint_E0241","enabled":true},{"patternId":"PyLint_W0404","enabled":true},{"patternId":"PyLint_E0704","enabled":true},{"patternId":"PyLint_E0703","enabled":true},{"patternId":"PyLint_E0302","enabled":true},{"patternId":"PyLint_W1301","enabled":true},{"patternId":"PyLint_R0201","enabled":true},{"patternId":"PyLint_E0113","enabled":true},{"patternId":"PyLint_W0410","enabled":true},{"patternId":"PyLint_C0123","enabled":true},{"patternId":"PyLint_E0115","enabled":true},{"patternId":"PyLint_E0114","enabled":true},{"patternId":"PyLint_E1126","enabled":true},{"patternId":"PyLint_W0702","enabled":true},{"patternId":"PyLint_W1303","enabled":true},{"patternId":"PyLint_W0622","enabled":true},{"patternId":"PyLint_W0222","enabled":true},{"patternId":"PyLint_W0233","enabled":true},{"patternId":"PyLint_W1305","enabled":true},{"patternId":"PyLint_E1127","enabled":true},{"patternId":"PyLint_E0112","enabled":true},{"patternId":"PyLint_W0611","enabled":true},{"patternId":"PyLint_W0601","enabled":true},{"patternId":"PyLint_W1300","enabled":true},{"patternId":"PyLint_W0124","enabled":true},{"patternId":"PyLint_R0203","enabled":true},{"patternId":"PyLint_E0236","enabled":true},{"patternId":"PyLint_W0612","enabled":true},{"patternId":"PyLint_W0604","enabled":true},{"patternId":"PyLint_W0705","enabled":true},{"patternId":"PyLint_E0238","enabled":true},{"patternId":"PyLint_W0602","enabled":true},{"patternId":"PyLint_R0102","enabled":true},{"patternId":"PyLint_R0202","enabled":true},{"patternId":"PyLint_E0240","enabled":true},{"patternId":"PyLint_W0623","enabled":true},{"patternId":"PyLint_W0711","enabled":true},{"patternId":"PyLint_E0116","enabled":true},{"patternId":"PyLint_E0239","enabled":true},{"patternId":"PyLint_E1132","enabled":true},{"patternId":"PyLint_W1307","enabled":true},{"patternId":"PyLint_C0200","enabled":true},{"patternId":"PyLint_E0301","enabled":true},{"patternId":"PyLint_W1306","enabled":true},{"patternId":"PyLint_W1302","enabled":true},{"patternId":"PyLint_E0110","enabled":true},{"patternId":"PyLint_E1125","enabled":true}]} \ No newline at end of file +{"patterns":[{"patternId":"Custom_Javascript_Scopes","enabled":true},{"patternId":"Custom_Javascript_EvalWith","enabled":true},{"patternId":"Custom_Javascript_TryCatch","enabled":true},{"patternId":"Custom_Scala_NonFatal","enabled":true},{"patternId":"bitwise","enabled":true},{"patternId":"maxparams","enabled":true},{"patternId":"CSSLint_universal_selector","enabled":true},{"patternId":"CSSLint_unqualified_attributes","enabled":true},{"patternId":"CSSLint_zero_units","enabled":true},{"patternId":"CSSLint_overqualified_elements","enabled":true},{"patternId":"CSSLint_shorthand","enabled":true},{"patternId":"CSSLint_duplicate_background_images","enabled":true},{"patternId":"CSSLint_box_model","enabled":true},{"patternId":"CSSLint_compatible_vendor_prefixes","enabled":true},{"patternId":"CSSLint_display_property_grouping","enabled":true},{"patternId":"CSSLint_duplicate_properties","enabled":true},{"patternId":"CSSLint_empty_rules","enabled":true},{"patternId":"CSSLint_errors","enabled":true},{"patternId":"CSSLint_gradients","enabled":true},{"patternId":"CSSLint_important","enabled":true},{"patternId":"CSSLint_known_properties","enabled":true},{"patternId":"CSSLint_text_indent","enabled":true},{"patternId":"CSSLint_unique_headings","enabled":true},{"patternId":"PyLint_E0100","enabled":true},{"patternId":"PyLint_E0101","enabled":true},{"patternId":"PyLint_E0102","enabled":true},{"patternId":"PyLint_E0103","enabled":true},{"patternId":"PyLint_E0104","enabled":true},{"patternId":"PyLint_E0105","enabled":true},{"patternId":"PyLint_E0106","enabled":true},{"patternId":"PyLint_E0107","enabled":true},{"patternId":"PyLint_E0108","enabled":true},{"patternId":"PyLint_E0202","enabled":true},{"patternId":"PyLint_E0203","enabled":true},{"patternId":"PyLint_E0211","enabled":true},{"patternId":"PyLint_E0601","enabled":true},{"patternId":"PyLint_E0603","enabled":true},{"patternId":"PyLint_E0604","enabled":true},{"patternId":"PyLint_E0701","enabled":true},{"patternId":"PyLint_E0702","enabled":true},{"patternId":"PyLint_E0710","enabled":true},{"patternId":"PyLint_E0711","enabled":true},{"patternId":"PyLint_E0712","enabled":true},{"patternId":"PyLint_E1003","enabled":true},{"patternId":"PyLint_E1102","enabled":true},{"patternId":"PyLint_E1111","enabled":true},{"patternId":"PyLint_E1120","enabled":true},{"patternId":"PyLint_E1121","enabled":true},{"patternId":"PyLint_E1123","enabled":true},{"patternId":"PyLint_E1124","enabled":true},{"patternId":"PyLint_E1200","enabled":true},{"patternId":"PyLint_E1201","enabled":true},{"patternId":"PyLint_E1205","enabled":true},{"patternId":"PyLint_E1206","enabled":true},{"patternId":"PyLint_E1300","enabled":true},{"patternId":"PyLint_E1301","enabled":true},{"patternId":"PyLint_E1302","enabled":true},{"patternId":"PyLint_E1303","enabled":true},{"patternId":"PyLint_E1304","enabled":true},{"patternId":"PyLint_E1305","enabled":true},{"patternId":"PyLint_E1306","enabled":true},{"patternId":"rulesets-codesize.xml-CyclomaticComplexity","enabled":true},{"patternId":"rulesets-codesize.xml-NPathComplexity","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessiveMethodLength","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessiveClassLength","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessiveParameterList","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessivePublicCount","enabled":true},{"patternId":"rulesets-codesize.xml-TooManyFields","enabled":true},{"patternId":"rulesets-codesize.xml-TooManyMethods","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessiveClassComplexity","enabled":true},{"patternId":"rulesets-controversial.xml-Superglobals","enabled":true},{"patternId":"rulesets-design.xml-ExitExpression","enabled":true},{"patternId":"rulesets-design.xml-EvalExpression","enabled":true},{"patternId":"rulesets-design.xml-GotoStatement","enabled":true},{"patternId":"rulesets-design.xml-NumberOfChildren","enabled":true},{"patternId":"rulesets-design.xml-DepthOfInheritance","enabled":true},{"patternId":"rulesets-unusedcode.xml-UnusedPrivateField","enabled":true},{"patternId":"rulesets-unusedcode.xml-UnusedLocalVariable","enabled":true},{"patternId":"rulesets-unusedcode.xml-UnusedPrivateMethod","enabled":true},{"patternId":"rulesets-unusedcode.xml-UnusedFormalParameter","enabled":true},{"patternId":"PyLint_C0303","enabled":true},{"patternId":"PyLint_C1001","enabled":true},{"patternId":"rulesets-naming.xml-ShortVariable","enabled":true},{"patternId":"rulesets-naming.xml-LongVariable","enabled":true},{"patternId":"rulesets-naming.xml-ShortMethodName","enabled":true},{"patternId":"rulesets-naming.xml-ConstantNamingConventions","enabled":true},{"patternId":"rulesets-naming.xml-BooleanGetMethodName","enabled":true},{"patternId":"PyLint_W0101","enabled":true},{"patternId":"PyLint_W0102","enabled":true},{"patternId":"PyLint_W0104","enabled":true},{"patternId":"PyLint_W0105","enabled":true},{"patternId":"Custom_Scala_GetCalls","enabled":true},{"patternId":"ScalaStyle_EqualsHashCodeChecker","enabled":true},{"patternId":"ScalaStyle_ParameterNumberChecker","enabled":true},{"patternId":"ScalaStyle_ReturnChecker","enabled":true},{"patternId":"ScalaStyle_NullChecker","enabled":true},{"patternId":"ScalaStyle_NoCloneChecker","enabled":true},{"patternId":"ScalaStyle_NoFinalizeChecker","enabled":true},{"patternId":"ScalaStyle_CovariantEqualsChecker","enabled":true},{"patternId":"ScalaStyle_StructuralTypeChecker","enabled":true},{"patternId":"ScalaStyle_MethodLengthChecker","enabled":true},{"patternId":"ScalaStyle_NumberOfMethodsInTypeChecker","enabled":true},{"patternId":"ScalaStyle_WhileChecker","enabled":true},{"patternId":"ScalaStyle_VarFieldChecker","enabled":true},{"patternId":"ScalaStyle_VarLocalChecker","enabled":true},{"patternId":"ScalaStyle_RedundantIfChecker","enabled":true},{"patternId":"ScalaStyle_DeprecatedJavaChecker","enabled":true},{"patternId":"ScalaStyle_EmptyClassChecker","enabled":true},{"patternId":"ScalaStyle_NotImplementedErrorUsage","enabled":true},{"patternId":"Custom_Scala_GroupImports","enabled":true},{"patternId":"Custom_Scala_ReservedKeywords","enabled":true},{"patternId":"Custom_Scala_ElseIf","enabled":true},{"patternId":"Custom_Scala_CallByNameAsLastArguments","enabled":true},{"patternId":"Custom_Scala_WildcardImportOnMany","enabled":true},{"patternId":"Custom_Scala_UtilTryForTryCatch","enabled":true},{"patternId":"Custom_Scala_ProhibitObjectName","enabled":true},{"patternId":"Custom_Scala_ImportsAtBeginningOfPackage","enabled":true},{"patternId":"Custom_Scala_NameResultsAndParameters","enabled":true},{"patternId":"Custom_Scala_IncompletePatternMatching","enabled":true},{"patternId":"Custom_Scala_UsefulTypeAlias","enabled":true},{"patternId":"Custom_Scala_JavaThreads","enabled":true},{"patternId":"Custom_Scala_DirectPromiseCreation","enabled":true},{"patternId":"Custom_Scala_StructuralTypes","enabled":true},{"patternId":"Custom_Scala_CollectionLastHead","enabled":true},{"patternId":"PyLint_W0106","enabled":true},{"patternId":"PyLint_W0107","enabled":true},{"patternId":"PyLint_W0108","enabled":true},{"patternId":"PyLint_W0109","enabled":true},{"patternId":"PyLint_W0110","enabled":true},{"patternId":"PyLint_W0120","enabled":true},{"patternId":"PyLint_W0122","enabled":true},{"patternId":"PyLint_W0150","enabled":true},{"patternId":"PyLint_W0199","enabled":true},{"patternId":"rulesets-cleancode.xml-ElseExpression","enabled":true},{"patternId":"rulesets-cleancode.xml-StaticAccess","enabled":true},{"patternId":"ScalaStyle_NonASCIICharacterChecker","enabled":true},{"patternId":"ScalaStyle_FieldNamesChecker","enabled":true},{"patternId":"Custom_Scala_WithNameCalls","enabled":true},{"patternId":"strictexception_AvoidRethrowingException","enabled":true},{"patternId":"strings_AppendCharacterWithChar","enabled":true},{"patternId":"braces_IfElseStmtsMustUseBraces","enabled":true},{"patternId":"basic_AvoidDecimalLiteralsInBigDecimalConstructor","enabled":true},{"patternId":"basic_CheckSkipResult","enabled":true},{"patternId":"javabeans_MissingSerialVersionUID","enabled":true},{"patternId":"migrating_ShortInstantiation","enabled":true},{"patternId":"design_AvoidInstanceofChecksInCatchClause","enabled":true},{"patternId":"naming_LongVariable","enabled":true},{"patternId":"migrating_ReplaceEnumerationWithIterator","enabled":true},{"patternId":"j2ee_DoNotCallSystemExit","enabled":true},{"patternId":"unusedcode_UnusedLocalVariable","enabled":true},{"patternId":"strings_InefficientStringBuffering","enabled":true},{"patternId":"basic_DontUseFloatTypeForLoopIndices","enabled":true},{"patternId":"basic_AvoidBranchingStatementAsLastInLoop","enabled":true},{"patternId":"migrating_JUnit4TestShouldUseTestAnnotation","enabled":true},{"patternId":"optimizations_AddEmptyString","enabled":true},{"patternId":"logging-jakarta-commons_ProperLogger","enabled":true},{"patternId":"optimizations_RedundantFieldInitializer","enabled":true},{"patternId":"logging-java_AvoidPrintStackTrace","enabled":true},{"patternId":"empty_EmptyFinallyBlock","enabled":true},{"patternId":"design_CompareObjectsWithEquals","enabled":true},{"patternId":"basic_ClassCastExceptionWithToArray","enabled":true},{"patternId":"strictexception_DoNotExtendJavaLangError","enabled":true},{"patternId":"junit_UnnecessaryBooleanAssertion","enabled":true},{"patternId":"design_SimplifyBooleanExpressions","enabled":true},{"patternId":"basic_ForLoopShouldBeWhileLoop","enabled":true},{"patternId":"basic_BigIntegerInstantiation","enabled":true},{"patternId":"optimizations_UseArrayListInsteadOfVector","enabled":true},{"patternId":"optimizations_UnnecessaryWrapperObjectCreation","enabled":true},{"patternId":"strings_StringBufferInstantiationWithChar","enabled":true},{"patternId":"basic_JumbledIncrementer","enabled":true},{"patternId":"design_SwitchStmtsShouldHaveDefault","enabled":true},{"patternId":"strictexception_AvoidThrowingRawExceptionTypes","enabled":true},{"patternId":"migrating_LongInstantiation","enabled":true},{"patternId":"design_SimplifyBooleanReturns","enabled":true},{"patternId":"empty_EmptyInitializer","enabled":true},{"patternId":"design_FieldDeclarationsShouldBeAtStartOfClass","enabled":true},{"patternId":"unnecessary_UnnecessaryConversionTemporary","enabled":true},{"patternId":"design_AvoidProtectedFieldInFinalClass","enabled":true},{"patternId":"junit_UseAssertTrueInsteadOfAssertEquals","enabled":true},{"patternId":"naming_PackageCase","enabled":true},{"patternId":"migrating_JUnitUseExpected","enabled":true},{"patternId":"controversial_UnnecessaryConstructor","enabled":true},{"patternId":"naming_MethodNamingConventions","enabled":true},{"patternId":"design_DefaultLabelNotLastInSwitchStmt","enabled":true},{"patternId":"basic_UnconditionalIfStatement","enabled":true},{"patternId":"design_SingularField","enabled":true},{"patternId":"design_AssignmentToNonFinalStatic","enabled":true},{"patternId":"braces_WhileLoopsMustUseBraces","enabled":true},{"patternId":"logging-java_SystemPrintln","enabled":true},{"patternId":"strings_UseStringBufferLength","enabled":true},{"patternId":"controversial_AvoidUsingNativeCode","enabled":true},{"patternId":"strictexception_AvoidLosingExceptionInformation","enabled":true},{"patternId":"imports_ImportFromSamePackage","enabled":true},{"patternId":"finalizers_AvoidCallingFinalize","enabled":true},{"patternId":"finalizers_FinalizeOverloaded","enabled":true},{"patternId":"naming_ClassNamingConventions","enabled":true},{"patternId":"logging-java_LoggerIsNotStaticFinal","enabled":true},{"patternId":"finalizers_FinalizeOnlyCallsSuperFinalize","enabled":true},{"patternId":"unnecessary_UselessOverridingMethod","enabled":true},{"patternId":"naming_SuspiciousConstantFieldName","enabled":true},{"patternId":"design_OptimizableToArrayCall","enabled":true},{"patternId":"imports_UnnecessaryFullyQualifiedName","enabled":true},{"patternId":"migrating_ReplaceHashtableWithMap","enabled":true},{"patternId":"unusedcode_UnusedPrivateField","enabled":true},{"patternId":"strings_UnnecessaryCaseChange","enabled":true},{"patternId":"migrating_IntegerInstantiation","enabled":true},{"patternId":"design_NonStaticInitializer","enabled":true},{"patternId":"design_MissingBreakInSwitch","enabled":true},{"patternId":"design_AvoidReassigningParameters","enabled":true},{"patternId":"basic_AvoidThreadGroup","enabled":true},{"patternId":"empty_EmptyCatchBlock","parameters":{"allowCommentedBlocks":"true"},"enabled":true},{"patternId":"codesize_ExcessiveParameterList","parameters":{"minimum":"8","violationSuppressRegex":"\"\"","violationSuppressXPath":"\"\""},"enabled":true},{"patternId":"naming_SuspiciousHashcodeMethodName","enabled":true},{"patternId":"migrating_JUnit4TestShouldUseBeforeAnnotation","enabled":true},{"patternId":"design_UncommentedEmptyMethodBody","enabled":true},{"patternId":"basic_BrokenNullCheck","enabled":true},{"patternId":"strings_ConsecutiveLiteralAppends","enabled":true},{"patternId":"strings_StringInstantiation","enabled":true},{"patternId":"design_EqualsNull","enabled":true},{"patternId":"basic_OverrideBothEqualsAndHashcode","enabled":true},{"patternId":"design_InstantiationToGetClass","enabled":true},{"patternId":"basic_BooleanInstantiation","enabled":true},{"patternId":"strings_AvoidStringBufferField","enabled":true},{"patternId":"basic_ReturnFromFinallyBlock","enabled":true},{"patternId":"empty_EmptyTryBlock","enabled":true},{"patternId":"naming_SuspiciousEqualsMethodName","enabled":true},{"patternId":"basic_ExtendsObject","enabled":true},{"patternId":"strings_UselessStringValueOf","enabled":true},{"patternId":"design_UnsynchronizedStaticDateFormatter","enabled":true},{"patternId":"design_UseCollectionIsEmpty","enabled":true},{"patternId":"controversial_AvoidFinalLocalVariable","enabled":true},{"patternId":"strictexception_AvoidThrowingNullPointerException","enabled":true},{"patternId":"design_AvoidProtectedMethodInFinalClassNotExtending","enabled":true},{"patternId":"optimizations_PrematureDeclaration","enabled":true},{"patternId":"empty_EmptySwitchStatements","enabled":true},{"patternId":"basic_MisplacedNullCheck","enabled":true},{"patternId":"optimizations_UseStringBufferForStringAppends","enabled":true},{"patternId":"strings_StringToString","enabled":true},{"patternId":"naming_MethodWithSameNameAsEnclosingClass","enabled":true},{"patternId":"migrating_ReplaceVectorWithList","enabled":true},{"patternId":"imports_UnusedImports","enabled":true},{"patternId":"unnecessary_UnnecessaryFinalModifier","enabled":true},{"patternId":"basic_AvoidMultipleUnaryOperators","enabled":true},{"patternId":"junit_SimplifyBooleanAssertion","enabled":true},{"patternId":"unnecessary_UselessParentheses","enabled":true},{"patternId":"design_IdempotentOperations","enabled":true},{"patternId":"braces_IfStmtsMustUseBraces","enabled":true},{"patternId":"strings_UseIndexOfChar","enabled":true},{"patternId":"naming_NoPackage","enabled":true},{"patternId":"finalizers_FinalizeDoesNotCallSuperFinalize","enabled":true},{"patternId":"design_UseVarargs","enabled":true},{"patternId":"unusedcode_UnusedFormalParameter","enabled":true},{"patternId":"design_ReturnEmptyArrayRatherThanNull","enabled":true},{"patternId":"junit_UseAssertNullInsteadOfAssertTrue","enabled":true},{"patternId":"design_UseUtilityClass","enabled":true},{"patternId":"design_AvoidDeeplyNestedIfStmts","enabled":true},{"patternId":"empty_EmptyStatementNotInLoop","enabled":true},{"patternId":"junit_UseAssertSameInsteadOfAssertTrue","enabled":true},{"patternId":"braces_ForLoopsMustUseBraces","enabled":true},{"patternId":"controversial_DoNotCallGarbageCollectionExplicitly","enabled":true},{"patternId":"naming_GenericsNaming","enabled":true},{"patternId":"strings_UseEqualsToCompareStrings","enabled":true},{"patternId":"optimizations_AvoidArrayLoops","enabled":true},{"patternId":"empty_EmptyStaticInitializer","enabled":true},{"patternId":"design_UncommentedEmptyConstructor","enabled":true},{"patternId":"empty_EmptyStatementBlock","enabled":true},{"patternId":"basic_CollapsibleIfStatements","enabled":true},{"patternId":"design_FinalFieldCouldBeStatic","enabled":true},{"patternId":"logging-java_MoreThanOneLogger","enabled":true},{"patternId":"codesize_ExcessiveClassLength","enabled":true},{"patternId":"design_ImmutableField","enabled":true},{"patternId":"controversial_OneDeclarationPerLine","enabled":true},{"patternId":"empty_EmptyWhileStmt","enabled":true},{"patternId":"unnecessary_UnnecessaryReturn","enabled":true},{"patternId":"strings_InefficientEmptyStringCheck","enabled":true},{"patternId":"design_UseNotifyAllInsteadOfNotify","enabled":true},{"patternId":"strictexception_DoNotThrowExceptionInFinally","enabled":true},{"patternId":"junit_UseAssertEqualsInsteadOfAssertTrue","enabled":true},{"patternId":"typeresolution_CloneMethodMustImplementCloneable","enabled":true},{"patternId":"codesize_NPathComplexity","enabled":true},{"patternId":"imports_DontImportJavaLang","enabled":true},{"patternId":"empty_EmptySynchronizedBlock","enabled":true},{"patternId":"migrating_JUnit4TestShouldUseAfterAnnotation","enabled":true},{"patternId":"design_AvoidConstantsInterface","enabled":true},{"patternId":"unnecessary_UselessOperationOnImmutable","enabled":true},{"patternId":"design_PositionLiteralsFirstInComparisons","enabled":true},{"patternId":"migrating_ByteInstantiation","enabled":true},{"patternId":"junit_JUnitSpelling","enabled":true},{"patternId":"junit_JUnitTestsShouldIncludeAssert","enabled":true},{"patternId":"finalizers_EmptyFinalizer","enabled":true},{"patternId":"design_NonCaseLabelInSwitchStatement","enabled":true},{"patternId":"android_DoNotHardCodeSDCard","enabled":true},{"patternId":"design_LogicInversion","enabled":true},{"patternId":"unusedcode_UnusedPrivateMethod","enabled":true},{"patternId":"naming_AvoidDollarSigns","enabled":true},{"patternId":"finalizers_FinalizeShouldBeProtected","enabled":true},{"patternId":"clone_ProperCloneImplementation","enabled":true},{"patternId":"basic_CheckResultSet","enabled":true},{"patternId":"controversial_AvoidPrefixingMethodParameters","enabled":true},{"patternId":"migrating_JUnit4SuitesShouldUseSuiteAnnotation","enabled":true},{"patternId":"empty_EmptyIfStmt","enabled":true},{"patternId":"basic_DontCallThreadRun","enabled":true},{"patternId":"junit_JUnitStaticSuite","enabled":true},{"patternId":"optimizations_UseArraysAsList","enabled":true},{"patternId":"design_MissingStaticMethodInNonInstantiatableClass","enabled":true},{"patternId":"unusedcode_UnusedModifier","enabled":true},{"patternId":"Style_MethodName","enabled":true},{"patternId":"Metrics_CyclomaticComplexity","enabled":true},{"patternId":"Lint_DuplicateMethods","enabled":true},{"patternId":"Style_Lambda","enabled":true},{"patternId":"Lint_UselessSetterCall","enabled":true},{"patternId":"Style_VariableName","enabled":true},{"patternId":"Lint_AmbiguousOperator","enabled":true},{"patternId":"Style_LeadingCommentSpace","enabled":true},{"patternId":"Style_CaseEquality","enabled":true},{"patternId":"Lint_StringConversionInInterpolation","enabled":true},{"patternId":"Performance_ReverseEach","enabled":true},{"patternId":"Lint_LiteralInCondition","enabled":true},{"patternId":"Performance_Sample","enabled":true},{"patternId":"Style_NonNilCheck","enabled":true},{"patternId":"Lint_RescueException","enabled":true},{"patternId":"Lint_UselessElseWithoutRescue","enabled":true},{"patternId":"Style_ConstantName","enabled":true},{"patternId":"Lint_LiteralInInterpolation","enabled":true},{"patternId":"Lint_NestedMethodDefinition","enabled":true},{"patternId":"Style_DoubleNegation","enabled":true},{"patternId":"Lint_SpaceBeforeFirstArg","enabled":true},{"patternId":"Lint_Debugger","enabled":true},{"patternId":"Style_ClassVars","enabled":true},{"patternId":"Lint_EmptyEnsure","enabled":true},{"patternId":"Style_MultilineBlockLayout","enabled":true},{"patternId":"Lint_UnusedBlockArgument","enabled":true},{"patternId":"Lint_UselessAccessModifier","enabled":true},{"patternId":"Performance_Size","enabled":true},{"patternId":"Lint_EachWithObjectArgument","enabled":true},{"patternId":"Style_Alias","enabled":true},{"patternId":"Lint_Loop","enabled":true},{"patternId":"Style_NegatedWhile","enabled":true},{"patternId":"Style_ColonMethodCall","enabled":true},{"patternId":"Lint_AmbiguousRegexpLiteral","enabled":true},{"patternId":"Lint_UnusedMethodArgument","enabled":true},{"patternId":"Style_MultilineIfThen","enabled":true},{"patternId":"Lint_EnsureReturn","enabled":true},{"patternId":"Style_NegatedIf","enabled":true},{"patternId":"Lint_Eval","enabled":true},{"patternId":"Style_NilComparison","enabled":true},{"patternId":"Style_ArrayJoin","enabled":true},{"patternId":"Lint_ConditionPosition","enabled":true},{"patternId":"Lint_UnreachableCode","enabled":true},{"patternId":"Performance_Count","enabled":true},{"patternId":"Lint_EmptyInterpolation","enabled":true},{"patternId":"Style_LambdaCall","enabled":true},{"patternId":"Lint_HandleExceptions","enabled":true},{"patternId":"Lint_ShadowingOuterLocalVariable","enabled":true},{"patternId":"Lint_EndAlignment","enabled":true},{"patternId":"Style_MultilineTernaryOperator","enabled":true},{"patternId":"Style_AutoResourceCleanup","enabled":true},{"patternId":"Lint_ElseLayout","enabled":true},{"patternId":"Style_NestedTernaryOperator","enabled":true},{"patternId":"Style_OneLineConditional","enabled":true},{"patternId":"Style_EmptyElse","enabled":true},{"patternId":"Lint_UselessComparison","enabled":true},{"patternId":"Metrics_PerceivedComplexity","enabled":true},{"patternId":"Style_InfiniteLoop","enabled":true},{"patternId":"Rails_Date","enabled":true},{"patternId":"Style_EvenOdd","enabled":true},{"patternId":"Style_IndentationConsistency","enabled":true},{"patternId":"Style_ModuleFunction","enabled":true},{"patternId":"Lint_UselessAssignment","enabled":true},{"patternId":"Style_EachWithObject","enabled":true},{"patternId":"Performance_Detect","enabled":true},{"patternId":"duplicate_key","enabled":true},{"patternId":"no_interpolation_in_single_quotes","enabled":true},{"patternId":"no_backticks","enabled":true},{"patternId":"no_unnecessary_fat_arrows","enabled":true},{"patternId":"indentation","enabled":true},{"patternId":"ensure_comprehensions","enabled":true},{"patternId":"no_stand_alone_at","enabled":true},{"patternId":"cyclomatic_complexity","enabled":true},{"patternId":"Deserialize","enabled":true},{"patternId":"SymbolDoS","enabled":true},{"patternId":"SkipBeforeFilter","enabled":true},{"patternId":"SanitizeMethods","enabled":true},{"patternId":"SelectTag","enabled":true},{"patternId":"XMLDoS","enabled":true},{"patternId":"SimpleFormat","enabled":true},{"patternId":"Evaluation","enabled":true},{"patternId":"BasicAuth","enabled":true},{"patternId":"JRubyXML","enabled":true},{"patternId":"RenderInline","enabled":true},{"patternId":"YAMLParsing","enabled":true},{"patternId":"Redirect","enabled":true},{"patternId":"UnsafeReflection","enabled":true},{"patternId":"SSLVerify","enabled":true},{"patternId":"HeaderDoS","enabled":true},{"patternId":"TranslateBug","enabled":true},{"patternId":"Execute","enabled":true},{"patternId":"JSONParsing","enabled":true},{"patternId":"LinkTo","enabled":true},{"patternId":"FileDisclosure","enabled":true},{"patternId":"SafeBufferManipulation","enabled":true},{"patternId":"ModelAttributes","enabled":true},{"patternId":"ResponseSplitting","enabled":true},{"patternId":"DigestDoS","enabled":true},{"patternId":"Send","enabled":true},{"patternId":"MailTo","enabled":true},{"patternId":"SymbolDoSCVE","enabled":true},{"patternId":"StripTags","enabled":true},{"patternId":"MassAssignment","enabled":true},{"patternId":"RegexDoS","enabled":true},{"patternId":"SelectVulnerability","enabled":true},{"patternId":"FileAccess","enabled":true},{"patternId":"ContentTag","enabled":true},{"patternId":"SessionSettings","enabled":true},{"patternId":"FilterSkipping","enabled":true},{"patternId":"CreateWith","enabled":true},{"patternId":"JSONEncoding","enabled":true},{"patternId":"SQLCVEs","enabled":true},{"patternId":"ForgerySetting","enabled":true},{"patternId":"QuoteTableName","enabled":true},{"patternId":"I18nXSS","enabled":true},{"patternId":"WithoutProtection","enabled":true},{"patternId":"CrossSiteScripting","enabled":true},{"patternId":"SingleQuotes","enabled":true},{"patternId":"NestedAttributes","enabled":true},{"patternId":"DetailedExceptions","enabled":true},{"patternId":"LinkToHref","enabled":true},{"patternId":"RenderDoS","enabled":true},{"patternId":"ModelSerialize","enabled":true},{"patternId":"SQL","enabled":true},{"patternId":"Render","enabled":true},{"patternId":"UnscopedFind","enabled":true},{"patternId":"ValidationRegex","enabled":true},{"patternId":"EscapeFunction","enabled":true},{"patternId":"Custom_Scala_FieldNamesChecker","enabled":true},{"patternId":"Custom_Scala_ObjDeserialization","enabled":true},{"patternId":"Custom_Scala_RSAPadding","enabled":true},{"patternId":"ESLint_no-extra-boolean-cast","enabled":true},{"patternId":"ESLint_no-iterator","enabled":true},{"patternId":"ESLint_no-invalid-regexp","enabled":true},{"patternId":"ESLint_no-obj-calls","enabled":true},{"patternId":"ESLint_no-sparse-arrays","enabled":true},{"patternId":"ESLint_no-unreachable","enabled":true},{"patternId":"ESLint_no-dupe-keys","enabled":true},{"patternId":"ESLint_no-multi-str","enabled":true},{"patternId":"ESLint_no-extend-native","enabled":true},{"patternId":"ESLint_guard-for-in","enabled":true},{"patternId":"ESLint_no-func-assign","enabled":true},{"patternId":"ESLint_no-extra-semi","enabled":true},{"patternId":"ESLint_camelcase","enabled":true},{"patternId":"ESLint_no-mixed-spaces-and-tabs","enabled":true},{"patternId":"ESLint_no-undef","enabled":true},{"patternId":"ESLint_semi","enabled":true},{"patternId":"ESLint_no-empty-character-class","enabled":true},{"patternId":"ESLint_complexity","enabled":true},{"patternId":"ESLint_no-dupe-class-members","enabled":true},{"patternId":"ESLint_no-debugger","enabled":true},{"patternId":"ESLint_block-scoped-var","enabled":true},{"patternId":"ESLint_no-loop-func","enabled":true},{"patternId":"ESLint_no-use-before-define","enabled":true},{"patternId":"ESLint_no-console","enabled":true},{"patternId":"ESLint_require-yield","enabled":true},{"patternId":"ESLint_no-redeclare","enabled":true},{"patternId":"ESLint_no-undefined","enabled":true},{"patternId":"ESLint_use-isnan","enabled":true},{"patternId":"ESLint_no-control-regex","enabled":true},{"patternId":"ESLint_no-const-assign","enabled":true},{"patternId":"ESLint_no-new","enabled":true},{"patternId":"ESLint_new-cap","enabled":true},{"patternId":"ESLint_no-irregular-whitespace","enabled":true},{"patternId":"ESLint_object-shorthand","enabled":true},{"patternId":"ESLint_no-ex-assign","enabled":true},{"patternId":"ESLint_wrap-iife","enabled":true},{"patternId":"ESLint_arrow-parens","enabled":true},{"patternId":"ESLint_no-constant-condition","enabled":true},{"patternId":"ESLint_no-octal","enabled":true},{"patternId":"ESLint_no-dupe-args","enabled":true},{"patternId":"ESLint_quotes","enabled":true},{"patternId":"ESLint_no-fallthrough","enabled":true},{"patternId":"ESLint_no-delete-var","enabled":true},{"patternId":"ESLint_no-caller","enabled":true},{"patternId":"ESLint_no-cond-assign","enabled":true},{"patternId":"ESLint_no-this-before-super","enabled":true},{"patternId":"ESLint_no-negated-in-lhs","enabled":true},{"patternId":"ESLint_no-inner-declarations","enabled":true},{"patternId":"ESLint_eqeqeq","enabled":true},{"patternId":"ESLint_curly","enabled":true},{"patternId":"ESLint_arrow-spacing","enabled":true},{"patternId":"ESLint_no-empty","enabled":true},{"patternId":"ESLint_no-unused-vars","enabled":true},{"patternId":"ESLint_generator-star-spacing","enabled":true},{"patternId":"ESLint_no-duplicate-case","enabled":true},{"patternId":"ESLint_valid-typeof","enabled":true},{"patternId":"ESLint_no-regex-spaces","enabled":true},{"patternId":"ESLint_no-class-assign","enabled":true},{"patternId":"PyLint_W0221","enabled":true},{"patternId":"PyLint_E0117","enabled":true},{"patternId":"PyLint_E0001","enabled":true},{"patternId":"PyLint_E0241","enabled":true},{"patternId":"PyLint_W0404","enabled":true},{"patternId":"PyLint_E0704","enabled":true},{"patternId":"PyLint_E0703","enabled":true},{"patternId":"PyLint_E0302","enabled":true},{"patternId":"PyLint_W1301","enabled":true},{"patternId":"PyLint_R0201","enabled":true},{"patternId":"PyLint_E0113","enabled":true},{"patternId":"PyLint_W0410","enabled":true},{"patternId":"PyLint_C0123","enabled":true},{"patternId":"PyLint_E0115","enabled":true},{"patternId":"PyLint_E0114","enabled":true},{"patternId":"PyLint_E1126","enabled":true},{"patternId":"PyLint_W0702","enabled":true},{"patternId":"PyLint_W1303","enabled":true},{"patternId":"PyLint_W0622","enabled":true},{"patternId":"PyLint_W0222","enabled":true},{"patternId":"PyLint_W0233","enabled":true},{"patternId":"PyLint_W1305","enabled":true},{"patternId":"PyLint_E1127","enabled":true},{"patternId":"PyLint_E0112","enabled":true},{"patternId":"PyLint_W0611","enabled":true},{"patternId":"PyLint_W0601","enabled":true},{"patternId":"PyLint_W1300","enabled":true},{"patternId":"PyLint_W0124","enabled":true},{"patternId":"PyLint_R0203","enabled":true},{"patternId":"PyLint_E0236","enabled":true},{"patternId":"PyLint_W0612","enabled":true},{"patternId":"PyLint_W0604","enabled":true},{"patternId":"PyLint_W0705","enabled":true},{"patternId":"PyLint_E0238","enabled":true},{"patternId":"PyLint_W0602","enabled":true},{"patternId":"PyLint_R0102","enabled":true},{"patternId":"PyLint_R0202","enabled":true},{"patternId":"PyLint_E0240","enabled":true},{"patternId":"PyLint_W0623","enabled":true},{"patternId":"PyLint_W0711","enabled":true},{"patternId":"PyLint_E0116","enabled":true},{"patternId":"PyLint_E0239","enabled":true},{"patternId":"PyLint_E1132","enabled":true},{"patternId":"PyLint_W1307","enabled":true},{"patternId":"PyLint_C0200","enabled":true},{"patternId":"PyLint_E0301","enabled":true},{"patternId":"PyLint_W1306","enabled":true},{"patternId":"PyLint_W1302","enabled":true},{"patternId":"PyLint_E0110","enabled":true},{"patternId":"PyLint_E1125","enabled":true}]} \ No newline at end of file From 65f4f8063273b65b258aaf2be73e0609afb9583a Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 16 Feb 2016 10:48:46 -0800 Subject: [PATCH 088/375] Add getter for key parent --- .../com/google/gcloud/datastore/BaseKey.java | 2 ++ .../gcloud/datastore/IncompleteKey.java | 19 +++++++++++++++++ .../google/gcloud/datastore/BaseKeyTest.java | 5 +++++ .../gcloud/datastore/IncompleteKeyTest.java | 21 ++++++++++++++++--- 4 files changed, 44 insertions(+), 3 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java index a8ad7d4e7734..4ab6f51b6767 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java @@ -157,6 +157,8 @@ public String kind() { return leaf().kind(); } + abstract BaseKey parent(); + @Override public int hashCode() { return Objects.hash(projectId(), namespace(), path()); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java index 2ccd59e725a8..7c987693833e 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java @@ -84,6 +84,25 @@ static IncompleteKey fromPb(DatastoreV1.Key keyPb) { return new IncompleteKey(projectId, namespace, path); } + /** + * Returns the key's parent. + */ + @Override + public Key parent() { + List ancestors = ancestors(); + if (!ancestors.isEmpty()) { + PathElement parent = ancestors.get(ancestors.size() - 1); + Key.Builder keyBuilder; + if (parent.hasName()) { + keyBuilder = Key.builder(projectId(), parent.kind(), parent.name()); + } else { + keyBuilder = Key.builder(projectId(), parent.kind(), parent.id()); + } + return keyBuilder.ancestors(ancestors.subList(0, ancestors.size() - 1)).build(); + } + return null; + } + public static Builder builder(String projectId, String kind) { return new Builder(projectId, kind); } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java index 8615ee025bd1..43db4695b191 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java @@ -50,6 +50,11 @@ protected BaseKey build() { protected Object fromPb(byte[] bytesPb) throws InvalidProtocolBufferException { return null; } + + @Override + protected BaseKey parent() { + return null; + } }; } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/IncompleteKeyTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/IncompleteKeyTest.java index 7edbf133d330..6cc425bbb90f 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/IncompleteKeyTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/IncompleteKeyTest.java @@ -17,21 +17,30 @@ package com.google.gcloud.datastore; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import org.junit.Before; import org.junit.Test; public class IncompleteKeyTest { +private static IncompleteKey pk1, pk2; + private static Key parent; + + @Before + public void setUp() { + pk1 = IncompleteKey.builder("ds", "kind1").build(); + parent = Key.builder("ds", "kind2", 10).build(); + pk2 = IncompleteKey.builder(parent, "kind3").build(); + } + @Test public void testBuilders() throws Exception { - IncompleteKey pk1 = IncompleteKey.builder("ds", "kind1").build(); assertEquals("ds", pk1.projectId()); assertEquals("kind1", pk1.kind()); assertTrue(pk1.ancestors().isEmpty()); - Key parent = Key.builder("ds", "kind2", 10).build(); - IncompleteKey pk2 = IncompleteKey.builder(parent, "kind3").build(); assertEquals("ds", pk2.projectId()); assertEquals("kind3", pk2.kind()); assertEquals(parent.path(), pk2.ancestors()); @@ -42,4 +51,10 @@ public void testBuilders() throws Exception { assertEquals("kind4", pk3.kind()); assertEquals(parent.path(), pk3.ancestors()); } + + @Test + public void testParent() { + assertNull(pk1.parent()); + assertEquals(parent, pk2.parent()); + } } From c2f8952befa41581dcad9a9bd8951837d9c7d39f Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 16 Feb 2016 14:26:49 -0800 Subject: [PATCH 089/375] Expose consistency parameter to users of LocalGcdHelper --- .../datastore/testing/LocalGcdHelper.java | 27 ++++++++++++++----- .../gcloud/datastore/DatastoreTest.java | 2 +- .../gcloud/datastore/LocalGcdHelperTest.java | 4 +-- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java index 7c60da50b0b0..b5e0148fdf04 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java @@ -17,6 +17,7 @@ package com.google.gcloud.datastore.testing; import static com.google.common.base.MoreObjects.firstNonNull; +import static com.google.common.base.Preconditions.checkArgument; import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.base.Strings; @@ -85,6 +86,7 @@ public class LocalGcdHelper { private static final String GCLOUD = "gcloud"; private static final Path INSTALLED_GCD_PATH; private static final String GCD_VERSION_PREFIX = "gcd-emulator "; + private static final double DEFAULT_CONSISTENCY = 0.9; static { INSTALLED_GCD_PATH = installedGcdPath(); @@ -398,9 +400,15 @@ public LocalGcdHelper(String projectId, int port) { * All content is written to a temporary directory that will be deleted when * {@link #stop()} is called or when the program terminates) to make sure that no left-over * data from prior runs is used. + * + * @param consistency the fraction of job application attempts that will succeed, with 0.0 + * resulting in no attempts succeeding, and 1.0 resulting in all attempts succeeding. Defaults + * to 0.9. Note that setting this to 1.0 may mask incorrect assumptions about the consistency + * of non-ancestor queries; non-ancestor queries are eventually consistent. */ - public void start() throws IOException, InterruptedException { + public void start(double consistency) throws IOException, InterruptedException { // send a quick request in case we have a hanging process from a previous run + checkArgument(consistency >= 0.0 && consistency <= 1.0, "Consistency must be between 0 and 1"); sendQuitRequest(port); // Each run is associated with its own folder that is deleted once test completes. gcdPath = Files.createTempDirectory("gcd"); @@ -415,7 +423,7 @@ public void start() throws IOException, InterruptedException { } else { gcdExecutablePath = INSTALLED_GCD_PATH; } - startGcd(gcdExecutablePath); + startGcd(gcdExecutablePath, consistency); } private void downloadGcd() throws IOException { @@ -453,7 +461,8 @@ private void downloadGcd() throws IOException { } } - private void startGcd(Path executablePath) throws IOException, InterruptedException { + private void startGcd(Path executablePath, double consistency) + throws IOException, InterruptedException { // cleanup any possible data for the same project File datasetFolder = new File(gcdPath.toFile(), projectId); deleteRecurse(datasetFolder.toPath()); @@ -486,7 +495,8 @@ private void startGcd(Path executablePath) throws IOException, InterruptedExcept startProcess = CommandWrapper.create() .command(gcdAbsolutePath.toString(), "start", "--testing", "--allow_remote_shutdown", - "--port=" + Integer.toString(port), projectId) + "--port=" + Integer.toString(port), "--consistency=" + Double.toString(consistency), + projectId) .directory(gcdPath) .start(); processReader = ProcessStreamReader.start(startProcess.getInputStream()); @@ -578,10 +588,10 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO }); } - public static LocalGcdHelper start(String projectId, int port) + public static LocalGcdHelper start(String projectId, int port, double consistency) throws IOException, InterruptedException { LocalGcdHelper helper = new LocalGcdHelper(projectId, port); - helper.start(); + helper.start(consistency); return helper; } @@ -590,10 +600,13 @@ public static void main(String... args) throws IOException, InterruptedException String action = parsedArgs.get("action"); int port = (parsedArgs.get("port") == null) ? DEFAULT_PORT : Integer.parseInt(parsedArgs.get("port")); + double consistency = + parsedArgs.get("consistency") == null + ? DEFAULT_CONSISTENCY : Double.parseDouble(parsedArgs.get("consistency")); switch (action) { case "START": if (!isActive(DEFAULT_PROJECT_ID, port)) { - LocalGcdHelper helper = start(DEFAULT_PROJECT_ID, port); + LocalGcdHelper helper = start(DEFAULT_PROJECT_ID, port, consistency); try (FileWriter writer = new FileWriter(".local_gcd_helper")) { writer.write(helper.gcdPath.toAbsolutePath().toString() + System.lineSeparator()); writer.write(Integer.toString(port)); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index e9eed027e8e0..92f232c18a56 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -118,7 +118,7 @@ public class DatastoreTest { @BeforeClass public static void beforeClass() throws IOException, InterruptedException { if (!LocalGcdHelper.isActive(PROJECT_ID, PORT)) { - gcdHelper = LocalGcdHelper.start(PROJECT_ID, PORT); + gcdHelper = LocalGcdHelper.start(PROJECT_ID, PORT, 1.0); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelperTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelperTest.java index 40ea62c5a7e0..5d761a713506 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelperTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelperTest.java @@ -49,7 +49,7 @@ public void testFindAvailablePort() { @Test public void testSendQuitRequest() throws IOException, InterruptedException { - LocalGcdHelper gcdHelper = LocalGcdHelper.start(PROJECT_ID, PORT); + LocalGcdHelper gcdHelper = LocalGcdHelper.start(PROJECT_ID, PORT, 0.75); assertTrue(LocalGcdHelper.sendQuitRequest(PORT)); long timeoutMillis = 30000; long startTime = System.currentTimeMillis(); @@ -64,7 +64,7 @@ public void testSendQuitRequest() throws IOException, InterruptedException { @Test public void testStartStop() throws IOException, InterruptedException { - LocalGcdHelper gcdHelper = LocalGcdHelper.start(PROJECT_ID, PORT); + LocalGcdHelper gcdHelper = LocalGcdHelper.start(PROJECT_ID, PORT, 0.75); assertFalse(LocalGcdHelper.isActive("wrong-project-id", PORT)); assertTrue(LocalGcdHelper.isActive(PROJECT_ID, PORT)); gcdHelper.stop(); From 274b9ae5dfe0b8fc749dc5e55c38f574f09f8f0b Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 16 Feb 2016 16:12:08 -0800 Subject: [PATCH 090/375] Add set(...) javadoc, fix key namespace issue, fix ListValue.of(...), other minor fixes --- .../google/gcloud/datastore/BaseEntity.java | 141 +++++++++++++++++- .../gcloud/datastore/IncompleteKey.java | 24 +-- .../google/gcloud/datastore/ListValue.java | 17 ++- .../datastore/testing/LocalGcdHelper.java | 5 +- .../gcloud/datastore/IncompleteKeyTest.java | 17 ++- 5 files changed, 177 insertions(+), 27 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java index af05cb42c315..389514c3bd83 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java @@ -129,16 +129,36 @@ public B remove(String name) { return self(); } + /** + * Sets a property. + * + * @param name name of the property + * @param value value associated with the property + */ public B set(String name, Value value) { properties.put(name, value); return self(); } + /** + * Sets a property of type {@link StringValue}. + * + * @param name name of the property + * @param value value associated with the property + */ public B set(String name, String value) { properties.put(name, of(value)); return self(); } + /** + * Sets a list property containing elements of type {@link StringValue}. + * + * @param name name of the property + * @param first the first string in the list + * @param second the second string in the list + * @param others other strings in the list + */ public B set(String name, String first, String second, String... others) { List values = new LinkedList<>(); values.add(of(first)); @@ -150,11 +170,25 @@ public B set(String name, String first, String second, String... others) { return self(); } + /** + * Sets a property of type {@link LongValue}. + * + * @param name name of the property + * @param value value associated with the property + */ public B set(String name, long value) { properties.put(name, of(value)); return self(); } + /** + * Sets a list property containing elements of type {@link LongValue}. + * + * @param name name of the property + * @param first the first long in the list + * @param second the second long in the list + * @param others other longs in the list + */ public B set(String name, long first, long second, long... others) { List values = new LinkedList<>(); values.add(of(first)); @@ -166,11 +200,25 @@ public B set(String name, long first, long second, long... others) { return self(); } + /** + * Sets a property of type {@link DoubleValue}. + * + * @param name name of the property + * @param value value associated with the property + */ public B set(String name, double value) { properties.put(name, of(value)); return self(); } + /** + * Sets a list property containing elements of type {@link DoubleValue}. + * + * @param name name of the property + * @param first the first double in the list + * @param second the second double in the list + * @param others other doubles in the list + */ public B set(String name, double first, double second, double... others) { List values = new LinkedList<>(); values.add(of(first)); @@ -182,11 +230,25 @@ public B set(String name, double first, double second, double... others) { return self(); } + /** + * Sets a property of type {@link BooleanValue}. + * + * @param name name of the property + * @param value value associated with the property + */ public B set(String name, boolean value) { properties.put(name, of(value)); return self(); } + /** + * Sets a list property containing elements of type {@link BooleanValue}. + * + * @param name name of the property + * @param first the first boolean in the list + * @param second the second boolean in the list + * @param others other booleans in the list + */ public B set(String name, boolean first, boolean second, boolean... others) { List values = new LinkedList<>(); values.add(of(first)); @@ -198,11 +260,25 @@ public B set(String name, boolean first, boolean second, boolean... others) { return self(); } + /** + * Sets a property of type {@link DateTimeValue}. + * + * @param name name of the property + * @param value value associated with the property + */ public B set(String name, DateTime value) { properties.put(name, of(value)); return self(); } + /** + * Sets a list property containing elements of type {@link DateTimeValue}. + * + * @param name name of the property + * @param first the first {@link DateTime} in the list + * @param second the second {@link DateTime} in the list + * @param others other {@link DateTime}s in the list + */ public B set(String name, DateTime first, DateTime second, DateTime... others) { List values = new LinkedList<>(); values.add(of(first)); @@ -214,11 +290,25 @@ public B set(String name, DateTime first, DateTime second, DateTime... others) { return self(); } + /** + * Sets a property of type {@link KeyValue}. + * + * @param name name of the property + * @param value value associated with the property + */ public B set(String name, Key value) { properties.put(name, of(value)); return self(); } + /** + * Sets a list property containing elements of type {@link KeyValue}. + * + * @param name name of the property + * @param first the first {@link Key} in the list + * @param second the second {@link Key} in the list + * @param others other {@link Key}s in the list + */ public B set(String name, Key first, Key second, Key... others) { List values = new LinkedList<>(); values.add(of(first)); @@ -230,11 +320,25 @@ public B set(String name, Key first, Key second, Key... others) { return self(); } + /** + * Sets a property of type {@link EntityValue}. + * + * @param name name of the property + * @param value value associated with the property + */ public B set(String name, FullEntity value) { properties.put(name, of(value)); return self(); } + /** + * Sets a list property containing elements of type {@link EntityValue}. + * + * @param name name of the property + * @param first the first {@link FullEntity} in the list + * @param second the second {@link FullEntity} in the list + * @param others other entities in the list + */ public B set(String name, FullEntity first, FullEntity second, FullEntity... others) { List values = new LinkedList<>(); values.add(of(first)); @@ -246,21 +350,49 @@ public B set(String name, FullEntity first, FullEntity second, FullEntity< return self(); } + /** + * Sets a property of type {@link ListValue}. + * + * @param name name of the property + * @param values list of values associated with the property + */ public B set(String name, List> values) { properties.put(name, of(values)); return self(); } - public B set(String name, Value first, Value second, Value... other) { - properties.put(name, of(first, second, other)); + /** + * Sets a property of type {@link ListValue}. + * + * @param name name of the property + * @param first the first value in the list + * @param second the second value in the list + * @param others other values in the list + */ + public B set(String name, Value first, Value second, Value... others) { + properties.put(name, of(first, second, others)); return self(); } + /** + * Sets a property of type {@link BlobValue}. + * + * @param name name of the property + * @param value value associated with the property + */ public B set(String name, Blob value) { properties.put(name, of(value)); return self(); } + /** + * Sets a list property containing elements of type {@link BlobValue}. + * + * @param name name of the property + * @param first the first {@link Blob} in the list + * @param second the second {@link Blob} in the list + * @param others other {@link Blob}s in the list + */ public B set(String name, Blob first, Blob second, Blob... others) { List values = new LinkedList<>(); values.add(of(first)); @@ -272,6 +404,11 @@ public B set(String name, Blob first, Blob second, Blob... others) { return self(); } + /** + * Sets a property of type {@code NullValue}. + * + * @param name name of the property + */ public B setNull(String name) { properties.put(name, of()); return self(); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java index 7c987693833e..2192384ef70b 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java @@ -90,17 +90,21 @@ static IncompleteKey fromPb(DatastoreV1.Key keyPb) { @Override public Key parent() { List ancestors = ancestors(); - if (!ancestors.isEmpty()) { - PathElement parent = ancestors.get(ancestors.size() - 1); - Key.Builder keyBuilder; - if (parent.hasName()) { - keyBuilder = Key.builder(projectId(), parent.kind(), parent.name()); - } else { - keyBuilder = Key.builder(projectId(), parent.kind(), parent.id()); - } - return keyBuilder.ancestors(ancestors.subList(0, ancestors.size() - 1)).build(); + if (ancestors.isEmpty()) { + return null; + } + PathElement parent = ancestors.get(ancestors.size() - 1); + Key.Builder keyBuilder; + if (parent.hasName()) { + keyBuilder = Key.builder(projectId(), parent.kind(), parent.name()); + } else { + keyBuilder = Key.builder(projectId(), parent.kind(), parent.id()); + } + String namespace = namespace(); + if (namespace != null) { + keyBuilder.namespace(namespace); } - return null; + return keyBuilder.ancestors(ancestors.subList(0, ancestors.size() - 1)).build(); } public static Builder builder(String projectId, String kind) { diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java index 494d8daedfff..475fd35f8b35 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java @@ -77,9 +77,8 @@ public Builder addValue(Value value) { return this; } - public Builder addValue(Value first, Value second, Value... other) { + public Builder addValue(Value first, Value... other) { addValue(first); - addValue(second); for (Value value : other) { addValue(value); } @@ -122,8 +121,12 @@ public ListValue(List> values) { this(builder().set(values)); } - public ListValue(Value first, Value second, Value... other) { - this(new Builder().addValue(first, second, other)); + public ListValue(Value first, Value... other) { + this(new Builder().addValue(first, other)); + } + + ListValue(Value first, Value second, Value... other) { + this(new Builder().addValue(first).addValue(second, other)); } private ListValue(Builder builder) { @@ -139,7 +142,11 @@ public static ListValue of(List> values) { return new ListValue(values); } - public static ListValue of(Value first, Value second, Value... other) { + public static ListValue of(Value first, Value... other) { + return new ListValue(first, other); + } + + static ListValue of(Value first, Value second, Value... other) { return new ListValue(first, second, other); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java index b5e0148fdf04..9d4ea65af634 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java @@ -600,12 +600,11 @@ public static void main(String... args) throws IOException, InterruptedException String action = parsedArgs.get("action"); int port = (parsedArgs.get("port") == null) ? DEFAULT_PORT : Integer.parseInt(parsedArgs.get("port")); - double consistency = - parsedArgs.get("consistency") == null - ? DEFAULT_CONSISTENCY : Double.parseDouble(parsedArgs.get("consistency")); switch (action) { case "START": if (!isActive(DEFAULT_PROJECT_ID, port)) { + double consistency = parsedArgs.get("consistency") == null + ? DEFAULT_CONSISTENCY : Double.parseDouble(parsedArgs.get("consistency")); LocalGcdHelper helper = start(DEFAULT_PROJECT_ID, port, consistency); try (FileWriter writer = new FileWriter(".local_gcd_helper")) { writer.write(helper.gcdPath.toAbsolutePath().toString() + System.lineSeparator()); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/IncompleteKeyTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/IncompleteKeyTest.java index 6cc425bbb90f..acd1dfd3c9e3 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/IncompleteKeyTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/IncompleteKeyTest.java @@ -25,14 +25,14 @@ public class IncompleteKeyTest { -private static IncompleteKey pk1, pk2; - private static Key parent; + private static IncompleteKey pk1, pk2; + private static Key parent1; @Before public void setUp() { pk1 = IncompleteKey.builder("ds", "kind1").build(); - parent = Key.builder("ds", "kind2", 10).build(); - pk2 = IncompleteKey.builder(parent, "kind3").build(); + parent1 = Key.builder("ds", "kind2", 10).namespace("ns").build(); + pk2 = IncompleteKey.builder(parent1, "kind3").build(); } @Test @@ -43,18 +43,21 @@ public void testBuilders() throws Exception { assertEquals("ds", pk2.projectId()); assertEquals("kind3", pk2.kind()); - assertEquals(parent.path(), pk2.ancestors()); + assertEquals(parent1.path(), pk2.ancestors()); assertEquals(pk2, IncompleteKey.builder(pk2).build()); IncompleteKey pk3 = IncompleteKey.builder(pk2).kind("kind4").build(); assertEquals("ds", pk3.projectId()); assertEquals("kind4", pk3.kind()); - assertEquals(parent.path(), pk3.ancestors()); + assertEquals(parent1.path(), pk3.ancestors()); } @Test public void testParent() { assertNull(pk1.parent()); - assertEquals(parent, pk2.parent()); + assertEquals(parent1, pk2.parent()); + Key parent2 = Key.builder("ds", "kind3", "name").namespace("ns").build(); + IncompleteKey pk3 = IncompleteKey.builder(parent2, "kind3").build(); + assertEquals(parent2, pk3.parent()); } } From 662f57f18845f8d6e5aadd52dddf2b118422c6e5 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 16 Feb 2016 17:05:49 -0800 Subject: [PATCH 091/375] remove unncessary changes to ListValue --- .../com/google/gcloud/datastore/BaseEntity.java | 2 +- .../com/google/gcloud/datastore/ListValue.java | 15 +++------------ 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java index 389514c3bd83..20c0b13e5001 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java @@ -370,7 +370,7 @@ public B set(String name, List> values) { * @param others other values in the list */ public B set(String name, Value first, Value second, Value... others) { - properties.put(name, of(first, second, others)); + properties.put(name, ListValue.builder().addValue(first).addValue(second, others).build()); return self(); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java index 475fd35f8b35..06282a2c79d1 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java @@ -70,17 +70,16 @@ private Builder() { super(ValueType.LIST); } - public Builder addValue(Value value) { + private void addValueHelper(Value value) { // see datastore_v1.proto definition for list_value Preconditions.checkArgument(value.type() != ValueType.LIST, "Cannot contain another list"); listBuilder.add(value); - return this; } public Builder addValue(Value first, Value... other) { - addValue(first); + addValueHelper(first); for (Value value : other) { - addValue(value); + addValueHelper(value); } return this; } @@ -125,10 +124,6 @@ public ListValue(Value first, Value... other) { this(new Builder().addValue(first, other)); } - ListValue(Value first, Value second, Value... other) { - this(new Builder().addValue(first).addValue(second, other)); - } - private ListValue(Builder builder) { super(builder); } @@ -146,10 +141,6 @@ public static ListValue of(Value first, Value... other) { return new ListValue(first, other); } - static ListValue of(Value first, Value second, Value... other) { - return new ListValue(first, second, other); - } - public static Builder builder() { return new Builder(); } From 53290f5107f753cbf82bec432534d48eb556cfbd Mon Sep 17 00:00:00 2001 From: aozarov Date: Wed, 17 Feb 2016 15:32:56 -0800 Subject: [PATCH 092/375] fix lint issue --- .../test/java/com/google/gcloud/datastore/DatastoreTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index d8337e7ae865..a289610fe841 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -473,7 +473,7 @@ public void testQueryPaginationWithLimit() throws DatastoreException { .andReturn(rpcMock); List responses = buildResponsesForQueryPaginationWithLimit(); List endCursors = Lists.newArrayListWithCapacity(responses.size()); - for (RunQueryResponse response: responses) { + for (RunQueryResponse response : responses) { EasyMock.expect(rpcMock.runQuery(EasyMock.anyObject(RunQueryRequest.class))) .andReturn(response); if (response.getBatch().getMoreResults() != QueryResultBatch.MoreResultsType.NOT_FINISHED) { From 1f6a7b3f07fbfb8f9cfdfb7cc83c13f32577c1f4 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Wed, 17 Feb 2016 17:28:13 -0800 Subject: [PATCH 093/375] support paging --- .../resourcemanager/ResourceManager.java | 5 +--- .../testing/LocalResourceManagerHelper.java | 27 ++++++++++++++----- .../LocalResourceManagerHelperTest.java | 26 +++++++++++++++--- .../ResourceManagerImplTest.java | 18 ++++++++++++- 4 files changed, 62 insertions(+), 14 deletions(-) diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java index af772dce6b60..b641fa74b584 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java @@ -147,8 +147,6 @@ public static ProjectListOption pageToken(String pageToken) { * *

The server can return fewer projects than requested. When there are more results than the * page size, the server will return a page token that can be used to fetch other results. - * Note: pagination is not yet supported; the server currently ignores this field and returns - * all results. */ public static ProjectListOption pageSize(int pageSize) { return new ProjectListOption(ResourceManagerRpc.Option.PAGE_SIZE, pageSize); @@ -228,8 +226,7 @@ public static ProjectListOption fields(ProjectField... fields) { * *

This method returns projects in an unspecified order. New projects do not necessarily appear * at the end of the list. Use {@link ProjectListOption} to filter this list, set page size, and - * set page tokens. Note that pagination is currently not implemented by the Cloud Resource - * Manager API. + * set page tokens. * * @see Cloud diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java index 25c763276b3b..f164766ade7a 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java @@ -34,7 +34,7 @@ import java.util.Map; import java.util.Random; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentSkipListMap; import java.util.logging.Level; import java.util.logging.Logger; import java.util.zip.GZIPInputStream; @@ -71,7 +71,7 @@ public class LocalResourceManagerHelper { ImmutableSet.of('-', '\'', '"', ' ', '!'); private final HttpServer server; - private final ConcurrentHashMap projects = new ConcurrentHashMap<>(); + private final ConcurrentSkipListMap projects = new ConcurrentSkipListMap<>(); private final int port; private static class Response { @@ -245,10 +245,10 @@ private static Map parseListOptions(String query) { options.put("filter", argEntry[1].split(" ")); break; case "pageToken": - // support pageToken when Cloud Resource Manager supports this (#421) + options.put("pageToken", argEntry[1]); break; case "pageSize": - // support pageSize when Cloud Resource Manager supports this (#421) + options.put("pageSize", Integer.parseInt(argEntry[1])); break; } } @@ -353,16 +353,27 @@ Response get(String projectId, String[] fields) { } Response list(Map options) { - // Use pageSize and pageToken options when Cloud Resource Manager does so (#421) List projectsSerialized = new ArrayList<>(); String[] filters = (String[]) options.get("filter"); if (filters != null && !isValidFilter(filters)) { return Error.INVALID_ARGUMENT.response("Could not parse the filter."); } String[] fields = (String[]) options.get("fields"); + int count = 0; + String pageToken = (String) options.get("pageToken"); + Integer pageSize = (Integer) options.get("pageSize"); + String nextPageToken = null; for (Project p : projects.values()) { + if (pageToken != null && p.getProjectId().compareTo(pageToken) < 0) { + continue; + } + if (pageSize != null && count >= pageSize) { + nextPageToken = p.getProjectId(); + break; + } boolean includeProject = includeProject(p, filters); if (includeProject) { + count++; try { projectsSerialized.add(jsonFactory.toString(extractFields(p, fields))); } catch (IOException e) { @@ -374,7 +385,11 @@ Response list(Map options) { StringBuilder responseBody = new StringBuilder(); responseBody.append("{\"projects\": ["); Joiner.on(",").appendTo(responseBody, projectsSerialized); - responseBody.append("]}"); + responseBody.append("]"); + if (nextPageToken != null) { + responseBody.append(", \"nextPageToken\": \"" + nextPageToken + "\""); + } + responseBody.append("}"); return new Response(HTTP_OK, responseBody.toString()); } diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java index 7eb0156d4e56..b5cf579cb860 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java @@ -19,6 +19,7 @@ import org.junit.Test; import java.util.HashMap; +import java.util.Iterator; import java.util.Map; public class LocalResourceManagerHelperTest { @@ -278,7 +279,7 @@ public void testGetWithOptions() { public void testList() { Tuple> projects = rpc.list(EMPTY_RPC_OPTIONS); - assertNull(projects.x()); // change this when #421 is resolved + assertNull(projects.x()); assertFalse(projects.y().iterator().hasNext()); rpc.create(COMPLETE_PROJECT); RESOURCE_MANAGER_HELPER.changeLifecycleState( @@ -296,12 +297,31 @@ public void testList() { } } + @Test + public void testListPaging() { + Map rpcOptions = new HashMap<>(); + rpcOptions.put(ResourceManagerRpc.Option.PAGE_SIZE, 1); + rpc.create(PARTIAL_PROJECT); + rpc.create(COMPLETE_PROJECT); + Tuple> projects = + rpc.list(rpcOptions); + assertNotNull(projects.x()); + Iterator iterator = + projects.y().iterator(); + compareReadWriteFields(COMPLETE_PROJECT, iterator.next()); + assertFalse(iterator.hasNext()); + rpcOptions = new HashMap<>(); + rpcOptions.put(ResourceManagerRpc.Option.PAGE_TOKEN, projects.x()); + projects = rpc.list(rpcOptions); + iterator = projects.y().iterator(); + compareReadWriteFields(PARTIAL_PROJECT, iterator.next()); + assertFalse(iterator.hasNext()); + } + @Test public void testListFieldOptions() { Map rpcOptions = new HashMap<>(); rpcOptions.put(ResourceManagerRpc.Option.FIELDS, "projects(projectId,name,labels)"); - rpcOptions.put(ResourceManagerRpc.Option.PAGE_TOKEN, "somePageToken"); - rpcOptions.put(ResourceManagerRpc.Option.PAGE_SIZE, 1); rpc.create(PROJECT_WITH_PARENT); Tuple> projects = rpc.list(rpcOptions); diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java index 37c54718fb4a..868d437a6f00 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java @@ -42,6 +42,7 @@ import org.junit.Test; import org.junit.rules.ExpectedException; +import java.util.Iterator; import java.util.Map; public class ResourceManagerImplTest { @@ -166,7 +167,7 @@ public void testGetWithOptions() { @Test public void testList() { Page projects = RESOURCE_MANAGER.list(); - assertFalse(projects.values().iterator().hasNext()); // TODO: change this when #421 is resolved + assertFalse(projects.values().iterator().hasNext()); RESOURCE_MANAGER.create(PARTIAL_PROJECT); RESOURCE_MANAGER.create(COMPLETE_PROJECT); for (Project p : RESOURCE_MANAGER.list().values()) { @@ -181,6 +182,21 @@ public void testList() { } } + @Test + public void tsetListPaging() { + RESOURCE_MANAGER.create(PARTIAL_PROJECT); + RESOURCE_MANAGER.create(COMPLETE_PROJECT); + Page page = RESOURCE_MANAGER.list(ProjectListOption.pageSize(1)); + assertNotNull(page.nextPageCursor()); + Iterator iterator = page.values().iterator(); + compareReadWriteFields(COMPLETE_PROJECT, iterator.next()); + assertFalse(iterator.hasNext()); + page = page.nextPage(); + iterator = page.values().iterator(); + compareReadWriteFields(PARTIAL_PROJECT, iterator.next()); + assertFalse(iterator.hasNext()); + } + @Test public void testListFieldOptions() { RESOURCE_MANAGER.create(COMPLETE_PROJECT); From 1dd2c04a45d1181de57e9efeeecef4e4f8c97c0f Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Wed, 17 Feb 2016 21:30:04 -0500 Subject: [PATCH 094/375] Fix broken hyperlink in comment --- .../main/java/com/google/gcloud/storage/StorageException.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageException.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageException.java index 0c952c9a65d6..ee85b80d6e13 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageException.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageException.java @@ -33,7 +33,7 @@ */ public class StorageException extends BaseServiceException { - // see: https://cloud.google.com/storage/docs/concepts-techniques#practices + // see: https://cloud.google.com/storage/docs/resumable-uploads-xml#practices private static final Set RETRYABLE_ERRORS = ImmutableSet.of( new Error(504, null), new Error(503, null), From 6b322fa1a0cacb7c79b1709df78fe6163d48ce07 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Thu, 18 Feb 2016 08:30:30 -0800 Subject: [PATCH 095/375] minor fixes --- .../testing/LocalResourceManagerHelper.java | 21 ++++++++++++------- .../LocalResourceManagerHelperTest.java | 1 + .../ResourceManagerImplTest.java | 3 ++- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java index f164766ade7a..4a88a9527a34 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java @@ -248,7 +248,9 @@ private static Map parseListOptions(String query) { options.put("pageToken", argEntry[1]); break; case "pageSize": - options.put("pageSize", Integer.parseInt(argEntry[1])); + int pageSize = Integer.valueOf(argEntry[1]); + checkArgument(pageSize > 0, "Page size must be greater than 0."); + options.put("pageSize", pageSize); break; } } @@ -363,10 +365,11 @@ Response list(Map options) { String pageToken = (String) options.get("pageToken"); Integer pageSize = (Integer) options.get("pageSize"); String nextPageToken = null; - for (Project p : projects.values()) { - if (pageToken != null && p.getProjectId().compareTo(pageToken) < 0) { - continue; - } + Map projectsToScan = projects; + if (pageToken != null) { + projectsToScan = projects.tailMap(pageToken); + } + for (Project p : projectsToScan.values()) { if (pageSize != null && count >= pageSize) { nextPageToken = p.getProjectId(); break; @@ -385,11 +388,13 @@ Response list(Map options) { StringBuilder responseBody = new StringBuilder(); responseBody.append("{\"projects\": ["); Joiner.on(",").appendTo(responseBody, projectsSerialized); - responseBody.append("]"); + responseBody.append(']'); if (nextPageToken != null) { - responseBody.append(", \"nextPageToken\": \"" + nextPageToken + "\""); + responseBody.append(", \"nextPageToken\": \""); + responseBody.append(nextPageToken); + responseBody.append('"'); } - responseBody.append("}"); + responseBody.append('}'); return new Response(HTTP_OK, responseBody.toString()); } diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java index b5cf579cb860..ebcb7dc48a65 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java @@ -316,6 +316,7 @@ public void testListPaging() { iterator = projects.y().iterator(); compareReadWriteFields(PARTIAL_PROJECT, iterator.next()); assertFalse(iterator.hasNext()); + assertNull(projects.x()); } @Test diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java index 868d437a6f00..8d64652a0696 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java @@ -183,7 +183,7 @@ public void testList() { } @Test - public void tsetListPaging() { + public void testListPaging() { RESOURCE_MANAGER.create(PARTIAL_PROJECT); RESOURCE_MANAGER.create(COMPLETE_PROJECT); Page page = RESOURCE_MANAGER.list(ProjectListOption.pageSize(1)); @@ -195,6 +195,7 @@ public void tsetListPaging() { iterator = page.values().iterator(); compareReadWriteFields(PARTIAL_PROJECT, iterator.next()); assertFalse(iterator.hasNext()); + assertNull(page.nextPageCursor()); } @Test From df32901b0d711c15728d4dcf184f64903fc14f8f Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Thu, 18 Feb 2016 09:51:13 -0800 Subject: [PATCH 096/375] Propagate page size error to user --- .../testing/LocalResourceManagerHelper.java | 6 ++++-- .../LocalResourceManagerHelperTest.java | 11 +++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java index 4a88a9527a34..4c26a44cd4e6 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java @@ -228,7 +228,7 @@ private static String[] parseFields(String query) { return null; } - private static Map parseListOptions(String query) { + private static Map parseListOptions(String query) throws IOException { Map options = new HashMap<>(); if (query != null) { String[] args = query.split("&"); @@ -249,7 +249,9 @@ private static Map parseListOptions(String query) { break; case "pageSize": int pageSize = Integer.valueOf(argEntry[1]); - checkArgument(pageSize > 0, "Page size must be greater than 0."); + if (pageSize < 1) { + throw new IOException("Page size must be greater than 0."); + } options.put("pageSize", pageSize); break; } diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java index ebcb7dc48a65..1c2e0ff9c667 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java @@ -297,6 +297,17 @@ public void testList() { } } + @Test + public void testInvalidListPaging() { + Map rpcOptions = new HashMap<>(); + rpcOptions.put(ResourceManagerRpc.Option.PAGE_SIZE, -1); + try { + rpc.list(rpcOptions); + } catch (Exception e) { + assertEquals("Page size must be greater than 0.", e.getMessage()); + } + } + @Test public void testListPaging() { Map rpcOptions = new HashMap<>(); From b9cd1a7aad8756330522baaa1db676938c9e261c Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Thu, 18 Feb 2016 13:40:58 -0800 Subject: [PATCH 097/375] catch ResourceManagerException instead of Exception --- .../gcloud/resourcemanager/LocalResourceManagerHelperTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java index 1c2e0ff9c667..6c20c4f1ae0e 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java @@ -303,7 +303,7 @@ public void testInvalidListPaging() { rpcOptions.put(ResourceManagerRpc.Option.PAGE_SIZE, -1); try { rpc.list(rpcOptions); - } catch (Exception e) { + } catch (ResourceManagerException e) { assertEquals("Page size must be greater than 0.", e.getMessage()); } } From ff2084764b6c75612d04a02084f76bd715064b24 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Wed, 17 Feb 2016 14:16:41 -0800 Subject: [PATCH 098/375] Add IAM Policy classes --- gcloud-java-core/pom.xml | 12 + .../java/com/google/gcloud/IamPolicy.java | 530 ++++++++++++++++++ .../java/com/google/gcloud/IamPolicyTest.java | 126 +++++ .../com/google/gcloud/SerializationTest.java | 49 ++ gcloud-java-resourcemanager/pom.xml | 12 - 5 files changed, 717 insertions(+), 12 deletions(-) create mode 100644 gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java create mode 100644 gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java create mode 100644 gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml index 3463f40b52bd..67d3af27d1a8 100644 --- a/gcloud-java-core/pom.xml +++ b/gcloud-java-core/pom.xml @@ -16,6 +16,18 @@ gcloud-java-core + + com.google.apis + google-api-services-cloudresourcemanager + v1beta1-rev10-1.21.0 + compile + + + com.google.guava + guava-jdk5 + + + com.google.auth google-auth-library-credentials diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java b/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java new file mode 100644 index 000000000000..31099729564a --- /dev/null +++ b/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java @@ -0,0 +1,530 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; + +/** + * An Identity and Access Management (IAM) policy. It is used to specify access control policies for + * Cloud Platform resources. A Policy consists of a list of ACLs (also known as bindings in Cloud + * IAM documentation). An ACL binds a list of identities to a role, where the identities can be user + * accounts, Google groups, Google domains, and service accounts. A role is a named list of + * permissions defined by IAM. + * + * @see Policy + */ +public class IamPolicy implements Serializable { + + static final long serialVersionUID = 1114489978726897720L; + + private final List acls; + private final String etag; + private final int version; + + public static class Identity implements Serializable { + + private static final long serialVersionUID = 30811617560110848L; + + private final Type type; + private final String id; + + /** + * The types of IAM identities. + */ + public enum Type { + /** + * Represents anyone who is on the internet; with or without a Google account. + */ + ALL_USERS, + + /** + * Represents anyone who is authenticated with a Google account or a service account. + */ + ALL_AUTHENTICATED_USERS, + + /** + * Represents a specific Google account. + */ + USER, + + /** + * Represents a service account. + */ + SERVICE_ACCOUNT, + + /** + * Represents a Google group. + */ + GROUP, + + /** + * Represents all the users of a Google Apps domain name. + */ + DOMAIN + } + + Identity(Type type, String id) { + this.type = type; + this.id = id; + } + + public Type type() { + return type; + } + + /** + * Returns the string identifier for this identity. The id corresponds to: + *

    + *
  • email address (for identities of type {@code USER}, {@code SERVICE_ACCOUNT}, and + * {@code GROUP}) + *
  • domain (for identities of type {@code DOMAIN}) + *
  • null (for identities of type {@code ALL_USERS} and {@code ALL_AUTHENTICATED_USERS}) + *
+ */ + public String id() { + return id; + } + + /** + * Returns a new identity representing anyone who is on the internet; with or without a Google + * account. + */ + public static Identity allUsers() { + return new Identity(Type.ALL_USERS, null); + } + + /** + * Returns a new identity representing anyone who is authenticated with a Google account or a + * service account. + */ + public static Identity allAuthenticatedUsers() { + return new Identity(Type.ALL_AUTHENTICATED_USERS, null); + } + + /** + * Returns a new user identity. + * + * @param email An email address that represents a specific Google account. For example, + * alice@gmail.com or joe@example.com. + */ + public static Identity user(String email) { + return new Identity(Type.USER, checkNotNull(email)); + } + + /** + * Returns a new service account identity. + * + * @param email An email address that represents a service account. For example, + * my-other-app@appspot.gserviceaccount.com. + */ + public static Identity serviceAccount(String email) { + return new Identity(Type.SERVICE_ACCOUNT, checkNotNull(email)); + } + + /** + * Returns a new group identity. + * + * @param email An email address that represents a Google group. For example, + * admins@example.com. + */ + public static Identity group(String email) { + return new Identity(Type.GROUP, checkNotNull(email)); + } + + /** + * Returns a new domain identity. + * + * @param domain A Google Apps domain name that represents all the users of that domain. For + * example, google.com or example.com. + */ + public static Identity domain(String domain) { + return new Identity(Type.DOMAIN, checkNotNull(domain)); + } + + @Override + public int hashCode() { + return Objects.hash(id, type); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Identity)) { + return false; + } + Identity other = (Identity) obj; + return Objects.equals(toPb(), other.toPb()); + } + + String toPb() { + switch (type) { + case ALL_USERS: + return "allUsers"; + case ALL_AUTHENTICATED_USERS: + return "allAuthenticatedUsers"; + case USER: + return "user:" + id; + case SERVICE_ACCOUNT: + return "serviceAccount:" + id; + case GROUP: + return "group:" + id; + default: + return "domain:" + id; + } + } + + static Identity fromPb(String identityStr) { + String[] info = identityStr.split(":"); + switch (info[0]) { + case "allUsers": + return allUsers(); + case "allAuthenticatedUsers": + return allAuthenticatedUsers(); + case "user": + return user(info[1]); + case "serviceAccount": + return serviceAccount(info[1]); + case "group": + return group(info[1]); + case "domain": + return domain(info[1]); + default: + throw new IllegalArgumentException("Unexpected identity type: " + info[0]); + } + } + } + + /** + * An ACL binds a list of identities to a role, where the identities can be user accounts, Google + * groups, Google domains, and service accounts. A role is a named list of permissions defined by + * IAM. + * + * @see
Binding + */ + public static class Acl implements Serializable { + + private static final long serialVersionUID = 3954282899483745158L; + + private final List identities; + private final String role; + + /** + * An ACL builder. + */ + public static class Builder { + private final List members = new LinkedList<>(); + private String role; + + Builder(String role) { + this.role = role; + } + + /** + * Sets the role associated with this ACL. + */ + public Builder role(String role) { + this.role = role; + return this; + } + + /** + * Replaces the builder's list of identities with the given list. + */ + public Builder identities(List identities) { + this.members.clear(); + this.members.addAll(identities); + return this; + } + + /** + * Adds one or more identities to the list of identities associated with the ACL. + */ + public Builder addIdentity(Identity first, Identity... others) { + members.add(first); + members.addAll(Arrays.asList(others)); + return this; + } + + /** + * Removes the specified identity from the ACL. + */ + public Builder removeIdentity(Identity identity) { + members.remove(identity); + return this; + } + + public Acl build() { + return new Acl(this); + } + } + + Acl(Builder builder) { + identities = ImmutableList.copyOf(checkNotNull(builder.members)); + role = checkNotNull(builder.role); + } + + /** + * Returns the list of identities associated with this ACL. + */ + public List identities() { + return identities; + } + + /** + * Returns the role associated with this ACL. + */ + public String role() { + return role; + } + + /** + * Returns an ACL builder for the specific role type. + * + * @param role string representing the role, without the "roles/" prefix. An example of a valid + * legacy role is "viewer". An example of a valid service-specific role is + * "pubsub.publisher". + */ + public static Builder builder(String role) { + return new Builder(role); + } + + /** + * Returns an ACL for the role type and list of identities provided. + * + * @param role string representing the role, without the "roles/" prefix. An example of a valid + * legacy role is "viewer". An example of a valid service-specific role is + * "pubsub.publisher". + * @param members list of identities associated with the role. + */ + public static Acl of(String role, List members) { + return new Acl(new Builder(role).identities(members)); + } + + /** + * Returns an ACL for the role type and identities provided. + * + * @param role string representing the role, without the "roles/" prefix. An example of a valid + * legacy role is "viewer". An example of a valid service-specific role is + * "pubsub.publisher". + * @param first identity associated with the role. + * @param others any other identities associated with the role. + */ + public static Acl of(String role, Identity first, Identity... others) { + return new Acl(new Builder(role).addIdentity(first, others)); + } + + public Builder toBuilder() { + return new Builder(role).identities(identities); + } + + @Override + public int hashCode() { + return Objects.hash(identities, role); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Acl)) { + return false; + } + Acl other = (Acl) obj; + return Objects.equals(toPb(), other.toPb()); + } + + com.google.api.services.cloudresourcemanager.model.Binding toPb() { + com.google.api.services.cloudresourcemanager.model.Binding bindingPb = + new com.google.api.services.cloudresourcemanager.model.Binding(); + bindingPb.setMembers(Lists.transform(identities, new Function() { + @Override + public String apply(Identity identity) { + return identity.toPb(); + } + })); + bindingPb.setRole("roles/" + role); + return bindingPb; + } + + static Acl fromPb(com.google.api.services.cloudresourcemanager.model.Binding bindingPb) { + return of( + bindingPb.getRole().substring("roles/".length()), + Lists.transform(bindingPb.getMembers(), new Function() { + @Override + public Identity apply(String memberPb) { + return Identity.fromPb(memberPb); + } + })); + } + } + + /** + * Builder for an IAM Policy. + */ + public static class Builder { + + private final List acls = new LinkedList<>(); + private String etag; + private int version; + + /** + * Replaces the builder's list of ACLs with the given list of ACLs. + */ + public Builder acls(List acls) { + this.acls.clear(); + this.acls.addAll(acls); + return this; + } + + /** + * Adds one or more ACLs to the policy. + */ + public Builder addAcl(Acl first, Acl... others) { + acls.add(first); + acls.addAll(Arrays.asList(others)); + return this; + } + + /** + * Removes the specified ACL. + */ + public Builder removeAcl(Acl acl) { + acls.remove(acl); + return this; + } + + /** + * Sets the policy's etag. + * + *

Etags are used for optimistic concurrency control as a way to help prevent simultaneous + * updates of a policy from overwriting each other. It is strongly suggested that systems make + * use of the etag in the read-modify-write cycle to perform policy updates in order to avoid + * race conditions. An etag is returned in the response to getIamPolicy, and systems are + * expected to put that etag in the request to setIamPolicy to ensure that their change will be + * applied to the same version of the policy. If no etag is provided in the call to + * setIamPolicy, then the existing policy is overwritten blindly. + */ + public Builder etag(String etag) { + this.etag = etag; + return this; + } + + /** + * Sets the version of the policy. The default version is 0. + */ + public Builder version(int version) { + this.version = version; + return this; + } + + public IamPolicy build() { + return new IamPolicy(this); + } + } + + IamPolicy(Builder builder) { + acls = ImmutableList.copyOf(builder.acls); + etag = builder.etag; + version = builder.version; + } + + /** + * The list of ACLs specified in the policy. + */ + public List acls() { + return acls; + } + + /** + * The policy's etag. + * + *

Etags are used for optimistic concurrency control as a way to help prevent simultaneous + * updates of a policy from overwriting each other. It is strongly suggested that systems make + * use of the etag in the read-modify-write cycle to perform policy updates in order to avoid + * race conditions. An etag is returned in the response to getIamPolicy, and systems are + * expected to put that etag in the request to setIamPolicy to ensure that their change will be + * applied to the same version of the policy. If no etag is provided in the call to + * setIamPolicy, then the existing policy is overwritten blindly. + */ + public String etag() { + return etag; + } + + /** + * The version of the policy. The default version is 0. + */ + public int version() { + return version; + } + + @Override + public int hashCode() { + return Objects.hash(acls, etag, version); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof IamPolicy)) { + return false; + } + IamPolicy other = (IamPolicy) obj; + return Objects.equals(toPb(), other.toPb()); + } + + public static Builder builder() { + return new Builder(); + } + + public Builder toBuilder() { + return new Builder().acls(acls).etag(etag).version(version); + } + + com.google.api.services.cloudresourcemanager.model.Policy toPb() { + com.google.api.services.cloudresourcemanager.model.Policy policyPb = + new com.google.api.services.cloudresourcemanager.model.Policy(); + policyPb.setBindings(Lists.transform( + acls, new Function() { + @Override + public com.google.api.services.cloudresourcemanager.model.Binding apply(Acl acl) { + return acl.toPb(); + } + })); + policyPb.setEtag(etag); + policyPb.setVersion(version); + return policyPb; + } + + static IamPolicy fromPb(com.google.api.services.cloudresourcemanager.model.Policy policyPb) { + Builder builder = new Builder(); + builder.acls(Lists.transform( + policyPb.getBindings(), + new Function() { + @Override + public Acl apply(com.google.api.services.cloudresourcemanager.model.Binding binding) { + return Acl.fromPb(binding); + } + })); + return builder.etag(policyPb.getEtag()).version(policyPb.getVersion()).build(); + } +} diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java new file mode 100644 index 000000000000..a87a0b5f287d --- /dev/null +++ b/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java @@ -0,0 +1,126 @@ +/* + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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.gcloud; + +import static org.junit.Assert.assertEquals; + +import com.google.common.collect.ImmutableList; +import com.google.gcloud.IamPolicy.Acl; +import com.google.gcloud.IamPolicy.Identity; + +import org.junit.Test; + +public class IamPolicyTest { + + private static final Identity ALL_USERS = Identity.allUsers(); + private static final Identity ALL_AUTHENTICATED_USERS = Identity.allAuthenticatedUsers(); + private static final Identity USER = Identity.user("abc@gmail.com"); + private static final Identity SERVICE_ACCOUNT = + Identity.serviceAccount("service-account@gmail.com"); + private static final Identity GROUP = Identity.group("group@gmail.com"); + private static final Identity DOMAIN = Identity.domain("google.com"); + private static final Acl ACL1 = Acl.of("viewer", USER, SERVICE_ACCOUNT, ALL_USERS); + private static final Acl ACL2 = Acl.of("editor", ALL_AUTHENTICATED_USERS, GROUP, DOMAIN); + private static final IamPolicy FULL_POLICY = + IamPolicy.builder().addAcl(ACL1, ACL2).etag("etag").version(1).build(); + private static final IamPolicy SIMPLE_POLICY = IamPolicy.builder().addAcl(ACL1, ACL2).build(); + + @Test + public void testIdentityOf() { + assertEquals(Identity.Type.ALL_USERS, ALL_USERS.type()); + assertEquals(null, ALL_USERS.id()); + assertEquals(Identity.Type.ALL_AUTHENTICATED_USERS, ALL_AUTHENTICATED_USERS.type()); + assertEquals(null, ALL_AUTHENTICATED_USERS.id()); + assertEquals(Identity.Type.USER, USER.type()); + assertEquals("abc@gmail.com", USER.id()); + assertEquals(Identity.Type.SERVICE_ACCOUNT, SERVICE_ACCOUNT.type()); + assertEquals("service-account@gmail.com", SERVICE_ACCOUNT.id()); + assertEquals(Identity.Type.GROUP, GROUP.type()); + assertEquals("group@gmail.com", GROUP.id()); + assertEquals(Identity.Type.DOMAIN, DOMAIN.type()); + assertEquals("google.com", DOMAIN.id()); + } + + @Test + public void testIdentityToAndFromPb() { + assertEquals(ALL_USERS, Identity.fromPb(ALL_USERS.toPb())); + assertEquals(ALL_AUTHENTICATED_USERS, Identity.fromPb(ALL_AUTHENTICATED_USERS.toPb())); + assertEquals(USER, Identity.fromPb(USER.toPb())); + assertEquals(SERVICE_ACCOUNT, Identity.fromPb(SERVICE_ACCOUNT.toPb())); + assertEquals(GROUP, Identity.fromPb(GROUP.toPb())); + assertEquals(DOMAIN, Identity.fromPb(DOMAIN.toPb())); + } + + @Test + public void testAclBuilder() { + Acl acl = Acl.builder("owner").addIdentity(USER, GROUP).build(); + assertEquals("owner", acl.role()); + assertEquals(ImmutableList.of(USER, GROUP), acl.identities()); + acl = acl.toBuilder().role("viewer").removeIdentity(GROUP).build(); + assertEquals("viewer", acl.role()); + assertEquals(ImmutableList.of(USER), acl.identities()); + acl = acl.toBuilder().identities(ImmutableList.of(SERVICE_ACCOUNT)).build(); + assertEquals("viewer", acl.role()); + assertEquals(ImmutableList.of(SERVICE_ACCOUNT), acl.identities()); + } + + @Test + public void testAclOf() { + assertEquals("viewer", ACL1.role()); + assertEquals(ImmutableList.of(USER, SERVICE_ACCOUNT, ALL_USERS), ACL1.identities()); + Acl aclFromIdentitiesList = Acl.of("editor", ImmutableList.of(USER, SERVICE_ACCOUNT)); + assertEquals("editor", aclFromIdentitiesList.role()); + assertEquals(ImmutableList.of(USER, SERVICE_ACCOUNT), aclFromIdentitiesList.identities()); + } + + @Test + public void testAclToBuilder() { + assertEquals(ACL1, ACL1.toBuilder().build()); + } + + @Test + public void testAclToAndFromPb() { + assertEquals(ACL1, Acl.fromPb(ACL1.toPb())); + } + + @Test + public void testIamPolicyBuilder() { + assertEquals(ImmutableList.of(ACL1, ACL2), FULL_POLICY.acls()); + assertEquals("etag", FULL_POLICY.etag()); + assertEquals(1, FULL_POLICY.version()); + IamPolicy policy = FULL_POLICY.toBuilder().acls(ImmutableList.of(ACL2)).build(); + assertEquals(ImmutableList.of(ACL2), policy.acls()); + assertEquals("etag", policy.etag()); + assertEquals(1, policy.version()); + policy = SIMPLE_POLICY.toBuilder().removeAcl(ACL2).build(); + assertEquals(ImmutableList.of(ACL1), policy.acls()); + assertEquals(null, policy.etag()); + assertEquals(0, policy.version()); + } + + @Test + public void testIamPolicyToBuilder() { + assertEquals(FULL_POLICY, FULL_POLICY.toBuilder().build()); + assertEquals(SIMPLE_POLICY, SIMPLE_POLICY.toBuilder().build()); + } + + @Test + public void testToAndFromPb() { + assertEquals(FULL_POLICY, IamPolicy.fromPb(FULL_POLICY.toPb())); + assertEquals(SIMPLE_POLICY, IamPolicy.fromPb(SIMPLE_POLICY.toPb())); + } +} diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java new file mode 100644 index 000000000000..b529b2c09ff5 --- /dev/null +++ b/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java @@ -0,0 +1,49 @@ +package com.google.gcloud; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotSame; + +import com.google.common.collect.ImmutableList; +import com.google.gcloud.IamPolicy.Acl; +import com.google.gcloud.IamPolicy.Identity; + +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +public class SerializationTest { + + private static final Identity IDENTITY = Identity.user("abc@gmail.com"); + private static final Acl ACL = Acl.of("viewer", ImmutableList.of(IDENTITY)); + private static final IamPolicy POLICY = + IamPolicy.builder().acls(ImmutableList.of(ACL)).etag("etag").version(1).build(); + + @Test + public void testModelAndRequests() throws Exception { + Serializable[] objects = {IDENTITY, ACL, POLICY}; + for (Serializable obj : objects) { + Object copy = serializeAndDeserialize(obj); + assertEquals(obj, obj); + assertEquals(obj, copy); + assertNotSame(obj, copy); + assertEquals(copy, copy); + } + } + + @SuppressWarnings("unchecked") + private T serializeAndDeserialize(T obj) throws IOException, ClassNotFoundException { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + try (ObjectOutputStream output = new ObjectOutputStream(bytes)) { + output.writeObject(obj); + } + try (ObjectInputStream input = + new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray()))) { + return (T) input.readObject(); + } + } +} diff --git a/gcloud-java-resourcemanager/pom.xml b/gcloud-java-resourcemanager/pom.xml index 1311e4dc1bb5..5e77ab48f5b5 100644 --- a/gcloud-java-resourcemanager/pom.xml +++ b/gcloud-java-resourcemanager/pom.xml @@ -21,18 +21,6 @@ gcloud-java-core ${project.version} - - com.google.apis - google-api-services-cloudresourcemanager - v1beta1-rev10-1.21.0 - compile - - - com.google.guava - guava-jdk5 - - - junit junit From 3f07b2ce044df15af9235de39d37f5827a9a6d6c Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Thu, 18 Feb 2016 16:29:47 -0800 Subject: [PATCH 099/375] move to/fromPb functions to Resource Manager --- gcloud-java-core/pom.xml | 12 --- .../java/com/google/gcloud/IamPolicy.java | 98 +------------------ .../java/com/google/gcloud/IamPolicyTest.java | 27 +---- gcloud-java-resourcemanager/pom.xml | 12 +++ .../resourcemanager/ResourceManagerImpl.java | 94 ++++++++++++++++++ .../ResourceManagerImplTest.java | 44 +++++++++ 6 files changed, 157 insertions(+), 130 deletions(-) diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml index 67d3af27d1a8..3463f40b52bd 100644 --- a/gcloud-java-core/pom.xml +++ b/gcloud-java-core/pom.xml @@ -16,18 +16,6 @@ gcloud-java-core - - com.google.apis - google-api-services-cloudresourcemanager - v1beta1-rev10-1.21.0 - compile - - - com.google.guava - guava-jdk5 - - - com.google.auth google-auth-library-credentials diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java b/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java index 31099729564a..a16ab790b363 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java @@ -18,9 +18,7 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.base.Function; import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; import java.io.Serializable; import java.util.Arrays; @@ -176,44 +174,7 @@ public boolean equals(Object obj) { return false; } Identity other = (Identity) obj; - return Objects.equals(toPb(), other.toPb()); - } - - String toPb() { - switch (type) { - case ALL_USERS: - return "allUsers"; - case ALL_AUTHENTICATED_USERS: - return "allAuthenticatedUsers"; - case USER: - return "user:" + id; - case SERVICE_ACCOUNT: - return "serviceAccount:" + id; - case GROUP: - return "group:" + id; - default: - return "domain:" + id; - } - } - - static Identity fromPb(String identityStr) { - String[] info = identityStr.split(":"); - switch (info[0]) { - case "allUsers": - return allUsers(); - case "allAuthenticatedUsers": - return allAuthenticatedUsers(); - case "user": - return user(info[1]); - case "serviceAccount": - return serviceAccount(info[1]); - case "group": - return group(info[1]); - case "domain": - return domain(info[1]); - default: - throw new IllegalArgumentException("Unexpected identity type: " + info[0]); - } + return Objects.equals(id, other.id()) && Objects.equals(type, other.type()); } } @@ -351,31 +312,7 @@ public boolean equals(Object obj) { return false; } Acl other = (Acl) obj; - return Objects.equals(toPb(), other.toPb()); - } - - com.google.api.services.cloudresourcemanager.model.Binding toPb() { - com.google.api.services.cloudresourcemanager.model.Binding bindingPb = - new com.google.api.services.cloudresourcemanager.model.Binding(); - bindingPb.setMembers(Lists.transform(identities, new Function() { - @Override - public String apply(Identity identity) { - return identity.toPb(); - } - })); - bindingPb.setRole("roles/" + role); - return bindingPb; - } - - static Acl fromPb(com.google.api.services.cloudresourcemanager.model.Binding bindingPb) { - return of( - bindingPb.getRole().substring("roles/".length()), - Lists.transform(bindingPb.getMembers(), new Function() { - @Override - public Identity apply(String memberPb) { - return Identity.fromPb(memberPb); - } - })); + return Objects.equals(identities, other.identities()) && Objects.equals(role, other.role()); } } @@ -489,7 +426,8 @@ public boolean equals(Object obj) { return false; } IamPolicy other = (IamPolicy) obj; - return Objects.equals(toPb(), other.toPb()); + return Objects.equals(acls, other.acls()) && Objects.equals(etag, other.etag()) + && Objects.equals(version, other.version()); } public static Builder builder() { @@ -499,32 +437,4 @@ public static Builder builder() { public Builder toBuilder() { return new Builder().acls(acls).etag(etag).version(version); } - - com.google.api.services.cloudresourcemanager.model.Policy toPb() { - com.google.api.services.cloudresourcemanager.model.Policy policyPb = - new com.google.api.services.cloudresourcemanager.model.Policy(); - policyPb.setBindings(Lists.transform( - acls, new Function() { - @Override - public com.google.api.services.cloudresourcemanager.model.Binding apply(Acl acl) { - return acl.toPb(); - } - })); - policyPb.setEtag(etag); - policyPb.setVersion(version); - return policyPb; - } - - static IamPolicy fromPb(com.google.api.services.cloudresourcemanager.model.Policy policyPb) { - Builder builder = new Builder(); - builder.acls(Lists.transform( - policyPb.getBindings(), - new Function() { - @Override - public Acl apply(com.google.api.services.cloudresourcemanager.model.Binding binding) { - return Acl.fromPb(binding); - } - })); - return builder.etag(policyPb.getEtag()).version(policyPb.getVersion()).build(); - } } diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java index a87a0b5f287d..76a57b5fef50 100644 --- a/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java +++ b/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java @@ -55,16 +55,6 @@ public void testIdentityOf() { assertEquals("google.com", DOMAIN.id()); } - @Test - public void testIdentityToAndFromPb() { - assertEquals(ALL_USERS, Identity.fromPb(ALL_USERS.toPb())); - assertEquals(ALL_AUTHENTICATED_USERS, Identity.fromPb(ALL_AUTHENTICATED_USERS.toPb())); - assertEquals(USER, Identity.fromPb(USER.toPb())); - assertEquals(SERVICE_ACCOUNT, Identity.fromPb(SERVICE_ACCOUNT.toPb())); - assertEquals(GROUP, Identity.fromPb(GROUP.toPb())); - assertEquals(DOMAIN, Identity.fromPb(DOMAIN.toPb())); - } - @Test public void testAclBuilder() { Acl acl = Acl.builder("owner").addIdentity(USER, GROUP).build(); @@ -82,9 +72,9 @@ public void testAclBuilder() { public void testAclOf() { assertEquals("viewer", ACL1.role()); assertEquals(ImmutableList.of(USER, SERVICE_ACCOUNT, ALL_USERS), ACL1.identities()); - Acl aclFromIdentitiesList = Acl.of("editor", ImmutableList.of(USER, SERVICE_ACCOUNT)); - assertEquals("editor", aclFromIdentitiesList.role()); - assertEquals(ImmutableList.of(USER, SERVICE_ACCOUNT), aclFromIdentitiesList.identities()); + Acl aclFromList = Acl.of("editor", ImmutableList.of(USER, SERVICE_ACCOUNT)); + assertEquals("editor", aclFromList.role()); + assertEquals(ImmutableList.of(USER, SERVICE_ACCOUNT), aclFromList.identities()); } @Test @@ -92,11 +82,6 @@ public void testAclToBuilder() { assertEquals(ACL1, ACL1.toBuilder().build()); } - @Test - public void testAclToAndFromPb() { - assertEquals(ACL1, Acl.fromPb(ACL1.toPb())); - } - @Test public void testIamPolicyBuilder() { assertEquals(ImmutableList.of(ACL1, ACL2), FULL_POLICY.acls()); @@ -117,10 +102,4 @@ public void testIamPolicyToBuilder() { assertEquals(FULL_POLICY, FULL_POLICY.toBuilder().build()); assertEquals(SIMPLE_POLICY, SIMPLE_POLICY.toBuilder().build()); } - - @Test - public void testToAndFromPb() { - assertEquals(FULL_POLICY, IamPolicy.fromPb(FULL_POLICY.toPb())); - assertEquals(SIMPLE_POLICY, IamPolicy.fromPb(SIMPLE_POLICY.toPb())); - } } diff --git a/gcloud-java-resourcemanager/pom.xml b/gcloud-java-resourcemanager/pom.xml index 5e77ab48f5b5..1311e4dc1bb5 100644 --- a/gcloud-java-resourcemanager/pom.xml +++ b/gcloud-java-resourcemanager/pom.xml @@ -21,6 +21,18 @@ gcloud-java-core ${project.version} + + com.google.apis + google-api-services-cloudresourcemanager + v1beta1-rev10-1.21.0 + compile + + + com.google.guava + guava-jdk5 + + + junit junit diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java index 4176b4e610ba..e641f3c75a31 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java @@ -23,8 +23,12 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.gcloud.BaseService; +import com.google.gcloud.IamPolicy; +import com.google.gcloud.IamPolicy.Acl; +import com.google.gcloud.IamPolicy.Identity; import com.google.gcloud.Page; import com.google.gcloud.PageImpl; import com.google.gcloud.PageImpl.NextPageFetcher; @@ -189,4 +193,94 @@ public Void call() { } return ImmutableMap.copyOf(temp); } + + static String identityToPb(Identity identity) { + switch (identity.type()) { + case ALL_USERS: + return "allUsers"; + case ALL_AUTHENTICATED_USERS: + return "allAuthenticatedUsers"; + case USER: + return "user:" + identity.id(); + case SERVICE_ACCOUNT: + return "serviceAccount:" + identity.id(); + case GROUP: + return "group:" + identity.id(); + default: + return "domain:" + identity.id(); + } + } + + static Identity identityFromPb(String identityStr) { + String[] info = identityStr.split(":"); + switch (info[0]) { + case "allUsers": + return Identity.allUsers(); + case "allAuthenticatedUsers": + return Identity.allAuthenticatedUsers(); + case "user": + return Identity.user(info[1]); + case "serviceAccount": + return Identity.serviceAccount(info[1]); + case "group": + return Identity.group(info[1]); + case "domain": + return Identity.domain(info[1]); + default: + throw new IllegalArgumentException("Unexpected identity type: " + info[0]); + } + } + + static com.google.api.services.cloudresourcemanager.model.Binding aclToPb(Acl acl) { + com.google.api.services.cloudresourcemanager.model.Binding bindingPb = + new com.google.api.services.cloudresourcemanager.model.Binding(); + bindingPb.setMembers(Lists.transform(acl.identities(), new Function() { + @Override + public String apply(Identity identity) { + return identityToPb(identity); + } + })); + bindingPb.setRole("roles/" + acl.role()); + return bindingPb; + } + + static Acl aclFromPb(com.google.api.services.cloudresourcemanager.model.Binding bindingPb) { + return Acl.of( + bindingPb.getRole().substring("roles/".length()), + Lists.transform(bindingPb.getMembers(), new Function() { + @Override + public Identity apply(String memberPb) { + return identityFromPb(memberPb); + } + })); + } + + static com.google.api.services.cloudresourcemanager.model.Policy policyToPb( + final IamPolicy policy) { + com.google.api.services.cloudresourcemanager.model.Policy policyPb = + new com.google.api.services.cloudresourcemanager.model.Policy(); + policyPb.setBindings(Lists.transform(policy.acls(), + new Function() { + @Override + public com.google.api.services.cloudresourcemanager.model.Binding apply(Acl acl) { + return aclToPb(acl); + } + })); + policyPb.setEtag(policy.etag()); + policyPb.setVersion(policy.version()); + return policyPb; + } + + static IamPolicy policyFromPb( + com.google.api.services.cloudresourcemanager.model.Policy policyPb) { + IamPolicy.Builder builder = new IamPolicy.Builder(); + builder.acls(Lists.transform(policyPb.getBindings(), + new Function() { + @Override + public Acl apply(com.google.api.services.cloudresourcemanager.model.Binding binding) { + return aclFromPb(binding); + } + })); + return builder.etag(policyPb.getEtag()).version(policyPb.getVersion()).build(); + } } diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java index 37c54718fb4a..623bf68d085c 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java @@ -25,6 +25,9 @@ import static org.junit.Assert.fail; import com.google.common.collect.ImmutableMap; +import com.google.gcloud.IamPolicy; +import com.google.gcloud.IamPolicy.Acl; +import com.google.gcloud.IamPolicy.Identity; import com.google.gcloud.Page; import com.google.gcloud.resourcemanager.ProjectInfo.ResourceId; import com.google.gcloud.resourcemanager.ResourceManager.ProjectField; @@ -64,6 +67,18 @@ public class ResourceManagerImplTest { .parent(PARENT) .build(); private static final Map EMPTY_RPC_OPTIONS = ImmutableMap.of(); + private static final Identity ALL_USERS = Identity.allUsers(); + private static final Identity ALL_AUTH_USERS = Identity.allAuthenticatedUsers(); + private static final Identity USER = Identity.user("abc@gmail.com"); + private static final Identity SERVICE_ACCOUNT = + Identity.serviceAccount("service-account@gmail.com"); + private static final Identity GROUP = Identity.group("group@gmail.com"); + private static final Identity DOMAIN = Identity.domain("google.com"); + private static final Acl ACL1 = Acl.of("viewer", USER, SERVICE_ACCOUNT, ALL_USERS); + private static final Acl ACL2 = Acl.of("editor", ALL_AUTH_USERS, GROUP, DOMAIN); + private static final IamPolicy FULL_POLICY = + IamPolicy.builder().addAcl(ACL1, ACL2).etag("etag").version(1).build(); + private static final IamPolicy SIMPLE_POLICY = IamPolicy.builder().addAcl(ACL1, ACL2).build(); @Rule public ExpectedException thrown = ExpectedException.none(); @@ -271,6 +286,35 @@ public void testUndelete() { } } + @Test + public void testIdentityToAndFromPb() { + assertEquals(ALL_USERS, + ResourceManagerImpl.identityFromPb(ResourceManagerImpl.identityToPb(ALL_USERS))); + assertEquals(ALL_AUTH_USERS, + ResourceManagerImpl.identityFromPb( + ResourceManagerImpl.identityToPb(ALL_AUTH_USERS))); + assertEquals(USER, ResourceManagerImpl.identityFromPb(ResourceManagerImpl.identityToPb(USER))); + assertEquals(SERVICE_ACCOUNT, + ResourceManagerImpl.identityFromPb(ResourceManagerImpl.identityToPb(SERVICE_ACCOUNT))); + assertEquals(GROUP, + ResourceManagerImpl.identityFromPb(ResourceManagerImpl.identityToPb(GROUP))); + assertEquals(DOMAIN, + ResourceManagerImpl.identityFromPb(ResourceManagerImpl.identityToPb(DOMAIN))); + } + + @Test + public void testAclToAndFromPb() { + assertEquals(ACL1, ResourceManagerImpl.aclFromPb(ResourceManagerImpl.aclToPb(ACL1))); + } + + @Test + public void testPolicyToAndFromPb() { + assertEquals(FULL_POLICY, + ResourceManagerImpl.policyFromPb(ResourceManagerImpl.policyToPb(FULL_POLICY))); + assertEquals(SIMPLE_POLICY, + ResourceManagerImpl.policyFromPb(ResourceManagerImpl.policyToPb(SIMPLE_POLICY))); + } + @Test public void testRetryableException() { ResourceManagerRpcFactory rpcFactoryMock = EasyMock.createMock(ResourceManagerRpcFactory.class); From c96469b6a135619708f08526c2f0d5cc50396c80 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Thu, 18 Feb 2016 17:33:13 -0800 Subject: [PATCH 100/375] variable rename to make codacy happy --- .../src/test/java/com/google/gcloud/IamPolicyTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java index 76a57b5fef50..0d4e9fbfa6c8 100644 --- a/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java +++ b/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java @@ -27,14 +27,14 @@ public class IamPolicyTest { private static final Identity ALL_USERS = Identity.allUsers(); - private static final Identity ALL_AUTHENTICATED_USERS = Identity.allAuthenticatedUsers(); + private static final Identity ALL_AUTH_USERS = Identity.allAuthenticatedUsers(); private static final Identity USER = Identity.user("abc@gmail.com"); private static final Identity SERVICE_ACCOUNT = Identity.serviceAccount("service-account@gmail.com"); private static final Identity GROUP = Identity.group("group@gmail.com"); private static final Identity DOMAIN = Identity.domain("google.com"); private static final Acl ACL1 = Acl.of("viewer", USER, SERVICE_ACCOUNT, ALL_USERS); - private static final Acl ACL2 = Acl.of("editor", ALL_AUTHENTICATED_USERS, GROUP, DOMAIN); + private static final Acl ACL2 = Acl.of("editor", ALL_AUTH_USERS, GROUP, DOMAIN); private static final IamPolicy FULL_POLICY = IamPolicy.builder().addAcl(ACL1, ACL2).etag("etag").version(1).build(); private static final IamPolicy SIMPLE_POLICY = IamPolicy.builder().addAcl(ACL1, ACL2).build(); @@ -43,8 +43,8 @@ public class IamPolicyTest { public void testIdentityOf() { assertEquals(Identity.Type.ALL_USERS, ALL_USERS.type()); assertEquals(null, ALL_USERS.id()); - assertEquals(Identity.Type.ALL_AUTHENTICATED_USERS, ALL_AUTHENTICATED_USERS.type()); - assertEquals(null, ALL_AUTHENTICATED_USERS.id()); + assertEquals(Identity.Type.ALL_AUTHENTICATED_USERS, ALL_AUTH_USERS.type()); + assertEquals(null, ALL_AUTH_USERS.id()); assertEquals(Identity.Type.USER, USER.type()); assertEquals("abc@gmail.com", USER.id()); assertEquals(Identity.Type.SERVICE_ACCOUNT, SERVICE_ACCOUNT.type()); From 3695ddc93486ab9282f4b5b0996d48bcf75cec6d Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 19 Feb 2016 07:46:43 -0800 Subject: [PATCH 101/375] Update version for release --- gcloud-java-bigquery/pom.xml | 2 +- gcloud-java-contrib/pom.xml | 2 +- gcloud-java-core/pom.xml | 2 +- gcloud-java-datastore/pom.xml | 2 +- gcloud-java-examples/pom.xml | 2 +- gcloud-java-resourcemanager/pom.xml | 2 +- gcloud-java-storage/pom.xml | 2 +- gcloud-java/pom.xml | 2 +- pom.xml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/gcloud-java-bigquery/pom.xml b/gcloud-java-bigquery/pom.xml index b1e516a2268b..6758f66336d8 100644 --- a/gcloud-java-bigquery/pom.xml +++ b/gcloud-java-bigquery/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.4-SNAPSHOT + 0.1.4 gcloud-java-bigquery diff --git a/gcloud-java-contrib/pom.xml b/gcloud-java-contrib/pom.xml index 35dfa606ae42..12f192d3fe31 100644 --- a/gcloud-java-contrib/pom.xml +++ b/gcloud-java-contrib/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.4-SNAPSHOT + 0.1.4 gcloud-java-contrib diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml index 3463f40b52bd..bc5e9c78ba87 100644 --- a/gcloud-java-core/pom.xml +++ b/gcloud-java-core/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.4-SNAPSHOT + 0.1.4 gcloud-java-core diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index 6ffc8045ddb1..4ca38253984c 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.4-SNAPSHOT + 0.1.4 gcloud-java-datastore diff --git a/gcloud-java-examples/pom.xml b/gcloud-java-examples/pom.xml index e5a95f67a9eb..d39cc33808ef 100644 --- a/gcloud-java-examples/pom.xml +++ b/gcloud-java-examples/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.4-SNAPSHOT + 0.1.4 gcloud-java-examples diff --git a/gcloud-java-resourcemanager/pom.xml b/gcloud-java-resourcemanager/pom.xml index 1311e4dc1bb5..dc4bb90fb695 100644 --- a/gcloud-java-resourcemanager/pom.xml +++ b/gcloud-java-resourcemanager/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.4-SNAPSHOT + 0.1.4 gcloud-java-resourcemanager diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml index 09487467a827..ff6588ca62be 100644 --- a/gcloud-java-storage/pom.xml +++ b/gcloud-java-storage/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.4-SNAPSHOT + 0.1.4 gcloud-java-storage diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml index 4d46ff7fd0f0..4afa7cb37a31 100644 --- a/gcloud-java/pom.xml +++ b/gcloud-java/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.4-SNAPSHOT + 0.1.4 diff --git a/pom.xml b/pom.xml index c3c3554d976a..86cea55be722 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.gcloud gcloud-java-pom pom - 0.1.4-SNAPSHOT + 0.1.4 GCloud Java https://github.com/GoogleCloudPlatform/gcloud-java From cf792d87b838a529c4c288ee6c28694259630d5c Mon Sep 17 00:00:00 2001 From: travis-ci Date: Fri, 19 Feb 2016 16:22:46 +0000 Subject: [PATCH 102/375] Updating version in README files. [ci skip] --- README.md | 6 +++--- gcloud-java-bigquery/README.md | 6 +++--- gcloud-java-contrib/README.md | 6 +++--- gcloud-java-core/README.md | 6 +++--- gcloud-java-datastore/README.md | 6 +++--- gcloud-java-examples/README.md | 6 +++--- gcloud-java-resourcemanager/README.md | 6 +++--- gcloud-java-storage/README.md | 6 +++--- gcloud-java/README.md | 6 +++--- 9 files changed, 27 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index d465105dfd41..b6c2473f9794 100644 --- a/README.md +++ b/README.md @@ -29,16 +29,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java - 0.1.3 + 0.1.4 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java:0.1.3' +compile 'com.google.gcloud:gcloud-java:0.1.4' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java" % "0.1.3" +libraryDependencies += "com.google.gcloud" % "gcloud-java" % "0.1.4" ``` Example Applications diff --git a/gcloud-java-bigquery/README.md b/gcloud-java-bigquery/README.md index ba6caa87783a..b406fb5496d2 100644 --- a/gcloud-java-bigquery/README.md +++ b/gcloud-java-bigquery/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-bigquery - 0.1.3 + 0.1.4 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-bigquery:0.1.3' +compile 'com.google.gcloud:gcloud-java-bigquery:0.1.4' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-bigquery" % "0.1.3" +libraryDependencies += "com.google.gcloud" % "gcloud-java-bigquery" % "0.1.4" ``` Example Application diff --git a/gcloud-java-contrib/README.md b/gcloud-java-contrib/README.md index 01f455e3a43c..7a935192891d 100644 --- a/gcloud-java-contrib/README.md +++ b/gcloud-java-contrib/README.md @@ -16,16 +16,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-contrib - 0.1.3 + 0.1.4 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-contrib:0.1.3' +compile 'com.google.gcloud:gcloud-java-contrib:0.1.4' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-contrib" % "0.1.3" +libraryDependencies += "com.google.gcloud" % "gcloud-java-contrib" % "0.1.4" ``` Java Versions diff --git a/gcloud-java-core/README.md b/gcloud-java-core/README.md index b7e5e05b6ad3..bc9463b9cc2b 100644 --- a/gcloud-java-core/README.md +++ b/gcloud-java-core/README.md @@ -19,16 +19,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-core - 0.1.3 + 0.1.4 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-core:0.1.3' +compile 'com.google.gcloud:gcloud-java-core:0.1.4' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-core" % "0.1.3" +libraryDependencies += "com.google.gcloud" % "gcloud-java-core" % "0.1.4" ``` Troubleshooting diff --git a/gcloud-java-datastore/README.md b/gcloud-java-datastore/README.md index 7d985e882a44..a1d024fcc96d 100644 --- a/gcloud-java-datastore/README.md +++ b/gcloud-java-datastore/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-datastore - 0.1.3 + 0.1.4 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-datastore:0.1.3' +compile 'com.google.gcloud:gcloud-java-datastore:0.1.4' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-datastore" % "0.1.3" +libraryDependencies += "com.google.gcloud" % "gcloud-java-datastore" % "0.1.4" ``` Example Application diff --git a/gcloud-java-examples/README.md b/gcloud-java-examples/README.md index 0ab9b3ca6924..59fbca11e219 100644 --- a/gcloud-java-examples/README.md +++ b/gcloud-java-examples/README.md @@ -19,16 +19,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-examples - 0.1.3 + 0.1.4 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-examples:0.1.3' +compile 'com.google.gcloud:gcloud-java-examples:0.1.4' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-examples" % "0.1.3" +libraryDependencies += "com.google.gcloud" % "gcloud-java-examples" % "0.1.4" ``` To run examples from your command line: diff --git a/gcloud-java-resourcemanager/README.md b/gcloud-java-resourcemanager/README.md index fc80190ebd05..9637b37d3bb8 100644 --- a/gcloud-java-resourcemanager/README.md +++ b/gcloud-java-resourcemanager/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-resourcemanager - 0.1.3 + 0.1.4 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-resourcemanager:0.1.3' +compile 'com.google.gcloud:gcloud-java-resourcemanager:0.1.4' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-resourcemanager" % "0.1.3" +libraryDependencies += "com.google.gcloud" % "gcloud-java-resourcemanager" % "0.1.4" ``` Example Application diff --git a/gcloud-java-storage/README.md b/gcloud-java-storage/README.md index 80b2ffd0cd67..3b013eb03724 100644 --- a/gcloud-java-storage/README.md +++ b/gcloud-java-storage/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-storage - 0.1.3 + 0.1.4 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-storage:0.1.3' +compile 'com.google.gcloud:gcloud-java-storage:0.1.4' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-storage" % "0.1.3" +libraryDependencies += "com.google.gcloud" % "gcloud-java-storage" % "0.1.4" ``` Example Application diff --git a/gcloud-java/README.md b/gcloud-java/README.md index 7443bf5e3392..c51b4e8fe7bc 100644 --- a/gcloud-java/README.md +++ b/gcloud-java/README.md @@ -27,16 +27,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java - 0.1.3 + 0.1.4 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java:0.1.3' +compile 'com.google.gcloud:gcloud-java:0.1.4' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java" % "0.1.3" +libraryDependencies += "com.google.gcloud" % "gcloud-java" % "0.1.4" ``` Troubleshooting From 60998b7d6ab6fb1ac7a8f88f28b7b77f9cb28e25 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 19 Feb 2016 08:38:20 -0800 Subject: [PATCH 103/375] Update version to 0.1.5-SNAPSHOT --- gcloud-java-bigquery/pom.xml | 2 +- gcloud-java-contrib/pom.xml | 2 +- gcloud-java-core/pom.xml | 2 +- gcloud-java-datastore/pom.xml | 2 +- gcloud-java-examples/pom.xml | 2 +- gcloud-java-resourcemanager/pom.xml | 2 +- gcloud-java-storage/pom.xml | 2 +- gcloud-java/pom.xml | 2 +- pom.xml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/gcloud-java-bigquery/pom.xml b/gcloud-java-bigquery/pom.xml index 6758f66336d8..0f41d8bc1eec 100644 --- a/gcloud-java-bigquery/pom.xml +++ b/gcloud-java-bigquery/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.4 + 0.1.5-SNAPSHOT gcloud-java-bigquery diff --git a/gcloud-java-contrib/pom.xml b/gcloud-java-contrib/pom.xml index 12f192d3fe31..dd976991e2af 100644 --- a/gcloud-java-contrib/pom.xml +++ b/gcloud-java-contrib/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.4 + 0.1.5-SNAPSHOT gcloud-java-contrib diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml index bc5e9c78ba87..d07a567b7e5a 100644 --- a/gcloud-java-core/pom.xml +++ b/gcloud-java-core/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.4 + 0.1.5-SNAPSHOT gcloud-java-core diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index 4ca38253984c..452986ba5ea3 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.4 + 0.1.5-SNAPSHOT gcloud-java-datastore diff --git a/gcloud-java-examples/pom.xml b/gcloud-java-examples/pom.xml index d39cc33808ef..862d48c89eaa 100644 --- a/gcloud-java-examples/pom.xml +++ b/gcloud-java-examples/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.4 + 0.1.5-SNAPSHOT gcloud-java-examples diff --git a/gcloud-java-resourcemanager/pom.xml b/gcloud-java-resourcemanager/pom.xml index dc4bb90fb695..40a865f4db68 100644 --- a/gcloud-java-resourcemanager/pom.xml +++ b/gcloud-java-resourcemanager/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.4 + 0.1.5-SNAPSHOT gcloud-java-resourcemanager diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml index ff6588ca62be..5e53c36c6221 100644 --- a/gcloud-java-storage/pom.xml +++ b/gcloud-java-storage/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.4 + 0.1.5-SNAPSHOT gcloud-java-storage diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml index 4afa7cb37a31..adfa716fe27b 100644 --- a/gcloud-java/pom.xml +++ b/gcloud-java/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.4 + 0.1.5-SNAPSHOT diff --git a/pom.xml b/pom.xml index 86cea55be722..4bc8f37c35de 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.gcloud gcloud-java-pom pom - 0.1.4 + 0.1.5-SNAPSHOT GCloud Java https://github.com/GoogleCloudPlatform/gcloud-java From a1ec7f46c9e4e53ad185039011f49113de48c53a Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Fri, 19 Feb 2016 10:32:17 -0800 Subject: [PATCH 104/375] Added local implementation of the service and tests. --- .../google/gcloud/testing/LocalDnsHelper.java | 1426 +++++++++++++++++ .../testing/OptionParsersAndExtractors.java | 279 ++++ .../gcloud/testing/LocalDnsHelperTest.java | 955 +++++++++++ 3 files changed, 2660 insertions(+) create mode 100644 gcloud-java-dns/src/main/java/com/google/gcloud/testing/LocalDnsHelper.java create mode 100644 gcloud-java-dns/src/main/java/com/google/gcloud/testing/OptionParsersAndExtractors.java create mode 100644 gcloud-java-dns/src/test/java/com/google/gcloud/testing/LocalDnsHelperTest.java diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/testing/LocalDnsHelper.java b/gcloud-java-dns/src/main/java/com/google/gcloud/testing/LocalDnsHelper.java new file mode 100644 index 000000000000..2d30cf9e5d90 --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/testing/LocalDnsHelper.java @@ -0,0 +1,1426 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.testing; + +import static com.google.common.base.Preconditions.checkNotNull; +import static java.net.HttpURLConnection.HTTP_NO_CONTENT; +import static java.net.HttpURLConnection.HTTP_OK; + +import com.google.api.client.json.JsonFactory; +import com.google.api.client.repackaged.com.google.common.base.Joiner; +import com.google.api.services.dns.model.Change; +import com.google.api.services.dns.model.ManagedZone; +import com.google.api.services.dns.model.Project; +import com.google.api.services.dns.model.Quota; +import com.google.api.services.dns.model.ResourceRecordSet; +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 com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.google.common.io.ByteStreams; +import com.google.gcloud.dns.DnsOptions; + +import com.sun.net.httpserver.Headers; +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; + +import org.joda.time.format.ISODateTimeFormat; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.math.BigInteger; +import java.net.InetSocketAddress; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.NavigableSet; +import java.util.Objects; +import java.util.Random; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ConcurrentSkipListMap; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.zip.GZIPInputStream; + +import javax.annotation.Nullable; + +/** + * A utility to create local Google Cloud DNS mock. + * + *

The mock runs in a separate thread, listening for HTTP requests on the local machine at an + * ephemeral port. + * + *

While the mock attempts to simulate the service, there are some differences in the behaviour. + * The mock will accept any project ID and never returns a notFound or another error because of + * project ID. It assumes that all project IDs exists and that the user has all the necessary + * privileges to manipulate any project. Similarly, the local simulation does not work with any + * verification of domain name ownership. Any request for creating a managed zone will be approved. + * The mock does not track quota and will allow the user to exceed it. The mock provides only basic + * validation of the DNS data for records of type A and AAAA. It does not validate any other record + * types. + */ +public class LocalDnsHelper { + + private final ConcurrentSkipListMap projects + = new ConcurrentSkipListMap<>(); + private static final URI BASE_CONTEXT; + private static final Logger log = Logger.getLogger(LocalDnsHelper.class.getName()); + private static final JsonFactory jsonFactory = + new com.google.api.client.json.jackson.JacksonFactory(); + private static final Random ID_GENERATOR = new Random(); + private static final String VERSION = "v1"; + private static final String CONTEXT = "/" + VERSION + "/projects"; + private static final Set SUPPORTED_COMPRESSION_ENCODINGS = + ImmutableSet.of("gzip", "x-gzip"); + private static final List TYPES = ImmutableList.of("A", "AAAA", "CNAME", "MX", "NAPTR", + "NS", "PTR", "SOA", "SPF", "SRV", "TXT"); + + static { + try { + BASE_CONTEXT = new URI(CONTEXT); + } catch (URISyntaxException e) { + throw new RuntimeException( + "Could not initialize LocalDnsHelper due to URISyntaxException.", e); + } + } + + private long delayChange; + private final HttpServer server; + private final int port; + + /** + * For matching URLs to operations. + */ + private enum CallRegex { + CHANGE_CREATE("POST", "/[^/]+/managedZones/[^/]+/changes"), + CHANGE_GET("GET", "/[^/]+/managedZones/[^/]+/changes/[^/]+"), + CHANGE_LIST("GET", "/[^/]+/managedZones/[^/]+/changes"), + ZONE_CREATE("POST", "/[^/]+/managedZones"), + ZONE_DELETE("DELETE", "/[^/]+/managedZones/[^/]+"), + ZONE_GET("GET", "/[^/]+/managedZones/[^/]+"), + ZONE_LIST("GET", "/[^/]+/managedZones"), + PROJECT_GET("GET", "/[^/]+"), + RECORD_LIST("GET", "/[^/]+/managedZones/[^/]+/rrsets"); + + private String method; + private String pathRegex; + + CallRegex(String method, String pathRegex) { + this.pathRegex = pathRegex; + this.method = method; + } + } + + /** + * Wraps DNS data by adding a timestamp and id which is used for paging and listing. + */ + static class RrsetWrapper { + static final Function WRAP_FUNCTION = + new Function() { + @Nullable + @Override + public RrsetWrapper apply(@Nullable ResourceRecordSet input) { + return new RrsetWrapper(input); + } + }; + private final ResourceRecordSet rrset; + private final Long timestamp = System.currentTimeMillis(); + private String id; + + RrsetWrapper(ResourceRecordSet rrset) { + // The constructor creates a copy in order to prevent side effects. + this.rrset = new ResourceRecordSet(); + this.rrset.setName(rrset.getName()); + this.rrset.setTtl(rrset.getTtl()); + this.rrset.setRrdatas(ImmutableList.copyOf(rrset.getRrdatas())); + this.rrset.setType(rrset.getType()); + } + + void setId(String id) { + this.id = id; + } + + String id() { + return id; + } + + /** + * Equals does not care about the listing id and timestamp metadata, just the rrset. + */ + @Override + public boolean equals(Object other) { + return (other instanceof RrsetWrapper) && Objects.equals(rrset, ((RrsetWrapper) other).rrset); + } + + @Override + public int hashCode() { + return Objects.hash(rrset); + } + + ResourceRecordSet rrset() { + return rrset; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("rrset", rrset) + .add("timestamp", timestamp) + .add("id", id) + .toString(); + } + } + + /** + * Associates a project with a collection of ManagedZones. Thread safe. + */ + static class ProjectContainer { + private final Project project; + private final ConcurrentSkipListMap zones = + new ConcurrentSkipListMap<>(); + + ProjectContainer(Project project) { + this.project = project; + } + + Project project() { + return project; + } + + ConcurrentSkipListMap zones() { + return zones; + } + } + + /** + * Associates a zone with a collection of changes and dns record. Thread safe. + */ + static class ZoneContainer { + private final ManagedZone zone; + /** + * DNS records are held in a map to allow for atomic replacement of record sets when applying + * changes. The key for the map is always the zone name. The collection of records is immutable + * and must always exist, i.e., dnsRecords.get(zone.getName()) is never null. + */ + private final ConcurrentSkipListMap> + dnsRecords = new ConcurrentSkipListMap<>(); + private final ConcurrentLinkedQueue changes = new ConcurrentLinkedQueue<>(); + + ZoneContainer(ManagedZone zone) { + this.zone = zone; + this.dnsRecords.put(zone.getName(), ImmutableList.of()); + } + + ManagedZone zone() { + return zone; + } + + ConcurrentSkipListMap> dnsRecords() { + return dnsRecords; + } + + ConcurrentLinkedQueue changes() { + return changes; + } + + Change findChange(String changeId) { + for (Change current : changes) { + if (changeId.equals(current.getId())) { + return current; + } + } + return null; + } + } + + static class Response { + private final int code; + private final String body; + + Response(int code, String body) { + this.code = code; + this.body = body; + } + + int code() { + return code; + } + + String body() { + return body; + } + } + + private enum Error { + REQUIRED(400, "global", "required", "REQUIRED"), + INTERNAL_ERROR(500, "global", "internalError", "INTERNAL_ERROR"), + BAD_REQUEST(400, "global", "badRequest", "BAD_REQUEST"), + INVALID(400, "global", "invalid", "INVALID"), + NOT_AVAILABLE(400, "global", "managedZoneDnsNameNotAvailable", "NOT_AVAILABLE"), + NOT_FOUND(404, "global", "notFound", "NOT_FOUND"), + ALREADY_EXISTS(409, "global", "alreadyExists", "ALREADY_EXISTS"), + CONDITION_NOT_MET(412, "global", "conditionNotMet", "CONDITION_NOT_MET"), + INVALID_ZONE_APEX(400, "global", "invalidZoneApex", "INVALID_ZONE_APEX"); + + private final int code; + private final String domain; + private final String reason; + private final String status; + + Error(int code, String domain, String reason, String status) { + this.code = code; + this.domain = domain; + this.reason = reason; + this.status = status; + } + + Response response(String message) { + try { + return new Response(code, toJson(message)); + } catch (IOException e) { + return Error.INTERNAL_ERROR.response("Error when generating JSON error response."); + } + } + + private String toJson(String message) throws IOException { + Map errors = new HashMap<>(); + errors.put("domain", domain); + errors.put("message", message); + errors.put("reason", reason); + Map args = new HashMap<>(); + args.put("errors", ImmutableList.of(errors)); + args.put("code", code); + args.put("message", message); + args.put("status", status); + return jsonFactory.toString(ImmutableMap.of("error", args)); + } + } + + private class RequestHandler implements HttpHandler { + + /** + * Chooses the proper handler for a request. + */ + private Response pickHandler(HttpExchange exchange, CallRegex regex) { + switch (regex) { + case CHANGE_GET: + return handleChangeGet(exchange); + case CHANGE_LIST: + return handleChangeList(exchange); + case ZONE_GET: + return handleZoneGet(exchange); + case ZONE_DELETE: + return handleZoneDelete(exchange); + case ZONE_LIST: + return handleZoneList(exchange); + case PROJECT_GET: + return handleProjectGet(exchange); + case RECORD_LIST: + return handleDnsRecordList(exchange); + case ZONE_CREATE: + try { + return handleZoneCreate(exchange); + } catch (IOException ex) { + return Error.BAD_REQUEST.response(ex.getMessage()); + } + case CHANGE_CREATE: + try { + return handleChangeCreate(exchange); + } catch (IOException ex) { + return Error.BAD_REQUEST.response(ex.getMessage()); + } + default: + return Error.INTERNAL_ERROR.response("Operation without a handler."); + } + } + + @Override + public void handle(HttpExchange exchange) throws IOException { + String requestMethod = exchange.getRequestMethod(); + String rawPath = exchange.getRequestURI().getRawPath(); + for (CallRegex regex : CallRegex.values()) { + if (requestMethod.equals(regex.method) && rawPath.matches(regex.pathRegex)) { + // there is a match, pass the handling accordingly + Response response = pickHandler(exchange, regex); + writeResponse(exchange, response); + return; // only one match is possible + } + } + // could not be matched, the service returns 404 page not found here + writeResponse(exchange, Error.NOT_FOUND.response("The url does not match any API call.")); + } + + // todo(mderka) Test handlers using gcloud-java-dns. Issue #665. + private Response handleZoneDelete(HttpExchange exchange) { + String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); + String[] tokens = path.split("/"); + String projectId = tokens[1]; + String zoneName = tokens[3]; + return deleteZone(projectId, zoneName); + } + + private Response handleZoneGet(HttpExchange exchange) { + String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); + String[] tokens = path.split("/"); + String projectId = tokens[1]; + String zoneName = tokens[3]; + String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); + String[] fields = OptionParsersAndExtractors.parseGetOptions(query); + return getZone(projectId, zoneName, fields); + } + + private Response handleZoneList(HttpExchange exchange) { + String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); + String[] tokens = path.split("/"); + String projectId = tokens[1]; + String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); + Map options = OptionParsersAndExtractors.parseListZonesOptions(query); + return listZones(projectId, options); + } + + private Response handleProjectGet(HttpExchange exchange) { + String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); + String[] tokens = path.split("/"); + String projectId = tokens[1]; + String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); + String[] fields = OptionParsersAndExtractors.parseGetOptions(query); + return getProject(projectId, fields); + } + + /** + * @throws IOException if the request cannot be parsed. + */ + private Response handleChangeCreate(HttpExchange exchange) throws IOException { + String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); + String[] tokens = path.split("/"); + String projectId = tokens[1]; + String zoneName = tokens[3]; + String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); + String[] fields = OptionParsersAndExtractors.parseGetOptions(query); + String requestBody = decodeContent(exchange.getRequestHeaders(), exchange.getRequestBody()); + Change change = jsonFactory.fromString(requestBody, Change.class); + return createChange(projectId, zoneName, change, fields); + } + + private Response handleChangeGet(HttpExchange exchange) { + String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); + String[] tokens = path.split("/"); + String projectId = tokens[1]; + String zoneName = tokens[3]; + String changeId = tokens[5]; + String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); + String[] fields = OptionParsersAndExtractors.parseGetOptions(query); + return getChange(projectId, zoneName, changeId, fields); + } + + private Response handleChangeList(HttpExchange exchange) { + String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); + String[] tokens = path.split("/"); + String projectId = tokens[1]; + String zoneName = tokens[3]; + String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); + Map options = OptionParsersAndExtractors.parseListChangesOptions(query); + return listChanges(projectId, zoneName, options); + } + + private Response handleDnsRecordList(HttpExchange exchange) { + String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); + String[] tokens = path.split("/"); + String projectId = tokens[1]; + String zoneName = tokens[3]; + String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); + Map options = OptionParsersAndExtractors.parseListDnsRecordsOptions(query); + return listDnsRecords(projectId, zoneName, options); + } + + /** + * @throws IOException if the request cannot be parsed. + */ + private Response handleZoneCreate(HttpExchange exchange) throws IOException { + String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); + String[] tokens = path.split("/"); + String projectId = tokens[1]; + String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); + String[] options = OptionParsersAndExtractors.parseGetOptions(query); + String requestBody = decodeContent(exchange.getRequestHeaders(), exchange.getRequestBody()); + ManagedZone zone; + try { + // IllegalArgumentException if the request body is an empty string + zone = jsonFactory.fromString(requestBody, ManagedZone.class); + } catch (IllegalArgumentException ex) { + return Error.REQUIRED.response( + "The 'entity.managedZone' parameter is required but was missing."); + } + return createZone(projectId, zone, options); + } + } + + private LocalDnsHelper(long delay) { + this.delayChange = delay; // 0 makes this synchronous + try { + server = HttpServer.create(new InetSocketAddress(0), 0); + port = server.getAddress().getPort(); + server.createContext(CONTEXT, new RequestHandler()); + } catch (IOException e) { + throw new RuntimeException("Could not bind the mock DNS server.", e); + } + } + + /** + * Accessor for testing purposes. + */ + ConcurrentSkipListMap projects() { + return projects; + } + + /** + * Creates new {@link LocalDnsHelper} instance that listens to requests on the local machine. This + * instance processes changes separate threads. The parameter determines how long a thread should + * wait before processing a change. If it is set to 0, the threading is turned off and the mock + * will behave synchronously. + * + * @param delay delay for processing changes in ms or 0 for synchronous processing + */ + public static LocalDnsHelper create(Long delay) { + return new LocalDnsHelper(delay); + } + + /** + * Returns a DnsOptions instance that sets the host to use the mock server. + */ + public DnsOptions options() { + return DnsOptions.builder().host("http://localhost:" + port).build(); + } + + /** + * Starts the thread that runs the local DNS server. + */ + public void start() { + server.start(); + } + + /** + * Stops the thread that runs the mock DNS server. + */ + public void stop() { + server.stop(1); + } + + private static void writeResponse(HttpExchange exchange, Response response) { + exchange.getResponseHeaders().set("Content-type", "application/json; charset=UTF-8"); + OutputStream outputStream = exchange.getResponseBody(); + try { + exchange.getResponseHeaders().add("Connection", "close"); + exchange.sendResponseHeaders(response.code(), response.body().length()); + outputStream.write(response.body().getBytes(StandardCharsets.UTF_8)); + outputStream.close(); + } catch (IOException e) { + log.log(Level.WARNING, "IOException encountered when sending response.", e); + } + } + + /** + * Decodes content of the HttpRequest. + */ + private static String decodeContent(Headers headers, InputStream inputStream) throws IOException { + List contentEncoding = headers.get("Content-encoding"); + InputStream input = inputStream; + try { + if (contentEncoding != null && !contentEncoding.isEmpty()) { + String encoding = contentEncoding.get(0); + if (SUPPORTED_COMPRESSION_ENCODINGS.contains(encoding)) { + input = new GZIPInputStream(inputStream); + } else if (!encoding.equals("identity")) { + throw new IOException( + "The request has the following unsupported HTTP content encoding: " + encoding); + } + } + return new String(ByteStreams.toByteArray(input), StandardCharsets.UTF_8); + } catch (IOException e) { + throw new IOException("Exception encountered when decoding request content.", e); + } + } + + /** + * Generates a JSON response. Tested. + */ + static Response toListResponse(List serializedObjects, String pageToken, + boolean includePageToken) { + // start building response + StringBuilder responseBody = new StringBuilder(); + responseBody.append("{\"projects\": ["); + Joiner.on(",").appendTo(responseBody, serializedObjects); + responseBody.append("]"); + // add page token only if exists and is asked for + if (pageToken != null && includePageToken) { + responseBody.append(",\"pageToken\": \"").append(pageToken).append("\""); + } + responseBody.append("}"); + return new Response(HTTP_OK, responseBody.toString()); + } + + /** + * Prepares DNS records that are created by default for each zone. + */ + private static ImmutableList defaultRecords(ManagedZone zone) { + ResourceRecordSet soa = new ResourceRecordSet(); + soa.setTtl(21600); + soa.setName(zone.getDnsName()); + soa.setRrdatas(ImmutableList.of( + // taken from the service + "ns-cloud-c1.googledomains.com. cloud-dns-hostmaster.google.com. 0 21600 3600 1209600 312" + )); + soa.setType("SOA"); + ResourceRecordSet ns = new ResourceRecordSet(); + ns.setTtl(21600); + ns.setName(zone.getDnsName()); + ns.setRrdatas(zone.getNameServers()); + ns.setType("NS"); + RrsetWrapper nsWrapper = new RrsetWrapper(ns); + RrsetWrapper soaWrapper = new RrsetWrapper(soa); + ImmutableList results = ImmutableList.of(nsWrapper, soaWrapper); + nsWrapper.setId(getUniqueId(results)); + soaWrapper.setId(getUniqueId(results)); + return results; + } + + /** + * Returns a list of four nameservers randomly chosen from the predefined set. + */ + static List randomNameservers() { + ArrayList nameservers = Lists.newArrayList( + "dns1.googlecloud.com", "dns2.googlecloud.com", "dns3.googlecloud.com", + "dns4.googlecloud.com", "dns5.googlecloud.com", "dns6.googlecloud.com" + ); + while (nameservers.size() != 4) { + int index = ID_GENERATOR.nextInt(nameservers.size()); + nameservers.remove(index); + } + return nameservers; + } + + /** + * Returns a hex string id (used for a dns record) unique withing the set of wrappers. + */ + static String getUniqueId(List wrappers) { + TreeSet ids = Sets.newTreeSet(Lists.transform(wrappers, + new Function() { + @Nullable + @Override + public String apply(@Nullable RrsetWrapper input) { + return input.id() == null ? "null" : input.id(); + } + })); + String id; + do { + id = Long.toHexString(System.currentTimeMillis()) + + Long.toHexString(Math.abs(ID_GENERATOR.nextLong())); + if (!ids.contains(id)) { + return id; + } + } while (ids.contains(id)); + return id; + } + + /** + * Tests if a DNS record matches name and type (if provided). Used for filtering. + */ + static boolean matchesCriteria(ResourceRecordSet record, String name, String type) { + if (type != null && !record.getType().equals(type)) { + return false; + } + if (name != null && !record.getName().equals(name)) { + return false; + } + return true; + } + + /** + * Returns a project container. Never returns null because we assume that all projects exists. + */ + ProjectContainer findProject(String projectId) { + ProjectContainer defaultProject = createProject(projectId); + projects.putIfAbsent(projectId, defaultProject); + return projects.get(projectId); + } + + /** + * Returns a zone container. Returns null if zone does not exist within project. + */ + ZoneContainer findZone(String projectId, String zoneName) { + ProjectContainer projectContainer = findProject(projectId); // never null + return projectContainer.zones().get(zoneName); + } + + /** + * Returns a change found by its id. Returns null if such a change does not exist. + */ + Change findChange(String projectId, String zoneName, String changeId) { + ZoneContainer wrapper = findZone(projectId, zoneName); + return wrapper == null ? null : wrapper.findChange(changeId); + } + + /** + * Returns a response to get change call. + */ + Response getChange(String projectId, String zoneName, String changeId, String[] fields) { + Change change = findChange(projectId, zoneName, changeId); + if (change == null) { + ZoneContainer zone = findZone(projectId, zoneName); + if (zone == null) { + // zone does not exist + return Error.NOT_FOUND.response(String.format( + "The 'parameters.managedZone' resource named '%s' does not exist.", zoneName)); + } + // zone exists but change does not + return Error.NOT_FOUND.response(String.format( + "The 'parameters.changeId' resource named '%s' does not exist.", changeId)); + } + Change result = OptionParsersAndExtractors.extractFields(change, fields); + try { + return new Response(HTTP_OK, jsonFactory.toString(result)); + } catch (IOException e) { + return Error.INTERNAL_ERROR.response(String.format( + "Error when serializing change %s in managed zone %s in project %s.", + changeId, zoneName, projectId)); + } + // todo(mderka) Test field options within #665. + } + + /** + * Returns a response to get zone call. + */ + Response getZone(String projectId, String zoneName, String[] fields) { + ZoneContainer container = findZone(projectId, zoneName); + if (container == null) { + return Error.NOT_FOUND.response(String.format( + "The 'parameters.managedZone' resource named '%s' does not exist.", zoneName)); + } + ManagedZone result = OptionParsersAndExtractors.extractFields(container.zone(), fields); + try { + return new Response(HTTP_OK, jsonFactory.toString(result)); + } catch (IOException e) { + return Error.INTERNAL_ERROR.response(String.format( + "Error when serializing managed zone %s in project %s.", zoneName, projectId)); + } + // todo(mderka) Test field options within #665. + } + + /** + * We assume that every project exists. If we do not have it in the collection yet, we just create + * a new default project instance with default quota. + */ + Response getProject(String projectId, String[] fields) { + ProjectContainer defaultProject = createProject(projectId); + projects.putIfAbsent(projectId, defaultProject); + Project project = projects.get(projectId).project(); // project is now guaranteed to exist + Project result = OptionParsersAndExtractors.extractFields(project, fields); + try { + return new Response(HTTP_OK, jsonFactory.toString(result)); + } catch (IOException e) { + return Error.INTERNAL_ERROR.response( + String.format("Error when serializing project %s.", projectId)); + } + // todo(mderka) Test field options within #665. + } + + /** + * Creates a project. It generates a project number randomly (we do not have project numbers + * available). + */ + private ProjectContainer createProject(String projectId) { + Quota quota = new Quota(); + quota.setManagedZones(10000); + quota.setRrsetsPerManagedZone(10000); + quota.setRrsetAdditionsPerChange(100); + quota.setRrsetDeletionsPerChange(100); + quota.setTotalRrdataSizePerChange(10000); + quota.setResourceRecordsPerRrset(100); + Project project = new Project(); + project.setId(projectId); + project.setNumber(new BigInteger(String.valueOf( + Math.abs(ID_GENERATOR.nextLong() % Long.MAX_VALUE)))); + project.setQuota(quota); + return new ProjectContainer(project); + } + + /** + * Deletes a zone. + */ + Response deleteZone(String projectId, String zoneName) { + ProjectContainer projectContainer = projects.get(projectId); + ZoneContainer previous = projectContainer.zones.remove(zoneName); + return previous == null + // map was not in the collection + ? Error.NOT_FOUND.response(String.format( + "The 'parameters.managedZone' resource named '%s' does not exist.", zoneName)) + : new Response(HTTP_NO_CONTENT, "{}"); + } + + /** + * Creates new managed zone and stores it in the collection. Assumes that project exists. + */ + Response createZone(String projectId, ManagedZone zone, String[] fields) { + checkNotNull(zone, "Zone to create cannot be null"); + // check if the provided data is valid + Response errorResponse = checkZone(zone); + if (errorResponse != null) { + return errorResponse; + } + // create a copy of the managed zone in order to avoid side effects + ManagedZone completeZone = new ManagedZone(); + completeZone.setName(zone.getName()); + completeZone.setDnsName(zone.getDnsName()); + completeZone.setNameServerSet(zone.getNameServerSet()); + completeZone.setCreationTime(ISODateTimeFormat.dateTime().withZoneUTC() + .print(System.currentTimeMillis())); + completeZone.setId( + new BigInteger(String.valueOf(Math.abs(ID_GENERATOR.nextLong() % Long.MAX_VALUE)))); + completeZone.setNameServers(randomNameservers()); + ZoneContainer zoneContainer = new ZoneContainer(completeZone); + // create the default NS and SOA records + zoneContainer.dnsRecords().put(zone.getName(), defaultRecords(completeZone)); + // place the zone in the data collection + ProjectContainer projectContainer = findProject(projectId); + ZoneContainer oldValue = projectContainer.zones().putIfAbsent( + completeZone.getName(), zoneContainer); + if (oldValue != null) { + return Error.ALREADY_EXISTS.response(String.format( + "The resource 'entity.managedZone' named '%s' already exists", completeZone.getName())); + } + // now return the desired attributes + ManagedZone result = OptionParsersAndExtractors.extractFields(completeZone, fields); + try { + return new Response(HTTP_OK, jsonFactory.toString(result)); + } catch (IOException e) { + return Error.INTERNAL_ERROR.response( + String.format("Error when serializing managed zone %s.", result.getName())); + } + // todo(mderka) Test field options within #665. + } + + /** + * Creates a new change, stores it, and invokes processing in a new thread. + */ + Response createChange(String projectId, String zoneName, Change change, String[] fields) { + ZoneContainer zoneContainer = findZone(projectId, zoneName); + if (zoneContainer == null) { + return Error.NOT_FOUND.response(String.format( + "The 'parameters.managedZone' resource named %s does not exist.", zoneName)); + } + // check that the change to be applied is valid + Response response = checkChange(change, zoneContainer); + if (response != null) { + return response; + } + // start applying + Change completeChange = new Change(); // copy to avoid side effects + if (change.getAdditions() != null) { + completeChange.setAdditions(ImmutableList.copyOf(change.getAdditions())); + } + if (change.getDeletions() != null) { + completeChange.setDeletions(ImmutableList.copyOf(change.getDeletions())); + } + /* we need to get the proper ID in concurrent environment + the element fell on an index between 0 and maxId + we will reset all IDs in this range (all of them are valid) */ + ConcurrentLinkedQueue changeSequence = zoneContainer.changes(); + changeSequence.add(completeChange); + int maxId = changeSequence.size(); + int index = 0; + for (Change c : changeSequence) { + if (index == maxId) { + break; + } + c.setId(String.valueOf(++index)); // indexing from 1 + } + completeChange.setStatus("pending"); // not finished yet + completeChange.setStartTime(ISODateTimeFormat.dateTime().withZoneUTC() + .print(System.currentTimeMillis())); // accepted + invokeChange(projectId, zoneName, completeChange.getId()); + Change result = OptionParsersAndExtractors.extractFields(completeChange, fields); + try { + return new Response(HTTP_OK, jsonFactory.toString(result)); + } catch (IOException e) { + return Error.INTERNAL_ERROR.response( + String.format("Error when serializing change %s in managed zone %s in project %s.", + result.getId(), zoneName, projectId)); + } + // todo(mderka) Test field options within #665. + } + + /** + * Applies change. Uses a new thread which applies the change only if DELAY_CHANGE is > 0. + */ + private Thread invokeChange(final String projectId, final String zoneName, + final String changeId) { + if (delayChange > 0) { + Thread thread = new Thread() { + @Override + public void run() { + try { + Thread.sleep(delayChange); // simulate delayed execution + } catch (InterruptedException ex) { + log.log(Level.WARNING, "Thread was interrupted while sleeping.", ex); + } + // start applying the changes + applyExistingChange(projectId, zoneName, changeId); + } + }; + thread.start(); + return thread; + } else { + applyExistingChange(projectId, zoneName, changeId); + return null; + } + } + + /** + * Applies changes to a zone. Repeatedly tries until succeeds. Thread safe and deadlock safe. + */ + private void applyExistingChange(String projectId, String zoneName, String changeId) { + Change change = findChange(projectId, zoneName, changeId); + if (change == null) { + return; // no such change exists, nothing to do + } + ZoneContainer wrapper = findZone(projectId, zoneName); + ConcurrentSkipListMap> dnsRecords = wrapper.dnsRecords(); + while (true) { + // managed zone must have a set of records which is not null + ImmutableList original = dnsRecords.get(zoneName); + assert original != null; + List copy = Lists.newLinkedList(original); + // apply deletions first + List deletions = change.getDeletions(); + if (deletions != null) { + List transformedDeletions = Lists.transform(deletions, + RrsetWrapper.WRAP_FUNCTION); + copy.removeAll(transformedDeletions); + } + // apply additions + List additions = change.getAdditions(); + if (additions != null) { + for (ResourceRecordSet addition : additions) { + String id = getUniqueId(copy); + RrsetWrapper rrsetWrapper = new RrsetWrapper(addition); + rrsetWrapper.setId(id); + copy.add(rrsetWrapper); + } + } + // make it immutable and replace + boolean success = dnsRecords.replace(zoneName, original, ImmutableList.copyOf(copy)); + if (success) { + break; // success if no other thread modified the value in the meantime + } + } + // set status to done + change.setStatus("done"); + } + + /** + * Lists zones. Next page token is the last listed zone name and is returned only of there is more + * to list. + */ + Response listZones(String projectId, Map options) { + Response response = checkListOptions(options); + if (response != null) { + return response; + } + ConcurrentSkipListMap containers = findProject(projectId).zones(); + String[] fields = (String[]) options.get("fields"); + String dnsName = (String) options.get("dnsName"); + String pageToken = (String) options.get("pageToken"); + Integer maxResults = options.get("maxResults") == null + ? null : Integer.valueOf((String) options.get("maxResults")); + // matches will be included in the result if true + boolean listing = (pageToken == null || !containers.containsKey(pageToken)); + boolean sizeReached = false; // maximum result size was reached, we should not return more + boolean hasMorePages = false; // should next page token be included in the response? + LinkedList serializedZones = new LinkedList<>(); + String lastZoneName = null; + for (ZoneContainer zoneContainer : containers.values()) { + ManagedZone zone = zoneContainer.zone(); + if (listing) { + if (dnsName == null || zone.getDnsName().equals(dnsName)) { + lastZoneName = zone.getName(); + if (sizeReached) { + // we do not add this, just note that there would be more and there should be a token + hasMorePages = true; + break; + } else { + try { + serializedZones.addLast(jsonFactory.toString( + OptionParsersAndExtractors.extractFields(zone, fields))); + } catch (IOException e) { + return Error.INTERNAL_ERROR.response(String.format( + "Error when serializing managed zone %s in project %s", zone.getName(), + projectId)); + } + } + } + } + // either we are listing already, or we check if we should start in the next iteration + listing = zone.getName().equals(pageToken) || listing; + sizeReached = (maxResults != null) && maxResults.equals(serializedZones.size()); + } + boolean includePageToken = + hasMorePages && (fields == null || ImmutableList.copyOf(fields).contains("pageToken")); + return toListResponse(serializedZones, lastZoneName, includePageToken); + // todo(mderka) Test field and listing options within #665. + } + + /** + * Lists DNS records for a zone. Next page token is ID of the last record listed. + */ + Response listDnsRecords(String projectId, String zoneName, Map options) { + Response response = checkListOptions(options); + if (response != null) { + return response; + } + ZoneContainer zoneContainer = findZone(projectId, zoneName); + if (zoneContainer == null) { + return Error.NOT_FOUND.response(String.format( + "The 'parameters.managedZone' resource named '%s' does not exist.", zoneName)); + } + List dnsRecords = zoneContainer.dnsRecords().get(zoneName); + String[] fields = (String[]) options.get("fields"); + String name = (String) options.get("name"); + String type = (String) options.get("type"); + String pageToken = (String) options.get("pageToken"); + Integer maxResults = options.get("maxResults") == null + ? null : Integer.valueOf((String) options.get("maxResults")); + boolean listing = (pageToken == null); // matches will be included in the result if true + boolean sizeReached = false; // maximum result size was reached, we should not return more + boolean hasMorePages = false; // should next page token be included in the response? + LinkedList serializedRrsets = new LinkedList<>(); + String lastRecordId = null; + for (RrsetWrapper recordWrapper : dnsRecords) { + ResourceRecordSet record = recordWrapper.rrset(); + if (listing) { + if (matchesCriteria(record, name, type)) { + lastRecordId = recordWrapper.id(); + if (sizeReached) { + // we do not add this, just note that there would be more and there should be a token + hasMorePages = true; + break; + } else { + try { + serializedRrsets.addLast(jsonFactory.toString( + OptionParsersAndExtractors.extractFields(record, fields))); + } catch (IOException e) { + return Error.INTERNAL_ERROR.response(String.format( + "Error when serializing resource record set in managed zone %s in project %s", + zoneName, projectId)); + } + } + } + } + // either we are listing already, or we check if we should start in the next iteration + listing = recordWrapper.id().equals(pageToken) || listing; + sizeReached = (maxResults != null) && maxResults.equals(serializedRrsets.size()); + } + boolean includePageToken = + hasMorePages && (fields == null || ImmutableList.copyOf(fields).contains("pageToken")); + return toListResponse(serializedRrsets, lastRecordId, includePageToken); + // todo(mderka) Test field and listing options within #665. + } + + /** + * Lists changes. Next page token is ID of the last change listed. + */ + Response listChanges(String projectId, String zoneName, Map options) { + Response response = checkListOptions(options); + if (response != null) { + return response; + } + ZoneContainer zoneContainer = findZone(projectId, zoneName); + // take a sorted snapshot of the current change list + TreeMap changes = new TreeMap<>(); + for (Change c : zoneContainer.changes()) { + if (c.getId() != null) { + changes.put(Integer.valueOf(c.getId()), c); + } + } + String[] fields = (String[]) options.get("fields"); + String sortOrder = (String) options.get("sortOrder"); + String pageToken = (String) options.get("pageToken"); + Integer maxResults = options.get("maxResults") == null + ? null : Integer.valueOf((String) options.get("maxResults")); + // we are not reading sort by as it the only key is the change sequence + NavigableSet keys; + if ("descending".equals(sortOrder)) { + keys = changes.descendingKeySet(); + } else { + keys = changes.navigableKeySet(); + } + boolean listing = (pageToken == null); // matches will be included in the result if true + boolean sizeReached = false; // maximum result size was reached, we should not return more + boolean hasMorePages = false; // should next page token be included in the response? + LinkedList serializedResults = new LinkedList<>(); + String lastChangeId = null; + for (Integer key : keys) { + Change change = changes.get(key); + if (listing) { + lastChangeId = change.getId(); + if (sizeReached) { + // we do not add this, just note that there would be more and there should be a token + hasMorePages = true; + break; + } else { + try { + serializedResults.addLast(jsonFactory.toString( + OptionParsersAndExtractors.extractFields(change, fields))); + } catch (IOException e) { + return Error.INTERNAL_ERROR.response(String.format( + "Error when serializing change %s in managed zone %s in project %s", + change.getId(), zoneName, projectId)); + } + } + } + + // either we are listing already, or we check if we should start in the next iteration + listing = change.getId().equals(pageToken) || listing; + sizeReached = (maxResults != null) && maxResults.equals(serializedResults.size()); + } + boolean includePageToken = + hasMorePages && (fields == null || ImmutableList.copyOf(fields).contains("pageToken")); + return toListResponse(serializedResults, lastChangeId, includePageToken); + // todo(mderka) Test field and listing options within #665. + } + + /** + * Validates a zone to be created. + */ + static Response checkZone(ManagedZone zone) { + if (zone.getName() == null) { + return Error.REQUIRED.response( + "The 'entity.managedZone.name' parameter is required but was missing."); + } + if (zone.getDnsName() == null) { + return Error.REQUIRED.response( + "The 'entity.managedZone.dnsName' parameter is required but was missing."); + } + if (zone.getDescription() == null) { + return Error.REQUIRED.response( + "The 'entity.managedZone.description' parameter is required but was missing."); + } + try { + int number = Integer.valueOf(zone.getName()); + return Error.INVALID.response( + String.format("Invalid value for 'entity.managedZone.name': '%s'", number)); + } catch (NumberFormatException ex) { + // expected + } + if (zone.getName().isEmpty()) { + return Error.INVALID.response( + String.format("Invalid value for 'entity.managedZone.name': '%s'", zone.getName())); + } + if (zone.getDnsName().isEmpty() || !zone.getDnsName().endsWith(".")) { + return Error.INVALID.response( + String.format("Invalid value for 'entity.managedZone.dnsName': '%s'", zone.getDnsName())); + } + TreeSet forbidden = Sets.newTreeSet( + ImmutableList.of("google.com.", "com.", "example.com.", "net.", "org.")); + if (forbidden.contains(zone.getDnsName())) { + return Error.NOT_AVAILABLE.response(String.format( + "The '%s' managed zone is not available to be created.", zone.getDnsName())); + } + return null; + } + + /** + * Validates a change to be created. + */ + static Response checkChange(Change change, ZoneContainer zone) { + checkNotNull(zone); + if ((change.getDeletions() != null && change.getDeletions().size() > 0) + || (change.getAdditions() != null && change.getAdditions().size() > 0)) { + // ok, this is what we want + } else { + return Error.REQUIRED.response("The 'entity.change' parameter is required but was missing."); + } + if (change.getAdditions() != null) { + int counter = 0; + for (ResourceRecordSet addition : change.getAdditions()) { + Response response = checkRrset(addition, zone, counter, "additions"); + if (response != null) { + return response; + } + counter++; + } + } + if (change.getDeletions() != null) { + int counter = 0; + for (ResourceRecordSet deletion : change.getDeletions()) { + Response response = checkRrset(deletion, zone, counter, "deletions"); + if (response != null) { + return response; + } + counter++; + } + } + return additionsMeetDeletions(change.getAdditions(), change.getDeletions(), zone); + // null if everything is ok + } + + /** + * Checks a rrset within a change. + * + * @param type [additions|deletions] + * @param index the index or addition or deletion in the list + * @param zone the zone that this change is applied to + */ + static Response checkRrset(ResourceRecordSet rrset, ZoneContainer zone, int index, String type) { + if (rrset.getName() == null || !rrset.getName().endsWith(zone.zone().getDnsName())) { + return Error.INVALID.response(String.format( + "Invalid value for 'entity.change.%s[%s].name': '%s'", type, index, rrset.getName())); + } + if (rrset.getType() == null || !TYPES.contains(rrset.getType())) { + return Error.INVALID.response(String.format( + "Invalid value for 'entity.change.%s[%s].type': '%s'", type, index, rrset.getType())); + } + if (rrset.getTtl() != null && rrset.getTtl() != 0 && rrset.getTtl() < 0) { + return Error.INVALID.response(String.format( + "Invalid value for 'entity.change.%s[%s].ttl': '%s'", type, index, rrset.getTtl())); + } + if (rrset.getRrdatas() == null || rrset.isEmpty()) { + return Error.INVALID.response(String.format( + "Invalid value for 'entity.change.%s[%s].rrdata': '%s'", type, index, "")); + } + int counter = 0; + for (String record : rrset.getRrdatas()) { + if (!checkRrData(record, rrset.getType())) { + return Error.INVALID.response(String.format( + "Invalid value for 'entity.change.%s[%s].rrdata[%s]': '%s'", + type, index, counter, record)); + } + counter++; + } + if ("deletions".equals(type)) { + // check that deletion has a match by name and type + boolean found = false; + for (RrsetWrapper rrsetWrapper : zone.dnsRecords().get(zone.zone().getName())) { + ResourceRecordSet wrappedRrset = rrsetWrapper.rrset(); + if (rrset.getName().equals(wrappedRrset.getName()) + && rrset.getType().equals(wrappedRrset.getType())) { + found = true; + break; + } + } + if (!found) { + return Error.NOT_FOUND.response(String.format( + "The 'entity.change.deletions[%s]' resource named '%s (%s)' does not exist.", + index, rrset.getName(), rrset.getType())); + } + // if found, we still need an exact match + if ("deletions".equals(type) + && !zone.dnsRecords().get(zone.zone().getName()).contains(new RrsetWrapper(rrset))) { + // such a record does not exist + return Error.CONDITION_NOT_MET.response(String.format( + "Precondition not met for 'entity.change.deletions[%s]", index)); + } + } + return null; + } + + /** + * Checks that for each record that already exists, we have a matching deletion. Furthermore, + * check that mandatory SOA and NS records stay. + */ + static Response additionsMeetDeletions(List additions, + List deletions, ZoneContainer zone) { + if (additions != null) { + int index = 0; + for (ResourceRecordSet rrset : additions) { + for (RrsetWrapper wrapper : zone.dnsRecords().get(zone.zone().getName())) { + ResourceRecordSet wrappedRrset = wrapper.rrset(); + if (rrset.getName().equals(wrappedRrset.getName()) + && rrset.getType().equals(wrappedRrset.getType())) { + // such a record exist and we must have a deletion + if (deletions == null || !deletions.contains(wrappedRrset)) { + return Error.ALREADY_EXISTS.response(String.format( + "The 'entity.change.additions[%s]' resource named '%s (%s)' already exists.", + index, rrset.getName(), rrset.getType())); + } + } + } + if (rrset.getType().equals("SOA") && findByNameAndType(deletions, null, "SOA") == null) { + return Error.INVALID_ZONE_APEX.response(String.format("The resource record set 'entity" + + ".change.additions[%s]' is invalid because a zone must contain exactly one resource" + + " record set of type 'SOA' at the apex.", index)); + } + if (rrset.getType().equals("NS") && findByNameAndType(deletions, null, "NS") == null) { + return Error.INVALID_ZONE_APEX.response(String.format("The resource record set 'entity" + + ".change.additions[%s]' is invalid because a zone must contain exactly one resource" + + " record set of type 'NS' at the apex.", index)); + } + index++; + } + } + if (deletions != null) { + int index = 0; + for (ResourceRecordSet rrset : deletions) { + if (rrset.getType().equals("SOA") && findByNameAndType(additions, null, "SOA") == null) { + return Error.INVALID_ZONE_APEX.response(String.format("The resource record set 'entity" + + ".change.deletions[%s]' is invalid because a zone must contain exactly one resource" + + " record set of type 'SOA' at the apex.", index)); + } + if (rrset.getType().equals("NS") && findByNameAndType(additions, null, "NS") == null) { + return Error.INVALID_ZONE_APEX.response(String.format("The resource record set 'entity" + + ".change.deletions[%s]' is invalid because a zone must contain exactly one resource" + + " record set of type 'NS' at the apex.", index)); + } + index++; + } + } + return null; + } + + /** + * Helper for searching rrsets in a collection. + */ + private static ResourceRecordSet findByNameAndType(Iterable records, + String name, String type) { + if (records != null) { + for (ResourceRecordSet rrset : records) { + if ((name == null || name.equals(rrset.getName())) + && (type == null || type.equals(rrset.getType()))) { + return rrset; + } + } + } + return null; + } + + /** + * We only provide the most basic validation for A and AAAA records. + */ + static boolean checkRrData(String data, String type) { + // todo add validation for other records + String[] tokens; + switch (type) { + case "A": + tokens = data.split("\\."); + if (tokens.length != 4) { + return false; + } + for (String token : tokens) { + try { + Integer number = Integer.valueOf(token); + if (number < 0 || number > 255) { + return false; + } + } catch (NumberFormatException ex) { + return false; + } + } + return true; + case "AAAA": + tokens = data.split(":", -1); + if (tokens.length != 8) { + return false; + } + for (String token : tokens) { + try { + if (!token.isEmpty()) { + // empty is ok + Long number = Long.parseLong(token, 16); + if (number < 0 || number > 0xFFFF) { + return false; + } + } + } catch (NumberFormatException ex) { + return false; + } + } + return true; + default: + return true; + } + } + + /** + * Check supplied listing options. + */ + static Response checkListOptions(Map options) { + // for general listing + String maxResultsString = (String) options.get("maxResults"); + if (maxResultsString != null) { + Integer maxResults = null; + try { + maxResults = Integer.valueOf(maxResultsString); + } catch (NumberFormatException ex) { + return Error.INVALID.response(String.format( + "Invalid integer value': '%s'.", maxResultsString)); + } + if (maxResults <= 0) { + return Error.INVALID.response(String.format( + "Invalid value for 'parameters.maxResults': '%s'", maxResults)); + } + } + String dnsName = (String) options.get("dnsName"); + if (dnsName != null) { + if (!dnsName.endsWith(".")) { + return Error.INVALID.response(String.format( + "Invalid value for 'parameters.dnsName': '%s'", dnsName)); + } + } + // for listing dns records, name must be fully qualified + String name = (String) options.get("name"); + if (name != null) { + if (!name.endsWith(".")) { + return Error.INVALID.response(String.format( + "Invalid value for 'parameters.name': '%s'", name)); + } + } + String type = (String) options.get("type"); // must be provided with name + if (type != null) { + if (name == null) { + return Error.INVALID.response("Invalid value for 'parameters.name': ''"); + } + if (!TYPES.contains(type)) { + return Error.INVALID.response(String.format( + "Invalid value for 'parameters.type': '%s'", type)); + } + } + // for listing changes + String order = (String) options.get("sortOrder"); + if (order != null && !"ascending".equals(order) && !"descending".equals(order)) { + return Error.INVALID.response(String.format( + "Invalid value for 'parameters.sortOrder': '%s'", order)); + } + String sortBy = (String) options.get("sortBy"); // case insensitive + if (sortBy != null && !"changesequence".equals(sortBy.toLowerCase())) { + return Error.INVALID.response(String.format( + "Invalid string value: '%s'. Allowed values: [changesequence]", sortBy)); + } + return null; + } +} diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/testing/OptionParsersAndExtractors.java b/gcloud-java-dns/src/main/java/com/google/gcloud/testing/OptionParsersAndExtractors.java new file mode 100644 index 000000000000..f94cb15779ca --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/testing/OptionParsersAndExtractors.java @@ -0,0 +1,279 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.testing; + +import com.google.api.services.dns.model.Change; +import com.google.api.services.dns.model.ManagedZone; +import com.google.api.services.dns.model.Project; +import com.google.api.services.dns.model.ResourceRecordSet; + +import java.util.HashMap; +import java.util.Map; + +/** + * Utility helpers for LocalDnsHelper. + */ +class OptionParsersAndExtractors { + + /** + * Makes a map of list options. Expects query to be only query part of the url (i.e., what follows + * the '?'). + */ + static Map parseListZonesOptions(String query) { + Map options = new HashMap<>(); + if (query != null) { + String[] args = query.split("&"); + for (String arg : args) { + String[] argEntry = arg.split("="); + switch (argEntry[0]) { + case "fields": + // List fields are in the form "managedZones(field1, field2, ...)" + options.put( + "fields", + argEntry[1].substring("managedZones(".length(), argEntry[1].length() - 1) + .split(",")); + break; + case "dnsName": + options.put("dnsName", argEntry[1]); + break; + case "pageToken": + options.put("pageToken", argEntry[1]); + break; + case "maxResults": + // parsing to int is done while handling + options.put("maxResults", argEntry[1]); + break; + default: + break; + } + } + } + return options; + } + + /** + * Makes a map of list options. Expects query to be only query part of the url (i.e., what follows + * the '?'). This format is common for all of zone, change and project. + */ + static String[] parseGetOptions(String query) { + if (query != null) { + String[] args = query.split("&"); + for (String arg : args) { + String[] argEntry = arg.split("="); + if (argEntry[0].equals("fields")) { + // List fields are in the form "fields=field1, field2,..." + return argEntry[1].split(","); + } + } + } + return null; + } + + /** + * Extracts only request fields. + */ + static ManagedZone extractFields(ManagedZone fullZone, String[] fields) { + if (fields == null) { + return fullZone; + } + ManagedZone managedZone = new ManagedZone(); + for (String field : fields) { + switch (field) { + case "creationTime": + managedZone.setCreationTime(fullZone.getCreationTime()); + break; + case "description": + managedZone.setDescription(fullZone.getDescription()); + break; + case "dnsName": + managedZone.setDnsName(fullZone.getDnsName()); + break; + case "id": + managedZone.setId(fullZone.getId()); + break; + case "name": + managedZone.setName(fullZone.getName()); + break; + case "nameServerSet": + managedZone.setNameServerSet(fullZone.getNameServerSet()); + break; + case "nameServers": + managedZone.setNameServers(fullZone.getNameServers()); + break; + default: + break; + } + } + return managedZone; + } + + /** + * Extracts only request fields. + */ + static Change extractFields(Change fullChange, String[] fields) { + if (fields == null) { + return fullChange; + } + Change change = new Change(); + for (String field : fields) { + switch (field) { + case "additions": + // todo the fragmentation is ignored here as our api does not support it + change.setAdditions(fullChange.getAdditions()); + break; + case "deletions": + // todo the fragmentation is ignored here as our api does not support it + change.setDeletions(fullChange.getDeletions()); + break; + case "id": + change.setId(fullChange.getId()); + break; + case "startTime": + change.setStartTime(fullChange.getStartTime()); + break; + case "status": + change.setStatus(fullChange.getStatus()); + break; + default: + break; + } + } + return change; + } + + /** + * Extracts only request fields. + */ + static Project extractFields(Project fullProject, String[] fields) { + if (fields == null) { + return fullProject; + } + Project project = new Project(); + for (String field : fields) { + switch (field) { + case "id": + project.setId(fullProject.getId()); + break; + case "number": + project.setNumber(fullProject.getNumber()); + break; + case "quota": + project.setQuota(fullProject.getQuota()); + break; + default: + break; + } + } + return project; + } + + /** + * Extracts only request fields. + */ + static ResourceRecordSet extractFields(ResourceRecordSet fullRecord, String[] fields) { + if (fields == null) { + return fullRecord; + } + ResourceRecordSet record = new ResourceRecordSet(); + for (String field : fields) { + switch (field) { + case "name": + record.setName(fullRecord.getName()); + break; + case "rrdatas": + record.setRrdatas(fullRecord.getRrdatas()); + break; + case "type": + record.setType(fullRecord.getType()); + break; + case "ttl": + record.setTtl(fullRecord.getTtl()); + break; + default: + break; + } + } + return record; + } + + static Map parseListChangesOptions(String query) { + Map options = new HashMap<>(); + if (query != null) { + String[] args = query.split("&"); + for (String arg : args) { + String[] argEntry = arg.split("="); + switch (argEntry[0]) { + case "fields": + // todo we do not support fragmentation in deletions and additions + options.put( + "fields", + argEntry[1].substring("changes(".length(), argEntry[1].length() - 1).split(",")); + break; + case "name": + options.put("name", argEntry[1]); + break; + case "pageToken": + options.put("pageToken", argEntry[1]); + break; + case "sortBy": + options.put("sortBy", argEntry[1]); + break; + case "sortOrder": + options.put("sortOrder", argEntry[1]); + break; + case "maxResults": + // parsing to int is done while handling + options.put("maxResults", argEntry[1]); + break; + default: + break; + } + } + } + return options; + } + + static Map parseListDnsRecordsOptions(String query) { + Map options = new HashMap<>(); + if (query != null) { + String[] args = query.split("&"); + for (String arg : args) { + String[] argEntry = arg.split("="); + switch (argEntry[0]) { + case "fields": + options.put( + "fields", + argEntry[1].substring("rrsets(".length(), argEntry[1].length() - 1).split(",")); + break; + case "name": + options.put("name", argEntry[1]); + break; + case "pageToken": + options.put("pageToken", argEntry[1]); + break; + case "maxResults": + // parsing to int is done while handling + options.put("maxResults", argEntry[1]); + break; + default: + break; + } + } + } + return options; + } +} diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/testing/LocalDnsHelperTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/testing/LocalDnsHelperTest.java new file mode 100644 index 000000000000..1f851045659c --- /dev/null +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/testing/LocalDnsHelperTest.java @@ -0,0 +1,955 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.testing; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.google.api.services.dns.model.Change; +import com.google.api.services.dns.model.ManagedZone; +import com.google.api.services.dns.model.ResourceRecordSet; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +public class LocalDnsHelperTest { + + private static final String RRSET_TYPE = "A"; + private static final ResourceRecordSet RRSET1 = new ResourceRecordSet(); + private static final ResourceRecordSet RRSET2 = new ResourceRecordSet(); + private static final ResourceRecordSet RRSET_KEEP = new ResourceRecordSet(); + private static final String PROJECT_ID1 = "2135436541254"; + private static final String PROJECT_ID2 = "882248761325"; + private static final String ZONE_NAME1 = "my little zone"; + private static final String ZONE_NAME2 = "another zone name"; + private static final ManagedZone ZONE1 = new ManagedZone(); + private static final ManagedZone ZONE2 = new ManagedZone(); + private static final String DNS_NAME = "www.example.com."; + private static final Change CHANGE1 = new Change(); + private static final Change CHANGE2 = new Change(); + private static final Change CHANGE_KEEP = new Change(); + private Map optionsMap; + private LocalDnsHelper localDns; + private ManagedZone minimalZone = new ManagedZone(); // to be adjusted as needed + + @BeforeClass + public static void before() { + RRSET1.setName(DNS_NAME); + RRSET1.setType(RRSET_TYPE); + RRSET1.setRrdatas(ImmutableList.of("1.1.1.1")); + ZONE1.setName(ZONE_NAME1); + ZONE1.setDescription(""); + ZONE1.setDnsName(DNS_NAME); + ZONE2.setName(ZONE_NAME2); + ZONE2.setDescription(""); + ZONE2.setDnsName(DNS_NAME); + RRSET2.setName(DNS_NAME); + RRSET2.setType(RRSET_TYPE); + RRSET_KEEP.setName(DNS_NAME); + RRSET_KEEP.setType("MX"); + RRSET_KEEP.setRrdatas(ImmutableList.of("255.255.255.254")); + RRSET2.setRrdatas(ImmutableList.of("123.132.153.156")); + CHANGE1.setAdditions(ImmutableList.of(RRSET1, RRSET2)); + CHANGE2.setDeletions(ImmutableList.of(RRSET2)); + CHANGE_KEEP.setAdditions(ImmutableList.of(RRSET_KEEP)); + } + + @Before + public void setUp() { + localDns = LocalDnsHelper.create(0L); // synchronous + optionsMap = new HashMap<>(); + minimalZone = copyZone(ZONE1); + } + + @After + public void after() { + localDns = null; + } + + @Test + public void testMatchesCriteria() { + assertTrue(LocalDnsHelper.matchesCriteria(RRSET1, RRSET1.getName(), RRSET1.getType())); + assertFalse(LocalDnsHelper.matchesCriteria(RRSET1, RRSET1.getName(), "anothertype")); + assertTrue(LocalDnsHelper.matchesCriteria(RRSET1, null, RRSET1.getType())); + assertTrue(LocalDnsHelper.matchesCriteria(RRSET1, RRSET1.getName(), null)); + assertFalse(LocalDnsHelper.matchesCriteria(RRSET1, "anothername", RRSET1.getType())); + } + + @Test + public void testGetUniqueId() { + assertNotNull(LocalDnsHelper.getUniqueId(Lists.newLinkedList())); + } + + @Test + public void testFindProject() { + assertEquals(0, localDns.projects().size()); + LocalDnsHelper.ProjectContainer project = localDns.findProject(PROJECT_ID1); + assertNotNull(project); + assertTrue(localDns.projects().containsKey(PROJECT_ID1)); + assertNotNull(localDns.findProject(PROJECT_ID2)); + assertTrue(localDns.projects().containsKey(PROJECT_ID2)); + assertTrue(localDns.projects().containsKey(PROJECT_ID1)); + assertNotNull(project.zones()); + assertEquals(0, project.zones().size()); + assertNotNull(project.project()); + assertNotNull(project.project().getQuota()); + } + + @Test + public void testCreateAndFindZone() { + LocalDnsHelper.ZoneContainer zone1 = localDns.findZone(PROJECT_ID1, ZONE_NAME1); + assertTrue(localDns.projects().containsKey(PROJECT_ID1)); + assertNull(zone1); + localDns.createZone(PROJECT_ID1, ZONE1, null); // we do not care about options + zone1 = localDns.findZone(PROJECT_ID1, ZONE1.getName()); + assertNotNull(zone1); + // cannot call equals because id and timestamp got assigned + assertEquals(ZONE_NAME1, zone1.zone().getName()); + assertNotNull(zone1.changes()); + assertTrue(zone1.changes().isEmpty()); + assertNotNull(zone1.dnsRecords()); + assertEquals(2, zone1.dnsRecords().get(ZONE_NAME1).size()); // default SOA and NS + localDns.createZone(PROJECT_ID2, ZONE1, null); // project does not exits yet + assertEquals(ZONE1.getName(), localDns.findZone(PROJECT_ID2, ZONE_NAME1).zone().getName()); + } + + @Test + public void testDeleteZone() { + localDns.createZone(PROJECT_ID1, ZONE1, null); + LocalDnsHelper.Response response = localDns.deleteZone(PROJECT_ID1, ZONE1.getName()); + assertEquals(204, response.code()); + // deleting non-existent zone + response = localDns.deleteZone(PROJECT_ID1, ZONE1.getName()); + assertEquals(404, response.code()); + assertNull(localDns.findZone(PROJECT_ID1, ZONE1.getName())); + localDns.createZone(PROJECT_ID1, ZONE1, null); + localDns.createZone(PROJECT_ID1, ZONE2, null); + assertNotNull(localDns.findZone(PROJECT_ID1, ZONE1.getName())); + assertNotNull(localDns.findZone(PROJECT_ID1, ZONE2.getName())); + // delete in reverse order + response = localDns.deleteZone(PROJECT_ID1, ZONE1.getName()); + assertEquals(204, response.code()); + assertNull(localDns.findZone(PROJECT_ID1, ZONE1.getName())); + assertNotNull(localDns.findZone(PROJECT_ID1, ZONE2.getName())); + localDns.deleteZone(PROJECT_ID1, ZONE2.getName()); + assertEquals(204, response.code()); + assertNull(localDns.findZone(PROJECT_ID1, ZONE1.getName())); + assertNull(localDns.findZone(PROJECT_ID1, ZONE2.getName())); + } + + @Test + public void testCreateAndApplyChange() { + localDns = LocalDnsHelper.create(5 * 1000L); // we will be using threads here + localDns.createZone(PROJECT_ID1, ZONE1, null); + assertNull(localDns.findZone(PROJECT_ID1, ZONE_NAME1).findChange("1")); + LocalDnsHelper.Response response + = localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); // add + assertEquals(200, response.code()); + assertNotNull(localDns.findZone(PROJECT_ID1, ZONE_NAME1).findChange("1")); + assertNull(localDns.findZone(PROJECT_ID1, ZONE_NAME1).findChange("2")); + localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); // add + response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); // add + assertEquals(200, response.code()); + assertNotNull(localDns.findZone(PROJECT_ID1, ZONE_NAME1).findChange("1")); + assertNotNull(localDns.findZone(PROJECT_ID1, ZONE_NAME1).findChange("2")); + localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE2, null); // delete + assertNotNull(localDns.findZone(PROJECT_ID1, ZONE_NAME1).findChange("1")); + assertNotNull(localDns.findZone(PROJECT_ID1, ZONE_NAME1).findChange("2")); + assertNotNull(localDns.findZone(PROJECT_ID1, ZONE_NAME1).findChange("3")); + localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE_KEEP, null); // id is "4" + // check execution + Change change = localDns.findChange(PROJECT_ID1, ZONE_NAME1, "4"); + for (int i = 0; i < 10 && !change.getStatus().equals("done"); i++) { + // change has not been finished yet; wait at most 20 seconds + // it takes 5 seconds for the thread to kick in in the first place + try { + Thread.sleep(2 * 1000); + } catch (InterruptedException e) { + fail("Test was interrupted"); + } + } + assertEquals("done", change.getStatus()); + List list = + localDns.findZone(PROJECT_ID1, ZONE_NAME1).dnsRecords().get(ZONE_NAME1); + assertTrue(list.contains(new LocalDnsHelper.RrsetWrapper(RRSET_KEEP))); + } + + @Test + public void testFindChange() { + localDns.createZone(PROJECT_ID1, ZONE1, null); + Change change = localDns.findChange(PROJECT_ID1, ZONE1.getName(), "somerandomchange"); + assertNull(change); + localDns.createChange(PROJECT_ID1, ZONE1.getName(), CHANGE1, null); + // changes are sequential so we should find ID 1 + assertNotNull(localDns.findChange(PROJECT_ID1, ZONE1.getName(), "1")); + // add another + localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE2, null); + assertNotNull(localDns.findChange(PROJECT_ID1, ZONE1.getName(), "1")); + assertNotNull(localDns.findChange(PROJECT_ID1, ZONE1.getName(), "2")); + // try to find non-existent change + assertNull(localDns.findChange(PROJECT_ID1, ZONE1.getName(), "3")); + // try to find a change in yet non-existent project + assertNull(localDns.findChange(PROJECT_ID2, ZONE1.getName(), "3")); + } + + @Test + public void testRandomNameServers() { + assertEquals(4, LocalDnsHelper.randomNameservers().size()); + assertEquals(4, LocalDnsHelper.randomNameservers().size()); + assertEquals(4, LocalDnsHelper.randomNameservers().size()); + assertEquals(4, LocalDnsHelper.randomNameservers().size()); + } + + @Test + public void testGetProject() { + // only interested in no exceptions and non-null response here + assertNotNull(localDns.getProject(PROJECT_ID1, null)); + assertNotNull(localDns.getProject(PROJECT_ID2, null)); + } + + @Test + public void testGetZone() { + // non-existent + LocalDnsHelper.Response response = localDns.getZone(PROJECT_ID1, ZONE_NAME1, null); + assertEquals(404, response.code()); + assertTrue(response.body().contains("does not exist")); + // existent + localDns.createZone(PROJECT_ID1, ZONE1, null); + response = localDns.getZone(PROJECT_ID1, ZONE1.getName(), null); + assertEquals(200, response.code()); + } + + @Test + public void testCreateZone() { + // only interested in no exceptions and non-null response here + LocalDnsHelper.Response response = localDns.createZone(PROJECT_ID1, ZONE1, null); + assertEquals(200, response.code()); + assertEquals(1, localDns.projects().get(PROJECT_ID1).zones().size()); + try { + localDns.createZone(PROJECT_ID1, null, null); + fail("Zone cannot be null"); + } catch (NullPointerException ex) { + // expected + } + // create zone twice + response = localDns.createZone(PROJECT_ID1, ZONE1, null); + assertEquals(409, response.code()); + assertTrue(response.body().contains("already exists")); + } + + @Test + public void testCreateChange() { + // non-existent zone + LocalDnsHelper.Response response = + localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); + assertEquals(404, response.code()); + + // existent zone + assertNotNull(localDns.createZone(PROJECT_ID1, ZONE1, null)); + assertNull(localDns.findChange(PROJECT_ID1, ZONE_NAME1, "1")); + response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); + assertEquals(200, response.code()); + assertNotNull(localDns.findChange(PROJECT_ID1, ZONE_NAME1, "1")); + } + + @Test + public void testGetChange() { + // existent + assertEquals(200, localDns.createZone(PROJECT_ID1, ZONE1, null).code()); + assertEquals(200, localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null).code()); + assertEquals(200, localDns.getChange(PROJECT_ID1, ZONE_NAME1, "1", null).code()); + // non-existent + LocalDnsHelper.Response response = localDns.getChange(PROJECT_ID1, ZONE_NAME1, "2", null); + assertEquals(404, response.code()); + assertTrue(response.body().contains("parameters.changeId")); + // non-existent zone + response = localDns.getChange(PROJECT_ID1, ZONE_NAME2, "1", null); + assertEquals(404, response.code()); + assertTrue(response.body().contains("parameters.managedZone")); + } + + @Test + public void testListZones() { + // only interested in no exceptions and non-null response here + optionsMap.put("dnsName", null); + optionsMap.put("fields", null); + optionsMap.put("pageToken", null); + optionsMap.put("maxResults", null); + LocalDnsHelper.Response response = localDns.listZones(PROJECT_ID1, optionsMap); + assertEquals(200, response.code()); + // some zones exists + localDns.createZone(PROJECT_ID1, ZONE1, null); + response = localDns.listZones(PROJECT_ID1, optionsMap); + assertEquals(200, response.code()); + localDns.createZone(PROJECT_ID1, ZONE2, null); + response = localDns.listZones(PROJECT_ID1, optionsMap); + assertEquals(200, response.code()); + // error in options + optionsMap.put("maxResults", "aaa"); + response = localDns.listZones(PROJECT_ID1, optionsMap); + assertEquals(400, response.code()); + optionsMap.put("maxResults", "0"); + response = localDns.listZones(PROJECT_ID1, optionsMap); + assertEquals(400, response.code()); + optionsMap.put("maxResults", "-1"); + response = localDns.listZones(PROJECT_ID1, optionsMap); + assertEquals(400, response.code()); + optionsMap.put("maxResults", "15"); + response = localDns.listZones(PROJECT_ID1, optionsMap); + assertEquals(200, response.code()); + optionsMap.put("dnsName", "aaa"); + response = localDns.listZones(PROJECT_ID1, optionsMap); + assertEquals(400, response.code()); + optionsMap.put("dnsName", "aaa."); + response = localDns.listZones(PROJECT_ID1, optionsMap); + assertEquals(200, response.code()); + } + + @Test + public void testListDnsRecords() { + // only interested in no exceptions and non-null response here + optionsMap.put("name", null); + optionsMap.put("fields", null); + optionsMap.put("type", null); + optionsMap.put("pageToken", null); + optionsMap.put("maxResults", null); + // no zone exists + LocalDnsHelper.Response response = localDns.listDnsRecords(PROJECT_ID1, ZONE_NAME1, + optionsMap); + assertEquals(404, response.code()); + // zone exists but has no records + localDns.createZone(PROJECT_ID1, ZONE1, null); + localDns.listDnsRecords(PROJECT_ID1, ZONE_NAME1, optionsMap); + // zone has records + localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); + response = localDns.listDnsRecords(PROJECT_ID1, ZONE_NAME1, optionsMap); + assertEquals(200, response.code()); + // error in options + optionsMap.put("maxResults", "aaa"); + response = localDns.listZones(PROJECT_ID1, optionsMap); + assertEquals(400, response.code()); + optionsMap.put("maxResults", "0"); + response = localDns.listZones(PROJECT_ID1, optionsMap); + assertEquals(400, response.code()); + optionsMap.put("maxResults", "-1"); + response = localDns.listZones(PROJECT_ID1, optionsMap); + assertEquals(400, response.code()); + optionsMap.put("maxResults", "15"); + response = localDns.listZones(PROJECT_ID1, optionsMap); + assertEquals(200, response.code()); + optionsMap.put("name", "aaa"); + response = localDns.listZones(PROJECT_ID1, optionsMap); + assertEquals(400, response.code()); + optionsMap.put("name", "aaa."); + response = localDns.listZones(PROJECT_ID1, optionsMap); + assertEquals(200, response.code()); + optionsMap.put("name", null); + optionsMap.put("type", "A"); + response = localDns.listZones(PROJECT_ID1, optionsMap); + assertEquals(400, response.code()); + optionsMap.put("name", "aaa."); + optionsMap.put("type", "a"); + response = localDns.listZones(PROJECT_ID1, optionsMap); + assertEquals(400, response.code()); + optionsMap.put("name", "aaaa."); + optionsMap.put("type", "A"); + response = localDns.listZones(PROJECT_ID1, optionsMap); + assertEquals(200, response.code()); + } + + @Test + public void testListChanges() { + optionsMap.put("sortBy", null); + optionsMap.put("sortOrder", null); + optionsMap.put("fields", null); + optionsMap.put("pageToken", null); + optionsMap.put("maxResults", null); + // no such zone exists + LocalDnsHelper.Response response = localDns.listDnsRecords(PROJECT_ID1, ZONE_NAME1, optionsMap); + assertEquals(404, response.code()); + assertTrue(response.body().contains("managedZone")); + // zone exists but has no changes + localDns.createZone(PROJECT_ID1, ZONE1, null); + assertNotNull(localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap)); + // zone has changes + localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); + assertNotNull(localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap)); + localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); + localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE2, null); + localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE2, null); + assertNotNull(localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap)); + // error in options + optionsMap.put("maxResults", "aaa"); + response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); + assertEquals(400, response.code()); + optionsMap.put("maxResults", "0"); + response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); + assertEquals(400, response.code()); + optionsMap.put("maxResults", "-1"); + response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); + assertEquals(400, response.code()); + optionsMap.put("maxResults", "15"); + response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); + assertEquals(200, response.code()); + optionsMap.put("dnsName", "aaa"); + response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); + assertEquals(400, response.code()); + optionsMap.put("dnsName", "aaa."); + response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); + assertEquals(200, response.code()); + optionsMap.put("sortBy", "changeSequence"); + response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); + assertEquals(200, response.code()); + optionsMap.put("sortBy", "something else"); + response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); + assertEquals(400, response.code()); + assertTrue(response.body().contains("Allowed values: [changesequence]")); + optionsMap.put("sortBy", "ChAnGeSeQuEnCe"); // is not case sensitive + response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); + assertEquals(200, response.code()); + optionsMap.put("sortOrder", "ascending"); + response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); + assertEquals(200, response.code()); + optionsMap.put("sortBy", null); + optionsMap.put("sortOrder", "descending"); + response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); + assertEquals(200, response.code()); + optionsMap.put("sortOrder", "somethingelse"); + response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); + assertEquals(400, response.code()); + assertTrue(response.body().contains("parameters.sortOrder")); + } + + @Test + public void testToListResponse() { + LocalDnsHelper.Response response = LocalDnsHelper.toListResponse( + Lists.newArrayList("some", "multiple", "words"), "IncludeThisPageToken", true); + assertTrue(response.body().contains("IncludeThisPageToken")); + response = LocalDnsHelper.toListResponse( + Lists.newArrayList("some", "multiple", "words"), "IncludeThisPageToken", false); + assertFalse(response.body().contains("IncludeThisPageToken")); + response = LocalDnsHelper.toListResponse( + Lists.newArrayList("some", "multiple", "words"), null, true); + assertFalse(response.body().contains("pageToken")); + } + + @Test + public void testCheckZone() { + // no name + ManagedZone copy = copyZone(minimalZone); + copy.setName(null); + LocalDnsHelper.Response response = LocalDnsHelper.checkZone(copy); + assertEquals(400, response.code()); + assertTrue(response.body().contains("entity.managedZone.name")); + // no description + copy = copyZone(minimalZone); + copy.setDescription(null); + response = LocalDnsHelper.checkZone(copy); + assertEquals(400, response.code()); + assertTrue(response.body().contains("entity.managedZone.description")); + // no description + copy = copyZone(minimalZone); + copy.setDnsName(null); + response = LocalDnsHelper.checkZone(copy); + assertEquals(400, response.code()); + assertTrue(response.body().contains("entity.managedZone.dnsName")); + // zone name is a number + copy = copyZone(minimalZone); + copy.setName("123456"); + response = LocalDnsHelper.checkZone(copy); + assertEquals(400, response.code()); + assertTrue(response.body().contains("entity.managedZone.name")); + assertTrue(response.body().contains("Invalid")); + // dns name does not end with period + copy = copyZone(minimalZone); + copy.setDnsName("aaaaaa.com"); + response = LocalDnsHelper.checkZone(copy); + assertEquals(400, response.code()); + assertTrue(response.body().contains("entity.managedZone.dnsName")); + assertTrue(response.body().contains("Invalid")); + // dns name is reserved + copy = copyZone(minimalZone); + copy.setDnsName("com."); + response = LocalDnsHelper.checkZone(copy); + assertEquals(400, response.code()); + assertTrue(response.body().contains("not available to be created.")); + // empty description should pass + copy = copyZone(minimalZone); + copy.setDescription(""); + assertNull(LocalDnsHelper.checkZone(copy)); + } + + @Test + public void testCreateZoneValidatesZone() { + // no name + ManagedZone copy = copyZone(minimalZone); + copy.setName(null); + LocalDnsHelper.Response response = localDns.createZone(PROJECT_ID1, copy, null); + assertEquals(400, response.code()); + assertTrue(response.body().contains("entity.managedZone.name")); + // no description + copy = copyZone(minimalZone); + copy.setDescription(null); + response = localDns.createZone(PROJECT_ID1, copy, null); + assertEquals(400, response.code()); + assertTrue(response.body().contains("entity.managedZone.description")); + // no dns name + copy = copyZone(minimalZone); + copy.setDnsName(null); + response = localDns.createZone(PROJECT_ID1, copy, null); + assertEquals(400, response.code()); + assertTrue(response.body().contains("entity.managedZone.dnsName")); + // zone name is a number + copy = copyZone(minimalZone); + copy.setName("123456"); + response = localDns.createZone(PROJECT_ID1, copy, null); + assertEquals(400, response.code()); + assertTrue(response.body().contains("entity.managedZone.name")); + assertTrue(response.body().contains("Invalid")); + // dns name does not end with period + copy = copyZone(minimalZone); + copy.setDnsName("aaaaaa.com"); + response = localDns.createZone(PROJECT_ID1, copy, null); + assertEquals(400, response.code()); + assertTrue(response.body().contains("entity.managedZone.dnsName")); + assertTrue(response.body().contains("Invalid")); + // dns name is reserved + copy = copyZone(minimalZone); + copy.setDnsName("com."); + response = localDns.createZone(PROJECT_ID1, copy, null); + assertEquals(400, response.code()); + assertTrue(response.body().contains("not available to be created.")); + // empty description should pass + copy = copyZone(minimalZone); + copy.setDescription(""); + response = localDns.createZone(PROJECT_ID1, copy, null); + assertEquals(200, response.code()); + } + + @Test + public void testCheckListOptions() { + // listing zones + optionsMap.put("maxResults", "-1"); + LocalDnsHelper.Response response = LocalDnsHelper.checkListOptions(optionsMap); + assertEquals(400, response.code()); + assertTrue(response.body().contains("parameters.maxResults")); + optionsMap.put("maxResults", "0"); + response = LocalDnsHelper.checkListOptions(optionsMap); + assertEquals(400, response.code()); + assertTrue(response.body().contains("parameters.maxResults")); + optionsMap.put("maxResults", "aaaa"); + response = LocalDnsHelper.checkListOptions(optionsMap); + assertEquals(400, response.code()); + assertTrue(response.body().contains("integer")); + optionsMap.put("maxResults", "15"); + response = LocalDnsHelper.checkListOptions(optionsMap); + assertNull(response); + optionsMap.put("dnsName", "aaa"); + response = LocalDnsHelper.checkListOptions(optionsMap); + assertEquals(400, response.code()); + assertTrue(response.body().contains("parameters.dnsName")); + optionsMap.put("dnsName", "aaa."); + response = LocalDnsHelper.checkListOptions(optionsMap); + assertNull(response); + // listing dns records + optionsMap.put("name", "aaa"); + response = LocalDnsHelper.checkListOptions(optionsMap); + assertEquals(400, response.code()); + assertTrue(response.body().contains("parameters.name")); + optionsMap.put("name", "aaa."); + response = LocalDnsHelper.checkListOptions(optionsMap); + assertNull(response); + optionsMap.put("name", null); + optionsMap.put("type", "A"); + response = LocalDnsHelper.checkListOptions(optionsMap); + assertEquals(400, response.code()); + assertTrue(response.body().contains("parameters.name")); + optionsMap.put("name", "aaa."); + optionsMap.put("type", "a"); + response = LocalDnsHelper.checkListOptions(optionsMap); + assertEquals(400, response.code()); + assertTrue(response.body().contains("parameters.type")); + optionsMap.put("name", "aaaa."); + optionsMap.put("type", "A"); + response = LocalDnsHelper.checkListOptions(optionsMap); + assertNull(response); + // listing changes + optionsMap.put("sortBy", "changeSequence"); + response = LocalDnsHelper.checkListOptions(optionsMap); + assertNull(response); + optionsMap.put("sortBy", "something else"); + response = LocalDnsHelper.checkListOptions(optionsMap); + assertEquals(400, response.code()); + assertTrue(response.body().contains("Allowed values: [changesequence]")); + optionsMap.put("sortBy", "ChAnGeSeQuEnCe"); // is not case sensitive + response = LocalDnsHelper.checkListOptions(optionsMap); + assertNull(response); + optionsMap.put("sortOrder", "ascending"); + response = LocalDnsHelper.checkListOptions(optionsMap); + assertNull(response); + optionsMap.put("sortOrder", "descending"); + response = LocalDnsHelper.checkListOptions(optionsMap); + assertNull(response); + optionsMap.put("sortOrder", "somethingelse"); + response = LocalDnsHelper.checkListOptions(optionsMap); + assertEquals(400, response.code()); + assertTrue(response.body().contains("parameters.sortOrder")); + } + + @Test + public void testCheckRrset() { + ResourceRecordSet valid = new ResourceRecordSet(); + valid.setName(ZONE1.getDnsName()); + valid.setType("A"); + valid.setRrdatas(ImmutableList.of("0.255.1.5")); + valid.setTtl(500); + Change validChange = new Change(); + validChange.setAdditions(ImmutableList.of(valid)); + localDns.createZone(PROJECT_ID1, ZONE1, null); + localDns.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + // delete with field mismatch + LocalDnsHelper.ZoneContainer zone = localDns.findZone(PROJECT_ID1, ZONE_NAME1); + valid.setTtl(valid.getTtl() + 20); + LocalDnsHelper.Response response = LocalDnsHelper.checkRrset(valid, zone, 0, "deletions"); + assertEquals(412, response.code()); + assertTrue(response.body().contains("entity.change.deletions[0]")); + } + + @Test + public void testCheckRrdata() { + // A + assertTrue(LocalDnsHelper.checkRrData("255.255.255.255", "A")); + assertTrue(LocalDnsHelper.checkRrData("13.15.145.165", "A")); + assertTrue(LocalDnsHelper.checkRrData("0.0.0.0", "A")); + assertFalse(LocalDnsHelper.checkRrData("255.255.255.256", "A")); + assertFalse(LocalDnsHelper.checkRrData("-1.255.255.255", "A")); + assertFalse(LocalDnsHelper.checkRrData(".255.255.254", "A")); + assertFalse(LocalDnsHelper.checkRrData("111.255.255.", "A")); + assertFalse(LocalDnsHelper.checkRrData("111.255..22", "A")); + assertFalse(LocalDnsHelper.checkRrData("111.255.aa.22", "A")); + assertFalse(LocalDnsHelper.checkRrData("", "A")); + assertFalse(LocalDnsHelper.checkRrData("...", "A")); + assertFalse(LocalDnsHelper.checkRrData("111.255.12", "A")); + assertFalse(LocalDnsHelper.checkRrData("111.255.12.11.11", "A")); + // AAAA + assertTrue(LocalDnsHelper.checkRrData(":::::::", "AAAA")); + assertTrue(LocalDnsHelper.checkRrData("1F:fa:09fd::343:aaaa:AAAA:", "AAAA")); + assertTrue(LocalDnsHelper.checkRrData("0000:FFFF:09fd::343:aaaa:AAAA:", "AAAA")); + assertFalse(LocalDnsHelper.checkRrData("-2:::::::", "AAAA")); + assertTrue(LocalDnsHelper.checkRrData("0:::::::", "AAAA")); + assertFalse(LocalDnsHelper.checkRrData("::1FFFF:::::", "AAAA")); + assertFalse(LocalDnsHelper.checkRrData("::aqaa:::::", "AAAA")); + assertFalse(LocalDnsHelper.checkRrData("::::::::", "AAAA")); // too long + assertFalse(LocalDnsHelper.checkRrData("::::::", "AAAA")); // too short + } + + @Test + public void testCheckChange() { + ResourceRecordSet validA = new ResourceRecordSet(); + validA.setName(ZONE1.getDnsName()); + validA.setType("A"); + validA.setRrdatas(ImmutableList.of("0.255.1.5")); + ResourceRecordSet invalidA = new ResourceRecordSet(); + invalidA.setName(ZONE1.getDnsName()); + invalidA.setType("A"); + invalidA.setRrdatas(ImmutableList.of("0.-255.1.5")); + Change validChange = new Change(); + validChange.setAdditions(ImmutableList.of(validA)); + Change invalidChange = new Change(); + invalidChange.setAdditions(ImmutableList.of(invalidA)); + LocalDnsHelper.ZoneContainer zoneContainer = new LocalDnsHelper.ZoneContainer(ZONE1); + LocalDnsHelper.Response response = LocalDnsHelper.checkChange(validChange, zoneContainer); + assertNull(response); + response = LocalDnsHelper.checkChange(invalidChange, zoneContainer); + assertEquals(400, response.code()); + assertTrue(response.body().contains("additions[0].rrdata[0]")); + // only empty additions/deletions + Change empty = new Change(); + empty.setAdditions(ImmutableList.of()); + empty.setDeletions(ImmutableList.of()); + response = LocalDnsHelper.checkChange(empty, zoneContainer); + assertEquals(400, response.code()); + assertTrue(response.body().contains( + "The 'entity.change' parameter is required but was missing.")); + // null additions/deletions + empty = new Change(); + response = LocalDnsHelper.checkChange(empty, zoneContainer); + assertEquals(400, response.code()); + assertTrue(response.body().contains( + "The 'entity.change' parameter is required but was missing.")); + // non-matching name + validA.setName(ZONE1.getDnsName() + ".aaa."); + response = LocalDnsHelper.checkChange(validChange, zoneContainer); + assertEquals(400, response.code()); + assertTrue(response.body().contains("additions[0].name")); + // wrong type + validA.setName(ZONE1.getDnsName()); // revert + validA.setType("ABCD"); + response = LocalDnsHelper.checkChange(validChange, zoneContainer); + assertEquals(400, response.code()); + assertTrue(response.body().contains("additions[0].type")); + // wrong ttl + validA.setType("A"); // revert + validA.setTtl(-1); + response = LocalDnsHelper.checkChange(validChange, zoneContainer); + assertEquals(400, response.code()); + assertTrue(response.body().contains("additions[0].ttl")); + validA.setTtl(null); + // null name + validA.setName(null); + response = LocalDnsHelper.checkChange(validChange, zoneContainer); + assertEquals(400, response.code()); + assertTrue(response.body().contains("additions[0].name")); + validA.setName(ZONE1.getDnsName()); + // null type + validA.setType(null); + response = LocalDnsHelper.checkChange(validChange, zoneContainer); + assertEquals(400, response.code()); + assertTrue(response.body().contains("additions[0].type")); + validA.setType("A"); + // null rrdata + List temp = validA.getRrdatas(); // preserve + validA.setRrdatas(null); + response = LocalDnsHelper.checkChange(validChange, zoneContainer); + assertEquals(400, response.code()); + assertTrue(response.body().contains("additions[0].rrdata")); + validA.setRrdatas(temp); + // delete non-existent + ResourceRecordSet nonExistent = new ResourceRecordSet(); + nonExistent.setName(ZONE1.getDnsName()); + nonExistent.setType("AAAA"); + nonExistent.setRrdatas(ImmutableList.of(":::::::")); + Change delete = new Change(); + delete.setDeletions(ImmutableList.of(nonExistent)); + response = LocalDnsHelper.checkChange(delete, zoneContainer); + assertEquals(404, response.code()); + assertTrue(response.body().contains("deletions[0]")); + + } + + @Test + public void testAdditionsMeetDeletions() { + ResourceRecordSet validA = new ResourceRecordSet(); + validA.setName(ZONE1.getDnsName()); + validA.setType("A"); + validA.setRrdatas(ImmutableList.of("0.255.1.5")); + Change validChange = new Change(); + validChange.setAdditions(ImmutableList.of(validA)); + localDns.createZone(PROJECT_ID1, ZONE1, null); + localDns.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + LocalDnsHelper.ZoneContainer container = localDns.findZone(PROJECT_ID1, ZONE_NAME1); + LocalDnsHelper.Response response = + LocalDnsHelper.additionsMeetDeletions(ImmutableList.of(validA), null, container); + assertEquals(409, response.code()); + assertTrue(response.body().contains("already exists")); + + } + + @Test + public void testCreateChangeValidatesChangeContent() { + ResourceRecordSet validA = new ResourceRecordSet(); + validA.setName(ZONE1.getDnsName()); + validA.setType("A"); + validA.setRrdatas(ImmutableList.of("0.255.1.5")); + Change validChange = new Change(); + validChange.setAdditions(ImmutableList.of(validA)); + localDns.createZone(PROJECT_ID1, ZONE1, null); + localDns.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + LocalDnsHelper.Response response = + localDns.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + assertEquals(409, response.code()); + assertTrue(response.body().contains("already exists")); + // delete with field mismatch + Change delete = new Change(); + validA.setTtl(20); // mismatch + delete.setDeletions(ImmutableList.of(validA)); + response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, delete, null); + assertEquals(412, response.code()); + assertTrue(response.body().contains("entity.change.deletions[0]")); + // delete and add SOA + Change addition = new Change(); + ImmutableList rrsetWrappers + = localDns.findZone(PROJECT_ID1, ZONE_NAME1).dnsRecords().get(ZONE_NAME1); + LinkedList deletions = new LinkedList<>(); + LinkedList additions = new LinkedList<>(); + for (LocalDnsHelper.RrsetWrapper wrapper : rrsetWrappers) { + ResourceRecordSet rrset = wrapper.rrset(); + if (rrset.getType().equals("SOA")) { + deletions.add(rrset); + ResourceRecordSet copy = copyRrset(rrset); + copy.setName("x." + copy.getName()); + additions.add(copy); + break; + } + } + delete.setDeletions(deletions); + addition.setAdditions(additions); + response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, delete, null); + assertEquals(400, response.code()); + assertTrue(response.body().contains( + "zone must contain exactly one resource record set of type 'SOA' at the apex")); + assertTrue(response.body().contains("deletions[0]")); + response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, addition, null); + assertEquals(400, response.code()); + assertTrue(response.body().contains( + "zone must contain exactly one resource record set of type 'SOA' at the apex")); + assertTrue(response.body().contains("additions[0]")); + // delete NS + deletions = new LinkedList<>(); + additions = new LinkedList<>(); + for (LocalDnsHelper.RrsetWrapper wrapper : rrsetWrappers) { + ResourceRecordSet rrset = wrapper.rrset(); + if (rrset.getType().equals("NS")) { + deletions.add(rrset); + ResourceRecordSet copy = copyRrset(rrset); + copy.setName("x." + copy.getName()); + additions.add(copy); + break; + } + } + delete.setDeletions(deletions); + addition.setAdditions(additions); + response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, delete, null); + assertEquals(400, response.code()); + assertTrue(response.body().contains( + "zone must contain exactly one resource record set of type 'NS' at the apex")); + response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, addition, null); + assertEquals(400, response.code()); + assertTrue(response.body().contains( + "zone must contain exactly one resource record set of type 'NS' at the apex")); + assertTrue(response.body().contains("additions[0]")); + // change (delete + add) + addition.setDeletions(deletions); + response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, addition, null); + assertEquals(200, response.code()); + } + + @Test + public void testCreateChangeValidatesChange() { + localDns.createZone(PROJECT_ID1, ZONE1, null); + ResourceRecordSet validA = new ResourceRecordSet(); + validA.setName(ZONE1.getDnsName()); + validA.setType("A"); + validA.setRrdatas(ImmutableList.of("0.255.1.5")); + ResourceRecordSet invalidA = new ResourceRecordSet(); + invalidA.setName(ZONE1.getDnsName()); + invalidA.setType("A"); + invalidA.setRrdatas(ImmutableList.of("0.-255.1.5")); + Change validChange = new Change(); + validChange.setAdditions(ImmutableList.of(validA)); + Change invalidChange = new Change(); + invalidChange.setAdditions(ImmutableList.of(invalidA)); + LocalDnsHelper.Response response = + localDns.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + assertEquals(200, response.code()); + response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, invalidChange, null); + assertEquals(400, response.code()); + // only empty additions/deletions + Change empty = new Change(); + empty.setAdditions(ImmutableList.of()); + empty.setDeletions(ImmutableList.of()); + response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, empty, null); + assertEquals(400, response.code()); + assertTrue(response.body().contains( + "The 'entity.change' parameter is required but was missing.")); + // non-matching name + validA.setName(ZONE1.getDnsName() + ".aaa."); + response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + assertEquals(400, response.code()); + assertTrue(response.body().contains("additions[0].name")); + // wrong type + validA.setName(ZONE1.getDnsName()); // revert + validA.setType("ABCD"); + response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + assertEquals(400, response.code()); + assertTrue(response.body().contains("additions[0].type")); + // wrong ttl + validA.setType("A"); // revert + validA.setTtl(-1); + response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + assertEquals(400, response.code()); + assertTrue(response.body().contains("additions[0].ttl")); + validA.setTtl(null); // revert + // null name + validA.setName(null); + response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + assertEquals(400, response.code()); + assertTrue(response.body().contains("additions[0].name")); + validA.setName(ZONE1.getDnsName()); + // null type + validA.setType(null); + response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + assertEquals(400, response.code()); + assertTrue(response.body().contains("additions[0].type")); + validA.setType("A"); + // null rrdata + List temp = validA.getRrdatas(); // preserve + validA.setRrdatas(null); + response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + assertEquals(400, response.code()); + assertTrue(response.body().contains("additions[0].rrdata")); + validA.setRrdatas(temp); + // delete non-existent + ResourceRecordSet nonExistent = new ResourceRecordSet(); + nonExistent.setName(ZONE1.getDnsName()); + nonExistent.setType("AAAA"); + nonExistent.setRrdatas(ImmutableList.of(":::::::")); + Change delete = new Change(); + delete.setDeletions(ImmutableList.of(nonExistent)); + response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, delete, null); + assertEquals(404, response.code()); + assertTrue(response.body().contains("deletions[0]")); + } + + private static ManagedZone copyZone(ManagedZone original) { + ManagedZone copy = new ManagedZone(); + copy.setDescription(original.getDescription()); + copy.setName(original.getName()); + copy.setCreationTime(original.getCreationTime()); + copy.setId(original.getId()); + copy.setNameServerSet(original.getNameServerSet()); + copy.setDnsName(original.getDnsName()); + if (original.getNameServers() != null) { + copy.setNameServers(ImmutableList.copyOf(original.getNameServers())); + } + return copy; + } + + private static ResourceRecordSet copyRrset(ResourceRecordSet set) { + ResourceRecordSet copy = new ResourceRecordSet(); + if (set.getRrdatas() != null) { + copy.setRrdatas(ImmutableList.copyOf(set.getRrdatas())); + } + copy.setTtl(set.getTtl()); + copy.setName(set.getName()); + copy.setType(set.getType()); + return copy; + } +} From d72a8c66d5e57143c175971b44e78e8b40715f3c Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Fri, 19 Feb 2016 16:25:40 -0800 Subject: [PATCH 105/375] Added "do not use production projects for tests" Added statement about not using production projects for running integration tests. --- CONTRIBUTING.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bf87d471e34a..3d93f2d032c7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -32,6 +32,8 @@ When changes are made to authentication and project ID-related code, authenticat Known issue: If you have installed the Google Cloud SDK, be sure to log in (using `gcloud auth login`) before running tests. Though the Datastore tests use a local Datastore emulator that doesn't require authentication, they will not run if you have the Google Cloud SDK installed but aren't authenticated. +**Please, do not use your production projects for executing integration tests.** While we do our best to make our tests independent of your project's state and content, they do perform create, modify and deletes, and you do not want to have your production data accidentally modified. + Adding Features --------------- In order to add a feature to gcloud-java: From e44e12a2b996d1649704a9ce124f670c23bd6c7e Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 19 Feb 2016 20:08:22 -0800 Subject: [PATCH 106/375] Make BaseIamPolicy in core and a subclass in Resource Manager --- .../{IamPolicy.java => BaseIamPolicy.java} | 245 ++++-------------- .../com/google/gcloud/BaseIamPolicyTest.java | 50 ++++ .../java/com/google/gcloud/IamPolicyTest.java | 105 -------- .../com/google/gcloud/SerializationTest.java | 49 ---- .../gcloud/resourcemanager/IamPolicy.java | 162 ++++++++++++ .../resourcemanager/ResourceManagerImpl.java | 94 ------- .../gcloud/resourcemanager/IamPolicyTest.java | 91 +++++++ .../ResourceManagerImplTest.java | 44 ---- .../resourcemanager/SerializationTest.java | 7 +- 9 files changed, 360 insertions(+), 487 deletions(-) rename gcloud-java-core/src/main/java/com/google/gcloud/{IamPolicy.java => BaseIamPolicy.java} (50%) create mode 100644 gcloud-java-core/src/test/java/com/google/gcloud/BaseIamPolicyTest.java delete mode 100644 gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java delete mode 100644 gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java create mode 100644 gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/IamPolicy.java create mode 100644 gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/IamPolicyTest.java diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java b/gcloud-java-core/src/main/java/com/google/gcloud/BaseIamPolicy.java similarity index 50% rename from gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java rename to gcloud-java-core/src/main/java/com/google/gcloud/BaseIamPolicy.java index a16ab790b363..bc0aed43b95d 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/BaseIamPolicy.java @@ -21,29 +21,28 @@ import com.google.common.collect.ImmutableList; import java.io.Serializable; -import java.util.Arrays; -import java.util.LinkedList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; /** - * An Identity and Access Management (IAM) policy. It is used to specify access control policies for - * Cloud Platform resources. A Policy consists of a list of ACLs (also known as bindings in Cloud - * IAM documentation). An ACL binds a list of identities to a role, where the identities can be user - * accounts, Google groups, Google domains, and service accounts. A role is a named list of - * permissions defined by IAM. + * Base class for Identity and Access Management (IAM) policies. IAM policies are used to specify + * access settings for Cloud Platform resources. A Policy consists of a list of bindings. An binding + * assigns a list of identities to a role, where the identities can be user accounts, Google groups, + * Google domains, and service accounts. A role is a named list of permissions defined by IAM. * * @see Policy */ -public class IamPolicy implements Serializable { +public abstract class BaseIamPolicy implements Serializable { - static final long serialVersionUID = 1114489978726897720L; + private static final long serialVersionUID = 1114489978726897720L; - private final List acls; + private final Map> bindings; private final String etag; private final int version; - public static class Identity implements Serializable { + public static final class Identity implements Serializable { private static final long serialVersionUID = 30811617560110848L; @@ -85,7 +84,7 @@ public enum Type { DOMAIN } - Identity(Type type, String id) { + private Identity(Type type, String id) { this.type = type; this.id = id; } @@ -178,177 +177,38 @@ public boolean equals(Object obj) { } } - /** - * An ACL binds a list of identities to a role, where the identities can be user accounts, Google - * groups, Google domains, and service accounts. A role is a named list of permissions defined by - * IAM. - * - * @see Binding - */ - public static class Acl implements Serializable { - - private static final long serialVersionUID = 3954282899483745158L; - - private final List identities; - private final String role; - - /** - * An ACL builder. - */ - public static class Builder { - private final List members = new LinkedList<>(); - private String role; - - Builder(String role) { - this.role = role; - } - - /** - * Sets the role associated with this ACL. - */ - public Builder role(String role) { - this.role = role; - return this; - } - - /** - * Replaces the builder's list of identities with the given list. - */ - public Builder identities(List identities) { - this.members.clear(); - this.members.addAll(identities); - return this; - } - - /** - * Adds one or more identities to the list of identities associated with the ACL. - */ - public Builder addIdentity(Identity first, Identity... others) { - members.add(first); - members.addAll(Arrays.asList(others)); - return this; - } - - /** - * Removes the specified identity from the ACL. - */ - public Builder removeIdentity(Identity identity) { - members.remove(identity); - return this; - } - - public Acl build() { - return new Acl(this); - } - } - - Acl(Builder builder) { - identities = ImmutableList.copyOf(checkNotNull(builder.members)); - role = checkNotNull(builder.role); - } - - /** - * Returns the list of identities associated with this ACL. - */ - public List identities() { - return identities; - } - - /** - * Returns the role associated with this ACL. - */ - public String role() { - return role; - } - - /** - * Returns an ACL builder for the specific role type. - * - * @param role string representing the role, without the "roles/" prefix. An example of a valid - * legacy role is "viewer". An example of a valid service-specific role is - * "pubsub.publisher". - */ - public static Builder builder(String role) { - return new Builder(role); - } - - /** - * Returns an ACL for the role type and list of identities provided. - * - * @param role string representing the role, without the "roles/" prefix. An example of a valid - * legacy role is "viewer". An example of a valid service-specific role is - * "pubsub.publisher". - * @param members list of identities associated with the role. - */ - public static Acl of(String role, List members) { - return new Acl(new Builder(role).identities(members)); - } - - /** - * Returns an ACL for the role type and identities provided. - * - * @param role string representing the role, without the "roles/" prefix. An example of a valid - * legacy role is "viewer". An example of a valid service-specific role is - * "pubsub.publisher". - * @param first identity associated with the role. - * @param others any other identities associated with the role. - */ - public static Acl of(String role, Identity first, Identity... others) { - return new Acl(new Builder(role).addIdentity(first, others)); - } - - public Builder toBuilder() { - return new Builder(role).identities(identities); - } - - @Override - public int hashCode() { - return Objects.hash(identities, role); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof Acl)) { - return false; - } - Acl other = (Acl) obj; - return Objects.equals(identities, other.identities()) && Objects.equals(role, other.role()); - } - } - /** * Builder for an IAM Policy. */ - public static class Builder { + protected abstract static class BaseBuilder> { - private final List acls = new LinkedList<>(); + private final Map> bindings = new HashMap<>(); private String etag; private int version; /** - * Replaces the builder's list of ACLs with the given list of ACLs. + * Replaces the builder's list of bindings with the given list of bindings. */ - public Builder acls(List acls) { - this.acls.clear(); - this.acls.addAll(acls); - return this; + public B bindings(Map> bindings) { + this.bindings.clear(); + this.bindings.putAll(bindings); + return self(); } /** - * Adds one or more ACLs to the policy. + * Adds one or more bindings to the policy. */ - public Builder addAcl(Acl first, Acl... others) { - acls.add(first); - acls.addAll(Arrays.asList(others)); - return this; + public B addBinding(R role, List identities) { + bindings.put(role, ImmutableList.copyOf(identities)); + return self(); } /** * Removes the specified ACL. */ - public Builder removeAcl(Acl acl) { - acls.remove(acl); - return this; + public B removeBinding(R role) { + bindings.remove(role); + return self(); } /** @@ -362,35 +222,40 @@ public Builder removeAcl(Acl acl) { * applied to the same version of the policy. If no etag is provided in the call to * setIamPolicy, then the existing policy is overwritten blindly. */ - public Builder etag(String etag) { + protected B etag(String etag) { this.etag = etag; - return this; + return self(); } /** - * Sets the version of the policy. The default version is 0. + * Sets the version of the policy. The default version is 0, meaning roles that are in alpha + * (non-legacy) roles are not permitted. If the version is 1, you may use roles other than + * "owner", "editor", and "viewer". */ - public Builder version(int version) { + protected B version(int version) { this.version = version; - return this; + return self(); } - public IamPolicy build() { - return new IamPolicy(this); + @SuppressWarnings("unchecked") + private B self() { + return (B) this; } + + public abstract BaseIamPolicy build(); } - IamPolicy(Builder builder) { - acls = ImmutableList.copyOf(builder.acls); - etag = builder.etag; - version = builder.version; + protected BaseIamPolicy(BaseBuilder> builder) { + this.bindings = builder.bindings; + this.etag = builder.etag; + this.version = builder.version; } /** * The list of ACLs specified in the policy. */ - public List acls() { - return acls; + public Map> bindings() { + return bindings; } /** @@ -415,26 +280,18 @@ public int version() { return version; } - @Override - public int hashCode() { - return Objects.hash(acls, etag, version); + public int baseHashCode() { + return Objects.hash(bindings, etag, version); } - @Override - public boolean equals(Object obj) { - if (!(obj instanceof IamPolicy)) { + public boolean baseEquals(Object obj) { + if (!(obj instanceof BaseIamPolicy)) { return false; } - IamPolicy other = (IamPolicy) obj; - return Objects.equals(acls, other.acls()) && Objects.equals(etag, other.etag()) + @SuppressWarnings("rawtypes") + BaseIamPolicy other = (BaseIamPolicy) obj; + return Objects.equals(bindings, other.bindings()) + && Objects.equals(etag, other.etag()) && Objects.equals(version, other.version()); } - - public static Builder builder() { - return new Builder(); - } - - public Builder toBuilder() { - return new Builder().acls(acls).etag(etag).version(version); - } } diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/BaseIamPolicyTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/BaseIamPolicyTest.java new file mode 100644 index 000000000000..0c26bc806812 --- /dev/null +++ b/gcloud-java-core/src/test/java/com/google/gcloud/BaseIamPolicyTest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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.gcloud; + +import static org.junit.Assert.assertEquals; + +import com.google.gcloud.BaseIamPolicy.Identity; + +import org.junit.Test; + +public class BaseIamPolicyTest { + + private static final Identity ALL_USERS = Identity.allUsers(); + private static final Identity ALL_AUTH_USERS = Identity.allAuthenticatedUsers(); + private static final Identity USER = Identity.user("abc@gmail.com"); + private static final Identity SERVICE_ACCOUNT = + Identity.serviceAccount("service-account@gmail.com"); + private static final Identity GROUP = Identity.group("group@gmail.com"); + private static final Identity DOMAIN = Identity.domain("google.com"); + + @Test + public void testIdentityOf() { + assertEquals(Identity.Type.ALL_USERS, ALL_USERS.type()); + assertEquals(null, ALL_USERS.id()); + assertEquals(Identity.Type.ALL_AUTHENTICATED_USERS, ALL_AUTH_USERS.type()); + assertEquals(null, ALL_AUTH_USERS.id()); + assertEquals(Identity.Type.USER, USER.type()); + assertEquals("abc@gmail.com", USER.id()); + assertEquals(Identity.Type.SERVICE_ACCOUNT, SERVICE_ACCOUNT.type()); + assertEquals("service-account@gmail.com", SERVICE_ACCOUNT.id()); + assertEquals(Identity.Type.GROUP, GROUP.type()); + assertEquals("group@gmail.com", GROUP.id()); + assertEquals(Identity.Type.DOMAIN, DOMAIN.type()); + assertEquals("google.com", DOMAIN.id()); + } +} diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java deleted file mode 100644 index 0d4e9fbfa6c8..000000000000 --- a/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * 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.gcloud; - -import static org.junit.Assert.assertEquals; - -import com.google.common.collect.ImmutableList; -import com.google.gcloud.IamPolicy.Acl; -import com.google.gcloud.IamPolicy.Identity; - -import org.junit.Test; - -public class IamPolicyTest { - - private static final Identity ALL_USERS = Identity.allUsers(); - private static final Identity ALL_AUTH_USERS = Identity.allAuthenticatedUsers(); - private static final Identity USER = Identity.user("abc@gmail.com"); - private static final Identity SERVICE_ACCOUNT = - Identity.serviceAccount("service-account@gmail.com"); - private static final Identity GROUP = Identity.group("group@gmail.com"); - private static final Identity DOMAIN = Identity.domain("google.com"); - private static final Acl ACL1 = Acl.of("viewer", USER, SERVICE_ACCOUNT, ALL_USERS); - private static final Acl ACL2 = Acl.of("editor", ALL_AUTH_USERS, GROUP, DOMAIN); - private static final IamPolicy FULL_POLICY = - IamPolicy.builder().addAcl(ACL1, ACL2).etag("etag").version(1).build(); - private static final IamPolicy SIMPLE_POLICY = IamPolicy.builder().addAcl(ACL1, ACL2).build(); - - @Test - public void testIdentityOf() { - assertEquals(Identity.Type.ALL_USERS, ALL_USERS.type()); - assertEquals(null, ALL_USERS.id()); - assertEquals(Identity.Type.ALL_AUTHENTICATED_USERS, ALL_AUTH_USERS.type()); - assertEquals(null, ALL_AUTH_USERS.id()); - assertEquals(Identity.Type.USER, USER.type()); - assertEquals("abc@gmail.com", USER.id()); - assertEquals(Identity.Type.SERVICE_ACCOUNT, SERVICE_ACCOUNT.type()); - assertEquals("service-account@gmail.com", SERVICE_ACCOUNT.id()); - assertEquals(Identity.Type.GROUP, GROUP.type()); - assertEquals("group@gmail.com", GROUP.id()); - assertEquals(Identity.Type.DOMAIN, DOMAIN.type()); - assertEquals("google.com", DOMAIN.id()); - } - - @Test - public void testAclBuilder() { - Acl acl = Acl.builder("owner").addIdentity(USER, GROUP).build(); - assertEquals("owner", acl.role()); - assertEquals(ImmutableList.of(USER, GROUP), acl.identities()); - acl = acl.toBuilder().role("viewer").removeIdentity(GROUP).build(); - assertEquals("viewer", acl.role()); - assertEquals(ImmutableList.of(USER), acl.identities()); - acl = acl.toBuilder().identities(ImmutableList.of(SERVICE_ACCOUNT)).build(); - assertEquals("viewer", acl.role()); - assertEquals(ImmutableList.of(SERVICE_ACCOUNT), acl.identities()); - } - - @Test - public void testAclOf() { - assertEquals("viewer", ACL1.role()); - assertEquals(ImmutableList.of(USER, SERVICE_ACCOUNT, ALL_USERS), ACL1.identities()); - Acl aclFromList = Acl.of("editor", ImmutableList.of(USER, SERVICE_ACCOUNT)); - assertEquals("editor", aclFromList.role()); - assertEquals(ImmutableList.of(USER, SERVICE_ACCOUNT), aclFromList.identities()); - } - - @Test - public void testAclToBuilder() { - assertEquals(ACL1, ACL1.toBuilder().build()); - } - - @Test - public void testIamPolicyBuilder() { - assertEquals(ImmutableList.of(ACL1, ACL2), FULL_POLICY.acls()); - assertEquals("etag", FULL_POLICY.etag()); - assertEquals(1, FULL_POLICY.version()); - IamPolicy policy = FULL_POLICY.toBuilder().acls(ImmutableList.of(ACL2)).build(); - assertEquals(ImmutableList.of(ACL2), policy.acls()); - assertEquals("etag", policy.etag()); - assertEquals(1, policy.version()); - policy = SIMPLE_POLICY.toBuilder().removeAcl(ACL2).build(); - assertEquals(ImmutableList.of(ACL1), policy.acls()); - assertEquals(null, policy.etag()); - assertEquals(0, policy.version()); - } - - @Test - public void testIamPolicyToBuilder() { - assertEquals(FULL_POLICY, FULL_POLICY.toBuilder().build()); - assertEquals(SIMPLE_POLICY, SIMPLE_POLICY.toBuilder().build()); - } -} diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java deleted file mode 100644 index b529b2c09ff5..000000000000 --- a/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.google.gcloud; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotSame; - -import com.google.common.collect.ImmutableList; -import com.google.gcloud.IamPolicy.Acl; -import com.google.gcloud.IamPolicy.Identity; - -import org.junit.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; - -public class SerializationTest { - - private static final Identity IDENTITY = Identity.user("abc@gmail.com"); - private static final Acl ACL = Acl.of("viewer", ImmutableList.of(IDENTITY)); - private static final IamPolicy POLICY = - IamPolicy.builder().acls(ImmutableList.of(ACL)).etag("etag").version(1).build(); - - @Test - public void testModelAndRequests() throws Exception { - Serializable[] objects = {IDENTITY, ACL, POLICY}; - for (Serializable obj : objects) { - Object copy = serializeAndDeserialize(obj); - assertEquals(obj, obj); - assertEquals(obj, copy); - assertNotSame(obj, copy); - assertEquals(copy, copy); - } - } - - @SuppressWarnings("unchecked") - private T serializeAndDeserialize(T obj) throws IOException, ClassNotFoundException { - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - try (ObjectOutputStream output = new ObjectOutputStream(bytes)) { - output.writeObject(obj); - } - try (ObjectInputStream input = - new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray()))) { - return (T) input.readObject(); - } - } -} diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/IamPolicy.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/IamPolicy.java new file mode 100644 index 000000000000..ccb436fd8a2f --- /dev/null +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/IamPolicy.java @@ -0,0 +1,162 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.resourcemanager; + +import com.google.common.base.Function; +import com.google.common.collect.Lists; +import com.google.gcloud.BaseIamPolicy; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * Base class for Identity and Access Management (IAM) policies. IAM policies are used to specify + * access settings for Cloud Platform resources. A Policy consists of a list of bindings. An binding + * assigns a list of identities to a role, where the identities can be user accounts, Google groups, + * Google domains, and service accounts. A role is a named list of permissions defined by IAM. + * + * @see Policy + */ +public class IamPolicy extends BaseIamPolicy implements Serializable { + + private static final long serialVersionUID = -5573557282693961850L; + + /** + * Builder for an IAM Policy. + */ + protected static class Builder extends BaseBuilder { + + Builder() {} + + Builder(Map> bindings, String etag, int version) { + bindings(bindings).etag(etag).version(version); + } + + @Override + public IamPolicy build() { + return new IamPolicy(this); + } + } + + private IamPolicy(Builder builder) { + super(builder); + } + + @Override + public int hashCode() { + return baseHashCode(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof IamPolicy)) { + return false; + } + IamPolicy other = (IamPolicy) obj; + return Objects.equals(bindings(), other.bindings()) + && Objects.equals(etag(), other.etag()) + && Objects.equals(version(), other.version()); + } + + public static Builder builder() { + return new Builder(); + } + + public Builder toBuilder() { + return new Builder(bindings(), etag(), version()); + } + + static String identityToPb(Identity identity) { + switch (identity.type()) { + case ALL_USERS: + return "allUsers"; + case ALL_AUTHENTICATED_USERS: + return "allAuthenticatedUsers"; + case USER: + return "user:" + identity.id(); + case SERVICE_ACCOUNT: + return "serviceAccount:" + identity.id(); + case GROUP: + return "group:" + identity.id(); + default: + return "domain:" + identity.id(); + } + } + + static Identity identityFromPb(String identityStr) { + String[] info = identityStr.split(":"); + switch (info[0]) { + case "allUsers": + return Identity.allUsers(); + case "allAuthenticatedUsers": + return Identity.allAuthenticatedUsers(); + case "user": + return Identity.user(info[1]); + case "serviceAccount": + return Identity.serviceAccount(info[1]); + case "group": + return Identity.group(info[1]); + case "domain": + return Identity.domain(info[1]); + default: + throw new IllegalArgumentException("Unexpected identity type: " + info[0]); + } + } + + com.google.api.services.cloudresourcemanager.model.Policy toPb() { + com.google.api.services.cloudresourcemanager.model.Policy policyPb = + new com.google.api.services.cloudresourcemanager.model.Policy(); + List bindingPbList = + new LinkedList<>(); + for (Map.Entry> binding : bindings().entrySet()) { + com.google.api.services.cloudresourcemanager.model.Binding bindingPb = + new com.google.api.services.cloudresourcemanager.model.Binding(); + bindingPb.setRole("roles/" + binding.getKey()); + bindingPb.setMembers(Lists.transform(binding.getValue(), new Function() { + @Override + public String apply(Identity identity) { + return identityToPb(identity); + } + })); + bindingPbList.add(bindingPb); + } + policyPb.setBindings(bindingPbList); + policyPb.setEtag(etag()); + policyPb.setVersion(version()); + return policyPb; + } + + static IamPolicy fromPb( + com.google.api.services.cloudresourcemanager.model.Policy policyPb) { + Map> bindings = new HashMap<>(); + for (com.google.api.services.cloudresourcemanager.model.Binding bindingPb : + policyPb.getBindings()) { + bindings.put(bindingPb.getRole().substring("roles/".length()), + Lists.transform(bindingPb.getMembers(), new Function() { + @Override + public Identity apply(String identityPb) { + return identityFromPb(identityPb); + } + })); + } + return new IamPolicy.Builder(bindings, policyPb.getEtag(), policyPb.getVersion()).build(); + } +} diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java index e641f3c75a31..4176b4e610ba 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java @@ -23,12 +23,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.gcloud.BaseService; -import com.google.gcloud.IamPolicy; -import com.google.gcloud.IamPolicy.Acl; -import com.google.gcloud.IamPolicy.Identity; import com.google.gcloud.Page; import com.google.gcloud.PageImpl; import com.google.gcloud.PageImpl.NextPageFetcher; @@ -193,94 +189,4 @@ public Void call() { } return ImmutableMap.copyOf(temp); } - - static String identityToPb(Identity identity) { - switch (identity.type()) { - case ALL_USERS: - return "allUsers"; - case ALL_AUTHENTICATED_USERS: - return "allAuthenticatedUsers"; - case USER: - return "user:" + identity.id(); - case SERVICE_ACCOUNT: - return "serviceAccount:" + identity.id(); - case GROUP: - return "group:" + identity.id(); - default: - return "domain:" + identity.id(); - } - } - - static Identity identityFromPb(String identityStr) { - String[] info = identityStr.split(":"); - switch (info[0]) { - case "allUsers": - return Identity.allUsers(); - case "allAuthenticatedUsers": - return Identity.allAuthenticatedUsers(); - case "user": - return Identity.user(info[1]); - case "serviceAccount": - return Identity.serviceAccount(info[1]); - case "group": - return Identity.group(info[1]); - case "domain": - return Identity.domain(info[1]); - default: - throw new IllegalArgumentException("Unexpected identity type: " + info[0]); - } - } - - static com.google.api.services.cloudresourcemanager.model.Binding aclToPb(Acl acl) { - com.google.api.services.cloudresourcemanager.model.Binding bindingPb = - new com.google.api.services.cloudresourcemanager.model.Binding(); - bindingPb.setMembers(Lists.transform(acl.identities(), new Function() { - @Override - public String apply(Identity identity) { - return identityToPb(identity); - } - })); - bindingPb.setRole("roles/" + acl.role()); - return bindingPb; - } - - static Acl aclFromPb(com.google.api.services.cloudresourcemanager.model.Binding bindingPb) { - return Acl.of( - bindingPb.getRole().substring("roles/".length()), - Lists.transform(bindingPb.getMembers(), new Function() { - @Override - public Identity apply(String memberPb) { - return identityFromPb(memberPb); - } - })); - } - - static com.google.api.services.cloudresourcemanager.model.Policy policyToPb( - final IamPolicy policy) { - com.google.api.services.cloudresourcemanager.model.Policy policyPb = - new com.google.api.services.cloudresourcemanager.model.Policy(); - policyPb.setBindings(Lists.transform(policy.acls(), - new Function() { - @Override - public com.google.api.services.cloudresourcemanager.model.Binding apply(Acl acl) { - return aclToPb(acl); - } - })); - policyPb.setEtag(policy.etag()); - policyPb.setVersion(policy.version()); - return policyPb; - } - - static IamPolicy policyFromPb( - com.google.api.services.cloudresourcemanager.model.Policy policyPb) { - IamPolicy.Builder builder = new IamPolicy.Builder(); - builder.acls(Lists.transform(policyPb.getBindings(), - new Function() { - @Override - public Acl apply(com.google.api.services.cloudresourcemanager.model.Binding binding) { - return aclFromPb(binding); - } - })); - return builder.etag(policyPb.getEtag()).version(policyPb.getVersion()).build(); - } } diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/IamPolicyTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/IamPolicyTest.java new file mode 100644 index 000000000000..e2f05ac8493b --- /dev/null +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/IamPolicyTest.java @@ -0,0 +1,91 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.resourcemanager; + +import static org.junit.Assert.assertEquals; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.gcloud.BaseIamPolicy.Identity; + +import org.junit.Test; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class IamPolicyTest { + + private static final Identity ALL_USERS = Identity.allUsers(); + private static final Identity ALL_AUTH_USERS = Identity.allAuthenticatedUsers(); + private static final Identity USER = Identity.user("abc@gmail.com"); + private static final Identity SERVICE_ACCOUNT = + Identity.serviceAccount("service-account@gmail.com"); + private static final Identity GROUP = Identity.group("group@gmail.com"); + private static final Identity DOMAIN = Identity.domain("google.com"); + private static final Map> BINDINGS = ImmutableMap.of( + "viewer", + ImmutableList.of(USER, SERVICE_ACCOUNT, ALL_USERS), + "editor", + ImmutableList.of(ALL_AUTH_USERS, GROUP, DOMAIN)); + private static final IamPolicy SIMPLE_POLICY = IamPolicy.builder() + .addBinding("viewer", ImmutableList.of(USER, SERVICE_ACCOUNT, ALL_USERS)) + .addBinding("editor", ImmutableList.of(ALL_AUTH_USERS, GROUP, DOMAIN)) + .build(); + private static final IamPolicy FULL_POLICY = + new IamPolicy.Builder(SIMPLE_POLICY.bindings(), "etag", 1).build(); + + @Test + public void testIamPolicyBuilder() { + assertEquals(BINDINGS, FULL_POLICY.bindings()); + assertEquals("etag", FULL_POLICY.etag()); + assertEquals(1, FULL_POLICY.version()); + Map> editorBinding = new HashMap<>(); + editorBinding.put("editor", BINDINGS.get("editor")); + IamPolicy policy = FULL_POLICY.toBuilder().bindings(editorBinding).build(); + assertEquals(ImmutableMap.of("editor", BINDINGS.get("editor")), policy.bindings()); + assertEquals("etag", policy.etag()); + assertEquals(1, policy.version()); + policy = SIMPLE_POLICY.toBuilder().removeBinding("editor").build(); + assertEquals(ImmutableMap.of("viewer", BINDINGS.get("viewer")), policy.bindings()); + assertEquals(null, policy.etag()); + assertEquals(0, policy.version()); + } + + @Test + public void testIamPolicyToBuilder() { + assertEquals(FULL_POLICY, FULL_POLICY.toBuilder().build()); + assertEquals(SIMPLE_POLICY, SIMPLE_POLICY.toBuilder().build()); + } + + @Test + public void testIdentityToAndFromPb() { + assertEquals(ALL_USERS, IamPolicy.identityFromPb(IamPolicy.identityToPb(ALL_USERS))); + assertEquals(ALL_AUTH_USERS, IamPolicy.identityFromPb(IamPolicy.identityToPb(ALL_AUTH_USERS))); + assertEquals(USER, IamPolicy.identityFromPb(IamPolicy.identityToPb(USER))); + assertEquals( + SERVICE_ACCOUNT, IamPolicy.identityFromPb(IamPolicy.identityToPb(SERVICE_ACCOUNT))); + assertEquals(GROUP, IamPolicy.identityFromPb(IamPolicy.identityToPb(GROUP))); + assertEquals(DOMAIN, IamPolicy.identityFromPb(IamPolicy.identityToPb(DOMAIN))); + } + + @Test + public void testPolicyToAndFromPb() { + assertEquals(FULL_POLICY, IamPolicy.fromPb(FULL_POLICY.toPb())); + assertEquals(SIMPLE_POLICY, IamPolicy.fromPb(SIMPLE_POLICY.toPb())); + } +} diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java index 623bf68d085c..37c54718fb4a 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java @@ -25,9 +25,6 @@ import static org.junit.Assert.fail; import com.google.common.collect.ImmutableMap; -import com.google.gcloud.IamPolicy; -import com.google.gcloud.IamPolicy.Acl; -import com.google.gcloud.IamPolicy.Identity; import com.google.gcloud.Page; import com.google.gcloud.resourcemanager.ProjectInfo.ResourceId; import com.google.gcloud.resourcemanager.ResourceManager.ProjectField; @@ -67,18 +64,6 @@ public class ResourceManagerImplTest { .parent(PARENT) .build(); private static final Map EMPTY_RPC_OPTIONS = ImmutableMap.of(); - private static final Identity ALL_USERS = Identity.allUsers(); - private static final Identity ALL_AUTH_USERS = Identity.allAuthenticatedUsers(); - private static final Identity USER = Identity.user("abc@gmail.com"); - private static final Identity SERVICE_ACCOUNT = - Identity.serviceAccount("service-account@gmail.com"); - private static final Identity GROUP = Identity.group("group@gmail.com"); - private static final Identity DOMAIN = Identity.domain("google.com"); - private static final Acl ACL1 = Acl.of("viewer", USER, SERVICE_ACCOUNT, ALL_USERS); - private static final Acl ACL2 = Acl.of("editor", ALL_AUTH_USERS, GROUP, DOMAIN); - private static final IamPolicy FULL_POLICY = - IamPolicy.builder().addAcl(ACL1, ACL2).etag("etag").version(1).build(); - private static final IamPolicy SIMPLE_POLICY = IamPolicy.builder().addAcl(ACL1, ACL2).build(); @Rule public ExpectedException thrown = ExpectedException.none(); @@ -286,35 +271,6 @@ public void testUndelete() { } } - @Test - public void testIdentityToAndFromPb() { - assertEquals(ALL_USERS, - ResourceManagerImpl.identityFromPb(ResourceManagerImpl.identityToPb(ALL_USERS))); - assertEquals(ALL_AUTH_USERS, - ResourceManagerImpl.identityFromPb( - ResourceManagerImpl.identityToPb(ALL_AUTH_USERS))); - assertEquals(USER, ResourceManagerImpl.identityFromPb(ResourceManagerImpl.identityToPb(USER))); - assertEquals(SERVICE_ACCOUNT, - ResourceManagerImpl.identityFromPb(ResourceManagerImpl.identityToPb(SERVICE_ACCOUNT))); - assertEquals(GROUP, - ResourceManagerImpl.identityFromPb(ResourceManagerImpl.identityToPb(GROUP))); - assertEquals(DOMAIN, - ResourceManagerImpl.identityFromPb(ResourceManagerImpl.identityToPb(DOMAIN))); - } - - @Test - public void testAclToAndFromPb() { - assertEquals(ACL1, ResourceManagerImpl.aclFromPb(ResourceManagerImpl.aclToPb(ACL1))); - } - - @Test - public void testPolicyToAndFromPb() { - assertEquals(FULL_POLICY, - ResourceManagerImpl.policyFromPb(ResourceManagerImpl.policyToPb(FULL_POLICY))); - assertEquals(SIMPLE_POLICY, - ResourceManagerImpl.policyFromPb(ResourceManagerImpl.policyToPb(SIMPLE_POLICY))); - } - @Test public void testRetryableException() { ResourceManagerRpcFactory rpcFactoryMock = EasyMock.createMock(ResourceManagerRpcFactory.class); diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java index 497de880254a..1049f40f5f17 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java @@ -19,7 +19,9 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.gcloud.BaseIamPolicy.Identity; import com.google.gcloud.PageImpl; import com.google.gcloud.RetryParams; @@ -53,6 +55,9 @@ public class SerializationTest { ResourceManager.ProjectGetOption.fields(ResourceManager.ProjectField.NAME); private static final ResourceManager.ProjectListOption PROJECT_LIST_OPTION = ResourceManager.ProjectListOption.filter("name:*"); + private static final Identity IDENTITY = Identity.user("abc@gmail.com"); + private static final IamPolicy POLICY = + IamPolicy.builder().addBinding("viewer", ImmutableList.of(IDENTITY)).build(); @Test public void testServiceOptions() throws Exception { @@ -70,7 +75,7 @@ public void testServiceOptions() throws Exception { @Test public void testModelAndRequests() throws Exception { Serializable[] objects = {PARTIAL_PROJECT_INFO, FULL_PROJECT_INFO, PROJECT, PAGE_RESULT, - PROJECT_GET_OPTION, PROJECT_LIST_OPTION}; + PROJECT_GET_OPTION, PROJECT_LIST_OPTION, IDENTITY, POLICY}; for (Serializable obj : objects) { Object copy = serializeAndDeserialize(obj); assertEquals(obj, obj); From 04f354a16a8759af38d3e883b9bb9dcc467744f3 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Tue, 23 Feb 2016 11:38:51 -0800 Subject: [PATCH 107/375] Added RPC layer of tests for local helpers. Closes #665. Debugged parsing for options. Fixed context for the server URLs and regular expression parsing. Fixed paging. Improved error detection for missing zones vs. non-existent changes. --- .../com/google/gcloud/spi/DefaultDnsRpc.java | 4 +- .../google/gcloud/testing/LocalDnsHelper.java | 126 +- .../testing/OptionParsersAndExtractors.java | 31 +- .../gcloud/testing/LocalDnsHelperTest.java | 1176 ++++++++++++++--- 4 files changed, 1097 insertions(+), 240 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java index 6ed9c7e0f216..b72a21445a80 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java @@ -162,7 +162,9 @@ public Change getChangeRequest(String zoneName, String changeRequestId, MapWhile the mock attempts to simulate the service, there are some differences in the behaviour. * The mock will accept any project ID and never returns a notFound or another error because of - * project ID. It assumes that all project IDs exists and that the user has all the necessary + * project ID. It assumes that all project IDs exist and that the user has all the necessary * privileges to manipulate any project. Similarly, the local simulation does not work with any * verification of domain name ownership. Any request for creating a managed zone will be approved. * The mock does not track quota and will allow the user to exceed it. The mock provides only basic @@ -92,11 +93,10 @@ public class LocalDnsHelper { = new ConcurrentSkipListMap<>(); private static final URI BASE_CONTEXT; private static final Logger log = Logger.getLogger(LocalDnsHelper.class.getName()); - private static final JsonFactory jsonFactory = - new com.google.api.client.json.jackson.JacksonFactory(); + private static final JsonFactory jsonFactory = new JacksonFactory(); private static final Random ID_GENERATOR = new Random(); private static final String VERSION = "v1"; - private static final String CONTEXT = "/" + VERSION + "/projects"; + private static final String CONTEXT = "/dns/" + VERSION + "/projects"; private static final Set SUPPORTED_COMPRESSION_ENCODINGS = ImmutableSet.of("gzip", "x-gzip"); private static final List TYPES = ImmutableList.of("A", "AAAA", "CNAME", "MX", "NAPTR", @@ -119,15 +119,15 @@ public class LocalDnsHelper { * For matching URLs to operations. */ private enum CallRegex { - CHANGE_CREATE("POST", "/[^/]+/managedZones/[^/]+/changes"), - CHANGE_GET("GET", "/[^/]+/managedZones/[^/]+/changes/[^/]+"), - CHANGE_LIST("GET", "/[^/]+/managedZones/[^/]+/changes"), - ZONE_CREATE("POST", "/[^/]+/managedZones"), - ZONE_DELETE("DELETE", "/[^/]+/managedZones/[^/]+"), - ZONE_GET("GET", "/[^/]+/managedZones/[^/]+"), - ZONE_LIST("GET", "/[^/]+/managedZones"), - PROJECT_GET("GET", "/[^/]+"), - RECORD_LIST("GET", "/[^/]+/managedZones/[^/]+/rrsets"); + CHANGE_CREATE("POST", CONTEXT + "/[^/]+/managedZones/[^/]+/changes"), + CHANGE_GET("GET", CONTEXT + "/[^/]+/managedZones/[^/]+/changes/[^/]+"), + CHANGE_LIST("GET", CONTEXT + "/[^/]+/managedZones/[^/]+/changes"), + ZONE_CREATE("POST", CONTEXT + "/[^/]+/managedZones"), + ZONE_DELETE("DELETE", CONTEXT + "/[^/]+/managedZones/[^/]+"), + ZONE_GET("GET", CONTEXT + "/[^/]+/managedZones/[^/]+"), + ZONE_LIST("GET", CONTEXT + "/[^/]+/managedZones"), + PROJECT_GET("GET", CONTEXT + "/[^/]+"), + RECORD_LIST("GET", CONTEXT + "/[^/]+/managedZones/[^/]+/rrsets"); private String method; private String pathRegex; @@ -220,14 +220,14 @@ ConcurrentSkipListMap zones() { } /** - * Associates a zone with a collection of changes and dns record. Thread safe. + * Associates a zone with a collection of changes and dns records. Thread safe. */ static class ZoneContainer { private final ManagedZone zone; /** * DNS records are held in a map to allow for atomic replacement of record sets when applying * changes. The key for the map is always the zone name. The collection of records is immutable - * and must always exist, i.e., dnsRecords.get(zone.getName()) is never null. + * and must always exist, i.e., dnsRecords.get(zone.getName()) is never {@code null}. */ private final ConcurrentSkipListMap> dnsRecords = new ConcurrentSkipListMap<>(); @@ -377,20 +377,19 @@ public void handle(HttpExchange exchange) throws IOException { writeResponse(exchange, Error.NOT_FOUND.response("The url does not match any API call.")); } - // todo(mderka) Test handlers using gcloud-java-dns. Issue #665. private Response handleZoneDelete(HttpExchange exchange) { String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); String[] tokens = path.split("/"); - String projectId = tokens[1]; - String zoneName = tokens[3]; + String projectId = tokens[0]; + String zoneName = tokens[2]; return deleteZone(projectId, zoneName); } private Response handleZoneGet(HttpExchange exchange) { String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); String[] tokens = path.split("/"); - String projectId = tokens[1]; - String zoneName = tokens[3]; + String projectId = tokens[0]; + String zoneName = tokens[2]; String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); String[] fields = OptionParsersAndExtractors.parseGetOptions(query); return getZone(projectId, zoneName, fields); @@ -399,7 +398,7 @@ private Response handleZoneGet(HttpExchange exchange) { private Response handleZoneList(HttpExchange exchange) { String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); String[] tokens = path.split("/"); - String projectId = tokens[1]; + String projectId = tokens[0]; String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); Map options = OptionParsersAndExtractors.parseListZonesOptions(query); return listZones(projectId, options); @@ -408,7 +407,7 @@ private Response handleZoneList(HttpExchange exchange) { private Response handleProjectGet(HttpExchange exchange) { String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); String[] tokens = path.split("/"); - String projectId = tokens[1]; + String projectId = tokens[0]; String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); String[] fields = OptionParsersAndExtractors.parseGetOptions(query); return getProject(projectId, fields); @@ -420,8 +419,8 @@ private Response handleProjectGet(HttpExchange exchange) { private Response handleChangeCreate(HttpExchange exchange) throws IOException { String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); String[] tokens = path.split("/"); - String projectId = tokens[1]; - String zoneName = tokens[3]; + String projectId = tokens[0]; + String zoneName = tokens[2]; String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); String[] fields = OptionParsersAndExtractors.parseGetOptions(query); String requestBody = decodeContent(exchange.getRequestHeaders(), exchange.getRequestBody()); @@ -432,9 +431,9 @@ private Response handleChangeCreate(HttpExchange exchange) throws IOException { private Response handleChangeGet(HttpExchange exchange) { String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); String[] tokens = path.split("/"); - String projectId = tokens[1]; - String zoneName = tokens[3]; - String changeId = tokens[5]; + String projectId = tokens[0]; + String zoneName = tokens[2]; + String changeId = tokens[4]; String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); String[] fields = OptionParsersAndExtractors.parseGetOptions(query); return getChange(projectId, zoneName, changeId, fields); @@ -443,8 +442,8 @@ private Response handleChangeGet(HttpExchange exchange) { private Response handleChangeList(HttpExchange exchange) { String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); String[] tokens = path.split("/"); - String projectId = tokens[1]; - String zoneName = tokens[3]; + String projectId = tokens[0]; + String zoneName = tokens[2]; String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); Map options = OptionParsersAndExtractors.parseListChangesOptions(query); return listChanges(projectId, zoneName, options); @@ -453,8 +452,8 @@ private Response handleChangeList(HttpExchange exchange) { private Response handleDnsRecordList(HttpExchange exchange) { String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); String[] tokens = path.split("/"); - String projectId = tokens[1]; - String zoneName = tokens[3]; + String projectId = tokens[0]; + String zoneName = tokens[2]; String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); Map options = OptionParsersAndExtractors.parseListDnsRecordsOptions(query); return listDnsRecords(projectId, zoneName, options); @@ -466,7 +465,7 @@ private Response handleDnsRecordList(HttpExchange exchange) { private Response handleZoneCreate(HttpExchange exchange) throws IOException { String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); String[] tokens = path.split("/"); - String projectId = tokens[1]; + String projectId = tokens[0]; String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); String[] options = OptionParsersAndExtractors.parseGetOptions(query); String requestBody = decodeContent(exchange.getRequestHeaders(), exchange.getRequestBody()); @@ -539,7 +538,9 @@ private static void writeResponse(HttpExchange exchange, Response response) { try { exchange.getResponseHeaders().add("Connection", "close"); exchange.sendResponseHeaders(response.code(), response.body().length()); - outputStream.write(response.body().getBytes(StandardCharsets.UTF_8)); + if (response.code() != 204) { + outputStream.write(response.body().getBytes(StandardCharsets.UTF_8)); + } outputStream.close(); } catch (IOException e) { log.log(Level.WARNING, "IOException encountered when sending response.", e); @@ -569,18 +570,20 @@ private static String decodeContent(Headers headers, InputStream inputStream) th } /** - * Generates a JSON response. Tested. + * Generates a JSON response. + * + * @param context managedZones | projects | rrsets | changes */ - static Response toListResponse(List serializedObjects, String pageToken, + static Response toListResponse(List serializedObjects, String context, String pageToken, boolean includePageToken) { // start building response StringBuilder responseBody = new StringBuilder(); - responseBody.append("{\"projects\": ["); + responseBody.append("{\"").append(context).append("\": ["); Joiner.on(",").appendTo(responseBody, serializedObjects); responseBody.append("]"); // add page token only if exists and is asked for if (pageToken != null && includePageToken) { - responseBody.append(",\"pageToken\": \"").append(pageToken).append("\""); + responseBody.append(",\"nextPageToken\": \"").append(pageToken).append("\""); } responseBody.append("}"); return new Response(HTTP_OK, responseBody.toString()); @@ -627,14 +630,13 @@ static List randomNameservers() { } /** - * Returns a hex string id (used for a dns record) unique withing the set of wrappers. + * Returns a hex string id (used for a dns record) unique within the set of wrappers. */ static String getUniqueId(List wrappers) { TreeSet ids = Sets.newTreeSet(Lists.transform(wrappers, new Function() { - @Nullable @Override - public String apply(@Nullable RrsetWrapper input) { + public String apply(RrsetWrapper input) { return input.id() == null ? "null" : input.id(); } })); @@ -663,7 +665,8 @@ static boolean matchesCriteria(ResourceRecordSet record, String name, String typ } /** - * Returns a project container. Never returns null because we assume that all projects exists. + * Returns a project container. Never returns {@code null} because we assume that all projects + * exists. */ ProjectContainer findProject(String projectId) { ProjectContainer defaultProject = createProject(projectId); @@ -672,7 +675,7 @@ ProjectContainer findProject(String projectId) { } /** - * Returns a zone container. Returns null if zone does not exist within project. + * Returns a zone container. Returns {@code null} if zone does not exist within project. */ ZoneContainer findZone(String projectId, String zoneName) { ProjectContainer projectContainer = findProject(projectId); // never null @@ -680,7 +683,7 @@ ZoneContainer findZone(String projectId, String zoneName) { } /** - * Returns a change found by its id. Returns null if such a change does not exist. + * Returns a change found by its id. Returns {@code null} if such a change does not exist. */ Change findChange(String projectId, String zoneName, String changeId) { ZoneContainer wrapper = findZone(projectId, zoneName); @@ -688,7 +691,7 @@ Change findChange(String projectId, String zoneName, String changeId) { } /** - * Returns a response to get change call. + * Returns a response to getChange service call. */ Response getChange(String projectId, String zoneName, String changeId, String[] fields) { Change change = findChange(projectId, zoneName, changeId); @@ -711,11 +714,10 @@ Response getChange(String projectId, String zoneName, String changeId, String[] "Error when serializing change %s in managed zone %s in project %s.", changeId, zoneName, projectId)); } - // todo(mderka) Test field options within #665. } /** - * Returns a response to get zone call. + * Returns a response to getZone service call. */ Response getZone(String projectId, String zoneName, String[] fields) { ZoneContainer container = findZone(projectId, zoneName); @@ -730,7 +732,6 @@ Response getZone(String projectId, String zoneName, String[] fields) { return Error.INTERNAL_ERROR.response(String.format( "Error when serializing managed zone %s in project %s.", zoneName, projectId)); } - // todo(mderka) Test field options within #665. } /** @@ -748,7 +749,6 @@ Response getProject(String projectId, String[] fields) { return Error.INTERNAL_ERROR.response( String.format("Error when serializing project %s.", projectId)); } - // todo(mderka) Test field options within #665. } /** @@ -798,6 +798,7 @@ Response createZone(String projectId, ManagedZone zone, String[] fields) { ManagedZone completeZone = new ManagedZone(); completeZone.setName(zone.getName()); completeZone.setDnsName(zone.getDnsName()); + completeZone.setDescription(zone.getDescription()); completeZone.setNameServerSet(zone.getNameServerSet()); completeZone.setCreationTime(ISODateTimeFormat.dateTime().withZoneUTC() .print(System.currentTimeMillis())); @@ -823,7 +824,6 @@ Response createZone(String projectId, ManagedZone zone, String[] fields) { return Error.INTERNAL_ERROR.response( String.format("Error when serializing managed zone %s.", result.getName())); } - // todo(mderka) Test field options within #665. } /** @@ -873,7 +873,6 @@ we will reset all IDs in this range (all of them are valid) */ String.format("Error when serializing change %s in managed zone %s in project %s.", result.getId(), zoneName, projectId)); } - // todo(mderka) Test field options within #665. } /** @@ -969,13 +968,13 @@ Response listZones(String projectId, Map options) { ManagedZone zone = zoneContainer.zone(); if (listing) { if (dnsName == null || zone.getDnsName().equals(dnsName)) { - lastZoneName = zone.getName(); if (sizeReached) { // we do not add this, just note that there would be more and there should be a token hasMorePages = true; break; } else { try { + lastZoneName = zone.getName(); serializedZones.addLast(jsonFactory.toString( OptionParsersAndExtractors.extractFields(zone, fields))); } catch (IOException e) { @@ -991,9 +990,8 @@ Response listZones(String projectId, Map options) { sizeReached = (maxResults != null) && maxResults.equals(serializedZones.size()); } boolean includePageToken = - hasMorePages && (fields == null || ImmutableList.copyOf(fields).contains("pageToken")); - return toListResponse(serializedZones, lastZoneName, includePageToken); - // todo(mderka) Test field and listing options within #665. + hasMorePages && (fields == null || ImmutableList.copyOf(fields).contains("nextPageToken")); + return toListResponse(serializedZones, "managedZones", lastZoneName, includePageToken); } /** @@ -1025,12 +1023,12 @@ Response listDnsRecords(String projectId, String zoneName, Map o ResourceRecordSet record = recordWrapper.rrset(); if (listing) { if (matchesCriteria(record, name, type)) { - lastRecordId = recordWrapper.id(); if (sizeReached) { // we do not add this, just note that there would be more and there should be a token hasMorePages = true; break; } else { + lastRecordId = recordWrapper.id(); try { serializedRrsets.addLast(jsonFactory.toString( OptionParsersAndExtractors.extractFields(record, fields))); @@ -1047,9 +1045,8 @@ Response listDnsRecords(String projectId, String zoneName, Map o sizeReached = (maxResults != null) && maxResults.equals(serializedRrsets.size()); } boolean includePageToken = - hasMorePages && (fields == null || ImmutableList.copyOf(fields).contains("pageToken")); - return toListResponse(serializedRrsets, lastRecordId, includePageToken); - // todo(mderka) Test field and listing options within #665. + hasMorePages && (fields == null || ImmutableList.copyOf(fields).contains("nextPageToken")); + return toListResponse(serializedRrsets, "rrsets", lastRecordId, includePageToken); } /** @@ -1061,6 +1058,10 @@ Response listChanges(String projectId, String zoneName, Map opti return response; } ZoneContainer zoneContainer = findZone(projectId, zoneName); + if (zoneContainer == null) { + return Error.NOT_FOUND.response(String.format( + "The 'parameters.managedZone' resource named '%s' does not exist", zoneName)); + } // take a sorted snapshot of the current change list TreeMap changes = new TreeMap<>(); for (Change c : zoneContainer.changes()) { @@ -1088,12 +1089,12 @@ Response listChanges(String projectId, String zoneName, Map opti for (Integer key : keys) { Change change = changes.get(key); if (listing) { - lastChangeId = change.getId(); if (sizeReached) { // we do not add this, just note that there would be more and there should be a token hasMorePages = true; break; } else { + lastChangeId = change.getId(); try { serializedResults.addLast(jsonFactory.toString( OptionParsersAndExtractors.extractFields(change, fields))); @@ -1110,9 +1111,8 @@ Response listChanges(String projectId, String zoneName, Map opti sizeReached = (maxResults != null) && maxResults.equals(serializedResults.size()); } boolean includePageToken = - hasMorePages && (fields == null || ImmutableList.copyOf(fields).contains("pageToken")); - return toListResponse(serializedResults, lastChangeId, includePageToken); - // todo(mderka) Test field and listing options within #665. + hasMorePages && (fields == null || ImmutableList.copyOf(fields).contains("nextPageToken")); + return toListResponse(serializedResults, "changes", lastChangeId, includePageToken); } /** diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/testing/OptionParsersAndExtractors.java b/gcloud-java-dns/src/main/java/com/google/gcloud/testing/OptionParsersAndExtractors.java index f94cb15779ca..26759f7e3ccc 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/testing/OptionParsersAndExtractors.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/testing/OptionParsersAndExtractors.java @@ -42,14 +42,19 @@ static Map parseListZonesOptions(String query) { switch (argEntry[0]) { case "fields": // List fields are in the form "managedZones(field1, field2, ...)" + String replaced = argEntry[1].replace("managedZones(", ","); + replaced = replaced.replace(")", ","); + // we will get empty strings, but it does not matter, they will be ignored options.put( "fields", - argEntry[1].substring("managedZones(".length(), argEntry[1].length() - 1) - .split(",")); + replaced.split(",")); break; case "dnsName": options.put("dnsName", argEntry[1]); break; + case "nextPageToken": + options.put("nextPageToken", argEntry[1]); + break; case "pageToken": options.put("pageToken", argEntry[1]); break; @@ -218,14 +223,16 @@ static Map parseListChangesOptions(String query) { String[] argEntry = arg.split("="); switch (argEntry[0]) { case "fields": - // todo we do not support fragmentation in deletions and additions - options.put( - "fields", - argEntry[1].substring("changes(".length(), argEntry[1].length() - 1).split(",")); + // todo we do not support fragmentation in deletions and additions in the library + String replaced = argEntry[1].replace("changes(", ",").replace(")", ","); + options.put("fields", replaced.split(",")); // empty strings will be ignored break; case "name": options.put("name", argEntry[1]); break; + case "nextPageToken": + options.put("nextPageToken", argEntry[1]); + break; case "pageToken": options.put("pageToken", argEntry[1]); break; @@ -255,16 +262,22 @@ static Map parseListDnsRecordsOptions(String query) { String[] argEntry = arg.split("="); switch (argEntry[0]) { case "fields": - options.put( - "fields", - argEntry[1].substring("rrsets(".length(), argEntry[1].length() - 1).split(",")); + String replace = argEntry[1].replace("rrsets(", ","); + replace = replace.replace(")", ","); + options.put("fields", replace.split(",")); // empty strings do not matter break; case "name": options.put("name", argEntry[1]); break; + case "type": + options.put("type", argEntry[1]); + break; case "pageToken": options.put("pageToken", argEntry[1]); break; + case "nextPageToken": + options.put("nextPageToken", argEntry[1]); + break; case "maxResults": // parsing to int is done while handling options.put("maxResults", argEntry[1]); diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/testing/LocalDnsHelperTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/testing/LocalDnsHelperTest.java index 1f851045659c..7a97b69846ef 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/testing/LocalDnsHelperTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/testing/LocalDnsHelperTest.java @@ -18,6 +18,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -25,11 +26,16 @@ import com.google.api.services.dns.model.Change; import com.google.api.services.dns.model.ManagedZone; +import com.google.api.services.dns.model.Project; import com.google.api.services.dns.model.ResourceRecordSet; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; +import com.google.gcloud.dns.DnsException; +import com.google.gcloud.spi.DefaultDnsRpc; +import com.google.gcloud.spi.DnsRpc; -import org.junit.After; +import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -55,8 +61,14 @@ public class LocalDnsHelperTest { private static final Change CHANGE1 = new Change(); private static final Change CHANGE2 = new Change(); private static final Change CHANGE_KEEP = new Change(); + private static final Change CHANGE_COMPLEX = new Change(); + private static final LocalDnsHelper LOCAL_DNS_HELPER = LocalDnsHelper.create(0L); // synchronous + private static final Map EMPTY_RPC_OPTIONS = ImmutableMap.of(); + private static final DnsRpc RPC = + new DefaultDnsRpc(LOCAL_DNS_HELPER.options()); + private static final String REAL_PROJECT_ID = LOCAL_DNS_HELPER.options().projectId(); private Map optionsMap; - private LocalDnsHelper localDns; + private ManagedZone minimalZone = new ManagedZone(); // to be adjusted as needed @BeforeClass @@ -67,9 +79,11 @@ public static void before() { ZONE1.setName(ZONE_NAME1); ZONE1.setDescription(""); ZONE1.setDnsName(DNS_NAME); + ZONE1.setNameServerSet("somenameserveset"); ZONE2.setName(ZONE_NAME2); ZONE2.setDescription(""); ZONE2.setDnsName(DNS_NAME); + ZONE2.setNameServerSet("somenameserveset"); RRSET2.setName(DNS_NAME); RRSET2.setType(RRSET_TYPE); RRSET_KEEP.setName(DNS_NAME); @@ -79,18 +93,27 @@ public static void before() { CHANGE1.setAdditions(ImmutableList.of(RRSET1, RRSET2)); CHANGE2.setDeletions(ImmutableList.of(RRSET2)); CHANGE_KEEP.setAdditions(ImmutableList.of(RRSET_KEEP)); + CHANGE_COMPLEX.setAdditions(ImmutableList.of(RRSET_KEEP)); + CHANGE_COMPLEX.setDeletions(ImmutableList.of(RRSET_KEEP)); + LOCAL_DNS_HELPER.start(); } @Before public void setUp() { - localDns = LocalDnsHelper.create(0L); // synchronous + resetProjects(); optionsMap = new HashMap<>(); minimalZone = copyZone(ZONE1); } - @After - public void after() { - localDns = null; + private static void resetProjects() { + for (String project : LOCAL_DNS_HELPER.projects().keySet()) { + LOCAL_DNS_HELPER.projects().remove(project); + } + } + + @AfterClass + public static void after() { + LOCAL_DNS_HELPER.stop(); } @Test @@ -109,13 +132,13 @@ public void testGetUniqueId() { @Test public void testFindProject() { - assertEquals(0, localDns.projects().size()); - LocalDnsHelper.ProjectContainer project = localDns.findProject(PROJECT_ID1); + assertEquals(0, LOCAL_DNS_HELPER.projects().size()); + LocalDnsHelper.ProjectContainer project = LOCAL_DNS_HELPER.findProject(PROJECT_ID1); assertNotNull(project); - assertTrue(localDns.projects().containsKey(PROJECT_ID1)); - assertNotNull(localDns.findProject(PROJECT_ID2)); - assertTrue(localDns.projects().containsKey(PROJECT_ID2)); - assertTrue(localDns.projects().containsKey(PROJECT_ID1)); + assertTrue(LOCAL_DNS_HELPER.projects().containsKey(PROJECT_ID1)); + assertNotNull(LOCAL_DNS_HELPER.findProject(PROJECT_ID2)); + assertTrue(LOCAL_DNS_HELPER.projects().containsKey(PROJECT_ID2)); + assertTrue(LOCAL_DNS_HELPER.projects().containsKey(PROJECT_ID1)); assertNotNull(project.zones()); assertEquals(0, project.zones().size()); assertNotNull(project.project()); @@ -124,11 +147,11 @@ public void testFindProject() { @Test public void testCreateAndFindZone() { - LocalDnsHelper.ZoneContainer zone1 = localDns.findZone(PROJECT_ID1, ZONE_NAME1); - assertTrue(localDns.projects().containsKey(PROJECT_ID1)); + LocalDnsHelper.ZoneContainer zone1 = LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE_NAME1); + assertTrue(LOCAL_DNS_HELPER.projects().containsKey(PROJECT_ID1)); assertNull(zone1); - localDns.createZone(PROJECT_ID1, ZONE1, null); // we do not care about options - zone1 = localDns.findZone(PROJECT_ID1, ZONE1.getName()); + LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); // we do not care about options + zone1 = LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE1.getName()); assertNotNull(zone1); // cannot call equals because id and timestamp got assigned assertEquals(ZONE_NAME1, zone1.zone().getName()); @@ -136,56 +159,99 @@ public void testCreateAndFindZone() { assertTrue(zone1.changes().isEmpty()); assertNotNull(zone1.dnsRecords()); assertEquals(2, zone1.dnsRecords().get(ZONE_NAME1).size()); // default SOA and NS - localDns.createZone(PROJECT_ID2, ZONE1, null); // project does not exits yet - assertEquals(ZONE1.getName(), localDns.findZone(PROJECT_ID2, ZONE_NAME1).zone().getName()); + LOCAL_DNS_HELPER.createZone(PROJECT_ID2, ZONE1, null); // project does not exits yet + assertEquals(ZONE1.getName(), + LOCAL_DNS_HELPER.findZone(PROJECT_ID2, ZONE_NAME1).zone().getName()); + } + + @Test + public void testCreateAndFindZoneUsingRpc() { + // zone does not exist yet + ManagedZone zone1 = RPC.getZone(ZONE_NAME1, EMPTY_RPC_OPTIONS); + assertTrue(LOCAL_DNS_HELPER.projects().containsKey(REAL_PROJECT_ID)); // check internal state + assertNull(zone1); + // create zone + ManagedZone createdZone = RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + assertEquals(ZONE1.getName(), createdZone.getName()); + assertEquals(ZONE1.getDescription(), createdZone.getDescription()); + assertEquals(ZONE1.getDnsName(), createdZone.getDnsName()); + assertEquals(4, createdZone.getNameServers().size()); + // get the same zone zone + ManagedZone zone = RPC.getZone(ZONE1.getName(), EMPTY_RPC_OPTIONS); + assertEquals(createdZone, zone); + // check that default records were created + DnsRpc.ListResult resourceRecordSetListResult + = RPC.listDnsRecords(ZONE1.getName(), EMPTY_RPC_OPTIONS); + assertEquals(2, Lists.newLinkedList(resourceRecordSetListResult.results()).size()); } @Test public void testDeleteZone() { - localDns.createZone(PROJECT_ID1, ZONE1, null); - LocalDnsHelper.Response response = localDns.deleteZone(PROJECT_ID1, ZONE1.getName()); + LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); + LocalDnsHelper.Response response = LOCAL_DNS_HELPER.deleteZone(PROJECT_ID1, ZONE1.getName()); assertEquals(204, response.code()); // deleting non-existent zone - response = localDns.deleteZone(PROJECT_ID1, ZONE1.getName()); + response = LOCAL_DNS_HELPER.deleteZone(PROJECT_ID1, ZONE1.getName()); assertEquals(404, response.code()); - assertNull(localDns.findZone(PROJECT_ID1, ZONE1.getName())); - localDns.createZone(PROJECT_ID1, ZONE1, null); - localDns.createZone(PROJECT_ID1, ZONE2, null); - assertNotNull(localDns.findZone(PROJECT_ID1, ZONE1.getName())); - assertNotNull(localDns.findZone(PROJECT_ID1, ZONE2.getName())); + assertNull(LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE1.getName())); + LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); + LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE2, null); + assertNotNull(LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE1.getName())); + assertNotNull(LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE2.getName())); // delete in reverse order - response = localDns.deleteZone(PROJECT_ID1, ZONE1.getName()); + response = LOCAL_DNS_HELPER.deleteZone(PROJECT_ID1, ZONE1.getName()); assertEquals(204, response.code()); - assertNull(localDns.findZone(PROJECT_ID1, ZONE1.getName())); - assertNotNull(localDns.findZone(PROJECT_ID1, ZONE2.getName())); - localDns.deleteZone(PROJECT_ID1, ZONE2.getName()); + assertNull(LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE1.getName())); + assertNotNull(LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE2.getName())); + LOCAL_DNS_HELPER.deleteZone(PROJECT_ID1, ZONE2.getName()); assertEquals(204, response.code()); - assertNull(localDns.findZone(PROJECT_ID1, ZONE1.getName())); - assertNull(localDns.findZone(PROJECT_ID1, ZONE2.getName())); + assertNull(LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE1.getName())); + assertNull(LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE2.getName())); + } + + @Test + public void testDeleteZoneUsingRpc() { + RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + assertTrue(RPC.deleteZone(ZONE1.getName())); + assertNull(RPC.getZone(ZONE1.getName(), EMPTY_RPC_OPTIONS)); + // deleting non-existent zone + assertFalse(RPC.deleteZone(ZONE1.getName())); + assertNull(RPC.getZone(ZONE1.getName(), EMPTY_RPC_OPTIONS)); + RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + RPC.create(ZONE2, EMPTY_RPC_OPTIONS); + assertNotNull(RPC.getZone(ZONE1.getName(), EMPTY_RPC_OPTIONS)); + assertNotNull(RPC.getZone(ZONE2.getName(), EMPTY_RPC_OPTIONS)); + // delete in reverse order + assertTrue(RPC.deleteZone(ZONE1.getName())); + assertNull(RPC.getZone(ZONE1.getName(), EMPTY_RPC_OPTIONS)); + assertNotNull(RPC.getZone(ZONE2.getName(), EMPTY_RPC_OPTIONS)); + assertTrue(RPC.deleteZone(ZONE2.getName())); + assertNull(RPC.getZone(ZONE1.getName(), EMPTY_RPC_OPTIONS)); + assertNull(RPC.getZone(ZONE2.getName(), EMPTY_RPC_OPTIONS)); } @Test public void testCreateAndApplyChange() { - localDns = LocalDnsHelper.create(5 * 1000L); // we will be using threads here - localDns.createZone(PROJECT_ID1, ZONE1, null); - assertNull(localDns.findZone(PROJECT_ID1, ZONE_NAME1).findChange("1")); + LocalDnsHelper localDnsThreaded = LocalDnsHelper.create(5 * 1000L); // using threads here + localDnsThreaded.createZone(PROJECT_ID1, ZONE1, null); + assertNull(localDnsThreaded.findZone(PROJECT_ID1, ZONE_NAME1).findChange("1")); LocalDnsHelper.Response response - = localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); // add + = localDnsThreaded.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); // add assertEquals(200, response.code()); - assertNotNull(localDns.findZone(PROJECT_ID1, ZONE_NAME1).findChange("1")); - assertNull(localDns.findZone(PROJECT_ID1, ZONE_NAME1).findChange("2")); - localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); // add - response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); // add + assertNotNull(localDnsThreaded.findZone(PROJECT_ID1, ZONE_NAME1).findChange("1")); + assertNull(localDnsThreaded.findZone(PROJECT_ID1, ZONE_NAME1).findChange("2")); + localDnsThreaded.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); // add + response = localDnsThreaded.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); // add assertEquals(200, response.code()); - assertNotNull(localDns.findZone(PROJECT_ID1, ZONE_NAME1).findChange("1")); - assertNotNull(localDns.findZone(PROJECT_ID1, ZONE_NAME1).findChange("2")); - localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE2, null); // delete - assertNotNull(localDns.findZone(PROJECT_ID1, ZONE_NAME1).findChange("1")); - assertNotNull(localDns.findZone(PROJECT_ID1, ZONE_NAME1).findChange("2")); - assertNotNull(localDns.findZone(PROJECT_ID1, ZONE_NAME1).findChange("3")); - localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE_KEEP, null); // id is "4" + assertNotNull(localDnsThreaded.findZone(PROJECT_ID1, ZONE_NAME1).findChange("1")); + assertNotNull(localDnsThreaded.findZone(PROJECT_ID1, ZONE_NAME1).findChange("2")); + localDnsThreaded.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE2, null); // delete + assertNotNull(localDnsThreaded.findZone(PROJECT_ID1, ZONE_NAME1).findChange("1")); + assertNotNull(localDnsThreaded.findZone(PROJECT_ID1, ZONE_NAME1).findChange("2")); + assertNotNull(localDnsThreaded.findZone(PROJECT_ID1, ZONE_NAME1).findChange("3")); + localDnsThreaded.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE_KEEP, null); // id is "4" // check execution - Change change = localDns.findChange(PROJECT_ID1, ZONE_NAME1, "4"); + Change change = localDnsThreaded.findChange(PROJECT_ID1, ZONE_NAME1, "4"); for (int i = 0; i < 10 && !change.getStatus().equals("done"); i++) { // change has not been finished yet; wait at most 20 seconds // it takes 5 seconds for the thread to kick in in the first place @@ -197,26 +263,70 @@ public void testCreateAndApplyChange() { } assertEquals("done", change.getStatus()); List list = - localDns.findZone(PROJECT_ID1, ZONE_NAME1).dnsRecords().get(ZONE_NAME1); + localDnsThreaded.findZone(PROJECT_ID1, ZONE_NAME1).dnsRecords().get(ZONE_NAME1); assertTrue(list.contains(new LocalDnsHelper.RrsetWrapper(RRSET_KEEP))); + localDnsThreaded.stop(); + } + + @Test + public void testCreateAndApplyChangeUsingRpc() { + // not using threads + RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + assertNull(RPC.getChangeRequest(ZONE1.getName(), "1", EMPTY_RPC_OPTIONS)); + //add + Change createdChange = RPC.applyChangeRequest(ZONE1.getName(), CHANGE1, EMPTY_RPC_OPTIONS); + assertEquals(createdChange.getAdditions(), CHANGE1.getAdditions()); + assertEquals(createdChange.getDeletions(), CHANGE1.getDeletions()); + assertNotNull(createdChange.getStartTime()); + assertEquals("1", createdChange.getId()); + Change retrievedChange = RPC.getChangeRequest(ZONE1.getName(), "1", EMPTY_RPC_OPTIONS); + assertEquals(createdChange, retrievedChange); + assertNull(RPC.getChangeRequest(ZONE1.getName(), "2", EMPTY_RPC_OPTIONS)); + try { + Change anotherChange = RPC.applyChangeRequest(ZONE1.getName(), CHANGE1, EMPTY_RPC_OPTIONS); + } catch (DnsException ex) { + assertEquals(409, ex.code()); + } + assertNotNull(RPC.getChangeRequest(ZONE1.getName(), "1", EMPTY_RPC_OPTIONS)); + assertNull(RPC.getChangeRequest(ZONE1.getName(), "2", EMPTY_RPC_OPTIONS)); + // delete + RPC.applyChangeRequest(ZONE1.getName(), CHANGE2, EMPTY_RPC_OPTIONS); + assertNotNull(RPC.getChangeRequest(ZONE1.getName(), "1", EMPTY_RPC_OPTIONS)); + assertNotNull(RPC.getChangeRequest(ZONE1.getName(), "2", EMPTY_RPC_OPTIONS)); + Change last = RPC.applyChangeRequest(ZONE1.getName(), CHANGE_KEEP, EMPTY_RPC_OPTIONS); + assertEquals("done", last.getStatus()); + // todo(mderka) replace with real call + List list = + LOCAL_DNS_HELPER.findZone(REAL_PROJECT_ID, ZONE_NAME1).dnsRecords().get(ZONE_NAME1); + assertTrue(list.contains(new LocalDnsHelper.RrsetWrapper(RRSET_KEEP))); + Iterable results = + RPC.listDnsRecords(ZONE1.getName(), EMPTY_RPC_OPTIONS).results(); + boolean ok = false; + for (ResourceRecordSet dnsRecord : results) { + if (dnsRecord.getName().equals(RRSET_KEEP.getName()) + && dnsRecord.getType().equals(RRSET_KEEP.getType())) { + ok = true; + } + } + assertTrue(ok); } @Test public void testFindChange() { - localDns.createZone(PROJECT_ID1, ZONE1, null); - Change change = localDns.findChange(PROJECT_ID1, ZONE1.getName(), "somerandomchange"); + LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); + Change change = LOCAL_DNS_HELPER.findChange(PROJECT_ID1, ZONE1.getName(), "somerandomchange"); assertNull(change); - localDns.createChange(PROJECT_ID1, ZONE1.getName(), CHANGE1, null); + LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE1.getName(), CHANGE1, null); // changes are sequential so we should find ID 1 - assertNotNull(localDns.findChange(PROJECT_ID1, ZONE1.getName(), "1")); + assertNotNull(LOCAL_DNS_HELPER.findChange(PROJECT_ID1, ZONE1.getName(), "1")); // add another - localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE2, null); - assertNotNull(localDns.findChange(PROJECT_ID1, ZONE1.getName(), "1")); - assertNotNull(localDns.findChange(PROJECT_ID1, ZONE1.getName(), "2")); + LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE2, null); + assertNotNull(LOCAL_DNS_HELPER.findChange(PROJECT_ID1, ZONE1.getName(), "1")); + assertNotNull(LOCAL_DNS_HELPER.findChange(PROJECT_ID1, ZONE1.getName(), "2")); // try to find non-existent change - assertNull(localDns.findChange(PROJECT_ID1, ZONE1.getName(), "3")); + assertNull(LOCAL_DNS_HELPER.findChange(PROJECT_ID1, ZONE1.getName(), "3")); // try to find a change in yet non-existent project - assertNull(localDns.findChange(PROJECT_ID2, ZONE1.getName(), "3")); + assertNull(LOCAL_DNS_HELPER.findChange(PROJECT_ID2, ZONE1.getName(), "3")); } @Test @@ -230,71 +340,375 @@ public void testRandomNameServers() { @Test public void testGetProject() { // only interested in no exceptions and non-null response here - assertNotNull(localDns.getProject(PROJECT_ID1, null)); - assertNotNull(localDns.getProject(PROJECT_ID2, null)); + assertNotNull(LOCAL_DNS_HELPER.getProject(PROJECT_ID1, null)); + assertNotNull(LOCAL_DNS_HELPER.getProject(PROJECT_ID2, null)); + Project project = RPC.getProject(EMPTY_RPC_OPTIONS); + assertNotNull(project.getQuota()); + assertEquals(REAL_PROJECT_ID, project.getId()); + // fields options + Map options = new HashMap<>(); + options.put(DnsRpc.Option.FIELDS, "number"); + project = RPC.getProject(options); + assertNull(project.getId()); + assertNotNull(project.getNumber()); + assertNull(project.getQuota()); + options.put(DnsRpc.Option.FIELDS, "id"); + project = RPC.getProject(options); + assertNotNull(project.getId()); + assertNull(project.getNumber()); + assertNull(project.getQuota()); + options.put(DnsRpc.Option.FIELDS, "quota"); + project = RPC.getProject(options); + assertNull(project.getId()); + assertNull(project.getNumber()); + assertNotNull(project.getQuota()); } @Test public void testGetZone() { // non-existent - LocalDnsHelper.Response response = localDns.getZone(PROJECT_ID1, ZONE_NAME1, null); + LocalDnsHelper.Response response = LOCAL_DNS_HELPER.getZone(PROJECT_ID1, ZONE_NAME1, null); assertEquals(404, response.code()); assertTrue(response.body().contains("does not exist")); // existent - localDns.createZone(PROJECT_ID1, ZONE1, null); - response = localDns.getZone(PROJECT_ID1, ZONE1.getName(), null); + LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); + response = LOCAL_DNS_HELPER.getZone(PROJECT_ID1, ZONE1.getName(), null); assertEquals(200, response.code()); } + @Test + public void testGetZoneUsingRpc() { + // non-existent + assertNull(RPC.getZone(ZONE_NAME1, EMPTY_RPC_OPTIONS)); + // existent + ManagedZone created = RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + ManagedZone zone = RPC.getZone(ZONE_NAME1, EMPTY_RPC_OPTIONS); + assertEquals(created, zone); + assertEquals(ZONE1.getName(), zone.getName()); + // field options + Map options = new HashMap<>(); + options.put(DnsRpc.Option.FIELDS, "id"); + zone = RPC.getZone(ZONE1.getName(), options); + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNotNull(zone.getId()); + options.put(DnsRpc.Option.FIELDS, "creationTime"); + zone = RPC.getZone(ZONE1.getName(), options); + assertNotNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + options.put(DnsRpc.Option.FIELDS, "dnsName"); + zone = RPC.getZone(ZONE1.getName(), options); + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNotNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + options.put(DnsRpc.Option.FIELDS, "description"); + zone = RPC.getZone(ZONE1.getName(), options); + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNotNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + options.put(DnsRpc.Option.FIELDS, "nameServers"); + zone = RPC.getZone(ZONE1.getName(), options); + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNotNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + options.put(DnsRpc.Option.FIELDS, "nameServerSet"); + zone = RPC.getZone(ZONE1.getName(), options); + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNotNull(zone.getNameServerSet()); + assertNull(zone.getId()); + // several combined + options.put(DnsRpc.Option.FIELDS, "nameServerSet,description,id,name"); + zone = RPC.getZone(ZONE1.getName(), options); + assertNull(zone.getCreationTime()); + assertNotNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNotNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNotNull(zone.getNameServerSet()); + assertNotNull(zone.getId()); + } + @Test public void testCreateZone() { // only interested in no exceptions and non-null response here - LocalDnsHelper.Response response = localDns.createZone(PROJECT_ID1, ZONE1, null); + LocalDnsHelper.Response response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); assertEquals(200, response.code()); - assertEquals(1, localDns.projects().get(PROJECT_ID1).zones().size()); + assertEquals(1, LOCAL_DNS_HELPER.projects().get(PROJECT_ID1).zones().size()); try { - localDns.createZone(PROJECT_ID1, null, null); + LOCAL_DNS_HELPER.createZone(PROJECT_ID1, null, null); fail("Zone cannot be null"); } catch (NullPointerException ex) { // expected } // create zone twice - response = localDns.createZone(PROJECT_ID1, ZONE1, null); + response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); assertEquals(409, response.code()); assertTrue(response.body().contains("already exists")); } + @Test + public void testCreateZoneUsingRpc() { + ManagedZone created = RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + assertEquals(created, LOCAL_DNS_HELPER.findZone(REAL_PROJECT_ID, ZONE1.getName()).zone()); + ManagedZone zone = RPC.getZone(ZONE_NAME1, EMPTY_RPC_OPTIONS); + assertEquals(created, zone); + try { + RPC.create(null, EMPTY_RPC_OPTIONS); + fail("Zone cannot be null"); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + assertTrue(ex.getMessage().contains("entity.managedZone")); + } + // create zone twice + try { + RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + } catch (DnsException ex) { + // expected + assertEquals(409, ex.code()); + assertTrue(ex.getMessage().contains("already exists")); + } + // field options + resetProjects(); + Map options = new HashMap<>(); + options.put(DnsRpc.Option.FIELDS, "id"); + zone = RPC.create(ZONE1, options); + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNotNull(zone.getId()); + resetProjects(); + options.put(DnsRpc.Option.FIELDS, "creationTime"); + zone = RPC.create(ZONE1, options); + assertNotNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + options.put(DnsRpc.Option.FIELDS, "dnsName"); + resetProjects(); + zone = RPC.create(ZONE1, options); + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNotNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + options.put(DnsRpc.Option.FIELDS, "description"); + resetProjects(); + zone = RPC.create(ZONE1, options); + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNotNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + options.put(DnsRpc.Option.FIELDS, "nameServers"); + resetProjects(); + zone = RPC.create(ZONE1, options); + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNotNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + options.put(DnsRpc.Option.FIELDS, "nameServerSet"); + resetProjects(); + zone = RPC.create(ZONE1, options); + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNotNull(zone.getNameServerSet()); + assertNull(zone.getId()); + // several combined + options.put(DnsRpc.Option.FIELDS, "nameServerSet,description,id,name"); + resetProjects(); + zone = RPC.create(ZONE1, options); + assertNull(zone.getCreationTime()); + assertNotNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNotNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNotNull(zone.getNameServerSet()); + assertNotNull(zone.getId()); + } + @Test public void testCreateChange() { // non-existent zone LocalDnsHelper.Response response = - localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); + LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); assertEquals(404, response.code()); - // existent zone - assertNotNull(localDns.createZone(PROJECT_ID1, ZONE1, null)); - assertNull(localDns.findChange(PROJECT_ID1, ZONE_NAME1, "1")); - response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); + assertNotNull(LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null)); + assertNull(LOCAL_DNS_HELPER.findChange(PROJECT_ID1, ZONE_NAME1, "1")); + response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); assertEquals(200, response.code()); - assertNotNull(localDns.findChange(PROJECT_ID1, ZONE_NAME1, "1")); + assertNotNull(LOCAL_DNS_HELPER.findChange(PROJECT_ID1, ZONE_NAME1, "1")); + } + + @Test + public void testCreateChangeUsingRpc() { + // non-existent zone + try { + RPC.applyChangeRequest(ZONE_NAME1, CHANGE1, EMPTY_RPC_OPTIONS); + } catch (DnsException ex) { + assertEquals(404, ex.code()); + } + // existent zone + RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + assertNull(RPC.getChangeRequest(ZONE_NAME1, "1", EMPTY_RPC_OPTIONS)); + Change created = RPC.applyChangeRequest(ZONE1.getName(), CHANGE1, EMPTY_RPC_OPTIONS); + assertEquals(created, RPC.getChangeRequest(ZONE_NAME1, "1", EMPTY_RPC_OPTIONS)); + // field options + RPC.applyChangeRequest(ZONE1.getName(), CHANGE_KEEP, EMPTY_RPC_OPTIONS); + Map options = new HashMap<>(); + options.put(DnsRpc.Option.FIELDS, "additions"); + Change complex = RPC.applyChangeRequest(ZONE1.getName(), CHANGE_COMPLEX, options); + assertNotNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNull(complex.getStatus()); + options.put(DnsRpc.Option.FIELDS, "deletions"); + complex = RPC.applyChangeRequest(ZONE1.getName(), CHANGE_COMPLEX, options); + assertNull(complex.getAdditions()); + assertNotNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNull(complex.getStatus()); + options.put(DnsRpc.Option.FIELDS, "id"); + complex = RPC.applyChangeRequest(ZONE1.getName(), CHANGE_COMPLEX, options); + assertNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNotNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNull(complex.getStatus()); + options.put(DnsRpc.Option.FIELDS, "startTime"); + complex = RPC.applyChangeRequest(ZONE1.getName(), CHANGE_COMPLEX, options); + assertNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNotNull(complex.getStartTime()); + assertNull(complex.getStatus()); + options.put(DnsRpc.Option.FIELDS, "status"); + complex = RPC.applyChangeRequest(ZONE1.getName(), CHANGE_COMPLEX, options); + assertNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNotNull(complex.getStatus()); } @Test public void testGetChange() { // existent - assertEquals(200, localDns.createZone(PROJECT_ID1, ZONE1, null).code()); - assertEquals(200, localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null).code()); - assertEquals(200, localDns.getChange(PROJECT_ID1, ZONE_NAME1, "1", null).code()); + assertEquals(200, LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null).code()); + assertEquals(200, LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null).code()); + assertEquals(200, LOCAL_DNS_HELPER.getChange(PROJECT_ID1, ZONE_NAME1, "1", null).code()); // non-existent - LocalDnsHelper.Response response = localDns.getChange(PROJECT_ID1, ZONE_NAME1, "2", null); + LocalDnsHelper.Response response = + LOCAL_DNS_HELPER.getChange(PROJECT_ID1, ZONE_NAME1, "2", null); assertEquals(404, response.code()); assertTrue(response.body().contains("parameters.changeId")); // non-existent zone - response = localDns.getChange(PROJECT_ID1, ZONE_NAME2, "1", null); + response = LOCAL_DNS_HELPER.getChange(PROJECT_ID1, ZONE_NAME2, "1", null); assertEquals(404, response.code()); assertTrue(response.body().contains("parameters.managedZone")); } + @Test + public void testGetChangeUsingRpc() { + // existent + RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + Change created = RPC.applyChangeRequest(ZONE1.getName(), CHANGE1, EMPTY_RPC_OPTIONS); + Change retrieved = RPC.getChangeRequest(ZONE1.getName(), "1", EMPTY_RPC_OPTIONS); + assertEquals(created, retrieved); + // non-existent + assertNull(RPC.getChangeRequest(ZONE1.getName(), "2", EMPTY_RPC_OPTIONS)); + // non-existent zone + try { + RPC.getChangeRequest(ZONE_NAME2, "1", EMPTY_RPC_OPTIONS); + } catch (DnsException ex) { + // expected + assertEquals(404, ex.code()); + } + // field options + RPC.applyChangeRequest(ZONE1.getName(), CHANGE_KEEP, EMPTY_RPC_OPTIONS); + Change change = RPC.applyChangeRequest(ZONE1.getName(), CHANGE_COMPLEX, EMPTY_RPC_OPTIONS); + Map options = new HashMap<>(); + options.put(DnsRpc.Option.FIELDS, "additions"); + Change complex = RPC.getChangeRequest(ZONE1.getName(), change.getId(), options); + assertNotNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNull(complex.getStatus()); + options.put(DnsRpc.Option.FIELDS, "deletions"); + complex = RPC.getChangeRequest(ZONE1.getName(), change.getId(), options); + assertNull(complex.getAdditions()); + assertNotNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNull(complex.getStatus()); + options.put(DnsRpc.Option.FIELDS, "id"); + complex = RPC.getChangeRequest(ZONE1.getName(), change.getId(), options); + assertNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNotNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNull(complex.getStatus()); + options.put(DnsRpc.Option.FIELDS, "startTime"); + complex = RPC.getChangeRequest(ZONE1.getName(), change.getId(), options); + assertNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNotNull(complex.getStartTime()); + assertNull(complex.getStatus()); + options.put(DnsRpc.Option.FIELDS, "status"); + complex = RPC.getChangeRequest(ZONE1.getName(), change.getId(), options); + assertNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNotNull(complex.getStatus()); + } + @Test public void testListZones() { // only interested in no exceptions and non-null response here @@ -302,36 +716,175 @@ public void testListZones() { optionsMap.put("fields", null); optionsMap.put("pageToken", null); optionsMap.put("maxResults", null); - LocalDnsHelper.Response response = localDns.listZones(PROJECT_ID1, optionsMap); + LocalDnsHelper.Response response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); assertEquals(200, response.code()); // some zones exists - localDns.createZone(PROJECT_ID1, ZONE1, null); - response = localDns.listZones(PROJECT_ID1, optionsMap); + LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); + response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); assertEquals(200, response.code()); - localDns.createZone(PROJECT_ID1, ZONE2, null); - response = localDns.listZones(PROJECT_ID1, optionsMap); + LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE2, null); + response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); assertEquals(200, response.code()); // error in options optionsMap.put("maxResults", "aaa"); - response = localDns.listZones(PROJECT_ID1, optionsMap); + response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); assertEquals(400, response.code()); optionsMap.put("maxResults", "0"); - response = localDns.listZones(PROJECT_ID1, optionsMap); + response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); assertEquals(400, response.code()); optionsMap.put("maxResults", "-1"); - response = localDns.listZones(PROJECT_ID1, optionsMap); + response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); assertEquals(400, response.code()); optionsMap.put("maxResults", "15"); - response = localDns.listZones(PROJECT_ID1, optionsMap); + response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); assertEquals(200, response.code()); optionsMap.put("dnsName", "aaa"); - response = localDns.listZones(PROJECT_ID1, optionsMap); + response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); assertEquals(400, response.code()); optionsMap.put("dnsName", "aaa."); - response = localDns.listZones(PROJECT_ID1, optionsMap); + response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); assertEquals(200, response.code()); } + @Test + public void testListZonesUsingRpc() { + Iterable results = RPC.listZones(EMPTY_RPC_OPTIONS).results(); + ImmutableList zones = ImmutableList.copyOf(results); + assertEquals(0, zones.size()); + // some zones exists + ManagedZone created = RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + results = RPC.listZones(EMPTY_RPC_OPTIONS).results(); + zones = ImmutableList.copyOf(results); + assertEquals(created, zones.get(0)); + assertEquals(1, zones.size()); + created = RPC.create(ZONE2, EMPTY_RPC_OPTIONS); + results = RPC.listZones(EMPTY_RPC_OPTIONS).results(); + zones = ImmutableList.copyOf(results); + assertEquals(2, zones.size()); + assertTrue(zones.contains(created)); + // error in options + Map options = new HashMap<>(); + options.put(DnsRpc.Option.PAGE_SIZE, 0); + try { + RPC.listZones(options); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + } + options = new HashMap<>(); + options.put(DnsRpc.Option.PAGE_SIZE, -1); + try { + RPC.listZones(options); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + } + // ok size + options = new HashMap<>(); + options.put(DnsRpc.Option.PAGE_SIZE, 1); + results = RPC.listZones(options).results(); + zones = ImmutableList.copyOf(results); + assertEquals(1, zones.size()); + // dns name problems + options = new HashMap<>(); + options.put(DnsRpc.Option.DNS_NAME, "aaa"); + try { + RPC.listZones(options); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + } + // ok name + options = new HashMap<>(); + options.put(DnsRpc.Option.DNS_NAME, "aaaa."); + results = RPC.listZones(options).results(); + zones = ImmutableList.copyOf(results); + assertEquals(0, zones.size()); + // field options + options = new HashMap<>(); + options.put(DnsRpc.Option.FIELDS, "managedZones(id)"); + ManagedZone zone = RPC.listZones(options).results().iterator().next(); + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNotNull(zone.getId()); + options.put(DnsRpc.Option.FIELDS, "managedZones(creationTime)"); + zone = RPC.listZones(options).results().iterator().next(); + assertNotNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + options.put(DnsRpc.Option.FIELDS, "managedZones(dnsName)"); + zone = RPC.listZones(options).results().iterator().next(); + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNotNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + options.put(DnsRpc.Option.FIELDS, "managedZones(description)"); + zone = RPC.listZones(options).results().iterator().next(); + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNotNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + options.put(DnsRpc.Option.FIELDS, "managedZones(nameServers)"); + zone = RPC.listZones(options).results().iterator().next(); + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNotNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + options.put(DnsRpc.Option.FIELDS, "managedZones(nameServerSet)"); + DnsRpc.ListResult managedZoneListResult = RPC.listZones(options); + zone = managedZoneListResult.results().iterator().next(); + assertNull(managedZoneListResult.pageToken()); + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNotNull(zone.getNameServerSet()); + assertNull(zone.getId()); + // several combined + options.put(DnsRpc.Option.FIELDS, + "managedZones(nameServerSet,description,id,name),nextPageToken"); + options.put(DnsRpc.Option.PAGE_SIZE, 1); + managedZoneListResult = RPC.listZones(options); + zone = managedZoneListResult.results().iterator().next(); + assertNull(zone.getCreationTime()); + assertNotNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNotNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNotNull(zone.getNameServerSet()); + assertNotNull(zone.getId()); + assertEquals(zone.getName(), managedZoneListResult.pageToken()); + // paging + options = new HashMap<>(); + options.put(DnsRpc.Option.PAGE_SIZE, 1); + managedZoneListResult = RPC.listZones(options); + ImmutableList page1 = ImmutableList.copyOf(managedZoneListResult.results()); + assertEquals(1, page1.size()); + options.put(DnsRpc.Option.PAGE_TOKEN, managedZoneListResult.pageToken()); + managedZoneListResult = RPC.listZones(options); + ImmutableList page2 = ImmutableList.copyOf(managedZoneListResult.results()); + assertEquals(1, page2.size()); + assertNotEquals(page1.get(0), page2.get(0)); + } + @Test public void testListDnsRecords() { // only interested in no exceptions and non-null response here @@ -341,49 +894,196 @@ public void testListDnsRecords() { optionsMap.put("pageToken", null); optionsMap.put("maxResults", null); // no zone exists - LocalDnsHelper.Response response = localDns.listDnsRecords(PROJECT_ID1, ZONE_NAME1, + LocalDnsHelper.Response response = LOCAL_DNS_HELPER.listDnsRecords(PROJECT_ID1, ZONE_NAME1, optionsMap); assertEquals(404, response.code()); // zone exists but has no records - localDns.createZone(PROJECT_ID1, ZONE1, null); - localDns.listDnsRecords(PROJECT_ID1, ZONE_NAME1, optionsMap); + LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); + LOCAL_DNS_HELPER.listDnsRecords(PROJECT_ID1, ZONE_NAME1, optionsMap); // zone has records - localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); - response = localDns.listDnsRecords(PROJECT_ID1, ZONE_NAME1, optionsMap); + LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); + response = LOCAL_DNS_HELPER.listDnsRecords(PROJECT_ID1, ZONE_NAME1, optionsMap); assertEquals(200, response.code()); // error in options optionsMap.put("maxResults", "aaa"); - response = localDns.listZones(PROJECT_ID1, optionsMap); + response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); assertEquals(400, response.code()); optionsMap.put("maxResults", "0"); - response = localDns.listZones(PROJECT_ID1, optionsMap); + response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); assertEquals(400, response.code()); optionsMap.put("maxResults", "-1"); - response = localDns.listZones(PROJECT_ID1, optionsMap); + response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); assertEquals(400, response.code()); optionsMap.put("maxResults", "15"); - response = localDns.listZones(PROJECT_ID1, optionsMap); + response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); assertEquals(200, response.code()); optionsMap.put("name", "aaa"); - response = localDns.listZones(PROJECT_ID1, optionsMap); + response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); assertEquals(400, response.code()); optionsMap.put("name", "aaa."); - response = localDns.listZones(PROJECT_ID1, optionsMap); + response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); assertEquals(200, response.code()); optionsMap.put("name", null); optionsMap.put("type", "A"); - response = localDns.listZones(PROJECT_ID1, optionsMap); + response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); assertEquals(400, response.code()); optionsMap.put("name", "aaa."); optionsMap.put("type", "a"); - response = localDns.listZones(PROJECT_ID1, optionsMap); + response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); assertEquals(400, response.code()); optionsMap.put("name", "aaaa."); optionsMap.put("type", "A"); - response = localDns.listZones(PROJECT_ID1, optionsMap); + response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); assertEquals(200, response.code()); } + @Test + public void testListDnsRecordsUsingRpc() { + // no zone exists + try { + RPC.listDnsRecords(ZONE_NAME1, EMPTY_RPC_OPTIONS); + } catch (DnsException ex) { + // expected + assertEquals(404, ex.code()); + } + // zone exists but has no records + RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + Iterable results = + RPC.listDnsRecords(ZONE_NAME1, EMPTY_RPC_OPTIONS).results(); + ImmutableList records = ImmutableList.copyOf(results); + assertEquals(2, records.size()); // contains default NS and SOA + // zone has records + RPC.applyChangeRequest(ZONE_NAME1, CHANGE_KEEP, EMPTY_RPC_OPTIONS); + results = RPC.listDnsRecords(ZONE_NAME1, EMPTY_RPC_OPTIONS).results(); + records = ImmutableList.copyOf(results); + assertEquals(3, records.size()); + // error in options + Map options = new HashMap<>(); + options.put(DnsRpc.Option.PAGE_SIZE, 0); + try { + RPC.listDnsRecords(ZONE1.getName(), options); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + } + options.put(DnsRpc.Option.PAGE_SIZE, -1); + try { + RPC.listDnsRecords(ZONE1.getName(), options); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + } + options.put(DnsRpc.Option.PAGE_SIZE, 1); + results = RPC.listDnsRecords(ZONE1.getName(), options).results(); + records = ImmutableList.copyOf(results); + assertEquals(1, records.size()); + options.put(DnsRpc.Option.PAGE_SIZE, 15); + results = RPC.listDnsRecords(ZONE1.getName(), options).results(); + records = ImmutableList.copyOf(results); + assertEquals(3, records.size()); + + // dnsName filter + options = new HashMap<>(); + options.put(DnsRpc.Option.NAME, "aaa"); + try { + RPC.listDnsRecords(ZONE1.getName(), options); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + } + options.put(DnsRpc.Option.NAME, "aaa."); + results = RPC.listDnsRecords(ZONE1.getName(), options).results(); + records = ImmutableList.copyOf(results); + assertEquals(0, records.size()); + options.put(DnsRpc.Option.NAME, null); + options.put(DnsRpc.Option.DNS_TYPE, "A"); + try { + RPC.listDnsRecords(ZONE1.getName(), options); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + } + options.put(DnsRpc.Option.NAME, "aaa."); + options.put(DnsRpc.Option.DNS_TYPE, "a"); + try { + RPC.listDnsRecords(ZONE1.getName(), options); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + } + options.put(DnsRpc.Option.NAME, DNS_NAME); + options.put(DnsRpc.Option.DNS_TYPE, "SOA"); + results = RPC.listDnsRecords(ZONE1.getName(), options).results(); + records = ImmutableList.copyOf(results); + assertEquals(1, records.size()); + // field options + options = new HashMap<>(); + options.put(DnsRpc.Option.FIELDS, "rrsets(name)"); + DnsRpc.ListResult resourceRecordSetListResult = + RPC.listDnsRecords(ZONE1.getName(), options); + records = ImmutableList.copyOf(resourceRecordSetListResult.results()); + ResourceRecordSet record = records.get(0); + assertNotNull(record.getName()); + assertNull(record.getRrdatas()); + assertNull(record.getType()); + assertNull(record.getTtl()); + assertNull(resourceRecordSetListResult.pageToken()); + options.put(DnsRpc.Option.FIELDS, "rrsets(rrdatas)"); + resourceRecordSetListResult = RPC.listDnsRecords(ZONE1.getName(), options); + records = ImmutableList.copyOf(resourceRecordSetListResult.results()); + record = records.get(0); + assertNull(record.getName()); + assertNotNull(record.getRrdatas()); + assertNull(record.getType()); + assertNull(record.getTtl()); + assertNull(resourceRecordSetListResult.pageToken()); + options.put(DnsRpc.Option.FIELDS, "rrsets(ttl)"); + resourceRecordSetListResult = RPC.listDnsRecords(ZONE1.getName(), options); + records = ImmutableList.copyOf(resourceRecordSetListResult.results()); + record = records.get(0); + assertNull(record.getName()); + assertNull(record.getRrdatas()); + assertNull(record.getType()); + assertNotNull(record.getTtl()); + assertNull(resourceRecordSetListResult.pageToken()); + options.put(DnsRpc.Option.FIELDS, "rrsets(type)"); + resourceRecordSetListResult = RPC.listDnsRecords(ZONE1.getName(), options); + records = ImmutableList.copyOf(resourceRecordSetListResult.results()); + record = records.get(0); + assertNull(record.getName()); + assertNull(record.getRrdatas()); + assertNotNull(record.getType()); + assertNull(record.getTtl()); + assertNull(resourceRecordSetListResult.pageToken()); + options.put(DnsRpc.Option.FIELDS, "nextPageToken"); + resourceRecordSetListResult = RPC.listDnsRecords(ZONE1.getName(), options); + records = ImmutableList.copyOf(resourceRecordSetListResult.results()); + record = records.get(0); + assertNull(record.getName()); + assertNull(record.getRrdatas()); + assertNull(record.getType()); + assertNull(record.getTtl()); + assertNull(resourceRecordSetListResult.pageToken()); + options.put(DnsRpc.Option.FIELDS, "nextPageToken,rrsets(name,rrdatas)"); + options.put(DnsRpc.Option.PAGE_SIZE, 1); + resourceRecordSetListResult = RPC.listDnsRecords(ZONE1.getName(), options); + records = ImmutableList.copyOf(resourceRecordSetListResult.results()); + assertEquals(1, records.size()); + record = records.get(0); + assertNotNull(record.getName()); + assertNotNull(record.getRrdatas()); + assertNull(record.getType()); + assertNull(record.getTtl()); + assertNotNull(resourceRecordSetListResult.pageToken()); + // paging + options.put(DnsRpc.Option.PAGE_TOKEN, resourceRecordSetListResult.pageToken()); + resourceRecordSetListResult = RPC.listDnsRecords(ZONE1.getName(), options); + records = ImmutableList.copyOf(resourceRecordSetListResult.results()); + assertEquals(1, records.size()); + ResourceRecordSet nextRecord = records.get(0); + assertNotEquals(record, nextRecord); + } + @Test public void testListChanges() { optionsMap.put("sortBy", null); @@ -392,72 +1092,214 @@ public void testListChanges() { optionsMap.put("pageToken", null); optionsMap.put("maxResults", null); // no such zone exists - LocalDnsHelper.Response response = localDns.listDnsRecords(PROJECT_ID1, ZONE_NAME1, optionsMap); + LocalDnsHelper.Response response = + LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); assertEquals(404, response.code()); assertTrue(response.body().contains("managedZone")); // zone exists but has no changes - localDns.createZone(PROJECT_ID1, ZONE1, null); - assertNotNull(localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap)); + LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); + assertNotNull(LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap)); // zone has changes - localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); - assertNotNull(localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap)); - localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); - localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE2, null); - localDns.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE2, null); - assertNotNull(localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap)); + LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); + assertNotNull(LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap)); + LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); + LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE2, null); + LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE2, null); + assertNotNull(LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap)); // error in options optionsMap.put("maxResults", "aaa"); - response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); + response = LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); assertEquals(400, response.code()); optionsMap.put("maxResults", "0"); - response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); + response = LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); assertEquals(400, response.code()); optionsMap.put("maxResults", "-1"); - response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); + response = LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); assertEquals(400, response.code()); optionsMap.put("maxResults", "15"); - response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); - assertEquals(200, response.code()); - optionsMap.put("dnsName", "aaa"); - response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); - assertEquals(400, response.code()); - optionsMap.put("dnsName", "aaa."); - response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); + response = LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); assertEquals(200, response.code()); optionsMap.put("sortBy", "changeSequence"); - response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); + response = LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); assertEquals(200, response.code()); optionsMap.put("sortBy", "something else"); - response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); + response = LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); assertEquals(400, response.code()); assertTrue(response.body().contains("Allowed values: [changesequence]")); optionsMap.put("sortBy", "ChAnGeSeQuEnCe"); // is not case sensitive - response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); + response = LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); assertEquals(200, response.code()); optionsMap.put("sortOrder", "ascending"); - response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); + response = LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); assertEquals(200, response.code()); optionsMap.put("sortBy", null); optionsMap.put("sortOrder", "descending"); - response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); + response = LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); assertEquals(200, response.code()); optionsMap.put("sortOrder", "somethingelse"); - response = localDns.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); + response = LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); assertEquals(400, response.code()); assertTrue(response.body().contains("parameters.sortOrder")); } + @Test + public void testListChangesUsingRpc() { + // no such zone exists + try { + RPC.listChangeRequests(ZONE_NAME1, EMPTY_RPC_OPTIONS); + } catch (DnsException ex) { + // expected + assertEquals(404, ex.code()); + } + // zone exists but has no changes + RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + Iterable results = RPC.listChangeRequests(ZONE1.getName(), EMPTY_RPC_OPTIONS).results(); + ImmutableList changes = ImmutableList.copyOf(results); + assertEquals(0, changes.size()); + // zone has changes + RPC.applyChangeRequest(ZONE1.getName(), CHANGE1, EMPTY_RPC_OPTIONS); + RPC.applyChangeRequest(ZONE1.getName(), CHANGE2, EMPTY_RPC_OPTIONS); + RPC.applyChangeRequest(ZONE1.getName(), CHANGE_KEEP, EMPTY_RPC_OPTIONS); + results = RPC.listChangeRequests(ZONE1.getName(), EMPTY_RPC_OPTIONS).results(); + changes = ImmutableList.copyOf(results); + assertEquals(3, changes.size()); + // error in options + Map options = new HashMap<>(); + options.put(DnsRpc.Option.PAGE_SIZE, 0); + try { + RPC.listChangeRequests(ZONE1.getName(), options); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + } + options.put(DnsRpc.Option.PAGE_SIZE, -1); + try { + RPC.listChangeRequests(ZONE1.getName(), options); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + } + options.put(DnsRpc.Option.PAGE_SIZE, 15); + try { + RPC.listChangeRequests(ZONE1.getName(), options); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + } + options = new HashMap<>(); + options.put(DnsRpc.Option.SORTING_ORDER, "descending"); + results = RPC.listChangeRequests(ZONE1.getName(), options).results(); + ImmutableList descending = ImmutableList.copyOf(results); + results = RPC.listChangeRequests(ZONE1.getName(), EMPTY_RPC_OPTIONS).results(); + ImmutableList ascending = ImmutableList.copyOf(results); + int size = 3; + assertEquals(size, descending.size()); + for (int i = 0; i < size; i++) { + assertEquals(descending.get(i), ascending.get(size - i - 1)); + } + options.put(DnsRpc.Option.SORTING_ORDER, "something else"); + try { + RPC.listChangeRequests(ZONE1.getName(), options); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + } + // field options + RPC.applyChangeRequest(ZONE1.getName(), CHANGE_COMPLEX, EMPTY_RPC_OPTIONS); + options = new HashMap<>(); + options.put(DnsRpc.Option.SORTING_ORDER, "descending"); + options.put(DnsRpc.Option.FIELDS, "changes(additions)"); + DnsRpc.ListResult changeListResult = + RPC.listChangeRequests(ZONE1.getName(), options); + changes = ImmutableList.copyOf(changeListResult.results()); + Change complex = changes.get(0); + assertNotNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNull(complex.getStatus()); + assertNull(changeListResult.pageToken()); + options.put(DnsRpc.Option.FIELDS, "changes(deletions)"); + changeListResult = RPC.listChangeRequests(ZONE1.getName(), options); + changes = ImmutableList.copyOf(changeListResult.results()); + complex = changes.get(0); + assertNull(complex.getAdditions()); + assertNotNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNull(complex.getStatus()); + assertNull(changeListResult.pageToken()); + options.put(DnsRpc.Option.FIELDS, "changes(id)"); + changeListResult = RPC.listChangeRequests(ZONE1.getName(), options); + changes = ImmutableList.copyOf(changeListResult.results()); + complex = changes.get(0); + assertNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNotNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNull(complex.getStatus()); + assertNull(changeListResult.pageToken()); + options.put(DnsRpc.Option.FIELDS, "changes(startTime)"); + changeListResult = RPC.listChangeRequests(ZONE1.getName(), options); + changes = ImmutableList.copyOf(changeListResult.results()); + complex = changes.get(0); + assertNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNotNull(complex.getStartTime()); + assertNull(complex.getStatus()); + assertNull(changeListResult.pageToken()); + options.put(DnsRpc.Option.FIELDS, "changes(status)"); + changeListResult = RPC.listChangeRequests(ZONE1.getName(), options); + changes = ImmutableList.copyOf(changeListResult.results()); + complex = changes.get(0); + assertNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNotNull(complex.getStatus()); + assertNull(changeListResult.pageToken()); + options.put(DnsRpc.Option.FIELDS, "nextPageToken"); + options.put(DnsRpc.Option.PAGE_SIZE, 1); + changeListResult = RPC.listChangeRequests(ZONE1.getName(), options); + changes = ImmutableList.copyOf(changeListResult.results()); + complex = changes.get(0); + assertNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNull(complex.getStatus()); + assertNotNull(changeListResult.pageToken()); + // paging + options.put(DnsRpc.Option.FIELDS, "nextPageToken,changes(id)"); + options.put(DnsRpc.Option.PAGE_SIZE, 1); + changeListResult = RPC.listChangeRequests(ZONE1.getName(), options); + changes = ImmutableList.copyOf(changeListResult.results()); + assertEquals(1, changes.size()); + final Change first = changes.get(0); + assertNotNull(changeListResult.pageToken()); + options.put(DnsRpc.Option.PAGE_TOKEN, changeListResult.pageToken()); + changeListResult = RPC.listChangeRequests(ZONE1.getName(), options); + changes = ImmutableList.copyOf(changeListResult.results()); + assertEquals(1, changes.size()); + Change second = changes.get(0); + assertNotEquals(first, second); + } + @Test public void testToListResponse() { LocalDnsHelper.Response response = LocalDnsHelper.toListResponse( - Lists.newArrayList("some", "multiple", "words"), "IncludeThisPageToken", true); + Lists.newArrayList("some", "multiple", "words"), "contextA", "IncludeThisPageToken", true); assertTrue(response.body().contains("IncludeThisPageToken")); + assertTrue(response.body().contains("contextA")); response = LocalDnsHelper.toListResponse( - Lists.newArrayList("some", "multiple", "words"), "IncludeThisPageToken", false); + Lists.newArrayList("some", "multiple", "words"), "contextB", "IncludeThisPageToken", false); assertFalse(response.body().contains("IncludeThisPageToken")); + assertTrue(response.body().contains("contextB")); response = LocalDnsHelper.toListResponse( - Lists.newArrayList("some", "multiple", "words"), null, true); + Lists.newArrayList("some", "multiple", "words"), "contextC", null, true); assertFalse(response.body().contains("pageToken")); + assertTrue(response.body().contains("contextC")); } @Test @@ -511,45 +1353,45 @@ public void testCreateZoneValidatesZone() { // no name ManagedZone copy = copyZone(minimalZone); copy.setName(null); - LocalDnsHelper.Response response = localDns.createZone(PROJECT_ID1, copy, null); + LocalDnsHelper.Response response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy, null); assertEquals(400, response.code()); assertTrue(response.body().contains("entity.managedZone.name")); // no description copy = copyZone(minimalZone); copy.setDescription(null); - response = localDns.createZone(PROJECT_ID1, copy, null); + response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy, null); assertEquals(400, response.code()); assertTrue(response.body().contains("entity.managedZone.description")); // no dns name copy = copyZone(minimalZone); copy.setDnsName(null); - response = localDns.createZone(PROJECT_ID1, copy, null); + response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy, null); assertEquals(400, response.code()); assertTrue(response.body().contains("entity.managedZone.dnsName")); // zone name is a number copy = copyZone(minimalZone); copy.setName("123456"); - response = localDns.createZone(PROJECT_ID1, copy, null); + response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy, null); assertEquals(400, response.code()); assertTrue(response.body().contains("entity.managedZone.name")); assertTrue(response.body().contains("Invalid")); // dns name does not end with period copy = copyZone(minimalZone); copy.setDnsName("aaaaaa.com"); - response = localDns.createZone(PROJECT_ID1, copy, null); + response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy, null); assertEquals(400, response.code()); assertTrue(response.body().contains("entity.managedZone.dnsName")); assertTrue(response.body().contains("Invalid")); // dns name is reserved copy = copyZone(minimalZone); copy.setDnsName("com."); - response = localDns.createZone(PROJECT_ID1, copy, null); + response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy, null); assertEquals(400, response.code()); assertTrue(response.body().contains("not available to be created.")); // empty description should pass copy = copyZone(minimalZone); copy.setDescription(""); - response = localDns.createZone(PROJECT_ID1, copy, null); + response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy, null); assertEquals(200, response.code()); } @@ -632,10 +1474,10 @@ public void testCheckRrset() { valid.setTtl(500); Change validChange = new Change(); validChange.setAdditions(ImmutableList.of(valid)); - localDns.createZone(PROJECT_ID1, ZONE1, null); - localDns.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); + LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); // delete with field mismatch - LocalDnsHelper.ZoneContainer zone = localDns.findZone(PROJECT_ID1, ZONE_NAME1); + LocalDnsHelper.ZoneContainer zone = LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE_NAME1); valid.setTtl(valid.getTtl() + 20); LocalDnsHelper.Response response = LocalDnsHelper.checkRrset(valid, zone, 0, "deletions"); assertEquals(412, response.code()); @@ -735,7 +1577,7 @@ public void testCheckChange() { assertTrue(response.body().contains("additions[0].type")); validA.setType("A"); // null rrdata - List temp = validA.getRrdatas(); // preserve + final List temp = validA.getRrdatas(); // preserve validA.setRrdatas(null); response = LocalDnsHelper.checkChange(validChange, zoneContainer); assertEquals(400, response.code()); @@ -762,9 +1604,9 @@ public void testAdditionsMeetDeletions() { validA.setRrdatas(ImmutableList.of("0.255.1.5")); Change validChange = new Change(); validChange.setAdditions(ImmutableList.of(validA)); - localDns.createZone(PROJECT_ID1, ZONE1, null); - localDns.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); - LocalDnsHelper.ZoneContainer container = localDns.findZone(PROJECT_ID1, ZONE_NAME1); + LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); + LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + LocalDnsHelper.ZoneContainer container = LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE_NAME1); LocalDnsHelper.Response response = LocalDnsHelper.additionsMeetDeletions(ImmutableList.of(validA), null, container); assertEquals(409, response.code()); @@ -780,23 +1622,23 @@ public void testCreateChangeValidatesChangeContent() { validA.setRrdatas(ImmutableList.of("0.255.1.5")); Change validChange = new Change(); validChange.setAdditions(ImmutableList.of(validA)); - localDns.createZone(PROJECT_ID1, ZONE1, null); - localDns.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); + LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); LocalDnsHelper.Response response = - localDns.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); assertEquals(409, response.code()); assertTrue(response.body().contains("already exists")); // delete with field mismatch Change delete = new Change(); validA.setTtl(20); // mismatch delete.setDeletions(ImmutableList.of(validA)); - response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, delete, null); + response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, delete, null); assertEquals(412, response.code()); assertTrue(response.body().contains("entity.change.deletions[0]")); // delete and add SOA Change addition = new Change(); ImmutableList rrsetWrappers - = localDns.findZone(PROJECT_ID1, ZONE_NAME1).dnsRecords().get(ZONE_NAME1); + = LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE_NAME1).dnsRecords().get(ZONE_NAME1); LinkedList deletions = new LinkedList<>(); LinkedList additions = new LinkedList<>(); for (LocalDnsHelper.RrsetWrapper wrapper : rrsetWrappers) { @@ -811,12 +1653,12 @@ public void testCreateChangeValidatesChangeContent() { } delete.setDeletions(deletions); addition.setAdditions(additions); - response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, delete, null); + response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, delete, null); assertEquals(400, response.code()); assertTrue(response.body().contains( "zone must contain exactly one resource record set of type 'SOA' at the apex")); assertTrue(response.body().contains("deletions[0]")); - response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, addition, null); + response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, addition, null); assertEquals(400, response.code()); assertTrue(response.body().contains( "zone must contain exactly one resource record set of type 'SOA' at the apex")); @@ -836,24 +1678,24 @@ public void testCreateChangeValidatesChangeContent() { } delete.setDeletions(deletions); addition.setAdditions(additions); - response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, delete, null); + response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, delete, null); assertEquals(400, response.code()); assertTrue(response.body().contains( "zone must contain exactly one resource record set of type 'NS' at the apex")); - response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, addition, null); + response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, addition, null); assertEquals(400, response.code()); assertTrue(response.body().contains( "zone must contain exactly one resource record set of type 'NS' at the apex")); assertTrue(response.body().contains("additions[0]")); // change (delete + add) addition.setDeletions(deletions); - response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, addition, null); + response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, addition, null); assertEquals(200, response.code()); } @Test public void testCreateChangeValidatesChange() { - localDns.createZone(PROJECT_ID1, ZONE1, null); + LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); ResourceRecordSet validA = new ResourceRecordSet(); validA.setName(ZONE1.getDnsName()); validA.setType("A"); @@ -867,52 +1709,52 @@ public void testCreateChangeValidatesChange() { Change invalidChange = new Change(); invalidChange.setAdditions(ImmutableList.of(invalidA)); LocalDnsHelper.Response response = - localDns.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); assertEquals(200, response.code()); - response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, invalidChange, null); + response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, invalidChange, null); assertEquals(400, response.code()); // only empty additions/deletions Change empty = new Change(); empty.setAdditions(ImmutableList.of()); empty.setDeletions(ImmutableList.of()); - response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, empty, null); + response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, empty, null); assertEquals(400, response.code()); assertTrue(response.body().contains( "The 'entity.change' parameter is required but was missing.")); // non-matching name validA.setName(ZONE1.getDnsName() + ".aaa."); - response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); assertEquals(400, response.code()); assertTrue(response.body().contains("additions[0].name")); // wrong type validA.setName(ZONE1.getDnsName()); // revert validA.setType("ABCD"); - response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); assertEquals(400, response.code()); assertTrue(response.body().contains("additions[0].type")); // wrong ttl validA.setType("A"); // revert validA.setTtl(-1); - response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); assertEquals(400, response.code()); assertTrue(response.body().contains("additions[0].ttl")); validA.setTtl(null); // revert // null name validA.setName(null); - response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); assertEquals(400, response.code()); assertTrue(response.body().contains("additions[0].name")); validA.setName(ZONE1.getDnsName()); // null type validA.setType(null); - response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); assertEquals(400, response.code()); assertTrue(response.body().contains("additions[0].type")); validA.setType("A"); // null rrdata - List temp = validA.getRrdatas(); // preserve + final List temp = validA.getRrdatas(); // preserve validA.setRrdatas(null); - response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); assertEquals(400, response.code()); assertTrue(response.body().contains("additions[0].rrdata")); validA.setRrdatas(temp); @@ -923,7 +1765,7 @@ public void testCreateChangeValidatesChange() { nonExistent.setRrdatas(ImmutableList.of(":::::::")); Change delete = new Change(); delete.setDeletions(ImmutableList.of(nonExistent)); - response = localDns.createChange(PROJECT_ID1, ZONE_NAME1, delete, null); + response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, delete, null); assertEquals(404, response.code()); assertTrue(response.body().contains("deletions[0]")); } From b2c2d40a9eff216ad86b168dafc39391ff326224 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 24 Feb 2016 17:18:49 +0100 Subject: [PATCH 108/375] Udpate dependencies: source plugin, bigquery, storage and fluido skin --- gcloud-java-bigquery/pom.xml | 2 +- gcloud-java-storage/pom.xml | 2 +- pom.xml | 2 +- src/site/site.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gcloud-java-bigquery/pom.xml b/gcloud-java-bigquery/pom.xml index 0f41d8bc1eec..f7304e276d75 100644 --- a/gcloud-java-bigquery/pom.xml +++ b/gcloud-java-bigquery/pom.xml @@ -30,7 +30,7 @@ com.google.apis google-api-services-bigquery - v2-rev261-1.21.0 + v2-rev270-1.21.0 compile diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml index 5e53c36c6221..d98fcd2647e2 100644 --- a/gcloud-java-storage/pom.xml +++ b/gcloud-java-storage/pom.xml @@ -24,7 +24,7 @@ com.google.apis google-api-services-storage - v1-rev60-1.21.0 + v1-rev62-1.21.0 compile diff --git a/pom.xml b/pom.xml index 4bc8f37c35de..28bcba708f7f 100644 --- a/pom.xml +++ b/pom.xml @@ -229,7 +229,7 @@ org.apache.maven.plugins maven-source-plugin - 2.4 + 3.0.0 attach-sources diff --git a/src/site/site.xml b/src/site/site.xml index 55047ce85c54..6279179eb389 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -20,7 +20,7 @@ org.apache.maven.skins maven-fluido-skin - 1.3.1 + 1.4 From ee78b22a2656517681ab157aecd1667fdb384a4e Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 22 Feb 2016 09:51:53 -0800 Subject: [PATCH 109/375] Fix equals, javadoc, bindings representation, and address other comments. --- .../java/com/google/gcloud/BaseIamPolicy.java | 297 ------------------ .../java/com/google/gcloud/IamPolicy.java | 213 +++++++++++++ .../main/java/com/google/gcloud/Identity.java | 208 ++++++++++++ .../java/com/google/gcloud/IamPolicyTest.java | 173 ++++++++++ .../java/com/google/gcloud/IdentityTest.java | 110 +++++++ .../gcloud/resourcemanager/IamPolicy.java | 162 ---------- .../google/gcloud/resourcemanager/Policy.java | 122 +++++++ .../gcloud/resourcemanager/IamPolicyTest.java | 91 ------ .../gcloud/resourcemanager/PolicyTest.java | 37 ++- .../resourcemanager/SerializationTest.java | 12 +- 10 files changed, 852 insertions(+), 573 deletions(-) delete mode 100644 gcloud-java-core/src/main/java/com/google/gcloud/BaseIamPolicy.java create mode 100644 gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java create mode 100644 gcloud-java-core/src/main/java/com/google/gcloud/Identity.java create mode 100644 gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java create mode 100644 gcloud-java-core/src/test/java/com/google/gcloud/IdentityTest.java delete mode 100644 gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/IamPolicy.java create mode 100644 gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java delete mode 100644 gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/IamPolicyTest.java rename gcloud-java-core/src/test/java/com/google/gcloud/BaseIamPolicyTest.java => gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/PolicyTest.java (55%) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/BaseIamPolicy.java b/gcloud-java-core/src/main/java/com/google/gcloud/BaseIamPolicy.java deleted file mode 100644 index bc0aed43b95d..000000000000 --- a/gcloud-java-core/src/main/java/com/google/gcloud/BaseIamPolicy.java +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright 2016 Google Inc. All Rights Reserved. - * - * 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.gcloud; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.collect.ImmutableList; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -/** - * Base class for Identity and Access Management (IAM) policies. IAM policies are used to specify - * access settings for Cloud Platform resources. A Policy consists of a list of bindings. An binding - * assigns a list of identities to a role, where the identities can be user accounts, Google groups, - * Google domains, and service accounts. A role is a named list of permissions defined by IAM. - * - * @see Policy - */ -public abstract class BaseIamPolicy implements Serializable { - - private static final long serialVersionUID = 1114489978726897720L; - - private final Map> bindings; - private final String etag; - private final int version; - - public static final class Identity implements Serializable { - - private static final long serialVersionUID = 30811617560110848L; - - private final Type type; - private final String id; - - /** - * The types of IAM identities. - */ - public enum Type { - /** - * Represents anyone who is on the internet; with or without a Google account. - */ - ALL_USERS, - - /** - * Represents anyone who is authenticated with a Google account or a service account. - */ - ALL_AUTHENTICATED_USERS, - - /** - * Represents a specific Google account. - */ - USER, - - /** - * Represents a service account. - */ - SERVICE_ACCOUNT, - - /** - * Represents a Google group. - */ - GROUP, - - /** - * Represents all the users of a Google Apps domain name. - */ - DOMAIN - } - - private Identity(Type type, String id) { - this.type = type; - this.id = id; - } - - public Type type() { - return type; - } - - /** - * Returns the string identifier for this identity. The id corresponds to: - *

    - *
  • email address (for identities of type {@code USER}, {@code SERVICE_ACCOUNT}, and - * {@code GROUP}) - *
  • domain (for identities of type {@code DOMAIN}) - *
  • null (for identities of type {@code ALL_USERS} and {@code ALL_AUTHENTICATED_USERS}) - *
- */ - public String id() { - return id; - } - - /** - * Returns a new identity representing anyone who is on the internet; with or without a Google - * account. - */ - public static Identity allUsers() { - return new Identity(Type.ALL_USERS, null); - } - - /** - * Returns a new identity representing anyone who is authenticated with a Google account or a - * service account. - */ - public static Identity allAuthenticatedUsers() { - return new Identity(Type.ALL_AUTHENTICATED_USERS, null); - } - - /** - * Returns a new user identity. - * - * @param email An email address that represents a specific Google account. For example, - * alice@gmail.com or joe@example.com. - */ - public static Identity user(String email) { - return new Identity(Type.USER, checkNotNull(email)); - } - - /** - * Returns a new service account identity. - * - * @param email An email address that represents a service account. For example, - * my-other-app@appspot.gserviceaccount.com. - */ - public static Identity serviceAccount(String email) { - return new Identity(Type.SERVICE_ACCOUNT, checkNotNull(email)); - } - - /** - * Returns a new group identity. - * - * @param email An email address that represents a Google group. For example, - * admins@example.com. - */ - public static Identity group(String email) { - return new Identity(Type.GROUP, checkNotNull(email)); - } - - /** - * Returns a new domain identity. - * - * @param domain A Google Apps domain name that represents all the users of that domain. For - * example, google.com or example.com. - */ - public static Identity domain(String domain) { - return new Identity(Type.DOMAIN, checkNotNull(domain)); - } - - @Override - public int hashCode() { - return Objects.hash(id, type); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof Identity)) { - return false; - } - Identity other = (Identity) obj; - return Objects.equals(id, other.id()) && Objects.equals(type, other.type()); - } - } - - /** - * Builder for an IAM Policy. - */ - protected abstract static class BaseBuilder> { - - private final Map> bindings = new HashMap<>(); - private String etag; - private int version; - - /** - * Replaces the builder's list of bindings with the given list of bindings. - */ - public B bindings(Map> bindings) { - this.bindings.clear(); - this.bindings.putAll(bindings); - return self(); - } - - /** - * Adds one or more bindings to the policy. - */ - public B addBinding(R role, List identities) { - bindings.put(role, ImmutableList.copyOf(identities)); - return self(); - } - - /** - * Removes the specified ACL. - */ - public B removeBinding(R role) { - bindings.remove(role); - return self(); - } - - /** - * Sets the policy's etag. - * - *

Etags are used for optimistic concurrency control as a way to help prevent simultaneous - * updates of a policy from overwriting each other. It is strongly suggested that systems make - * use of the etag in the read-modify-write cycle to perform policy updates in order to avoid - * race conditions. An etag is returned in the response to getIamPolicy, and systems are - * expected to put that etag in the request to setIamPolicy to ensure that their change will be - * applied to the same version of the policy. If no etag is provided in the call to - * setIamPolicy, then the existing policy is overwritten blindly. - */ - protected B etag(String etag) { - this.etag = etag; - return self(); - } - - /** - * Sets the version of the policy. The default version is 0, meaning roles that are in alpha - * (non-legacy) roles are not permitted. If the version is 1, you may use roles other than - * "owner", "editor", and "viewer". - */ - protected B version(int version) { - this.version = version; - return self(); - } - - @SuppressWarnings("unchecked") - private B self() { - return (B) this; - } - - public abstract BaseIamPolicy build(); - } - - protected BaseIamPolicy(BaseBuilder> builder) { - this.bindings = builder.bindings; - this.etag = builder.etag; - this.version = builder.version; - } - - /** - * The list of ACLs specified in the policy. - */ - public Map> bindings() { - return bindings; - } - - /** - * The policy's etag. - * - *

Etags are used for optimistic concurrency control as a way to help prevent simultaneous - * updates of a policy from overwriting each other. It is strongly suggested that systems make - * use of the etag in the read-modify-write cycle to perform policy updates in order to avoid - * race conditions. An etag is returned in the response to getIamPolicy, and systems are - * expected to put that etag in the request to setIamPolicy to ensure that their change will be - * applied to the same version of the policy. If no etag is provided in the call to - * setIamPolicy, then the existing policy is overwritten blindly. - */ - public String etag() { - return etag; - } - - /** - * The version of the policy. The default version is 0. - */ - public int version() { - return version; - } - - public int baseHashCode() { - return Objects.hash(bindings, etag, version); - } - - public boolean baseEquals(Object obj) { - if (!(obj instanceof BaseIamPolicy)) { - return false; - } - @SuppressWarnings("rawtypes") - BaseIamPolicy other = (BaseIamPolicy) obj; - return Objects.equals(bindings, other.bindings()) - && Objects.equals(etag, other.etag()) - && Objects.equals(version, other.version()); - } -} diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java b/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java new file mode 100644 index 000000000000..ed9dcf9503c7 --- /dev/null +++ b/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java @@ -0,0 +1,213 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +/** + * Base class for Identity and Access Management (IAM) policies. IAM policies are used to specify + * access settings for Cloud Platform resources. A policy is a map of bindings. A binding assigns + * a set of identities to a role, where the identities can be user accounts, Google groups, Google + * domains, and service accounts. A role is a named list of permissions defined by IAM. + * + * @param the data type of roles (should be serializable) + * @see Policy + */ +public abstract class IamPolicy implements Serializable { + + private static final long serialVersionUID = 1114489978726897720L; + + private final Map> bindings; + private final String etag; + private final Integer version; + + /** + * Builder for an IAM Policy. + * + * @param the data type of roles + * @param the subclass extending this abstract builder + */ + public abstract static class Builder> { + + private final Map> bindings = new HashMap<>(); + private String etag; + private Integer version; + + protected Builder() {} + + /** + * Replaces the builder's map of bindings with the given map of bindings. + */ + public final B bindings(Map> bindings) { + this.bindings.clear(); + for (Map.Entry> binding : bindings.entrySet()) { + this.bindings.put(binding.getKey(), new HashSet(binding.getValue())); + } + return self(); + } + + /** + * Adds a binding to the policy. + */ + public final B addBinding(R role, Set identities) { + checkArgument(!bindings.containsKey(role), + "The policy already contains a binding with the role " + role.toString()); + bindings.put(role, new HashSet(identities)); + return self(); + } + + /** + * Adds a binding to the policy. + */ + public final B addBinding(R role, Identity first, Identity... others) { + checkArgument(!bindings.containsKey(role), + "The policy already contains a binding with the role " + role.toString()); + HashSet identities = new HashSet<>(); + identities.add(first); + identities.addAll(Arrays.asList(others)); + bindings.put(role, identities); + return self(); + } + + /** + * Removes the binding associated with the specified role. + */ + public final B removeBinding(R role) { + bindings.remove(role); + return self(); + } + + /** + * Adds one or more identities to an existing binding. + */ + public final B addIdentity(R role, Identity first, Identity... others) { + Set identities = bindings.get(role); + identities.add(first); + identities.addAll(Arrays.asList(others)); + return self(); + } + + /** + * Removes one or more identities from an existing binding. + */ + public final B removeIdentity(R role, Identity first, Identity... others) { + bindings.get(role).remove(first); + bindings.get(role).removeAll(Arrays.asList(others)); + return self(); + } + + /** + * Sets the policy's etag. + * + *

Etags are used for optimistic concurrency control as a way to help prevent simultaneous + * updates of a policy from overwriting each other. It is strongly suggested that systems make + * use of the etag in the read-modify-write cycle to perform policy updates in order to avoid + * race conditions. An etag is returned in the response to getIamPolicy, and systems are + * expected to put that etag in the request to setIamPolicy to ensure that their change will be + * applied to the same version of the policy. If no etag is provided in the call to + * setIamPolicy, then the existing policy is overwritten blindly. + */ + protected final B etag(String etag) { + this.etag = etag; + return self(); + } + + /** + * Sets the version of the policy. The default version is 0, meaning only the "owner", "editor", + * and "viewer" roles are permitted. If the version is 1, you may also use other roles. + */ + protected final B version(Integer version) { + this.version = version; + return self(); + } + + @SuppressWarnings("unchecked") + private B self() { + return (B) this; + } + + public abstract IamPolicy build(); + } + + protected IamPolicy(Builder> builder) { + ImmutableMap.Builder> bindingsBuilder = ImmutableMap.builder(); + for (Map.Entry> binding : builder.bindings.entrySet()) { + bindingsBuilder.put(binding.getKey(), ImmutableSet.copyOf(binding.getValue())); + } + this.bindings = bindingsBuilder.build(); + this.etag = builder.etag; + this.version = builder.version; + } + + /** + * The map of bindings that comprises the policy. + */ + public Map> bindings() { + return bindings; + } + + /** + * The policy's etag. + * + *

Etags are used for optimistic concurrency control as a way to help prevent simultaneous + * updates of a policy from overwriting each other. It is strongly suggested that systems make + * use of the etag in the read-modify-write cycle to perform policy updates in order to avoid + * race conditions. An etag is returned in the response to getIamPolicy, and systems are + * expected to put that etag in the request to setIamPolicy to ensure that their change will be + * applied to the same version of the policy. If no etag is provided in the call to + * setIamPolicy, then the existing policy is overwritten blindly. + */ + public String etag() { + return etag; + } + + /** + * Sets the version of the policy. The default version is 0, meaning only the "owner", "editor", + * and "viewer" roles are permitted. If the version is 1, you may also use other roles. + */ + public Integer version() { + return version; + } + + @Override + public final int hashCode() { + return Objects.hash(getClass(), bindings, etag, version); + } + + @Override + public final boolean equals(Object obj) { + if (obj == null || !getClass().equals(obj.getClass())) { + return false; + } + @SuppressWarnings("rawtypes") + IamPolicy other = (IamPolicy) obj; + return Objects.equals(bindings, other.bindings()) + && Objects.equals(etag, other.etag()) + && Objects.equals(version, other.version()); + } +} diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/Identity.java b/gcloud-java-core/src/main/java/com/google/gcloud/Identity.java new file mode 100644 index 000000000000..0513916cc8b4 --- /dev/null +++ b/gcloud-java-core/src/main/java/com/google/gcloud/Identity.java @@ -0,0 +1,208 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.io.Serializable; +import java.util.Objects; + +/** + * An identity in an {@link IamPolicy}. + */ +public final class Identity implements Serializable { + + private static final long serialVersionUID = -8181841964597657446L; + + private final Type type; + private final String id; + + /** + * The types of IAM identities. + */ + public enum Type { + + /** + * Represents anyone who is on the internet; with or without a Google account. + */ + ALL_USERS, + + /** + * Represents anyone who is authenticated with a Google account or a service account. + */ + ALL_AUTHENTICATED_USERS, + + /** + * Represents a specific Google account. + */ + USER, + + /** + * Represents a service account. + */ + SERVICE_ACCOUNT, + + /** + * Represents a Google group. + */ + GROUP, + + /** + * Represents all the users of a Google Apps domain name. + */ + DOMAIN + } + + private Identity(Type type, String id) { + this.type = type; + this.id = id; + } + + public Type type() { + return type; + } + + /** + * Returns the string identifier for this identity. The id corresponds to: + *

    + *
  • email address (for identities of type {@code USER}, {@code SERVICE_ACCOUNT}, and + * {@code GROUP}) + *
  • domain (for identities of type {@code DOMAIN}) + *
  • null (for identities of type {@code ALL_USERS} and {@code ALL_AUTHENTICATED_USERS}) + *
+ */ + public String id() { + return id; + } + + /** + * Returns a new identity representing anyone who is on the internet; with or without a Google + * account. + */ + public static Identity allUsers() { + return new Identity(Type.ALL_USERS, null); + } + + /** + * Returns a new identity representing anyone who is authenticated with a Google account or a + * service account. + */ + public static Identity allAuthenticatedUsers() { + return new Identity(Type.ALL_AUTHENTICATED_USERS, null); + } + + /** + * Returns a new user identity. + * + * @param email An email address that represents a specific Google account. For example, + * alice@gmail.com or joe@example.com. + */ + public static Identity user(String email) { + return new Identity(Type.USER, checkNotNull(email)); + } + + /** + * Returns a new service account identity. + * + * @param email An email address that represents a service account. For example, + * my-other-app@appspot.gserviceaccount.com. + */ + public static Identity serviceAccount(String email) { + return new Identity(Type.SERVICE_ACCOUNT, checkNotNull(email)); + } + + /** + * Returns a new group identity. + * + * @param email An email address that represents a Google group. For example, + * admins@example.com. + */ + public static Identity group(String email) { + return new Identity(Type.GROUP, checkNotNull(email)); + } + + /** + * Returns a new domain identity. + * + * @param domain A Google Apps domain name that represents all the users of that domain. For + * example, google.com or example.com. + */ + public static Identity domain(String domain) { + return new Identity(Type.DOMAIN, checkNotNull(domain)); + } + + @Override + public int hashCode() { + return Objects.hash(id, type); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Identity)) { + return false; + } + Identity other = (Identity) obj; + return Objects.equals(id, other.id()) && Objects.equals(type, other.type()); + } + + /** + * Returns the string value associated with the identity. Used primarily for converting from + * {@code Identity} objects to strings for protobuf-generated policies. + */ + public String strValue() { + switch (type) { + case ALL_USERS: + return "allUsers"; + case ALL_AUTHENTICATED_USERS: + return "allAuthenticatedUsers"; + case USER: + return "user:" + id; + case SERVICE_ACCOUNT: + return "serviceAccount:" + id; + case GROUP: + return "group:" + id; + case DOMAIN: + return "domain:" + id; + default: + throw new IllegalArgumentException("Unexpected identity type: " + type); + } + } + + /** + * Converts a string to an {@code Identity}. Used primarily for converting protobuf-generated + * policy identities to {@code Identity} objects. + */ + public static Identity valueOf(String identityStr) { + String[] info = identityStr.split(":"); + switch (info[0]) { + case "allUsers": + return Identity.allUsers(); + case "allAuthenticatedUsers": + return Identity.allAuthenticatedUsers(); + case "user": + return Identity.user(info[1]); + case "serviceAccount": + return Identity.serviceAccount(info[1]); + case "group": + return Identity.group(info[1]); + case "domain": + return Identity.domain(info[1]); + default: + throw new IllegalArgumentException("Unexpected identity type: " + info[0]); + } + } +} diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java new file mode 100644 index 000000000000..b77b5e2df7fa --- /dev/null +++ b/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java @@ -0,0 +1,173 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + +import org.junit.Test; + +import java.util.Map; +import java.util.Set; + +public class IamPolicyTest { + + private static final Identity ALL_USERS = Identity.allUsers(); + private static final Identity ALL_AUTH_USERS = Identity.allAuthenticatedUsers(); + private static final Identity USER = Identity.user("abc@gmail.com"); + private static final Identity SERVICE_ACCOUNT = + Identity.serviceAccount("service-account@gmail.com"); + private static final Identity GROUP = Identity.group("group@gmail.com"); + private static final Identity DOMAIN = Identity.domain("google.com"); + private static final Map> BINDINGS = ImmutableMap.of( + "viewer", + ImmutableSet.of(USER, SERVICE_ACCOUNT, ALL_USERS), + "editor", + ImmutableSet.of(ALL_AUTH_USERS, GROUP, DOMAIN)); + private static final PolicyImpl SIMPLE_POLICY = PolicyImpl.builder() + .addBinding("viewer", ImmutableSet.of(USER, SERVICE_ACCOUNT, ALL_USERS)) + .addBinding("editor", ImmutableSet.of(ALL_AUTH_USERS, GROUP, DOMAIN)) + .build(); + private static final PolicyImpl FULL_POLICY = + new PolicyImpl.Builder(SIMPLE_POLICY.bindings(), "etag", 1).build(); + + static class PolicyImpl extends IamPolicy { + + static class Builder extends IamPolicy.Builder { + + private Builder() {} + + private Builder(Map> bindings, String etag, Integer version) { + bindings(bindings).etag(etag).version(version); + } + + @Override + public PolicyImpl build() { + return new PolicyImpl(this); + } + } + + PolicyImpl(Builder builder) { + super(builder); + } + + Builder toBuilder() { + return new Builder(bindings(), etag(), version()); + } + + static Builder builder() { + return new Builder(); + } + } + + @Test + public void testBuilder() { + assertEquals(BINDINGS, FULL_POLICY.bindings()); + assertEquals("etag", FULL_POLICY.etag()); + assertEquals(1, FULL_POLICY.version().intValue()); + Map> editorBinding = + ImmutableMap.>builder().put("editor", BINDINGS.get("editor")).build(); + PolicyImpl policy = FULL_POLICY.toBuilder().bindings(editorBinding).build(); + assertEquals(editorBinding, policy.bindings()); + assertEquals("etag", policy.etag()); + assertEquals(1, policy.version().intValue()); + policy = SIMPLE_POLICY.toBuilder().removeBinding("editor").build(); + assertEquals(ImmutableMap.of("viewer", BINDINGS.get("viewer")), policy.bindings()); + assertEquals(null, policy.etag()); + assertEquals(null, policy.version()); + policy = policy.toBuilder() + .removeIdentity("viewer", USER, ALL_USERS) + .addIdentity("viewer", DOMAIN, GROUP) + .build(); + assertEquals(ImmutableMap.of("viewer", ImmutableSet.of(SERVICE_ACCOUNT, DOMAIN, GROUP)), + policy.bindings()); + assertEquals(null, policy.etag()); + assertEquals(null, policy.version()); + policy = PolicyImpl.builder().addBinding("owner", USER, SERVICE_ACCOUNT).build(); + assertEquals( + ImmutableMap.of("owner", ImmutableSet.of(USER, SERVICE_ACCOUNT)), policy.bindings()); + assertEquals(null, policy.etag()); + assertEquals(null, policy.version()); + try { + SIMPLE_POLICY.toBuilder().addBinding("viewer", USER); + fail("Should have failed due to duplicate role."); + } catch (IllegalArgumentException e) { + assertEquals("The policy already contains a binding with the role viewer", e.getMessage()); + } + try { + SIMPLE_POLICY.toBuilder().addBinding("editor", ImmutableSet.of(USER)); + fail("Should have failed due to duplicate role."); + } catch (IllegalArgumentException e) { + assertEquals("The policy already contains a binding with the role editor", e.getMessage()); + } + } + + @Test + public void testEqualsHashCode() { + assertNotEquals(FULL_POLICY, null); + PolicyImpl emptyPolicy = PolicyImpl.builder().build(); + AnotherPolicyImpl anotherPolicy = new AnotherPolicyImpl.Builder().build(); + assertNotEquals(emptyPolicy, anotherPolicy); + assertNotEquals(emptyPolicy.hashCode(), anotherPolicy.hashCode()); + assertNotEquals(FULL_POLICY, SIMPLE_POLICY); + assertNotEquals(FULL_POLICY.hashCode(), SIMPLE_POLICY.hashCode()); + PolicyImpl copy = SIMPLE_POLICY.toBuilder().build(); + assertEquals(SIMPLE_POLICY, copy); + assertEquals(SIMPLE_POLICY.hashCode(), copy.hashCode()); + } + + @Test + public void testBindings() { + assertTrue(PolicyImpl.builder().build().bindings().isEmpty()); + assertEquals(BINDINGS, SIMPLE_POLICY.bindings()); + } + + @Test + public void testEtag() { + assertNull(SIMPLE_POLICY.etag()); + assertEquals("etag", FULL_POLICY.etag()); + } + + @Test + public void testVersion() { + assertNull(SIMPLE_POLICY.version()); + assertEquals(null, SIMPLE_POLICY.version()); + } + + static class AnotherPolicyImpl extends IamPolicy { + + static class Builder extends IamPolicy.Builder { + + private Builder() {} + + @Override + public AnotherPolicyImpl build() { + return new AnotherPolicyImpl(this); + } + } + + AnotherPolicyImpl(Builder builder) { + super(builder); + } + } +} diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/IdentityTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/IdentityTest.java new file mode 100644 index 000000000000..7abbc98521a0 --- /dev/null +++ b/gcloud-java-core/src/test/java/com/google/gcloud/IdentityTest.java @@ -0,0 +1,110 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +import org.junit.Test; + +public class IdentityTest { + + private static final Identity ALL_USERS = Identity.allUsers(); + private static final Identity ALL_AUTH_USERS = Identity.allAuthenticatedUsers(); + private static final Identity USER = Identity.user("abc@gmail.com"); + private static final Identity SERVICE_ACCOUNT = + Identity.serviceAccount("service-account@gmail.com"); + private static final Identity GROUP = Identity.group("group@gmail.com"); + private static final Identity DOMAIN = Identity.domain("google.com"); + + @Test + public void testAllUsers() { + assertEquals(Identity.Type.ALL_USERS, ALL_USERS.type()); + assertNull(ALL_USERS.id()); + } + + @Test + public void testAllAuthenticatedUsers() { + assertEquals(Identity.Type.ALL_AUTHENTICATED_USERS, ALL_AUTH_USERS.type()); + assertNull(ALL_AUTH_USERS.id()); + } + + @Test + public void testUser() { + assertEquals(Identity.Type.USER, USER.type()); + assertEquals("abc@gmail.com", USER.id()); + try { + Identity.user(null); + fail("Should have thrown exception due to null email address."); + } catch (NullPointerException e) { + // expected + } + } + + @Test + public void testServiceAccount() { + assertEquals(Identity.Type.SERVICE_ACCOUNT, SERVICE_ACCOUNT.type()); + assertEquals("service-account@gmail.com", SERVICE_ACCOUNT.id()); + try { + Identity.serviceAccount(null); + fail("Should have thrown exception due to null email address."); + } catch (NullPointerException e) { + // expected + } + } + + @Test + public void testGroup() { + assertEquals(Identity.Type.GROUP, GROUP.type()); + assertEquals("group@gmail.com", GROUP.id()); + try { + Identity.group(null); + fail("Should have thrown exception due to null email address."); + } catch (NullPointerException e) { + // expected + } + } + + @Test + public void testDomain() { + assertEquals(Identity.Type.DOMAIN, DOMAIN.type()); + assertEquals("google.com", DOMAIN.id()); + try { + Identity.domain(null); + fail("Should have thrown exception due to null domain."); + } catch (NullPointerException e) { + // expected + } + } + + @Test + public void testIdentityToAndFromPb() { + compareIdentities(ALL_USERS, Identity.valueOf(ALL_USERS.strValue())); + compareIdentities(ALL_AUTH_USERS, Identity.valueOf(ALL_AUTH_USERS.strValue())); + compareIdentities(USER, Identity.valueOf(USER.strValue())); + compareIdentities(SERVICE_ACCOUNT, Identity.valueOf(SERVICE_ACCOUNT.strValue())); + compareIdentities(GROUP, Identity.valueOf(GROUP.strValue())); + compareIdentities(DOMAIN, Identity.valueOf(DOMAIN.strValue())); + } + + private void compareIdentities(Identity expected, Identity actual) { + assertEquals(expected, actual); + assertEquals(expected.type(), actual.type()); + assertEquals(expected.id(), actual.id()); + } +} diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/IamPolicy.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/IamPolicy.java deleted file mode 100644 index ccb436fd8a2f..000000000000 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/IamPolicy.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright 2016 Google Inc. All Rights Reserved. - * - * 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.gcloud.resourcemanager; - -import com.google.common.base.Function; -import com.google.common.collect.Lists; -import com.google.gcloud.BaseIamPolicy; - -import java.io.Serializable; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -/** - * Base class for Identity and Access Management (IAM) policies. IAM policies are used to specify - * access settings for Cloud Platform resources. A Policy consists of a list of bindings. An binding - * assigns a list of identities to a role, where the identities can be user accounts, Google groups, - * Google domains, and service accounts. A role is a named list of permissions defined by IAM. - * - * @see Policy - */ -public class IamPolicy extends BaseIamPolicy implements Serializable { - - private static final long serialVersionUID = -5573557282693961850L; - - /** - * Builder for an IAM Policy. - */ - protected static class Builder extends BaseBuilder { - - Builder() {} - - Builder(Map> bindings, String etag, int version) { - bindings(bindings).etag(etag).version(version); - } - - @Override - public IamPolicy build() { - return new IamPolicy(this); - } - } - - private IamPolicy(Builder builder) { - super(builder); - } - - @Override - public int hashCode() { - return baseHashCode(); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof IamPolicy)) { - return false; - } - IamPolicy other = (IamPolicy) obj; - return Objects.equals(bindings(), other.bindings()) - && Objects.equals(etag(), other.etag()) - && Objects.equals(version(), other.version()); - } - - public static Builder builder() { - return new Builder(); - } - - public Builder toBuilder() { - return new Builder(bindings(), etag(), version()); - } - - static String identityToPb(Identity identity) { - switch (identity.type()) { - case ALL_USERS: - return "allUsers"; - case ALL_AUTHENTICATED_USERS: - return "allAuthenticatedUsers"; - case USER: - return "user:" + identity.id(); - case SERVICE_ACCOUNT: - return "serviceAccount:" + identity.id(); - case GROUP: - return "group:" + identity.id(); - default: - return "domain:" + identity.id(); - } - } - - static Identity identityFromPb(String identityStr) { - String[] info = identityStr.split(":"); - switch (info[0]) { - case "allUsers": - return Identity.allUsers(); - case "allAuthenticatedUsers": - return Identity.allAuthenticatedUsers(); - case "user": - return Identity.user(info[1]); - case "serviceAccount": - return Identity.serviceAccount(info[1]); - case "group": - return Identity.group(info[1]); - case "domain": - return Identity.domain(info[1]); - default: - throw new IllegalArgumentException("Unexpected identity type: " + info[0]); - } - } - - com.google.api.services.cloudresourcemanager.model.Policy toPb() { - com.google.api.services.cloudresourcemanager.model.Policy policyPb = - new com.google.api.services.cloudresourcemanager.model.Policy(); - List bindingPbList = - new LinkedList<>(); - for (Map.Entry> binding : bindings().entrySet()) { - com.google.api.services.cloudresourcemanager.model.Binding bindingPb = - new com.google.api.services.cloudresourcemanager.model.Binding(); - bindingPb.setRole("roles/" + binding.getKey()); - bindingPb.setMembers(Lists.transform(binding.getValue(), new Function() { - @Override - public String apply(Identity identity) { - return identityToPb(identity); - } - })); - bindingPbList.add(bindingPb); - } - policyPb.setBindings(bindingPbList); - policyPb.setEtag(etag()); - policyPb.setVersion(version()); - return policyPb; - } - - static IamPolicy fromPb( - com.google.api.services.cloudresourcemanager.model.Policy policyPb) { - Map> bindings = new HashMap<>(); - for (com.google.api.services.cloudresourcemanager.model.Binding bindingPb : - policyPb.getBindings()) { - bindings.put(bindingPb.getRole().substring("roles/".length()), - Lists.transform(bindingPb.getMembers(), new Function() { - @Override - public Identity apply(String identityPb) { - return identityFromPb(identityPb); - } - })); - } - return new IamPolicy.Builder(bindings, policyPb.getEtag(), policyPb.getVersion()).build(); - } -} diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java new file mode 100644 index 000000000000..09cbfa1db554 --- /dev/null +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java @@ -0,0 +1,122 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.resourcemanager; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Function; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import com.google.gcloud.IamPolicy; +import com.google.gcloud.Identity; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * An Identity and Access Management (IAM) policy for a project. IAM policies are used to specify + * access settings for Cloud Platform resources. A policy is a map of bindings. A binding assigns + * a set of identities to a role, where the identities can be user accounts, Google groups, Google + * domains, and service accounts. A role is a named list of permissions defined by IAM. Policies set + * at the project level control access both to the project and to resources associated with the + * project. + * + * @see Policy + */ +public class Policy extends IamPolicy { + + private static final long serialVersionUID = -5573557282693961850L; + + /** + * Builder for an IAM Policy. + */ + public static class Builder extends IamPolicy.Builder { + + private Builder() {} + + @VisibleForTesting + Builder(Map> bindings, String etag, Integer version) { + bindings(bindings).etag(etag).version(version); + } + + @Override + public Policy build() { + return new Policy(this); + } + } + + private Policy(Builder builder) { + super(builder); + } + + public static Builder builder() { + return new Builder(); + } + + public Builder toBuilder() { + return new Builder(bindings(), etag(), version()); + } + + com.google.api.services.cloudresourcemanager.model.Policy toPb() { + com.google.api.services.cloudresourcemanager.model.Policy policyPb = + new com.google.api.services.cloudresourcemanager.model.Policy(); + List bindingPbList = + new LinkedList<>(); + for (Map.Entry> binding : bindings().entrySet()) { + com.google.api.services.cloudresourcemanager.model.Binding bindingPb = + new com.google.api.services.cloudresourcemanager.model.Binding(); + bindingPb.setRole("roles/" + binding.getKey()); + bindingPb.setMembers( + Lists.transform( + new ArrayList<>(binding.getValue()), + new Function() { + @Override + public String apply(Identity identity) { + return identity.strValue(); + } + })); + bindingPbList.add(bindingPb); + } + policyPb.setBindings(bindingPbList); + policyPb.setEtag(etag()); + policyPb.setVersion(version()); + return policyPb; + } + + static Policy fromPb( + com.google.api.services.cloudresourcemanager.model.Policy policyPb) { + Map> bindings = new HashMap<>(); + for (com.google.api.services.cloudresourcemanager.model.Binding bindingPb : + policyPb.getBindings()) { + bindings.put( + bindingPb.getRole().substring("roles/".length()), + ImmutableSet.copyOf( + Lists.transform( + bindingPb.getMembers(), + new Function() { + @Override + public Identity apply(String identityPb) { + return Identity.valueOf(identityPb); + } + }))); + } + return new Policy.Builder(bindings, policyPb.getEtag(), policyPb.getVersion()).build(); + } +} diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/IamPolicyTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/IamPolicyTest.java deleted file mode 100644 index e2f05ac8493b..000000000000 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/IamPolicyTest.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2016 Google Inc. All Rights Reserved. - * - * 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.gcloud.resourcemanager; - -import static org.junit.Assert.assertEquals; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.gcloud.BaseIamPolicy.Identity; - -import org.junit.Test; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class IamPolicyTest { - - private static final Identity ALL_USERS = Identity.allUsers(); - private static final Identity ALL_AUTH_USERS = Identity.allAuthenticatedUsers(); - private static final Identity USER = Identity.user("abc@gmail.com"); - private static final Identity SERVICE_ACCOUNT = - Identity.serviceAccount("service-account@gmail.com"); - private static final Identity GROUP = Identity.group("group@gmail.com"); - private static final Identity DOMAIN = Identity.domain("google.com"); - private static final Map> BINDINGS = ImmutableMap.of( - "viewer", - ImmutableList.of(USER, SERVICE_ACCOUNT, ALL_USERS), - "editor", - ImmutableList.of(ALL_AUTH_USERS, GROUP, DOMAIN)); - private static final IamPolicy SIMPLE_POLICY = IamPolicy.builder() - .addBinding("viewer", ImmutableList.of(USER, SERVICE_ACCOUNT, ALL_USERS)) - .addBinding("editor", ImmutableList.of(ALL_AUTH_USERS, GROUP, DOMAIN)) - .build(); - private static final IamPolicy FULL_POLICY = - new IamPolicy.Builder(SIMPLE_POLICY.bindings(), "etag", 1).build(); - - @Test - public void testIamPolicyBuilder() { - assertEquals(BINDINGS, FULL_POLICY.bindings()); - assertEquals("etag", FULL_POLICY.etag()); - assertEquals(1, FULL_POLICY.version()); - Map> editorBinding = new HashMap<>(); - editorBinding.put("editor", BINDINGS.get("editor")); - IamPolicy policy = FULL_POLICY.toBuilder().bindings(editorBinding).build(); - assertEquals(ImmutableMap.of("editor", BINDINGS.get("editor")), policy.bindings()); - assertEquals("etag", policy.etag()); - assertEquals(1, policy.version()); - policy = SIMPLE_POLICY.toBuilder().removeBinding("editor").build(); - assertEquals(ImmutableMap.of("viewer", BINDINGS.get("viewer")), policy.bindings()); - assertEquals(null, policy.etag()); - assertEquals(0, policy.version()); - } - - @Test - public void testIamPolicyToBuilder() { - assertEquals(FULL_POLICY, FULL_POLICY.toBuilder().build()); - assertEquals(SIMPLE_POLICY, SIMPLE_POLICY.toBuilder().build()); - } - - @Test - public void testIdentityToAndFromPb() { - assertEquals(ALL_USERS, IamPolicy.identityFromPb(IamPolicy.identityToPb(ALL_USERS))); - assertEquals(ALL_AUTH_USERS, IamPolicy.identityFromPb(IamPolicy.identityToPb(ALL_AUTH_USERS))); - assertEquals(USER, IamPolicy.identityFromPb(IamPolicy.identityToPb(USER))); - assertEquals( - SERVICE_ACCOUNT, IamPolicy.identityFromPb(IamPolicy.identityToPb(SERVICE_ACCOUNT))); - assertEquals(GROUP, IamPolicy.identityFromPb(IamPolicy.identityToPb(GROUP))); - assertEquals(DOMAIN, IamPolicy.identityFromPb(IamPolicy.identityToPb(DOMAIN))); - } - - @Test - public void testPolicyToAndFromPb() { - assertEquals(FULL_POLICY, IamPolicy.fromPb(FULL_POLICY.toPb())); - assertEquals(SIMPLE_POLICY, IamPolicy.fromPb(SIMPLE_POLICY.toPb())); - } -} diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/BaseIamPolicyTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/PolicyTest.java similarity index 55% rename from gcloud-java-core/src/test/java/com/google/gcloud/BaseIamPolicyTest.java rename to gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/PolicyTest.java index 0c26bc806812..3383eebf470c 100644 --- a/gcloud-java-core/src/test/java/com/google/gcloud/BaseIamPolicyTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/PolicyTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Google Inc. All Rights Reserved. + * Copyright 2016 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,15 +14,16 @@ * limitations under the License. */ -package com.google.gcloud; +package com.google.gcloud.resourcemanager; import static org.junit.Assert.assertEquals; -import com.google.gcloud.BaseIamPolicy.Identity; +import com.google.common.collect.ImmutableSet; +import com.google.gcloud.Identity; import org.junit.Test; -public class BaseIamPolicyTest { +public class PolicyTest { private static final Identity ALL_USERS = Identity.allUsers(); private static final Identity ALL_AUTH_USERS = Identity.allAuthenticatedUsers(); @@ -31,20 +32,22 @@ public class BaseIamPolicyTest { Identity.serviceAccount("service-account@gmail.com"); private static final Identity GROUP = Identity.group("group@gmail.com"); private static final Identity DOMAIN = Identity.domain("google.com"); + private static final Policy SIMPLE_POLICY = Policy.builder() + .addBinding("viewer", ImmutableSet.of(USER, SERVICE_ACCOUNT, ALL_USERS)) + .addBinding("editor", ImmutableSet.of(ALL_AUTH_USERS, GROUP, DOMAIN)) + .build(); + private static final Policy FULL_POLICY = + new Policy.Builder(SIMPLE_POLICY.bindings(), "etag", 1).build(); @Test - public void testIdentityOf() { - assertEquals(Identity.Type.ALL_USERS, ALL_USERS.type()); - assertEquals(null, ALL_USERS.id()); - assertEquals(Identity.Type.ALL_AUTHENTICATED_USERS, ALL_AUTH_USERS.type()); - assertEquals(null, ALL_AUTH_USERS.id()); - assertEquals(Identity.Type.USER, USER.type()); - assertEquals("abc@gmail.com", USER.id()); - assertEquals(Identity.Type.SERVICE_ACCOUNT, SERVICE_ACCOUNT.type()); - assertEquals("service-account@gmail.com", SERVICE_ACCOUNT.id()); - assertEquals(Identity.Type.GROUP, GROUP.type()); - assertEquals("group@gmail.com", GROUP.id()); - assertEquals(Identity.Type.DOMAIN, DOMAIN.type()); - assertEquals("google.com", DOMAIN.id()); + public void testIamPolicyToBuilder() { + assertEquals(FULL_POLICY, FULL_POLICY.toBuilder().build()); + assertEquals(SIMPLE_POLICY, SIMPLE_POLICY.toBuilder().build()); + } + + @Test + public void testPolicyToAndFromPb() { + assertEquals(FULL_POLICY, Policy.fromPb(FULL_POLICY.toPb())); + assertEquals(SIMPLE_POLICY, Policy.fromPb(SIMPLE_POLICY.toPb())); } } diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java index 1049f40f5f17..99c0fd7572c0 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java @@ -19,9 +19,9 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; -import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.google.gcloud.BaseIamPolicy.Identity; +import com.google.common.collect.ImmutableSet; +import com.google.gcloud.Identity; import com.google.gcloud.PageImpl; import com.google.gcloud.RetryParams; @@ -55,9 +55,9 @@ public class SerializationTest { ResourceManager.ProjectGetOption.fields(ResourceManager.ProjectField.NAME); private static final ResourceManager.ProjectListOption PROJECT_LIST_OPTION = ResourceManager.ProjectListOption.filter("name:*"); - private static final Identity IDENTITY = Identity.user("abc@gmail.com"); - private static final IamPolicy POLICY = - IamPolicy.builder().addBinding("viewer", ImmutableList.of(IDENTITY)).build(); + private static final Policy POLICY = Policy.builder() + .addBinding("viewer", ImmutableSet.of(Identity.user("abc@gmail.com"))) + .build(); @Test public void testServiceOptions() throws Exception { @@ -75,7 +75,7 @@ public void testServiceOptions() throws Exception { @Test public void testModelAndRequests() throws Exception { Serializable[] objects = {PARTIAL_PROJECT_INFO, FULL_PROJECT_INFO, PROJECT, PAGE_RESULT, - PROJECT_GET_OPTION, PROJECT_LIST_OPTION, IDENTITY, POLICY}; + PROJECT_GET_OPTION, PROJECT_LIST_OPTION, POLICY}; for (Serializable obj : objects) { Object copy = serializeAndDeserialize(obj); assertEquals(obj, obj); From 1583e2c8b8763a003b5d0d16d27cf53a97410603 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 25 Feb 2016 16:20:54 +0100 Subject: [PATCH 110/375] Add pageToken to list fields option for GCS and resourcemanager --- .../resourcemanager/ResourceManager.java | 2 +- .../testing/LocalResourceManagerHelper.java | 24 +++++--- .../LocalResourceManagerHelperTest.java | 61 ++++++++++++++++++- .../ResourceManagerImplTest.java | 32 ++++++++++ .../com/google/gcloud/storage/Storage.java | 4 +- .../gcloud/storage/StorageImplTest.java | 12 ++-- 6 files changed, 120 insertions(+), 15 deletions(-) diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java index b641fa74b584..3d27f2a33ac8 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java @@ -162,7 +162,7 @@ public static ProjectListOption pageSize(int pageSize) { */ public static ProjectListOption fields(ProjectField... fields) { StringBuilder builder = new StringBuilder(); - builder.append("projects(").append(ProjectField.selector(fields)).append(")"); + builder.append("projects(").append(ProjectField.selector(fields)).append("),nextPageToken"); return new ProjectListOption(ResourceManagerRpc.Option.FIELDS, builder.toString()); } } diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java index 4c26a44cd4e6..2e3b8c25db41 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java @@ -236,10 +236,18 @@ private static Map parseListOptions(String query) throws IOExcep String[] argEntry = arg.split("="); switch (argEntry[0]) { case "fields": - // List fields are in the form "projects(field1, field2, ...)" - options.put( - "fields", - argEntry[1].substring("projects(".length(), argEntry[1].length() - 1).split(",")); + // List fields are in the form "projects(field1, field2, ...),nextPageToken" + String option = argEntry[1]; + int projectStart = option.indexOf("projects("); + int projectEnd = option.indexOf(')'); + if (projectStart != -1 && projectEnd != -1 + && projectEnd > projectStart + "projects(".length()) { + String projectFields = + option.substring(projectStart + "projects(".length(), projectEnd); + options.put("projectFields", projectFields.split(",")); + option = option.replace(option.substring(projectStart, projectEnd), ""); + } + options.put("listFields", option.split(",")); break; case "filter": options.put("filter", argEntry[1].split(" ")); @@ -362,7 +370,7 @@ Response list(Map options) { if (filters != null && !isValidFilter(filters)) { return Error.INVALID_ARGUMENT.response("Could not parse the filter."); } - String[] fields = (String[]) options.get("fields"); + String[] projectFields = (String[]) options.get("projectFields"); int count = 0; String pageToken = (String) options.get("pageToken"); Integer pageSize = (Integer) options.get("pageSize"); @@ -380,7 +388,7 @@ Response list(Map options) { if (includeProject) { count++; try { - projectsSerialized.add(jsonFactory.toString(extractFields(p, fields))); + projectsSerialized.add(jsonFactory.toString(extractFields(p, projectFields))); } catch (IOException e) { return Error.INTERNAL_ERROR.response( "Error when serializing project " + p.getProjectId()); @@ -391,7 +399,9 @@ Response list(Map options) { responseBody.append("{\"projects\": ["); Joiner.on(",").appendTo(responseBody, projectsSerialized); responseBody.append(']'); - if (nextPageToken != null) { + String[] listFields = (String[]) options.get("listFields"); + if (nextPageToken != null && (listFields == null + || ImmutableSet.copyOf(listFields).contains("nextPageToken"))) { responseBody.append(", \"nextPageToken\": \""); responseBody.append(nextPageToken); responseBody.append('"'); diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java index 6c20c4f1ae0e..978e9c2f0416 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java @@ -333,7 +333,8 @@ public void testListPaging() { @Test public void testListFieldOptions() { Map rpcOptions = new HashMap<>(); - rpcOptions.put(ResourceManagerRpc.Option.FIELDS, "projects(projectId,name,labels)"); + rpcOptions.put(ResourceManagerRpc.Option.FIELDS, + "projects(projectId,name,labels),nextPageToken"); rpc.create(PROJECT_WITH_PARENT); Tuple> projects = rpc.list(rpcOptions); @@ -349,6 +350,64 @@ public void testListFieldOptions() { assertNull(returnedProject.getCreateTime()); } + @Test + public void testListPageTokenFieldOptions() { + Map rpcOptions = new HashMap<>(); + rpcOptions.put(ResourceManagerRpc.Option.PAGE_SIZE, 1); + rpcOptions.put(ResourceManagerRpc.Option.FIELDS, "nextPageToken,projects(projectId,name)"); + rpc.create(PARTIAL_PROJECT); + rpc.create(COMPLETE_PROJECT); + Tuple> projects = + rpc.list(rpcOptions); + assertNotNull(projects.x()); + Iterator iterator = + projects.y().iterator(); + com.google.api.services.cloudresourcemanager.model.Project returnedProject = iterator.next(); + assertEquals(COMPLETE_PROJECT.getProjectId(), returnedProject.getProjectId()); + assertEquals(COMPLETE_PROJECT.getName(), returnedProject.getName()); + assertNull(returnedProject.getLabels()); + assertNull(returnedProject.getParent()); + assertNull(returnedProject.getProjectNumber()); + assertNull(returnedProject.getLifecycleState()); + assertNull(returnedProject.getCreateTime()); + assertFalse(iterator.hasNext()); + rpcOptions.put(ResourceManagerRpc.Option.PAGE_TOKEN, projects.x()); + projects = rpc.list(rpcOptions); + iterator = projects.y().iterator(); + returnedProject = iterator.next(); + assertEquals(PARTIAL_PROJECT.getProjectId(), returnedProject.getProjectId()); + assertEquals(PARTIAL_PROJECT.getName(), returnedProject.getName()); + assertNull(returnedProject.getLabels()); + assertNull(returnedProject.getParent()); + assertNull(returnedProject.getProjectNumber()); + assertNull(returnedProject.getLifecycleState()); + assertNull(returnedProject.getCreateTime()); + assertNull(projects.x()); + } + + @Test + public void testListNoPageTokenFieldOptions() { + Map rpcOptions = new HashMap<>(); + rpcOptions.put(ResourceManagerRpc.Option.PAGE_SIZE, 1); + rpcOptions.put(ResourceManagerRpc.Option.FIELDS, "projects(projectId,name)"); + rpc.create(PARTIAL_PROJECT); + rpc.create(COMPLETE_PROJECT); + Tuple> projects = + rpc.list(rpcOptions); + assertNull(projects.x()); + Iterator iterator = + projects.y().iterator(); + com.google.api.services.cloudresourcemanager.model.Project returnedProject = iterator.next(); + assertEquals(COMPLETE_PROJECT.getProjectId(), returnedProject.getProjectId()); + assertEquals(COMPLETE_PROJECT.getName(), returnedProject.getName()); + assertNull(returnedProject.getLabels()); + assertNull(returnedProject.getParent()); + assertNull(returnedProject.getProjectNumber()); + assertNull(returnedProject.getLifecycleState()); + assertNull(returnedProject.getCreateTime()); + assertFalse(iterator.hasNext()); + } + @Test public void testListFilterOptions() { Map rpcFilterOptions = new HashMap<>(); diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java index 8d64652a0696..1bc233311a4d 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java @@ -213,6 +213,38 @@ public void testListFieldOptions() { assertSame(RESOURCE_MANAGER, returnedProject.resourceManager()); } + @Test + public void testListPagingWithFieldOptions() { + RESOURCE_MANAGER.create(PARTIAL_PROJECT); + RESOURCE_MANAGER.create(COMPLETE_PROJECT); + Page projects = RESOURCE_MANAGER.list(LIST_FIELDS, ProjectListOption.pageSize(1)); + assertNotNull(projects.nextPageCursor()); + Iterator iterator = projects.values().iterator(); + Project returnedProject = iterator.next(); + assertEquals(COMPLETE_PROJECT.projectId(), returnedProject.projectId()); + assertEquals(COMPLETE_PROJECT.name(), returnedProject.name()); + assertEquals(COMPLETE_PROJECT.labels(), returnedProject.labels()); + assertNull(returnedProject.parent()); + assertNull(returnedProject.projectNumber()); + assertNull(returnedProject.state()); + assertNull(returnedProject.createTimeMillis()); + assertSame(RESOURCE_MANAGER, returnedProject.resourceManager()); + assertFalse(iterator.hasNext()); + projects = projects.nextPage(); + iterator = projects.values().iterator(); + returnedProject = iterator.next(); + assertEquals(PARTIAL_PROJECT.projectId(), returnedProject.projectId()); + assertEquals(PARTIAL_PROJECT.name(), returnedProject.name()); + assertEquals(PARTIAL_PROJECT.labels(), returnedProject.labels()); + assertNull(returnedProject.parent()); + assertNull(returnedProject.projectNumber()); + assertNull(returnedProject.state()); + assertNull(returnedProject.createTimeMillis()); + assertSame(RESOURCE_MANAGER, returnedProject.resourceManager()); + assertFalse(iterator.hasNext()); + assertNull(projects.nextPageCursor()); + } + @Test public void testListFilterOptions() { ProjectInfo matchingProject = ProjectInfo.builder("matching-project") diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index 0ebe013202b0..4acc1dbcad07 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -655,7 +655,7 @@ public static BucketListOption prefix(String prefix) { */ public static BucketListOption fields(BucketField... fields) { StringBuilder builder = new StringBuilder(); - builder.append("items(").append(BucketField.selector(fields)).append(")"); + builder.append("items(").append(BucketField.selector(fields)).append("),nextPageToken"); return new BucketListOption(StorageRpc.Option.FIELDS, builder.toString()); } } @@ -708,7 +708,7 @@ public static BlobListOption recursive(boolean recursive) { */ public static BlobListOption fields(BlobField... fields) { StringBuilder builder = new StringBuilder(); - builder.append("items(").append(BlobField.selector(fields)).append(")"); + builder.append("items(").append(BlobField.selector(fields)).append("),nextPageToken"); return new BlobListOption(StorageRpc.Option.FIELDS, builder.toString()); } } diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java index f49938c5e9c1..b14dcd057438 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java @@ -586,7 +586,8 @@ public void testListBucketsWithSelectedFields() { assertTrue(selector.contains("name")); assertTrue(selector.contains("acl")); assertTrue(selector.contains("location")); - assertEquals(24, selector.length()); + assertTrue(selector.contains("nextPageToken")); + assertEquals(38, selector.length()); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(bucketList.toArray(), Iterables.toArray(page.values(), Bucket.class)); } @@ -606,7 +607,8 @@ public void testListBucketsWithEmptyFields() { String selector = (String) capturedOptions.getValue().get(BLOB_LIST_FIELDS.rpcOption()); assertTrue(selector.contains("items")); assertTrue(selector.contains("name")); - assertEquals(11, selector.length()); + assertTrue(selector.contains("nextPageToken")); + assertEquals(25, selector.length()); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(bucketList.toArray(), Iterables.toArray(page.values(), Bucket.class)); } @@ -678,7 +680,8 @@ public void testListBlobsWithSelectedFields() { assertTrue(selector.contains("name")); assertTrue(selector.contains("contentType")); assertTrue(selector.contains("md5Hash")); - assertEquals(38, selector.length()); + assertTrue(selector.contains("nextPageToken")); + assertEquals(52, selector.length()); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(blobList.toArray(), Iterables.toArray(page.values(), Blob.class)); } @@ -706,7 +709,8 @@ public void testListBlobsWithEmptyFields() { assertTrue(selector.contains("items")); assertTrue(selector.contains("bucket")); assertTrue(selector.contains("name")); - assertEquals(18, selector.length()); + assertTrue(selector.contains("nextPageToken")); + assertEquals(32, selector.length()); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(blobList.toArray(), Iterables.toArray(page.values(), Blob.class)); } From 28f4a18ae41148f82ffe11bbb311f92f50da180f Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 25 Feb 2016 17:05:55 +0100 Subject: [PATCH 111/375] validateOpen throws ClosedChannelException in BaseWriteChannel and BlobReadChannel --- .../src/main/java/com/google/gcloud/BaseWriteChannel.java | 5 +++-- .../test/java/com/google/gcloud/BaseWriteChannelTest.java | 4 ++-- .../java/com/google/gcloud/storage/BlobReadChannel.java | 7 ++++--- .../com/google/gcloud/storage/BlobReadChannelTest.java | 7 ++++--- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/BaseWriteChannel.java b/gcloud-java-core/src/main/java/com/google/gcloud/BaseWriteChannel.java index e05383a65826..1d18a5a27e81 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/BaseWriteChannel.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/BaseWriteChannel.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.io.Serializable; import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; import java.util.Arrays; import java.util.Objects; @@ -114,9 +115,9 @@ private void flush() { } } - private void validateOpen() throws IOException { + private void validateOpen() throws ClosedChannelException { if (!isOpen) { - throw new IOException("stream is closed"); + throw new ClosedChannelException(); } } diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/BaseWriteChannelTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/BaseWriteChannelTest.java index e49a17b019e0..6d5306a3bc7f 100644 --- a/gcloud-java-core/src/test/java/com/google/gcloud/BaseWriteChannelTest.java +++ b/gcloud-java-core/src/test/java/com/google/gcloud/BaseWriteChannelTest.java @@ -32,6 +32,7 @@ import java.io.IOException; import java.io.Serializable; import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; import java.util.Arrays; import java.util.Random; @@ -102,8 +103,7 @@ public void testClose() throws IOException { @Test public void testValidateOpen() throws IOException { channel.close(); - thrown.expect(IOException.class); - thrown.expectMessage("stream is closed"); + thrown.expect(ClosedChannelException.class); channel.write(ByteBuffer.allocate(42)); } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobReadChannel.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobReadChannel.java index 121f2eb63589..2b9643434ecc 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobReadChannel.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobReadChannel.java @@ -29,6 +29,7 @@ import java.io.IOException; import java.io.Serializable; import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; import java.util.Map; import java.util.Objects; import java.util.concurrent.Callable; @@ -55,7 +56,7 @@ class BlobReadChannel implements ReadChannel { private byte[] buffer; BlobReadChannel(StorageOptions serviceOptions, BlobId blob, - Map requestOptions) { + Map requestOptions) { this.serviceOptions = serviceOptions; this.blob = blob; this.requestOptions = requestOptions; @@ -91,9 +92,9 @@ public void close() { } } - private void validateOpen() throws IOException { + private void validateOpen() throws ClosedChannelException { if (!isOpen) { - throw new IOException("stream is closed"); + throw new ClosedChannelException(); } } diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobReadChannelTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobReadChannelTest.java index ffb37e8c5032..5dc947df51f8 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobReadChannelTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobReadChannelTest.java @@ -39,6 +39,7 @@ import java.io.IOException; import java.nio.ByteBuffer; +import java.nio.channels.ClosedChannelException; import java.util.Arrays; import java.util.Map; import java.util.Random; @@ -156,15 +157,15 @@ public void testClose() { } @Test - public void testReadClosed() { + public void testReadClosed() throws IOException { replay(storageRpcMock); reader = new BlobReadChannel(options, BLOB_ID, EMPTY_RPC_OPTIONS); reader.close(); try { ByteBuffer readBuffer = ByteBuffer.allocate(DEFAULT_CHUNK_SIZE); reader.read(readBuffer); - fail("Expected BlobReadChannel read to throw IOException"); - } catch (IOException ex) { + fail("Expected BlobReadChannel read to throw ClosedChannelException"); + } catch (ClosedChannelException ex) { // expected } } From 08295eeca633772ebab9dafab62aa2cc1e8ad627 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Thu, 25 Feb 2016 09:13:01 -0800 Subject: [PATCH 112/375] Document exceptions and satisfy codacy's demands. --- .../java/com/google/gcloud/IamPolicy.java | 15 +++++++ .../java/com/google/gcloud/IdentityTest.java | 45 +++++++++---------- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java b/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java index ed9dcf9503c7..73c3e3fec6ac 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java @@ -58,6 +58,9 @@ public abstract static class Builder> { private String etag; private Integer version; + /** + * Constructor for IAM Policy builder. + */ protected Builder() {} /** @@ -73,6 +76,8 @@ public final B bindings(Map> bindings) { /** * Adds a binding to the policy. + * + * @throws IllegalArgumentException if the policy already contains a binding with the same role */ public final B addBinding(R role, Set identities) { checkArgument(!bindings.containsKey(role), @@ -83,6 +88,8 @@ public final B addBinding(R role, Set identities) { /** * Adds a binding to the policy. + * + * @throws IllegalArgumentException if the policy already contains a binding with the same role */ public final B addBinding(R role, Identity first, Identity... others) { checkArgument(!bindings.containsKey(role), @@ -104,8 +111,12 @@ public final B removeBinding(R role) { /** * Adds one or more identities to an existing binding. + * + * @throws IllegalArgumentException if the policy doesn't contain a binding with the specified + * role */ public final B addIdentity(R role, Identity first, Identity... others) { + checkArgument(bindings.containsKey(role), "The policy doesn't contain the specified role."); Set identities = bindings.get(role); identities.add(first); identities.addAll(Arrays.asList(others)); @@ -114,8 +125,12 @@ public final B addIdentity(R role, Identity first, Identity... others) { /** * Removes one or more identities from an existing binding. + * + * @throws IllegalArgumentException if the policy doesn't contain a binding with the specified + * role */ public final B removeIdentity(R role, Identity first, Identity... others) { + checkArgument(bindings.containsKey(role), "The policy doesn't contain the specified role."); bindings.get(role).remove(first); bindings.get(role).removeAll(Arrays.asList(others)); return self(); diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/IdentityTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/IdentityTest.java index 7abbc98521a0..828f1c839431 100644 --- a/gcloud-java-core/src/test/java/com/google/gcloud/IdentityTest.java +++ b/gcloud-java-core/src/test/java/com/google/gcloud/IdentityTest.java @@ -18,7 +18,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -import static org.junit.Assert.fail; import org.junit.Test; @@ -48,48 +47,44 @@ public void testAllAuthenticatedUsers() { public void testUser() { assertEquals(Identity.Type.USER, USER.type()); assertEquals("abc@gmail.com", USER.id()); - try { - Identity.user(null); - fail("Should have thrown exception due to null email address."); - } catch (NullPointerException e) { - // expected - } + } + + @Test(expected = NullPointerException.class) + public void testUserNullEmail() { + Identity.user(null); } @Test public void testServiceAccount() { assertEquals(Identity.Type.SERVICE_ACCOUNT, SERVICE_ACCOUNT.type()); assertEquals("service-account@gmail.com", SERVICE_ACCOUNT.id()); - try { - Identity.serviceAccount(null); - fail("Should have thrown exception due to null email address."); - } catch (NullPointerException e) { - // expected - } + } + + @Test(expected = NullPointerException.class) + public void testServiceAccountNullEmail() { + Identity.serviceAccount(null); } @Test public void testGroup() { assertEquals(Identity.Type.GROUP, GROUP.type()); assertEquals("group@gmail.com", GROUP.id()); - try { - Identity.group(null); - fail("Should have thrown exception due to null email address."); - } catch (NullPointerException e) { - // expected - } + } + + @Test(expected = NullPointerException.class) + public void testGroupNullEmail() { + Identity.group(null); } @Test public void testDomain() { assertEquals(Identity.Type.DOMAIN, DOMAIN.type()); assertEquals("google.com", DOMAIN.id()); - try { - Identity.domain(null); - fail("Should have thrown exception due to null domain."); - } catch (NullPointerException e) { - // expected - } + } + + @Test(expected = NullPointerException.class) + public void testDomainNullId() { + Identity.domain(null); } @Test From 5fea7ce3b1796f8dea70286a6fbfd2ed7ed0eed9 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 25 Feb 2016 19:12:00 +0100 Subject: [PATCH 113/375] Use Pattern to match list fields selector --- .../testing/LocalResourceManagerHelper.java | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java index 2e3b8c25db41..7caf7ef0e84d 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java @@ -37,6 +37,8 @@ import java.util.concurrent.ConcurrentSkipListMap; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.zip.GZIPInputStream; /** @@ -56,6 +58,8 @@ public class LocalResourceManagerHelper { private static final URI BASE_CONTEXT; private static final Set SUPPORTED_COMPRESSION_ENCODINGS = ImmutableSet.of("gzip", "x-gzip"); + private static final Pattern LIST_FIELDS_PATTERN = + Pattern.compile("(.*?)projects\\((.*?)\\)(.*?)"); static { try { @@ -237,17 +241,11 @@ private static Map parseListOptions(String query) throws IOExcep switch (argEntry[0]) { case "fields": // List fields are in the form "projects(field1, field2, ...),nextPageToken" - String option = argEntry[1]; - int projectStart = option.indexOf("projects("); - int projectEnd = option.indexOf(')'); - if (projectStart != -1 && projectEnd != -1 - && projectEnd > projectStart + "projects(".length()) { - String projectFields = - option.substring(projectStart + "projects(".length(), projectEnd); - options.put("projectFields", projectFields.split(",")); - option = option.replace(option.substring(projectStart, projectEnd), ""); + Matcher matcher = LIST_FIELDS_PATTERN.matcher(argEntry[1]); + if (matcher.matches()) { + options.put("projectFields", matcher.group(2).split(",")); + options.put("listFields", (matcher.group(1) + matcher.group(3)).split(",")); } - options.put("listFields", option.split(",")); break; case "filter": options.put("filter", argEntry[1].split(" ")); From a62c69dec52fcb1248c173fa3f2e104af9473048 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 25 Feb 2016 21:23:25 +0100 Subject: [PATCH 114/375] Handle no project fields are selected on list --- .../testing/LocalResourceManagerHelper.java | 23 +++++++++++++++---- .../LocalResourceManagerHelperTest.java | 17 ++++++++++++++ 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java index 7caf7ef0e84d..438439c44dd0 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java @@ -60,6 +60,7 @@ public class LocalResourceManagerHelper { ImmutableSet.of("gzip", "x-gzip"); private static final Pattern LIST_FIELDS_PATTERN = Pattern.compile("(.*?)projects\\((.*?)\\)(.*?)"); + private static final String[] NO_FIELDS = {}; static { try { @@ -245,6 +246,9 @@ private static Map parseListOptions(String query) throws IOExcep if (matcher.matches()) { options.put("projectFields", matcher.group(2).split(",")); options.put("listFields", (matcher.group(1) + matcher.group(3)).split(",")); + } else { + options.put("projectFields", NO_FIELDS); + options.put("listFields", argEntry[1].split(",")); } break; case "filter": @@ -393,14 +397,23 @@ Response list(Map options) { } } } - StringBuilder responseBody = new StringBuilder(); - responseBody.append("{\"projects\": ["); - Joiner.on(",").appendTo(responseBody, projectsSerialized); - responseBody.append(']'); String[] listFields = (String[]) options.get("listFields"); + StringBuilder responseBody = new StringBuilder(); + responseBody.append('{'); + boolean commaNeeded = false; + // If fields parameter is set but no project field is selected we must return no projects. + if (!(projectFields != null && projectFields.length == 0)) { + responseBody.append("\"projects\": ["); + Joiner.on(",").appendTo(responseBody, projectsSerialized); + responseBody.append(']'); + commaNeeded = true; + } if (nextPageToken != null && (listFields == null || ImmutableSet.copyOf(listFields).contains("nextPageToken"))) { - responseBody.append(", \"nextPageToken\": \""); + if (commaNeeded) { + responseBody.append(','); + } + responseBody.append("\"nextPageToken\": \""); responseBody.append(nextPageToken); responseBody.append('"'); } diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java index 978e9c2f0416..a3418fff98ab 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java @@ -408,6 +408,23 @@ public void testListNoPageTokenFieldOptions() { assertFalse(iterator.hasNext()); } + @Test + public void testListPageTokenNoFieldsOptions() { + Map rpcOptions = new HashMap<>(); + rpcOptions.put(ResourceManagerRpc.Option.PAGE_SIZE, 1); + rpcOptions.put(ResourceManagerRpc.Option.FIELDS, "nextPageToken"); + rpc.create(PARTIAL_PROJECT); + rpc.create(COMPLETE_PROJECT); + Tuple> projects = + rpc.list(rpcOptions); + assertNotNull(projects.x()); + assertNull(projects.y()); + rpcOptions.put(ResourceManagerRpc.Option.PAGE_TOKEN, projects.x()); + projects = rpc.list(rpcOptions); + assertNull(projects.x()); + assertNull(projects.y()); + } + @Test public void testListFilterOptions() { Map rpcFilterOptions = new HashMap<>(); From cbf737da9a05d69355199bf979e8e2b950aa56e1 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Wed, 24 Feb 2016 08:45:58 -0800 Subject: [PATCH 115/375] Added integration tests. --- .../main/java/com/google/gcloud/dns/Dns.java | 17 +- .../com/google/gcloud/spi/DefaultDnsRpc.java | 4 +- .../com/google/gcloud/dns/DnsImplTest.java | 2 +- .../java/com/google/gcloud/dns/DnsTest.java | 2 +- .../java/com/google/gcloud/dns/ITDnsTest.java | 1268 +++++++++++++++++ 5 files changed, 1283 insertions(+), 10 deletions(-) create mode 100644 gcloud-java-dns/src/test/java/com/google/gcloud/dns/ITDnsTest.java diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index 3ad2094ec2e3..b2cb9fbad371 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -68,7 +68,8 @@ static String selector(ProjectField... fields) { * The fields of a zone. * *

These values can be used to specify the fields to include in a partial response when calling - * {@link Dns#getZone(String, ZoneOption...)}. The name is always returned, even if not specified. + * {@link Dns#getZone(String, ZoneOption...)}. The name is always returned, even if not + * specified. */ enum ZoneField { CREATION_TIME("creationTime"), @@ -103,8 +104,8 @@ static String selector(ZoneField... fields) { * The fields of a DNS record. * *

These values can be used to specify the fields to include in a partial response when calling - * {@link Dns#listDnsRecords(String, DnsRecordListOption...)}. The name is always returned even if - * not selected. + * {@link Dns#listDnsRecords(String, DnsRecordListOption...)}. The name and type are always + * returned even if not selected. */ enum DnsRecordField { DNS_RECORDS("rrdatas"), @@ -125,6 +126,7 @@ String selector() { static String selector(DnsRecordField... fields) { Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); fieldStrings.add(NAME.selector()); + fieldStrings.add(TYPE.selector()); for (DnsRecordField field : fields) { fieldStrings.add(field.selector()); } @@ -198,7 +200,7 @@ class DnsRecordListOption extends AbstractOption implements Serializable { */ public static DnsRecordListOption fields(DnsRecordField... fields) { StringBuilder builder = new StringBuilder(); - builder.append("rrsets(").append(DnsRecordField.selector(fields)).append(')'); + builder.append("nextPageToken,rrsets(").append(DnsRecordField.selector(fields)).append(')'); return new DnsRecordListOption(DnsRpc.Option.FIELDS, builder.toString()); } @@ -234,7 +236,7 @@ public static DnsRecordListOption dnsName(String dnsName) { * Dns.DnsRecordListOption#dnsName(String)} must also be present. */ public static DnsRecordListOption type(DnsRecord.Type type) { - return new DnsRecordListOption(DnsRpc.Option.DNS_TYPE, type); + return new DnsRecordListOption(DnsRpc.Option.DNS_TYPE, type.name()); } } @@ -281,7 +283,7 @@ class ZoneListOption extends AbstractOption implements Serializable { */ public static ZoneListOption fields(ZoneField... fields) { StringBuilder builder = new StringBuilder(); - builder.append("managedZones(").append(ZoneField.selector(fields)).append(')'); + builder.append("nextPageToken,managedZones(").append(ZoneField.selector(fields)).append(')'); return new ZoneListOption(DnsRpc.Option.FIELDS, builder.toString()); } @@ -388,7 +390,8 @@ class ChangeRequestListOption extends AbstractOption implements Serializable { */ public static ChangeRequestListOption fields(ChangeRequestField... fields) { StringBuilder builder = new StringBuilder(); - builder.append("changes(").append(ChangeRequestField.selector(fields)).append(')'); + builder.append("nextPageToken,changes(").append(ChangeRequestField.selector(fields)) + .append(')'); return new ChangeRequestListOption(DnsRpc.Option.FIELDS, builder.toString()); } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java index 6ed9c7e0f216..1df0a8a2f831 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java @@ -162,7 +162,9 @@ public Change getChangeRequest(String zoneName, String changeRequestId, Map zones = DNS.listZones(); + Iterator zoneIterator = zones.iterateAll(); + while (zoneIterator.hasNext()) { + Zone zone = zoneIterator.next(); + List toDelete = new LinkedList<>(); + if (zone.name().startsWith(PREFIX)) { + Iterator dnsRecordIterator = zone.listDnsRecords().iterateAll(); + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + if (!ImmutableList.of(DnsRecord.Type.NS, DnsRecord.Type.SOA).contains(record.type())) { + toDelete.add(record); + } + } + if (!toDelete.isEmpty()) { + zone.applyChangeRequest(ChangeRequest.builder().deletions(toDelete).build()); + } + zone.delete(); + } + } + } + + private static List filter(Iterator iterator) { + List result = new LinkedList<>(); + while (iterator.hasNext()) { + Zone zone = iterator.next(); + if (zone.name().startsWith(PREFIX)) { + result.add(zone); + } + } + return result; + } + + @BeforeClass + public static void before() { + purge(); + } + + @AfterClass + public static void after() { + purge(); + } + + @Test + public void testCreateValidZone() { + Zone created = DNS.create(ZONE1); + assertEquals(ZONE1.description(), created.description()); + assertEquals(ZONE1.dnsName(), created.dnsName()); + assertEquals(ZONE1.name(), created.name()); + assertNotNull(created.creationTimeMillis()); + assertNotNull(created.nameServers()); + assertNull(created.nameServerSet()); + assertNotNull(created.id()); + Zone retrieved = DNS.getZone(ZONE1.name()); + assertEquals(created, retrieved); + created = DNS.create(ZONE_EMPTY_DESCRIPTION); + assertEquals(ZONE_EMPTY_DESCRIPTION.description(), created.description()); + assertEquals(ZONE_EMPTY_DESCRIPTION.dnsName(), created.dnsName()); + assertEquals(ZONE_EMPTY_DESCRIPTION.name(), created.name()); + assertNotNull(created.creationTimeMillis()); + assertNotNull(created.nameServers()); + assertNull(created.nameServerSet()); + assertNotNull(created.id()); + retrieved = DNS.getZone(ZONE_EMPTY_DESCRIPTION.name()); + assertEquals(created, retrieved); + } + + @After + public void tearDown() { + purge(); + } + + @Test + public void testCreateZoneWithErrors() { + try { + DNS.create(ZONE_MISSING_DNS_NAME); + fail("Zone is missing DNS name. The service returns an error."); + } catch (DnsException ex) { + // expected + // todo(mderka) test non-retryable when implemented within #593 + } + try { + DNS.create(ZONE_MISSING_DESCRIPTION); + fail("Zone is missing description name. The service returns an error."); + } catch (DnsException ex) { + // expected + // todo(mderka) test non-retryable when implemented within #593 + } + try { + DNS.create(ZONE_NAME_ERROR); + fail("Zone name is missing a period. The service returns an error."); + } catch (DnsException ex) { + // expected + // todo(mderka) test non-retryable when implemented within #593 + } + try { + DNS.create(ZONE_DNS_NO_PERIOD); + fail("Zone name is missing a period. The service returns an error."); + } catch (DnsException ex) { + // expected + // todo(mderka) test non-retryable when implemented within #593 + } + } + + @Test + public void testCreateZoneWithOptions() { + Zone created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.CREATION_TIME)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNotNull(created.creationTimeMillis()); + assertNull(created.description()); + assertNull(created.dnsName()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created.delete(); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.DESCRIPTION)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertEquals(ZONE1.description(), created.description()); + assertNull(created.dnsName()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created.delete(); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.DNS_NAME)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertEquals(ZONE1.dnsName(), created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created.delete(); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created.delete(); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVER_SET)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); // we did not set it + assertNull(created.id()); + created.delete(); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVERS)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertFalse(created.nameServers().isEmpty()); + assertNull(created.nameServerSet()); + assertNull(created.id()); + created.delete(); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertNotNull(created.nameServers()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNotNull(created.id()); + created.delete(); + // combination of multiple things + created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID, + Dns.ZoneField.NAME_SERVERS, Dns.ZoneField.NAME_SERVER_SET, Dns.ZoneField.DESCRIPTION)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertEquals(ZONE1.description(), created.description()); + assertFalse(created.nameServers().isEmpty()); + assertNull(created.nameServerSet()); // we did not set it + assertNotNull(created.id()); + } + + @Test + public void testZoneReload() { + Zone created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); + created = created.reload(Dns.ZoneOption.fields(Dns.ZoneField.CREATION_TIME)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNotNull(created.creationTimeMillis()); + assertNull(created.description()); + assertNull(created.dnsName()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created = created.reload(Dns.ZoneOption.fields(Dns.ZoneField.DESCRIPTION)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertEquals(ZONE1.description(), created.description()); + assertNull(created.dnsName()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created = created.reload(Dns.ZoneOption.fields(Dns.ZoneField.DNS_NAME)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertEquals(ZONE1.dnsName(), created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created = created.reload(Dns.ZoneOption.fields(Dns.ZoneField.NAME)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created = created.reload(Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVER_SET)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); // we did not set it + assertNull(created.id()); + created = created.reload(Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVERS)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertFalse(created.nameServers().isEmpty()); + assertNull(created.nameServerSet()); + assertNull(created.id()); + created = created.reload(Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertNotNull(created.nameServers()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNotNull(created.id()); + // combination of multiple things + created = created.reload(Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID, + Dns.ZoneField.NAME_SERVERS, Dns.ZoneField.NAME_SERVER_SET, Dns.ZoneField.DESCRIPTION)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertEquals(ZONE1.description(), created.description()); + assertFalse(created.nameServers().isEmpty()); + assertNull(created.nameServerSet()); // we did not set it + assertNotNull(created.id()); + } + + @Test + public void testGetZone() { + DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); + Zone created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.CREATION_TIME)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNotNull(created.creationTimeMillis()); + assertNull(created.description()); + assertNull(created.dnsName()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.DESCRIPTION)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertEquals(ZONE1.description(), created.description()); + assertNull(created.dnsName()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.DNS_NAME)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertEquals(ZONE1.dnsName(), created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.NAME)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVER_SET)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); // we did not set it + assertNull(created.id()); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVERS)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertFalse(created.nameServers().isEmpty()); + assertNull(created.nameServerSet()); + assertNull(created.id()); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertNotNull(created.nameServers()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNotNull(created.id()); + // combination of multiple things + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID, + Dns.ZoneField.NAME_SERVERS, Dns.ZoneField.NAME_SERVER_SET, Dns.ZoneField.DESCRIPTION)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertEquals(ZONE1.description(), created.description()); + assertFalse(created.nameServers().isEmpty()); + assertNull(created.nameServerSet()); // we did not set it + assertNotNull(created.id()); + } + + @Test + public void testListZones() { + List zones = filter(DNS.listZones().iterateAll()); + assertEquals(0, zones.size()); + // some zones exists + Zone created = DNS.create(ZONE1); + zones = filter(DNS.listZones().iterateAll()); + assertEquals(created, zones.get(0)); + assertEquals(1, zones.size()); + created = DNS.create(ZONE_EMPTY_DESCRIPTION); + zones = filter(DNS.listZones().iterateAll()); + assertEquals(2, zones.size()); + assertTrue(zones.contains(created)); + // error in options + try { + DNS.listZones(Dns.ZoneListOption.pageSize(0)); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test not-retryable + } + try { + DNS.listZones(Dns.ZoneListOption.pageSize(-1)); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test not-retryable + } + // ok size + zones = filter(DNS.listZones(Dns.ZoneListOption.pageSize(1000)).iterateAll()); + assertEquals(2, zones.size()); // we still have only 2 zones + // dns name problems + try { + DNS.listZones(Dns.ZoneListOption.dnsName("aaaaa")); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test not-retryable + } + // ok name + zones = filter(DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName())).iterateAll()); + assertEquals(1, zones.size()); + // field options + zones = ImmutableList.copyOf(DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(Dns.ZoneField.ZONE_ID)).iterateAll()); + assertEquals(1, zones.size()); + Zone zone = zones.get(0); + assertNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNull(zone.dnsName()); + assertNull(zone.description()); + assertNull(zone.nameServerSet()); + assertTrue(zone.nameServers().isEmpty()); + assertNotNull(zone.id()); + zones = ImmutableList.copyOf(DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(Dns.ZoneField.CREATION_TIME)).iterateAll()); + assertEquals(1, zones.size()); + zone = zones.get(0); + assertNotNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNull(zone.dnsName()); + assertNull(zone.description()); + assertNull(zone.nameServerSet()); + assertTrue(zone.nameServers().isEmpty()); + assertNull(zone.id()); + zones = ImmutableList.copyOf(DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(Dns.ZoneField.DNS_NAME)).iterateAll()); + assertEquals(1, zones.size()); + zone = zones.get(0); + assertNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNotNull(zone.dnsName()); + assertNull(zone.description()); + assertNull(zone.nameServerSet()); + assertTrue(zone.nameServers().isEmpty()); + assertNull(zone.id()); + zones = ImmutableList.copyOf(DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(Dns.ZoneField.DESCRIPTION)).iterateAll()); + assertEquals(1, zones.size()); + zone = zones.get(0); + assertNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNull(zone.dnsName()); + assertNotNull(zone.description()); + assertNull(zone.nameServerSet()); + assertTrue(zone.nameServers().isEmpty()); + assertNull(zone.id()); + zones = ImmutableList.copyOf(DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(Dns.ZoneField.NAME_SERVERS)).iterateAll()); + assertEquals(1, zones.size()); + zone = zones.get(0); + assertNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNull(zone.dnsName()); + assertNull(zone.description()); + assertNull(zone.nameServerSet()); + assertTrue(!zone.nameServers().isEmpty()); + assertNull(zone.id()); + zones = ImmutableList.copyOf(DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(Dns.ZoneField.NAME_SERVER_SET)).iterateAll()); + assertEquals(1, zones.size()); + zone = zones.get(0); + assertNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNull(zone.dnsName()); + assertNull(zone.description()); + assertNull(zone.nameServerSet()); // we cannot set it using gcloud java + assertTrue(zone.nameServers().isEmpty()); + assertNull(zone.id()); + // several combined + zones = filter(DNS.listZones(Dns.ZoneListOption.fields(Dns.ZoneField.ZONE_ID, + Dns.ZoneField.DESCRIPTION), + Dns.ZoneListOption.pageSize(1)).iterateAll()); + assertEquals(2, zones.size()); + for (Zone current : zones) { + assertNull(current.creationTimeMillis()); + assertNotNull(current.name()); + assertNull(current.dnsName()); + assertNotNull(current.description()); + assertNull(current.nameServerSet()); + assertTrue(zone.nameServers().isEmpty()); + assertNotNull(current.id()); + } + } + + @Test + public void testDeleteZoneUsingServiceObject() { + Zone created = DNS.create(ZONE1); + assertEquals(created, DNS.getZone(ZONE1.name())); + DNS.delete(ZONE1.name()); + assertNull(DNS.getZone(ZONE1.name())); + } + + @Test + public void testDeleteZoneUsingZoneObject() { + Zone created = DNS.create(ZONE1); + assertEquals(created, DNS.getZone(ZONE1.name())); + created.delete(); + assertNull(DNS.getZone(ZONE1.name())); + } + + private void assertEqChangesIgnoreStatus(ChangeRequest expected, ChangeRequest actual) { + ChangeRequest unifiedEx = ChangeRequest.fromPb(expected.toPb().setStatus("pending")); + ChangeRequest unifiedAct = ChangeRequest.fromPb(actual.toPb().setStatus("pending")); + assertEquals(unifiedEx, unifiedAct); + } + + private static void checkChangeComplete(String zoneName, String changeId) { + for (int i = 0; i < TIME_LIMIT; i++) { + ChangeRequest changeRequest = DNS.getChangeRequest(zoneName, changeId, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); + if (ChangeRequest.Status.DONE.equals(changeRequest.status())) { + break; + } else { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException("Thread was interrupted while waiting for change."); + } + } + } + } + + @Test + public void testCreateChangeUsingServiceObject() { + DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); + ChangeRequest created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); + assertEquals(CHANGE_ADD_ZONE1.additions(), created.additions()); + assertNotNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertEquals("1", created.id()); + assertTrue(ImmutableList.of(ChangeRequest.Status.PENDING, ChangeRequest.Status.DONE) + .contains(created.status())); + assertEqChangesIgnoreStatus(created, DNS.getChangeRequest(ZONE1.name(), "1")); + checkChangeComplete(ZONE1.name(), "1"); + DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + checkChangeComplete(ZONE1.name(), "2"); + // with options + created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); + assertTrue(created.additions().isEmpty()); + assertNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertEquals("3", created.id()); + assertNull(created.status()); + checkChangeComplete(ZONE1.name(), "3"); + DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + checkChangeComplete(ZONE1.name(), "4"); + created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); + assertTrue(created.additions().isEmpty()); + assertNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertEquals("5", created.id()); + assertNotNull(created.status()); + checkChangeComplete(ZONE1.name(), "5"); + DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + checkChangeComplete(ZONE1.name(), "6"); + created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); + assertTrue(created.additions().isEmpty()); + assertNotNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertEquals("7", created.id()); + assertNull(created.status()); + checkChangeComplete(ZONE1.name(), "7"); + DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + checkChangeComplete(ZONE1.name(), "8"); + created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); + assertEquals(CHANGE_ADD_ZONE1.additions(), created.additions()); + assertNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertEquals("9", created.id()); + assertNull(created.status()); + // finishes with delete otherwise we cannot delete the zone + checkChangeComplete(ZONE1.name(), "9"); + created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); + checkChangeComplete(ZONE1.name(), "10"); + assertEquals(CHANGE_DELETE_ZONE1.deletions(), created.deletions()); + assertNull(created.startTimeMillis()); + assertTrue(created.additions().isEmpty()); + assertEquals("10", created.id()); + assertNull(created.status()); + checkChangeComplete(ZONE1.name(), "10"); + } + + @Test + public void testCreateChangeUsingZoneObject() { + Zone zone = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); + ChangeRequest created = zone.applyChangeRequest(CHANGE_ADD_ZONE1); + assertEquals(CHANGE_ADD_ZONE1.additions(), created.additions()); + assertNotNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertEquals("1", created.id()); + assertTrue(ImmutableList.of(ChangeRequest.Status.PENDING, ChangeRequest.Status.DONE) + .contains(created.status())); + assertEqChangesIgnoreStatus(created, DNS.getChangeRequest(ZONE1.name(), "1")); + checkChangeComplete(ZONE1.name(), "1"); + zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + checkChangeComplete(ZONE1.name(), "2"); + // with options + created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); + assertTrue(created.additions().isEmpty()); + assertNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertEquals("3", created.id()); + assertNull(created.status()); + checkChangeComplete(ZONE1.name(), "3"); + zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + checkChangeComplete(ZONE1.name(), "4"); + created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); + assertTrue(created.additions().isEmpty()); + assertNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertEquals("5", created.id()); + assertNotNull(created.status()); + checkChangeComplete(ZONE1.name(), "5"); + zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + checkChangeComplete(ZONE1.name(), "6"); + created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); + assertTrue(created.additions().isEmpty()); + assertNotNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertEquals("7", created.id()); + assertNull(created.status()); + checkChangeComplete(ZONE1.name(), "7"); + zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + checkChangeComplete(ZONE1.name(), "8"); + created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); + assertEquals(CHANGE_ADD_ZONE1.additions(), created.additions()); + assertNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertEquals("9", created.id()); + assertNull(created.status()); + // finishes with delete otherwise we cannot delete the zone + checkChangeComplete(ZONE1.name(), "9"); + created = zone.applyChangeRequest(CHANGE_DELETE_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); + checkChangeComplete(ZONE1.name(), "10"); + assertEquals(CHANGE_DELETE_ZONE1.deletions(), created.deletions()); + assertNull(created.startTimeMillis()); + assertTrue(created.additions().isEmpty()); + assertEquals("10", created.id()); + assertNull(created.status()); + checkChangeComplete(ZONE1.name(), "10"); + } + + @Test + public void testListChangesUsingService() { + // no such zone exists + try { + DNS.listChangeRequests(ZONE1.name()); + fail(); + } catch (DnsException ex) { + // expected + assertEquals(404, ex.code()); + // todo(mderka) test retry functionality + } + // zone exists but has no changes + DNS.create(ZONE1); + ImmutableList changes = ImmutableList.copyOf( + DNS.listChangeRequests(ZONE1.name()).iterateAll()); + assertEquals(1, changes.size()); // default change creating SOA and NS + // zone has changes + ChangeRequest change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); + checkChangeComplete(ZONE1.name(), change.id()); + change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + checkChangeComplete(ZONE1.name(), change.id()); + change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); + checkChangeComplete(ZONE1.name(), change.id()); + change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + checkChangeComplete(ZONE1.name(), change.id()); + changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name()).iterateAll()); + assertEquals(5, changes.size()); + // error in options + try { + DNS.listChangeRequests(ZONE1.name(), Dns.ChangeRequestListOption.pageSize(0)); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test retry functionality + } + try { + DNS.listChangeRequests(ZONE1.name(), Dns.ChangeRequestListOption.pageSize(-1)); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test retry functionality + } + // sorting order + ImmutableList ascending = ImmutableList.copyOf(DNS.listChangeRequests( + ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING)).iterateAll()); + ImmutableList descending = ImmutableList.copyOf(DNS.listChangeRequests( + ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.DESCENDING)).iterateAll()); + int size = 5; + assertEquals(size, descending.size()); + assertEquals(size, ascending.size()); + for (int i = 0; i < size; i++) { + assertEquals(descending.get(i), ascending.get(size - i - 1)); + } + // field options + changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.ADDITIONS)).iterateAll()); + change = changes.get(1); + assertEquals(CHANGE_ADD_ZONE1.additions(), change.additions()); + assertTrue(change.deletions().isEmpty()); + assertEquals("1", change.id()); + assertNull(change.startTimeMillis()); + assertNull(change.status()); + changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.DELETIONS)).iterateAll()); + change = changes.get(2); + assertTrue(change.additions().isEmpty()); + assertNotNull(change.deletions()); + assertEquals("2", change.id()); + assertNull(change.startTimeMillis()); + assertNull(change.status()); + changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.ID)).iterateAll()); + change = changes.get(1); + assertTrue(change.additions().isEmpty()); + assertTrue(change.deletions().isEmpty()); + assertEquals("1", change.id()); + assertNull(change.startTimeMillis()); + assertNull(change.status()); + changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.START_TIME)).iterateAll()); + change = changes.get(1); + assertTrue(change.additions().isEmpty()); + assertTrue(change.deletions().isEmpty()); + assertEquals("1", change.id()); + assertNotNull(change.startTimeMillis()); + assertNull(change.status()); + changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.STATUS)).iterateAll()); + change = changes.get(1); + assertTrue(change.additions().isEmpty()); + assertTrue(change.deletions().isEmpty()); + assertEquals("1", change.id()); + assertNull(change.startTimeMillis()); + assertEquals(ChangeRequest.Status.DONE, change.status()); + } + + @Test + public void testListChangesUsingZoneObject() { + // zone exists but has no changes + Zone created = DNS.create(ZONE1); + ImmutableList changes = ImmutableList.copyOf( + created.listChangeRequests().iterateAll()); + assertEquals(1, changes.size()); // default change creating SOA and NS + // zone has changes + ChangeRequest change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); + checkChangeComplete(ZONE1.name(), change.id()); + change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + checkChangeComplete(ZONE1.name(), change.id()); + change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); + checkChangeComplete(ZONE1.name(), change.id()); + change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + checkChangeComplete(ZONE1.name(), change.id()); + changes = ImmutableList.copyOf(created.listChangeRequests().iterateAll()); + assertEquals(5, changes.size()); + // error in options + try { + created.listChangeRequests(Dns.ChangeRequestListOption.pageSize(0)); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test retry functionality + } + try { + created.listChangeRequests(Dns.ChangeRequestListOption.pageSize(-1)); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test retry functionality + } + // sorting order + ImmutableList ascending = ImmutableList.copyOf(created.listChangeRequests( + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING)).iterateAll()); + ImmutableList descending = ImmutableList.copyOf(created.listChangeRequests( + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.DESCENDING)).iterateAll()); + int size = 5; + assertEquals(size, descending.size()); + assertEquals(size, ascending.size()); + for (int i = 0; i < size; i++) { + assertEquals(descending.get(i), ascending.get(size - i - 1)); + } + // field options + changes = ImmutableList.copyOf(created.listChangeRequests( + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.ADDITIONS)).iterateAll()); + change = changes.get(1); + assertEquals(CHANGE_ADD_ZONE1.additions(), change.additions()); + assertTrue(change.deletions().isEmpty()); + assertEquals("1", change.id()); + assertNull(change.startTimeMillis()); + assertNull(change.status()); + changes = ImmutableList.copyOf(created.listChangeRequests( + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.DELETIONS)).iterateAll()); + change = changes.get(2); + assertTrue(change.additions().isEmpty()); + assertNotNull(change.deletions()); + assertEquals("2", change.id()); + assertNull(change.startTimeMillis()); + assertNull(change.status()); + changes = ImmutableList.copyOf(created.listChangeRequests( + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.ID)).iterateAll()); + change = changes.get(1); + assertTrue(change.additions().isEmpty()); + assertTrue(change.deletions().isEmpty()); + assertEquals("1", change.id()); + assertNull(change.startTimeMillis()); + assertNull(change.status()); + changes = ImmutableList.copyOf(created.listChangeRequests( + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.START_TIME)).iterateAll()); + change = changes.get(1); + assertTrue(change.additions().isEmpty()); + assertTrue(change.deletions().isEmpty()); + assertEquals("1", change.id()); + assertNotNull(change.startTimeMillis()); + assertNull(change.status()); + changes = ImmutableList.copyOf(created.listChangeRequests( + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.STATUS)).iterateAll()); + change = changes.get(1); + assertTrue(change.additions().isEmpty()); + assertTrue(change.deletions().isEmpty()); + assertEquals("1", change.id()); + assertNull(change.startTimeMillis()); + assertEquals(ChangeRequest.Status.DONE, change.status()); + } + + @Test + public void testGetChangeUsingZoneObject() { + Zone zone = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); + ChangeRequest created = zone.applyChangeRequest(CHANGE_ADD_ZONE1); + ChangeRequest retrieved = zone.getChangeRequest(created.id()); + assertEqChangesIgnoreStatus(created, retrieved); + checkChangeComplete(ZONE1.name(), "1"); + zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + checkChangeComplete(ZONE1.name(), "2"); + // with options + created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); + retrieved = zone.getChangeRequest(created.id(), + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); + assertEqChangesIgnoreStatus(created, retrieved); + checkChangeComplete(ZONE1.name(), "3"); + zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + checkChangeComplete(ZONE1.name(), "4"); + created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); + retrieved = zone.getChangeRequest(created.id(), + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); + assertEqChangesIgnoreStatus(created, retrieved); + checkChangeComplete(ZONE1.name(), "5"); + zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + checkChangeComplete(ZONE1.name(), "6"); + created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); + retrieved = zone.getChangeRequest(created.id(), + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); + assertEqChangesIgnoreStatus(created, retrieved); + checkChangeComplete(ZONE1.name(), "7"); + zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + checkChangeComplete(ZONE1.name(), "8"); + created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); + retrieved = zone.getChangeRequest(created.id(), + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); + assertEqChangesIgnoreStatus(created, retrieved); + // finishes with delete otherwise we cannot delete the zone + checkChangeComplete(ZONE1.name(), "9"); + created = zone.applyChangeRequest(CHANGE_DELETE_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); + retrieved = zone.getChangeRequest(created.id(), + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); + assertEqChangesIgnoreStatus(created, retrieved); + checkChangeComplete(ZONE1.name(), "10"); + } + + @Test + public void testGetChangeUsingServiceObject() { + Zone zone = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); + ChangeRequest created = zone.applyChangeRequest(CHANGE_ADD_ZONE1); + ChangeRequest retrieved = DNS.getChangeRequest(zone.name(), created.id()); + assertEqChangesIgnoreStatus(created, retrieved); + zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + // with options + created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); + retrieved = DNS.getChangeRequest(zone.name(), created.id(), + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); + assertEqChangesIgnoreStatus(created, retrieved); + zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); + retrieved = DNS.getChangeRequest(zone.name(), created.id(), + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); + assertEqChangesIgnoreStatus(created, retrieved); + zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); + retrieved = DNS.getChangeRequest(zone.name(), created.id(), + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); + assertEqChangesIgnoreStatus(created, retrieved); + zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); + retrieved = DNS.getChangeRequest(zone.name(), created.id(), + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); + assertEqChangesIgnoreStatus(created, retrieved); + // finishes with delete otherwise we cannot delete the zone + created = zone.applyChangeRequest(CHANGE_DELETE_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); + retrieved = DNS.getChangeRequest(zone.name(), created.id(), + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); + assertEqChangesIgnoreStatus(created, retrieved); + } + + @Test + public void testGetProject() { + // fetches all fields + ProjectInfo project = DNS.getProject(); + assertNotNull(project.quota()); + assertNotNull(project.number()); + assertNotNull(project.id()); + assertEquals(PROJECT_ID, project.id()); + // options + project = DNS.getProject(Dns.ProjectOption.fields(Dns.ProjectField.QUOTA)); + assertNotNull(project.quota()); + assertNull(project.number()); + assertNotNull(project.id()); // id is always returned + project = DNS.getProject(Dns.ProjectOption.fields(Dns.ProjectField.PROJECT_ID)); + assertNull(project.quota()); + assertNull(project.number()); + assertNotNull(project.id()); + project = DNS.getProject(Dns.ProjectOption.fields(Dns.ProjectField.PROJECT_NUMBER)); + assertNull(project.quota()); + assertNotNull(project.number()); + assertNotNull(project.id()); + project = DNS.getProject(Dns.ProjectOption.fields(Dns.ProjectField.PROJECT_NUMBER, + Dns.ProjectField.QUOTA, Dns.ProjectField.PROJECT_ID)); + assertNotNull(project.quota()); + assertNotNull(project.number()); + assertNotNull(project.id()); + } + + @Test + public void testListDnsRecordsUsingService() { + Zone zone = DNS.create(ZONE1); + ImmutableList dnsRecords = ImmutableList.copyOf( + DNS.listDnsRecords(zone.name()).iterateAll()); + assertEquals(2, dnsRecords.size()); + ImmutableList defaultRecords = + ImmutableList.of(DnsRecord.Type.NS, DnsRecord.Type.SOA); + for (DnsRecord record : dnsRecords) { + assertTrue(defaultRecords.contains(record.type())); + } + // field options + Iterator dnsRecordIterator = DNS.listDnsRecords(zone.name(), + Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TTL)).iterateAll(); + int counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertEquals(dnsRecords.get(counter).ttl(), record.ttl()); + assertEquals(dnsRecords.get(counter).name(), record.name()); + assertEquals(dnsRecords.get(counter).type(), record.type()); + assertTrue(record.records().isEmpty()); + counter++; + } + assertEquals(2, counter); + dnsRecordIterator = DNS.listDnsRecords(zone.name(), + Dns.DnsRecordListOption.fields(Dns.DnsRecordField.NAME)).iterateAll(); + counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertEquals(dnsRecords.get(counter).name(), record.name()); + assertEquals(dnsRecords.get(counter).type(), record.type()); + assertTrue(record.records().isEmpty()); + assertNull(record.ttl()); + counter++; + } + assertEquals(2, counter); + dnsRecordIterator = DNS.listDnsRecords(zone.name(), + Dns.DnsRecordListOption.fields(Dns.DnsRecordField.DNS_RECORDS)).iterateAll(); + counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertEquals(dnsRecords.get(counter).records(), record.records()); + assertEquals(dnsRecords.get(counter).name(), record.name()); + assertEquals(dnsRecords.get(counter).type(), record.type()); + assertNull(record.ttl()); + counter++; + } + assertEquals(2, counter); + dnsRecordIterator = DNS.listDnsRecords(zone.name(), + Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TYPE), + Dns.DnsRecordListOption.pageSize(1)).iterateAll(); // also test paging + counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertEquals(dnsRecords.get(counter).type(), record.type()); + assertEquals(dnsRecords.get(counter).name(), record.name()); + assertTrue(record.records().isEmpty()); + assertNull(record.ttl()); + counter++; + } + assertEquals(2, counter); + // test page size + Page dnsRecordPage = DNS.listDnsRecords(zone.name(), + Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TYPE), + Dns.DnsRecordListOption.pageSize(1)); + assertEquals(1, ImmutableList.copyOf(dnsRecordPage.values().iterator()).size()); + // test name filter + ChangeRequest change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); + checkChangeComplete(ZONE1.name(), change.id()); + dnsRecordIterator = DNS.listDnsRecords(ZONE1.name(), + Dns.DnsRecordListOption.dnsName(A_RECORD_ZONE1.name())).iterateAll(); + counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertTrue(ImmutableList.of(A_RECORD_ZONE1.type(), AAAA_RECORD_ZONE1.type()) + .contains(record.type())); + counter++; + } + assertEquals(2, counter); + // test type filter + checkChangeComplete(ZONE1.name(), change.id()); + dnsRecordIterator = DNS.listDnsRecords(ZONE1.name(), + Dns.DnsRecordListOption.dnsName(A_RECORD_ZONE1.name()), + Dns.DnsRecordListOption.type(A_RECORD_ZONE1.type())) + .iterateAll(); + counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertEquals(A_RECORD_ZONE1, record); + counter++; + } + assertEquals(1, counter); + change = zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + // check wrong arguments + try { + // name is not set + DNS.listDnsRecords(ZONE1.name(), + Dns.DnsRecordListOption.type(A_RECORD_ZONE1.type())); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test retry functionality when available + } + try { + DNS.listDnsRecords(ZONE1.name(), + Dns.DnsRecordListOption.pageSize(0)); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test retry functionality when available + } + try { + DNS.listDnsRecords(ZONE1.name(), + Dns.DnsRecordListOption.pageSize(-1)); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test retry functionality when available + } + checkChangeComplete(ZONE1.name(), change.id()); + } + + @Test + public void testListDnsRecordsUsingZoneObject() { + Zone zone = DNS.create(ZONE1); + ImmutableList dnsRecords = ImmutableList.copyOf( + zone.listDnsRecords().iterateAll()); + assertEquals(2, dnsRecords.size()); + ImmutableList defaultRecords = + ImmutableList.of(DnsRecord.Type.NS, DnsRecord.Type.SOA); + for (DnsRecord record : dnsRecords) { + assertTrue(defaultRecords.contains(record.type())); + } + // field options + Iterator dnsRecordIterator = zone.listDnsRecords( + Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TTL)).iterateAll(); + int counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertEquals(dnsRecords.get(counter).ttl(), record.ttl()); + assertEquals(dnsRecords.get(counter).name(), record.name()); + assertEquals(dnsRecords.get(counter).type(), record.type()); + assertTrue(record.records().isEmpty()); + counter++; + } + assertEquals(2, counter); + dnsRecordIterator = zone.listDnsRecords( + Dns.DnsRecordListOption.fields(Dns.DnsRecordField.NAME)).iterateAll(); + counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertEquals(dnsRecords.get(counter).name(), record.name()); + assertEquals(dnsRecords.get(counter).type(), record.type()); + assertTrue(record.records().isEmpty()); + assertNull(record.ttl()); + counter++; + } + assertEquals(2, counter); + dnsRecordIterator = zone.listDnsRecords( + Dns.DnsRecordListOption.fields(Dns.DnsRecordField.DNS_RECORDS)).iterateAll(); + counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertEquals(dnsRecords.get(counter).records(), record.records()); + assertEquals(dnsRecords.get(counter).name(), record.name()); + assertEquals(dnsRecords.get(counter).type(), record.type()); + assertNull(record.ttl()); + counter++; + } + assertEquals(2, counter); + dnsRecordIterator = zone.listDnsRecords( + Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TYPE), + Dns.DnsRecordListOption.pageSize(1)).iterateAll(); // also test paging + counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertEquals(dnsRecords.get(counter).type(), record.type()); + assertEquals(dnsRecords.get(counter).name(), record.name()); + assertTrue(record.records().isEmpty()); + assertNull(record.ttl()); + counter++; + } + assertEquals(2, counter); + // test page size + Page dnsRecordPage = zone.listDnsRecords( + Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TYPE), + Dns.DnsRecordListOption.pageSize(1)); + assertEquals(1, ImmutableList.copyOf(dnsRecordPage.values().iterator()).size()); + // test name filter + ChangeRequest change = zone.applyChangeRequest(CHANGE_ADD_ZONE1); + checkChangeComplete(ZONE1.name(), change.id()); + dnsRecordIterator = zone.listDnsRecords(Dns.DnsRecordListOption.dnsName(A_RECORD_ZONE1.name())) + .iterateAll(); + counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertTrue(ImmutableList.of(A_RECORD_ZONE1.type(), AAAA_RECORD_ZONE1.type()) + .contains(record.type())); + counter++; + } + assertEquals(2, counter); + // test type filter + checkChangeComplete(ZONE1.name(), change.id()); + dnsRecordIterator = zone.listDnsRecords(Dns.DnsRecordListOption.dnsName(A_RECORD_ZONE1.name()), + Dns.DnsRecordListOption.type(A_RECORD_ZONE1.type())) + .iterateAll(); + counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertEquals(A_RECORD_ZONE1, record); + counter++; + } + assertEquals(1, counter); + change = zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + // check wrong arguments + try { + // name is not set + zone.listDnsRecords(Dns.DnsRecordListOption.type(A_RECORD_ZONE1.type())); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test retry functionality when available + } + try { + zone.listDnsRecords(Dns.DnsRecordListOption.pageSize(0)); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test retry functionality when available + } + try { + zone.listDnsRecords(Dns.DnsRecordListOption.pageSize(-1)); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test retry functionality when available + } + checkChangeComplete(ZONE1.name(), change.id()); + } +} From a43962846940a6369ce25209470f5de2c6005e67 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 25 Feb 2016 23:53:46 +0100 Subject: [PATCH 116/375] Remove non-necessary commaNeeded variable --- .../resourcemanager/testing/LocalResourceManagerHelper.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java index 438439c44dd0..a077eb6144a5 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java @@ -400,17 +400,15 @@ Response list(Map options) { String[] listFields = (String[]) options.get("listFields"); StringBuilder responseBody = new StringBuilder(); responseBody.append('{'); - boolean commaNeeded = false; // If fields parameter is set but no project field is selected we must return no projects. if (!(projectFields != null && projectFields.length == 0)) { responseBody.append("\"projects\": ["); Joiner.on(",").appendTo(responseBody, projectsSerialized); responseBody.append(']'); - commaNeeded = true; } if (nextPageToken != null && (listFields == null || ImmutableSet.copyOf(listFields).contains("nextPageToken"))) { - if (commaNeeded) { + if (responseBody.length() > 1) { responseBody.append(','); } responseBody.append("\"nextPageToken\": \""); From 7d87d3ce92d781a5c3fbb204f1e99ba9ff500ef4 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 26 Feb 2016 08:05:10 -0800 Subject: [PATCH 117/375] Use enum for legacy roles, add input checks --- .../java/com/google/gcloud/IamPolicy.java | 50 +++++++++++++---- .../main/java/com/google/gcloud/Identity.java | 39 +++++++++---- .../java/com/google/gcloud/IamPolicyTest.java | 29 ++++++---- .../google/gcloud/resourcemanager/Policy.java | 56 ++++++++++++++++--- .../gcloud/resourcemanager/PolicyTest.java | 4 +- .../resourcemanager/SerializationTest.java | 2 +- 6 files changed, 137 insertions(+), 43 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java b/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java index 73c3e3fec6ac..748eaba2ab4c 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java @@ -23,8 +23,11 @@ import java.io.Serializable; import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; @@ -65,8 +68,14 @@ protected Builder() {} /** * Replaces the builder's map of bindings with the given map of bindings. + * + * @throws IllegalArgumentException if the provided map is null or contain any null values */ public final B bindings(Map> bindings) { + checkArgument(bindings != null, "The provided map of bindings cannot be null."); + for (Map.Entry> binding : bindings.entrySet()) { + verifyBinding(binding.getKey(), binding.getValue()); + } this.bindings.clear(); for (Map.Entry> binding : bindings.entrySet()) { this.bindings.put(binding.getKey(), new HashSet(binding.getValue())); @@ -78,10 +87,12 @@ public final B bindings(Map> bindings) { * Adds a binding to the policy. * * @throws IllegalArgumentException if the policy already contains a binding with the same role + * or if the role or any identities are null */ public final B addBinding(R role, Set identities) { + verifyBinding(role, identities); checkArgument(!bindings.containsKey(role), - "The policy already contains a binding with the role " + role.toString()); + "The policy already contains a binding with the role " + role.toString() + "."); bindings.put(role, new HashSet(identities)); return self(); } @@ -90,15 +101,23 @@ public final B addBinding(R role, Set identities) { * Adds a binding to the policy. * * @throws IllegalArgumentException if the policy already contains a binding with the same role + * or if the role or any identities are null */ public final B addBinding(R role, Identity first, Identity... others) { - checkArgument(!bindings.containsKey(role), - "The policy already contains a binding with the role " + role.toString()); HashSet identities = new HashSet<>(); identities.add(first); identities.addAll(Arrays.asList(others)); - bindings.put(role, identities); - return self(); + return addBinding(role, identities); + } + + private void verifyBinding(R role, Collection identities) { + checkArgument(role != null, "The role cannot be null."); + verifyIdentities(identities); + } + + private void verifyIdentities(Collection identities) { + checkArgument(identities != null, "A role cannot be assigned to a null set of identities."); + checkArgument(!identities.contains(null), "Null identities are not permitted."); } /** @@ -113,13 +132,16 @@ public final B removeBinding(R role) { * Adds one or more identities to an existing binding. * * @throws IllegalArgumentException if the policy doesn't contain a binding with the specified - * role + * role or any identities are null */ public final B addIdentity(R role, Identity first, Identity... others) { - checkArgument(bindings.containsKey(role), "The policy doesn't contain the specified role."); - Set identities = bindings.get(role); - identities.add(first); - identities.addAll(Arrays.asList(others)); + checkArgument(bindings.containsKey(role), + "The policy doesn't contain the role " + role.toString() + "."); + List toAdd = new LinkedList<>(); + toAdd.add(first); + toAdd.addAll(Arrays.asList(others)); + verifyIdentities(toAdd); + bindings.get(role).addAll(toAdd); return self(); } @@ -130,7 +152,8 @@ public final B addIdentity(R role, Identity first, Identity... others) { * role */ public final B removeIdentity(R role, Identity first, Identity... others) { - checkArgument(bindings.containsKey(role), "The policy doesn't contain the specified role."); + checkArgument(bindings.containsKey(role), + "The policy doesn't contain the role " + role.toString() + "."); bindings.get(role).remove(first); bindings.get(role).removeAll(Arrays.asList(others)); return self(); @@ -179,6 +202,11 @@ protected IamPolicy(Builder> builder) { this.version = builder.version; } + /** + * Returns a builder containing the properties of this IAM Policy. + */ + public abstract Builder> toBuilder(); + /** * The map of bindings that comprises the policy. */ diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/Identity.java b/gcloud-java-core/src/main/java/com/google/gcloud/Identity.java index 0513916cc8b4..d1644198f759 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/Identity.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/Identity.java @@ -18,11 +18,26 @@ import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.base.CaseFormat; + import java.io.Serializable; import java.util.Objects; /** - * An identity in an {@link IamPolicy}. + * An identity in an {@link IamPolicy}. The following types of identities are permitted in IAM + * policies: + *

    + *
  • Google account + *
  • Service account + *
  • Google group + *
  • Google Apps domain + *
+ * + *

There are also two special identities that represent all users and all Google-authenticated + * accounts. + * + * @see Concepts + * related to identity */ public final class Identity implements Serializable { @@ -82,7 +97,8 @@ public Type type() { *

  • email address (for identities of type {@code USER}, {@code SERVICE_ACCOUNT}, and * {@code GROUP}) *
  • domain (for identities of type {@code DOMAIN}) - *
  • null (for identities of type {@code ALL_USERS} and {@code ALL_AUTHENTICATED_USERS}) + *
  • {@code null} (for identities of type {@code ALL_USERS} and + * {@code ALL_AUTHENTICATED_USERS}) * */ public String id() { @@ -178,7 +194,7 @@ public String strValue() { case DOMAIN: return "domain:" + id; default: - throw new IllegalArgumentException("Unexpected identity type: " + type); + throw new IllegalStateException("Unexpected identity type: " + type); } } @@ -188,21 +204,22 @@ public String strValue() { */ public static Identity valueOf(String identityStr) { String[] info = identityStr.split(":"); - switch (info[0]) { - case "allUsers": + Type type = Type.valueOf(CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, info[0])); + switch (type) { + case ALL_USERS: return Identity.allUsers(); - case "allAuthenticatedUsers": + case ALL_AUTHENTICATED_USERS: return Identity.allAuthenticatedUsers(); - case "user": + case USER: return Identity.user(info[1]); - case "serviceAccount": + case SERVICE_ACCOUNT: return Identity.serviceAccount(info[1]); - case "group": + case GROUP: return Identity.group(info[1]); - case "domain": + case DOMAIN: return Identity.domain(info[1]); default: - throw new IllegalArgumentException("Unexpected identity type: " + info[0]); + throw new IllegalStateException("Unexpected identity type " + type); } } } diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java index b77b5e2df7fa..db0935c4766d 100644 --- a/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java +++ b/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java @@ -18,6 +18,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -71,7 +72,8 @@ public PolicyImpl build() { super(builder); } - Builder toBuilder() { + @Override + public Builder toBuilder() { return new Builder(bindings(), etag(), version()); } @@ -93,38 +95,38 @@ public void testBuilder() { assertEquals(1, policy.version().intValue()); policy = SIMPLE_POLICY.toBuilder().removeBinding("editor").build(); assertEquals(ImmutableMap.of("viewer", BINDINGS.get("viewer")), policy.bindings()); - assertEquals(null, policy.etag()); - assertEquals(null, policy.version()); + assertNull(policy.etag()); + assertNull(policy.version()); policy = policy.toBuilder() .removeIdentity("viewer", USER, ALL_USERS) .addIdentity("viewer", DOMAIN, GROUP) .build(); assertEquals(ImmutableMap.of("viewer", ImmutableSet.of(SERVICE_ACCOUNT, DOMAIN, GROUP)), policy.bindings()); - assertEquals(null, policy.etag()); - assertEquals(null, policy.version()); + assertNull(policy.etag()); + assertNull(policy.version()); policy = PolicyImpl.builder().addBinding("owner", USER, SERVICE_ACCOUNT).build(); assertEquals( ImmutableMap.of("owner", ImmutableSet.of(USER, SERVICE_ACCOUNT)), policy.bindings()); - assertEquals(null, policy.etag()); - assertEquals(null, policy.version()); + assertNull(policy.etag()); + assertNull(policy.version()); try { SIMPLE_POLICY.toBuilder().addBinding("viewer", USER); fail("Should have failed due to duplicate role."); } catch (IllegalArgumentException e) { - assertEquals("The policy already contains a binding with the role viewer", e.getMessage()); + assertEquals("The policy already contains a binding with the role viewer.", e.getMessage()); } try { SIMPLE_POLICY.toBuilder().addBinding("editor", ImmutableSet.of(USER)); fail("Should have failed due to duplicate role."); } catch (IllegalArgumentException e) { - assertEquals("The policy already contains a binding with the role editor", e.getMessage()); + assertEquals("The policy already contains a binding with the role editor.", e.getMessage()); } } @Test public void testEqualsHashCode() { - assertNotEquals(FULL_POLICY, null); + assertNotNull(FULL_POLICY); PolicyImpl emptyPolicy = PolicyImpl.builder().build(); AnotherPolicyImpl anotherPolicy = new AnotherPolicyImpl.Builder().build(); assertNotEquals(emptyPolicy, anotherPolicy); @@ -151,7 +153,7 @@ public void testEtag() { @Test public void testVersion() { assertNull(SIMPLE_POLICY.version()); - assertEquals(null, SIMPLE_POLICY.version()); + assertEquals(1, FULL_POLICY.version().intValue()); } static class AnotherPolicyImpl extends IamPolicy { @@ -169,5 +171,10 @@ public AnotherPolicyImpl build() { AnotherPolicyImpl(Builder builder) { super(builder); } + + @Override + public Builder toBuilder() { + return new Builder(); + } } } diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java index 09cbfa1db554..0d7118dcbbd7 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java @@ -17,6 +17,7 @@ package com.google.gcloud.resourcemanager; import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.CaseFormat; import com.google.common.base.Function; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; @@ -40,19 +41,59 @@ * * @see Policy */ -public class Policy extends IamPolicy { +public class Policy extends IamPolicy { private static final long serialVersionUID = -5573557282693961850L; + /** + * Represents legacy roles in an IAM Policy. + */ + public enum Role { + + /** + * Permissions for read-only actions that preserve state. + */ + VIEWER("roles/viewer"), + + /** + * All viewer permissions and permissions for actions that modify state. + */ + EDITOR("roles/editor"), + + /** + * All editor permissions and permissions for the following actions: + *
      + *
    • Manage access control for a resource. + *
    • Set up billing (for a project). + *
    + */ + OWNER("roles/owner"); + + private String strValue; + + private Role(String strValue) { + this.strValue = strValue; + } + + String strValue() { + return strValue; + } + + static Role fromStr(String roleStr) { + return Role.valueOf(CaseFormat.LOWER_CAMEL.to( + CaseFormat.UPPER_UNDERSCORE, roleStr.substring("roles/".length()))); + } + } + /** * Builder for an IAM Policy. */ - public static class Builder extends IamPolicy.Builder { + public static class Builder extends IamPolicy.Builder { private Builder() {} @VisibleForTesting - Builder(Map> bindings, String etag, Integer version) { + Builder(Map> bindings, String etag, Integer version) { bindings(bindings).etag(etag).version(version); } @@ -70,6 +111,7 @@ public static Builder builder() { return new Builder(); } + @Override public Builder toBuilder() { return new Builder(bindings(), etag(), version()); } @@ -79,10 +121,10 @@ com.google.api.services.cloudresourcemanager.model.Policy toPb() { new com.google.api.services.cloudresourcemanager.model.Policy(); List bindingPbList = new LinkedList<>(); - for (Map.Entry> binding : bindings().entrySet()) { + for (Map.Entry> binding : bindings().entrySet()) { com.google.api.services.cloudresourcemanager.model.Binding bindingPb = new com.google.api.services.cloudresourcemanager.model.Binding(); - bindingPb.setRole("roles/" + binding.getKey()); + bindingPb.setRole(binding.getKey().strValue()); bindingPb.setMembers( Lists.transform( new ArrayList<>(binding.getValue()), @@ -102,11 +144,11 @@ public String apply(Identity identity) { static Policy fromPb( com.google.api.services.cloudresourcemanager.model.Policy policyPb) { - Map> bindings = new HashMap<>(); + Map> bindings = new HashMap<>(); for (com.google.api.services.cloudresourcemanager.model.Binding bindingPb : policyPb.getBindings()) { bindings.put( - bindingPb.getRole().substring("roles/".length()), + Role.fromStr(bindingPb.getRole()), ImmutableSet.copyOf( Lists.transform( bindingPb.getMembers(), diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/PolicyTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/PolicyTest.java index 3383eebf470c..05d1b85bdbed 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/PolicyTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/PolicyTest.java @@ -33,8 +33,8 @@ public class PolicyTest { private static final Identity GROUP = Identity.group("group@gmail.com"); private static final Identity DOMAIN = Identity.domain("google.com"); private static final Policy SIMPLE_POLICY = Policy.builder() - .addBinding("viewer", ImmutableSet.of(USER, SERVICE_ACCOUNT, ALL_USERS)) - .addBinding("editor", ImmutableSet.of(ALL_AUTH_USERS, GROUP, DOMAIN)) + .addBinding(Policy.Role.VIEWER, ImmutableSet.of(USER, SERVICE_ACCOUNT, ALL_USERS)) + .addBinding(Policy.Role.EDITOR, ImmutableSet.of(ALL_AUTH_USERS, GROUP, DOMAIN)) .build(); private static final Policy FULL_POLICY = new Policy.Builder(SIMPLE_POLICY.bindings(), "etag", 1).build(); diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java index 99c0fd7572c0..35b72ae1713f 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java @@ -56,7 +56,7 @@ public class SerializationTest { private static final ResourceManager.ProjectListOption PROJECT_LIST_OPTION = ResourceManager.ProjectListOption.filter("name:*"); private static final Policy POLICY = Policy.builder() - .addBinding("viewer", ImmutableSet.of(Identity.user("abc@gmail.com"))) + .addBinding(Policy.Role.VIEWER, ImmutableSet.of(Identity.user("abc@gmail.com"))) .build(); @Test From 75269ff6a0b2b8518ad4dc562905089c20236412 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Fri, 26 Feb 2016 18:21:53 -0500 Subject: [PATCH 118/375] Removed unnecessary integration tests. Adjusted deleting objects. --- .../java/com/google/gcloud/dns/ITDnsTest.java | 1763 +++++++---------- 1 file changed, 700 insertions(+), 1063 deletions(-) diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ITDnsTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ITDnsTest.java index 07475c52cfda..e473d1c4912c 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ITDnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ITDnsTest.java @@ -26,10 +26,11 @@ import com.google.common.collect.ImmutableList; import com.google.gcloud.Page; -import org.junit.After; import org.junit.AfterClass; import org.junit.BeforeClass; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.Timeout; import java.util.Iterator; import java.util.LinkedList; @@ -41,7 +42,6 @@ public class ITDnsTest { // todo(mderka) Implement test for creating invalid change when DnsException is finished. #673 - public static final int TIME_LIMIT = 10; public static final String PREFIX = "gcldjvit-"; public static final Dns DNS = DnsOptions.builder().build().service(); public static final String PROJECT_ID = DNS.options().projectId(); @@ -80,16 +80,16 @@ public class ITDnsTest { .description(ZONE_DESCRIPTION1) .dnsName(ZONE_DNS_NAME_NO_PERIOD) .build(); - public static final DnsRecord A_RECORD_ZONE1 = DnsRecord - .builder("www." + ZONE1.dnsName(), DnsRecord.Type.A) - .records(ImmutableList.of("123.123.55.1")) - .ttl(25, TimeUnit.SECONDS) - .build(); - public static final DnsRecord AAAA_RECORD_ZONE1 = DnsRecord - .builder("www." + ZONE1.dnsName(), DnsRecord.Type.AAAA) - .records(ImmutableList.of("ed:ed:12:aa:36:3:3:105")) - .ttl(25, TimeUnit.SECONDS) - .build(); + public static final DnsRecord A_RECORD_ZONE1 = + DnsRecord.builder("www." + ZONE1.dnsName(), DnsRecord.Type.A) + .records(ImmutableList.of("123.123.55.1")) + .ttl(25, TimeUnit.SECONDS) + .build(); + public static final DnsRecord AAAA_RECORD_ZONE1 = + DnsRecord.builder("www." + ZONE1.dnsName(), DnsRecord.Type.AAAA) + .records(ImmutableList.of("ed:ed:12:aa:36:3:3:105")) + .ttl(25, TimeUnit.SECONDS) + .build(); public static final ChangeRequest CHANGE_ADD_ZONE1 = ChangeRequest.builder() .add(A_RECORD_ZONE1) .add(AAAA_RECORD_ZONE1) @@ -99,7 +99,7 @@ public class ITDnsTest { .delete(AAAA_RECORD_ZONE1) .build(); - public static void purge() { + public static void clear() { Page zones = DNS.listZones(); Iterator zoneIterator = zones.iterateAll(); while (zoneIterator.hasNext()) { @@ -114,7 +114,9 @@ public static void purge() { } } if (!toDelete.isEmpty()) { - zone.applyChangeRequest(ChangeRequest.builder().deletions(toDelete).build()); + ChangeRequest deletion = + zone.applyChangeRequest(ChangeRequest.builder().deletions(toDelete).build()); + checkChangeComplete(zone.name(), deletion.id()); } zone.delete(); } @@ -134,868 +136,617 @@ private static List filter(Iterator iterator) { @BeforeClass public static void before() { - purge(); + clear(); } @AfterClass public static void after() { - purge(); + clear(); } - @Test - public void testCreateValidZone() { - Zone created = DNS.create(ZONE1); - assertEquals(ZONE1.description(), created.description()); - assertEquals(ZONE1.dnsName(), created.dnsName()); - assertEquals(ZONE1.name(), created.name()); - assertNotNull(created.creationTimeMillis()); - assertNotNull(created.nameServers()); - assertNull(created.nameServerSet()); - assertNotNull(created.id()); - Zone retrieved = DNS.getZone(ZONE1.name()); - assertEquals(created, retrieved); - created = DNS.create(ZONE_EMPTY_DESCRIPTION); - assertEquals(ZONE_EMPTY_DESCRIPTION.description(), created.description()); - assertEquals(ZONE_EMPTY_DESCRIPTION.dnsName(), created.dnsName()); - assertEquals(ZONE_EMPTY_DESCRIPTION.name(), created.name()); - assertNotNull(created.creationTimeMillis()); - assertNotNull(created.nameServers()); - assertNull(created.nameServerSet()); - assertNotNull(created.id()); - retrieved = DNS.getZone(ZONE_EMPTY_DESCRIPTION.name()); - assertEquals(created, retrieved); + private static void assertEqChangesIgnoreStatus(ChangeRequest expected, ChangeRequest actual) { + ChangeRequest unifiedEx = ChangeRequest.fromPb(expected.toPb().setStatus("pending")); + ChangeRequest unifiedAct = ChangeRequest.fromPb(actual.toPb().setStatus("pending")); + assertEquals(unifiedEx, unifiedAct); } - @After - public void tearDown() { - purge(); + private static void checkChangeComplete(String zoneName, String changeId) { + while (true) { + ChangeRequest changeRequest = DNS.getChangeRequest(zoneName, changeId, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); + if (ChangeRequest.Status.DONE.equals(changeRequest.status())) { + break; + } + } } + @Rule + public Timeout globalTimeout = Timeout.seconds(300); + @Test - public void testCreateZoneWithErrors() { - try { - DNS.create(ZONE_MISSING_DNS_NAME); - fail("Zone is missing DNS name. The service returns an error."); - } catch (DnsException ex) { - // expected - // todo(mderka) test non-retryable when implemented within #593 - } - try { - DNS.create(ZONE_MISSING_DESCRIPTION); - fail("Zone is missing description name. The service returns an error."); - } catch (DnsException ex) { - // expected - // todo(mderka) test non-retryable when implemented within #593 - } - try { - DNS.create(ZONE_NAME_ERROR); - fail("Zone name is missing a period. The service returns an error."); - } catch (DnsException ex) { - // expected - // todo(mderka) test non-retryable when implemented within #593 - } + public void testCreateValidZone() { try { - DNS.create(ZONE_DNS_NO_PERIOD); - fail("Zone name is missing a period. The service returns an error."); - } catch (DnsException ex) { - // expected - // todo(mderka) test non-retryable when implemented within #593 + Zone created = DNS.create(ZONE1); + assertEquals(ZONE1.description(), created.description()); + assertEquals(ZONE1.dnsName(), created.dnsName()); + assertEquals(ZONE1.name(), created.name()); + assertNotNull(created.creationTimeMillis()); + assertNotNull(created.nameServers()); + assertNull(created.nameServerSet()); + assertNotNull(created.id()); + Zone retrieved = DNS.getZone(ZONE1.name()); + assertEquals(created, retrieved); + created = DNS.create(ZONE_EMPTY_DESCRIPTION); + assertEquals(ZONE_EMPTY_DESCRIPTION.description(), created.description()); + assertEquals(ZONE_EMPTY_DESCRIPTION.dnsName(), created.dnsName()); + assertEquals(ZONE_EMPTY_DESCRIPTION.name(), created.name()); + assertNotNull(created.creationTimeMillis()); + assertNotNull(created.nameServers()); + assertNull(created.nameServerSet()); + assertNotNull(created.id()); + retrieved = DNS.getZone(ZONE_EMPTY_DESCRIPTION.name()); + assertEquals(created, retrieved); + } finally { + DNS.delete(ZONE1.name()); + DNS.delete(ZONE_EMPTY_DESCRIPTION.name()); } } @Test - public void testCreateZoneWithOptions() { - Zone created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.CREATION_TIME)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNotNull(created.creationTimeMillis()); - assertNull(created.description()); - assertNull(created.dnsName()); - assertTrue(created.nameServers().isEmpty()); // never returns null - assertNull(created.nameServerSet()); - assertNull(created.id()); - created.delete(); - created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.DESCRIPTION)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNull(created.creationTimeMillis()); - assertEquals(ZONE1.description(), created.description()); - assertNull(created.dnsName()); - assertTrue(created.nameServers().isEmpty()); // never returns null - assertNull(created.nameServerSet()); - assertNull(created.id()); - created.delete(); - created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.DNS_NAME)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNull(created.creationTimeMillis()); - assertEquals(ZONE1.dnsName(), created.dnsName()); - assertNull(created.description()); - assertTrue(created.nameServers().isEmpty()); // never returns null - assertNull(created.nameServerSet()); - assertNull(created.id()); - created.delete(); - created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNull(created.creationTimeMillis()); - assertNull(created.dnsName()); - assertNull(created.description()); - assertTrue(created.nameServers().isEmpty()); // never returns null - assertNull(created.nameServerSet()); - assertNull(created.id()); - created.delete(); - created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVER_SET)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNull(created.creationTimeMillis()); - assertNull(created.dnsName()); - assertNull(created.description()); - assertTrue(created.nameServers().isEmpty()); // never returns null - assertNull(created.nameServerSet()); // we did not set it - assertNull(created.id()); - created.delete(); - created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVERS)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNull(created.creationTimeMillis()); - assertNull(created.dnsName()); - assertNull(created.description()); - assertFalse(created.nameServers().isEmpty()); - assertNull(created.nameServerSet()); - assertNull(created.id()); - created.delete(); - created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNull(created.creationTimeMillis()); - assertNull(created.dnsName()); - assertNull(created.description()); - assertNotNull(created.nameServers()); - assertTrue(created.nameServers().isEmpty()); // never returns null - assertNotNull(created.id()); - created.delete(); - // combination of multiple things - created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID, - Dns.ZoneField.NAME_SERVERS, Dns.ZoneField.NAME_SERVER_SET, Dns.ZoneField.DESCRIPTION)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNull(created.creationTimeMillis()); - assertNull(created.dnsName()); - assertEquals(ZONE1.description(), created.description()); - assertFalse(created.nameServers().isEmpty()); - assertNull(created.nameServerSet()); // we did not set it - assertNotNull(created.id()); + public void testCreateZoneWithErrors() { + try { + try { + DNS.create(ZONE_MISSING_DNS_NAME); + fail("Zone is missing DNS name. The service returns an error."); + } catch (DnsException ex) { + // expected + // todo(mderka) test non-retryable when implemented within #593 + } + try { + DNS.create(ZONE_MISSING_DESCRIPTION); + fail("Zone is missing description name. The service returns an error."); + } catch (DnsException ex) { + // expected + // todo(mderka) test non-retryable when implemented within #593 + } + try { + DNS.create(ZONE_NAME_ERROR); + fail("Zone name is missing a period. The service returns an error."); + } catch (DnsException ex) { + // expected + // todo(mderka) test non-retryable when implemented within #593 + } + try { + DNS.create(ZONE_DNS_NO_PERIOD); + fail("Zone name is missing a period. The service returns an error."); + } catch (DnsException ex) { + // expected + // todo(mderka) test non-retryable when implemented within #593 + } + } finally { + DNS.delete(ZONE_MISSING_DNS_NAME.name()); + DNS.delete(ZONE_MISSING_DESCRIPTION.name()); + DNS.delete(ZONE_NAME_ERROR.name()); + DNS.delete(ZONE_DNS_NO_PERIOD.name()); + } } @Test - public void testZoneReload() { - Zone created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); - created = created.reload(Dns.ZoneOption.fields(Dns.ZoneField.CREATION_TIME)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNotNull(created.creationTimeMillis()); - assertNull(created.description()); - assertNull(created.dnsName()); - assertTrue(created.nameServers().isEmpty()); // never returns null - assertNull(created.nameServerSet()); - assertNull(created.id()); - created = created.reload(Dns.ZoneOption.fields(Dns.ZoneField.DESCRIPTION)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNull(created.creationTimeMillis()); - assertEquals(ZONE1.description(), created.description()); - assertNull(created.dnsName()); - assertTrue(created.nameServers().isEmpty()); // never returns null - assertNull(created.nameServerSet()); - assertNull(created.id()); - created = created.reload(Dns.ZoneOption.fields(Dns.ZoneField.DNS_NAME)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNull(created.creationTimeMillis()); - assertEquals(ZONE1.dnsName(), created.dnsName()); - assertNull(created.description()); - assertTrue(created.nameServers().isEmpty()); // never returns null - assertNull(created.nameServerSet()); - assertNull(created.id()); - created = created.reload(Dns.ZoneOption.fields(Dns.ZoneField.NAME)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNull(created.creationTimeMillis()); - assertNull(created.dnsName()); - assertNull(created.description()); - assertTrue(created.nameServers().isEmpty()); // never returns null - assertNull(created.nameServerSet()); - assertNull(created.id()); - created = created.reload(Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVER_SET)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNull(created.creationTimeMillis()); - assertNull(created.dnsName()); - assertNull(created.description()); - assertTrue(created.nameServers().isEmpty()); // never returns null - assertNull(created.nameServerSet()); // we did not set it - assertNull(created.id()); - created = created.reload(Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVERS)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNull(created.creationTimeMillis()); - assertNull(created.dnsName()); - assertNull(created.description()); - assertFalse(created.nameServers().isEmpty()); - assertNull(created.nameServerSet()); - assertNull(created.id()); - created = created.reload(Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNull(created.creationTimeMillis()); - assertNull(created.dnsName()); - assertNull(created.description()); - assertNotNull(created.nameServers()); - assertTrue(created.nameServers().isEmpty()); // never returns null - assertNotNull(created.id()); - // combination of multiple things - created = created.reload(Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID, - Dns.ZoneField.NAME_SERVERS, Dns.ZoneField.NAME_SERVER_SET, Dns.ZoneField.DESCRIPTION)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNull(created.creationTimeMillis()); - assertNull(created.dnsName()); - assertEquals(ZONE1.description(), created.description()); - assertFalse(created.nameServers().isEmpty()); - assertNull(created.nameServerSet()); // we did not set it - assertNotNull(created.id()); + public void testCreateZoneWithOptions() { + try { + Zone created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.CREATION_TIME)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNotNull(created.creationTimeMillis()); + assertNull(created.description()); + assertNull(created.dnsName()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created.delete(); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.DESCRIPTION)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertEquals(ZONE1.description(), created.description()); + assertNull(created.dnsName()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created.delete(); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.DNS_NAME)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertEquals(ZONE1.dnsName(), created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created.delete(); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created.delete(); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVER_SET)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); // we did not set it + assertNull(created.id()); + created.delete(); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVERS)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertFalse(created.nameServers().isEmpty()); + assertNull(created.nameServerSet()); + assertNull(created.id()); + created.delete(); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertNotNull(created.nameServers()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNotNull(created.id()); + created.delete(); + // combination of multiple things + created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID, + Dns.ZoneField.NAME_SERVERS, Dns.ZoneField.NAME_SERVER_SET, Dns.ZoneField.DESCRIPTION)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertEquals(ZONE1.description(), created.description()); + assertFalse(created.nameServers().isEmpty()); + assertNull(created.nameServerSet()); // we did not set it + assertNotNull(created.id()); + } finally { + DNS.delete(ZONE1.name()); + } } @Test public void testGetZone() { - DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); - Zone created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.CREATION_TIME)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNotNull(created.creationTimeMillis()); - assertNull(created.description()); - assertNull(created.dnsName()); - assertTrue(created.nameServers().isEmpty()); // never returns null - assertNull(created.nameServerSet()); - assertNull(created.id()); - created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.DESCRIPTION)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNull(created.creationTimeMillis()); - assertEquals(ZONE1.description(), created.description()); - assertNull(created.dnsName()); - assertTrue(created.nameServers().isEmpty()); // never returns null - assertNull(created.nameServerSet()); - assertNull(created.id()); - created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.DNS_NAME)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNull(created.creationTimeMillis()); - assertEquals(ZONE1.dnsName(), created.dnsName()); - assertNull(created.description()); - assertTrue(created.nameServers().isEmpty()); // never returns null - assertNull(created.nameServerSet()); - assertNull(created.id()); - created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.NAME)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNull(created.creationTimeMillis()); - assertNull(created.dnsName()); - assertNull(created.description()); - assertTrue(created.nameServers().isEmpty()); // never returns null - assertNull(created.nameServerSet()); - assertNull(created.id()); - created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVER_SET)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNull(created.creationTimeMillis()); - assertNull(created.dnsName()); - assertNull(created.description()); - assertTrue(created.nameServers().isEmpty()); // never returns null - assertNull(created.nameServerSet()); // we did not set it - assertNull(created.id()); - created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVERS)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNull(created.creationTimeMillis()); - assertNull(created.dnsName()); - assertNull(created.description()); - assertFalse(created.nameServers().isEmpty()); - assertNull(created.nameServerSet()); - assertNull(created.id()); - created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNull(created.creationTimeMillis()); - assertNull(created.dnsName()); - assertNull(created.description()); - assertNotNull(created.nameServers()); - assertTrue(created.nameServers().isEmpty()); // never returns null - assertNotNull(created.id()); - // combination of multiple things - created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID, - Dns.ZoneField.NAME_SERVERS, Dns.ZoneField.NAME_SERVER_SET, Dns.ZoneField.DESCRIPTION)); - assertEquals(ZONE1.name(), created.name()); // always returned - assertNull(created.creationTimeMillis()); - assertNull(created.dnsName()); - assertEquals(ZONE1.description(), created.description()); - assertFalse(created.nameServers().isEmpty()); - assertNull(created.nameServerSet()); // we did not set it - assertNotNull(created.id()); + try { + DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); + Zone created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.CREATION_TIME)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNotNull(created.creationTimeMillis()); + assertNull(created.description()); + assertNull(created.dnsName()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.DESCRIPTION)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertEquals(ZONE1.description(), created.description()); + assertNull(created.dnsName()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.DNS_NAME)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertEquals(ZONE1.dnsName(), created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.NAME)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVER_SET)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); // we did not set it + assertNull(created.id()); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVERS)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertFalse(created.nameServers().isEmpty()); + assertNull(created.nameServerSet()); + assertNull(created.id()); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertNotNull(created.nameServers()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNotNull(created.id()); + // combination of multiple things + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID, + Dns.ZoneField.NAME_SERVERS, Dns.ZoneField.NAME_SERVER_SET, Dns.ZoneField.DESCRIPTION)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertEquals(ZONE1.description(), created.description()); + assertFalse(created.nameServers().isEmpty()); + assertNull(created.nameServerSet()); // we did not set it + assertNotNull(created.id()); + } finally { + DNS.delete(ZONE1.name()); + } } @Test public void testListZones() { - List zones = filter(DNS.listZones().iterateAll()); - assertEquals(0, zones.size()); - // some zones exists - Zone created = DNS.create(ZONE1); - zones = filter(DNS.listZones().iterateAll()); - assertEquals(created, zones.get(0)); - assertEquals(1, zones.size()); - created = DNS.create(ZONE_EMPTY_DESCRIPTION); - zones = filter(DNS.listZones().iterateAll()); - assertEquals(2, zones.size()); - assertTrue(zones.contains(created)); - // error in options - try { - DNS.listZones(Dns.ZoneListOption.pageSize(0)); - } catch (DnsException ex) { - // expected - assertEquals(400, ex.code()); - // todo(mderka) test not-retryable - } - try { - DNS.listZones(Dns.ZoneListOption.pageSize(-1)); - } catch (DnsException ex) { - // expected - assertEquals(400, ex.code()); - // todo(mderka) test not-retryable - } - // ok size - zones = filter(DNS.listZones(Dns.ZoneListOption.pageSize(1000)).iterateAll()); - assertEquals(2, zones.size()); // we still have only 2 zones - // dns name problems try { - DNS.listZones(Dns.ZoneListOption.dnsName("aaaaa")); - } catch (DnsException ex) { - // expected - assertEquals(400, ex.code()); - // todo(mderka) test not-retryable - } - // ok name - zones = filter(DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName())).iterateAll()); - assertEquals(1, zones.size()); - // field options - zones = ImmutableList.copyOf(DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), - Dns.ZoneListOption.fields(Dns.ZoneField.ZONE_ID)).iterateAll()); - assertEquals(1, zones.size()); - Zone zone = zones.get(0); - assertNull(zone.creationTimeMillis()); - assertNotNull(zone.name()); - assertNull(zone.dnsName()); - assertNull(zone.description()); - assertNull(zone.nameServerSet()); - assertTrue(zone.nameServers().isEmpty()); - assertNotNull(zone.id()); - zones = ImmutableList.copyOf(DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), - Dns.ZoneListOption.fields(Dns.ZoneField.CREATION_TIME)).iterateAll()); - assertEquals(1, zones.size()); - zone = zones.get(0); - assertNotNull(zone.creationTimeMillis()); - assertNotNull(zone.name()); - assertNull(zone.dnsName()); - assertNull(zone.description()); - assertNull(zone.nameServerSet()); - assertTrue(zone.nameServers().isEmpty()); - assertNull(zone.id()); - zones = ImmutableList.copyOf(DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), - Dns.ZoneListOption.fields(Dns.ZoneField.DNS_NAME)).iterateAll()); - assertEquals(1, zones.size()); - zone = zones.get(0); - assertNull(zone.creationTimeMillis()); - assertNotNull(zone.name()); - assertNotNull(zone.dnsName()); - assertNull(zone.description()); - assertNull(zone.nameServerSet()); - assertTrue(zone.nameServers().isEmpty()); - assertNull(zone.id()); - zones = ImmutableList.copyOf(DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), - Dns.ZoneListOption.fields(Dns.ZoneField.DESCRIPTION)).iterateAll()); - assertEquals(1, zones.size()); - zone = zones.get(0); - assertNull(zone.creationTimeMillis()); - assertNotNull(zone.name()); - assertNull(zone.dnsName()); - assertNotNull(zone.description()); - assertNull(zone.nameServerSet()); - assertTrue(zone.nameServers().isEmpty()); - assertNull(zone.id()); - zones = ImmutableList.copyOf(DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), - Dns.ZoneListOption.fields(Dns.ZoneField.NAME_SERVERS)).iterateAll()); - assertEquals(1, zones.size()); - zone = zones.get(0); - assertNull(zone.creationTimeMillis()); - assertNotNull(zone.name()); - assertNull(zone.dnsName()); - assertNull(zone.description()); - assertNull(zone.nameServerSet()); - assertTrue(!zone.nameServers().isEmpty()); - assertNull(zone.id()); - zones = ImmutableList.copyOf(DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), - Dns.ZoneListOption.fields(Dns.ZoneField.NAME_SERVER_SET)).iterateAll()); - assertEquals(1, zones.size()); - zone = zones.get(0); - assertNull(zone.creationTimeMillis()); - assertNotNull(zone.name()); - assertNull(zone.dnsName()); - assertNull(zone.description()); - assertNull(zone.nameServerSet()); // we cannot set it using gcloud java - assertTrue(zone.nameServers().isEmpty()); - assertNull(zone.id()); - // several combined - zones = filter(DNS.listZones(Dns.ZoneListOption.fields(Dns.ZoneField.ZONE_ID, - Dns.ZoneField.DESCRIPTION), - Dns.ZoneListOption.pageSize(1)).iterateAll()); - assertEquals(2, zones.size()); - for (Zone current : zones) { - assertNull(current.creationTimeMillis()); - assertNotNull(current.name()); - assertNull(current.dnsName()); - assertNotNull(current.description()); - assertNull(current.nameServerSet()); + List zones = filter(DNS.listZones().iterateAll()); + assertEquals(0, zones.size()); + // some zones exists + Zone created = DNS.create(ZONE1); + zones = filter(DNS.listZones().iterateAll()); + assertEquals(created, zones.get(0)); + assertEquals(1, zones.size()); + created = DNS.create(ZONE_EMPTY_DESCRIPTION); + zones = filter(DNS.listZones().iterateAll()); + assertEquals(2, zones.size()); + assertTrue(zones.contains(created)); + // error in options + try { + DNS.listZones(Dns.ZoneListOption.pageSize(0)); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test not-retryable + } + try { + DNS.listZones(Dns.ZoneListOption.pageSize(-1)); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test not-retryable + } + // ok size + zones = filter(DNS.listZones(Dns.ZoneListOption.pageSize(1000)).iterateAll()); + assertEquals(2, zones.size()); // we still have only 2 zones + // dns name problems + try { + DNS.listZones(Dns.ZoneListOption.dnsName("aaaaa")); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test not-retryable + } + // ok name + zones = filter(DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName())).iterateAll()); + assertEquals(1, zones.size()); + // field options + Iterator zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(Dns.ZoneField.ZONE_ID)).iterateAll(); + Zone zone = zoneIterator.next(); + assertNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNull(zone.dnsName()); + assertNull(zone.description()); + assertNull(zone.nameServerSet()); assertTrue(zone.nameServers().isEmpty()); - assertNotNull(current.id()); - } - } - - @Test - public void testDeleteZoneUsingServiceObject() { - Zone created = DNS.create(ZONE1); - assertEquals(created, DNS.getZone(ZONE1.name())); - DNS.delete(ZONE1.name()); - assertNull(DNS.getZone(ZONE1.name())); - } - - @Test - public void testDeleteZoneUsingZoneObject() { - Zone created = DNS.create(ZONE1); - assertEquals(created, DNS.getZone(ZONE1.name())); - created.delete(); - assertNull(DNS.getZone(ZONE1.name())); - } - - private void assertEqChangesIgnoreStatus(ChangeRequest expected, ChangeRequest actual) { - ChangeRequest unifiedEx = ChangeRequest.fromPb(expected.toPb().setStatus("pending")); - ChangeRequest unifiedAct = ChangeRequest.fromPb(actual.toPb().setStatus("pending")); - assertEquals(unifiedEx, unifiedAct); - } - - private static void checkChangeComplete(String zoneName, String changeId) { - for (int i = 0; i < TIME_LIMIT; i++) { - ChangeRequest changeRequest = DNS.getChangeRequest(zoneName, changeId, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); - if (ChangeRequest.Status.DONE.equals(changeRequest.status())) { - break; - } else { - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - throw new RuntimeException("Thread was interrupted while waiting for change."); - } + assertNotNull(zone.id()); + assertFalse(zoneIterator.hasNext()); + zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(Dns.ZoneField.CREATION_TIME)).iterateAll(); + zone = zoneIterator.next(); + assertNotNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNull(zone.dnsName()); + assertNull(zone.description()); + assertNull(zone.nameServerSet()); + assertTrue(zone.nameServers().isEmpty()); + assertNull(zone.id()); + assertFalse(zoneIterator.hasNext()); + zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(Dns.ZoneField.DNS_NAME)).iterateAll(); + zone = zoneIterator.next(); + assertNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNotNull(zone.dnsName()); + assertNull(zone.description()); + assertNull(zone.nameServerSet()); + assertTrue(zone.nameServers().isEmpty()); + assertNull(zone.id()); + assertFalse(zoneIterator.hasNext()); + zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(Dns.ZoneField.DESCRIPTION)).iterateAll(); + zone = zoneIterator.next(); + assertNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNull(zone.dnsName()); + assertNotNull(zone.description()); + assertNull(zone.nameServerSet()); + assertTrue(zone.nameServers().isEmpty()); + assertNull(zone.id()); + assertFalse(zoneIterator.hasNext()); + zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(Dns.ZoneField.NAME_SERVERS)).iterateAll(); + zone = zoneIterator.next(); + assertNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNull(zone.dnsName()); + assertNull(zone.description()); + assertNull(zone.nameServerSet()); + assertTrue(!zone.nameServers().isEmpty()); + assertNull(zone.id()); + assertFalse(zoneIterator.hasNext()); + zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(Dns.ZoneField.NAME_SERVER_SET)).iterateAll(); + zone = zoneIterator.next(); + assertNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNull(zone.dnsName()); + assertNull(zone.description()); + assertNull(zone.nameServerSet()); // we cannot set it using gcloud java + assertTrue(zone.nameServers().isEmpty()); + assertNull(zone.id()); + assertFalse(zoneIterator.hasNext()); + // several combined + zones = filter(DNS.listZones(Dns.ZoneListOption.fields(Dns.ZoneField.ZONE_ID, + Dns.ZoneField.DESCRIPTION), + Dns.ZoneListOption.pageSize(1)).iterateAll()); + assertEquals(2, zones.size()); + for (Zone current : zones) { + assertNull(current.creationTimeMillis()); + assertNotNull(current.name()); + assertNull(current.dnsName()); + assertNotNull(current.description()); + assertNull(current.nameServerSet()); + assertTrue(zone.nameServers().isEmpty()); + assertNotNull(current.id()); } + } finally { + DNS.delete(ZONE1.name()); + DNS.delete(ZONE_EMPTY_DESCRIPTION.name()); } } @Test - public void testCreateChangeUsingServiceObject() { - DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); - ChangeRequest created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); - assertEquals(CHANGE_ADD_ZONE1.additions(), created.additions()); - assertNotNull(created.startTimeMillis()); - assertTrue(created.deletions().isEmpty()); - assertEquals("1", created.id()); - assertTrue(ImmutableList.of(ChangeRequest.Status.PENDING, ChangeRequest.Status.DONE) - .contains(created.status())); - assertEqChangesIgnoreStatus(created, DNS.getChangeRequest(ZONE1.name(), "1")); - checkChangeComplete(ZONE1.name(), "1"); - DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - checkChangeComplete(ZONE1.name(), "2"); - // with options - created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); - assertTrue(created.additions().isEmpty()); - assertNull(created.startTimeMillis()); - assertTrue(created.deletions().isEmpty()); - assertEquals("3", created.id()); - assertNull(created.status()); - checkChangeComplete(ZONE1.name(), "3"); - DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - checkChangeComplete(ZONE1.name(), "4"); - created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); - assertTrue(created.additions().isEmpty()); - assertNull(created.startTimeMillis()); - assertTrue(created.deletions().isEmpty()); - assertEquals("5", created.id()); - assertNotNull(created.status()); - checkChangeComplete(ZONE1.name(), "5"); - DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - checkChangeComplete(ZONE1.name(), "6"); - created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); - assertTrue(created.additions().isEmpty()); - assertNotNull(created.startTimeMillis()); - assertTrue(created.deletions().isEmpty()); - assertEquals("7", created.id()); - assertNull(created.status()); - checkChangeComplete(ZONE1.name(), "7"); - DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - checkChangeComplete(ZONE1.name(), "8"); - created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); - assertEquals(CHANGE_ADD_ZONE1.additions(), created.additions()); - assertNull(created.startTimeMillis()); - assertTrue(created.deletions().isEmpty()); - assertEquals("9", created.id()); - assertNull(created.status()); - // finishes with delete otherwise we cannot delete the zone - checkChangeComplete(ZONE1.name(), "9"); - created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); - checkChangeComplete(ZONE1.name(), "10"); - assertEquals(CHANGE_DELETE_ZONE1.deletions(), created.deletions()); - assertNull(created.startTimeMillis()); - assertTrue(created.additions().isEmpty()); - assertEquals("10", created.id()); - assertNull(created.status()); - checkChangeComplete(ZONE1.name(), "10"); + public void testDeleteZone() { + try { + Zone created = DNS.create(ZONE1); + assertEquals(created, DNS.getZone(ZONE1.name())); + DNS.delete(ZONE1.name()); + assertNull(DNS.getZone(ZONE1.name())); + } finally { + DNS.delete(ZONE1.name()); + } } - @Test - public void testCreateChangeUsingZoneObject() { - Zone zone = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); - ChangeRequest created = zone.applyChangeRequest(CHANGE_ADD_ZONE1); - assertEquals(CHANGE_ADD_ZONE1.additions(), created.additions()); - assertNotNull(created.startTimeMillis()); - assertTrue(created.deletions().isEmpty()); - assertEquals("1", created.id()); - assertTrue(ImmutableList.of(ChangeRequest.Status.PENDING, ChangeRequest.Status.DONE) - .contains(created.status())); - assertEqChangesIgnoreStatus(created, DNS.getChangeRequest(ZONE1.name(), "1")); - checkChangeComplete(ZONE1.name(), "1"); - zone.applyChangeRequest(CHANGE_DELETE_ZONE1); - checkChangeComplete(ZONE1.name(), "2"); - // with options - created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); - assertTrue(created.additions().isEmpty()); - assertNull(created.startTimeMillis()); - assertTrue(created.deletions().isEmpty()); - assertEquals("3", created.id()); - assertNull(created.status()); - checkChangeComplete(ZONE1.name(), "3"); - zone.applyChangeRequest(CHANGE_DELETE_ZONE1); - checkChangeComplete(ZONE1.name(), "4"); - created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); - assertTrue(created.additions().isEmpty()); - assertNull(created.startTimeMillis()); - assertTrue(created.deletions().isEmpty()); - assertEquals("5", created.id()); - assertNotNull(created.status()); - checkChangeComplete(ZONE1.name(), "5"); - zone.applyChangeRequest(CHANGE_DELETE_ZONE1); - checkChangeComplete(ZONE1.name(), "6"); - created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); - assertTrue(created.additions().isEmpty()); - assertNotNull(created.startTimeMillis()); - assertTrue(created.deletions().isEmpty()); - assertEquals("7", created.id()); - assertNull(created.status()); - checkChangeComplete(ZONE1.name(), "7"); - zone.applyChangeRequest(CHANGE_DELETE_ZONE1); - checkChangeComplete(ZONE1.name(), "8"); - created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); - assertEquals(CHANGE_ADD_ZONE1.additions(), created.additions()); - assertNull(created.startTimeMillis()); - assertTrue(created.deletions().isEmpty()); - assertEquals("9", created.id()); - assertNull(created.status()); - // finishes with delete otherwise we cannot delete the zone - checkChangeComplete(ZONE1.name(), "9"); - created = zone.applyChangeRequest(CHANGE_DELETE_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); - checkChangeComplete(ZONE1.name(), "10"); - assertEquals(CHANGE_DELETE_ZONE1.deletions(), created.deletions()); - assertNull(created.startTimeMillis()); - assertTrue(created.additions().isEmpty()); - assertEquals("10", created.id()); - assertNull(created.status()); - checkChangeComplete(ZONE1.name(), "10"); - } @Test - public void testListChangesUsingService() { - // no such zone exists + public void testCreateChange() { try { - DNS.listChangeRequests(ZONE1.name()); - fail(); - } catch (DnsException ex) { - // expected - assertEquals(404, ex.code()); - // todo(mderka) test retry functionality - } - // zone exists but has no changes - DNS.create(ZONE1); - ImmutableList changes = ImmutableList.copyOf( - DNS.listChangeRequests(ZONE1.name()).iterateAll()); - assertEquals(1, changes.size()); // default change creating SOA and NS - // zone has changes - ChangeRequest change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); - checkChangeComplete(ZONE1.name(), change.id()); - change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - checkChangeComplete(ZONE1.name(), change.id()); - change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); - checkChangeComplete(ZONE1.name(), change.id()); - change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - checkChangeComplete(ZONE1.name(), change.id()); - changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name()).iterateAll()); - assertEquals(5, changes.size()); - // error in options - try { - DNS.listChangeRequests(ZONE1.name(), Dns.ChangeRequestListOption.pageSize(0)); - } catch (DnsException ex) { - // expected - assertEquals(400, ex.code()); - // todo(mderka) test retry functionality - } - try { - DNS.listChangeRequests(ZONE1.name(), Dns.ChangeRequestListOption.pageSize(-1)); - } catch (DnsException ex) { - // expected - assertEquals(400, ex.code()); - // todo(mderka) test retry functionality - } - // sorting order - ImmutableList ascending = ImmutableList.copyOf(DNS.listChangeRequests( - ZONE1.name(), - Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING)).iterateAll()); - ImmutableList descending = ImmutableList.copyOf(DNS.listChangeRequests( - ZONE1.name(), - Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.DESCENDING)).iterateAll()); - int size = 5; - assertEquals(size, descending.size()); - assertEquals(size, ascending.size()); - for (int i = 0; i < size; i++) { - assertEquals(descending.get(i), ascending.get(size - i - 1)); + DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); + ChangeRequest created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); + assertEquals(CHANGE_ADD_ZONE1.additions(), created.additions()); + assertNotNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertEquals("1", created.id()); + assertTrue(ImmutableList.of(ChangeRequest.Status.PENDING, ChangeRequest.Status.DONE) + .contains(created.status())); + assertEqChangesIgnoreStatus(created, DNS.getChangeRequest(ZONE1.name(), "1")); + checkChangeComplete(ZONE1.name(), "1"); + DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + checkChangeComplete(ZONE1.name(), "2"); + // with options + created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); + assertTrue(created.additions().isEmpty()); + assertNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertEquals("3", created.id()); + assertNull(created.status()); + checkChangeComplete(ZONE1.name(), "3"); + DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + checkChangeComplete(ZONE1.name(), "4"); + created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); + assertTrue(created.additions().isEmpty()); + assertNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertEquals("5", created.id()); + assertNotNull(created.status()); + checkChangeComplete(ZONE1.name(), "5"); + DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + checkChangeComplete(ZONE1.name(), "6"); + created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); + assertTrue(created.additions().isEmpty()); + assertNotNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertEquals("7", created.id()); + assertNull(created.status()); + checkChangeComplete(ZONE1.name(), "7"); + DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + checkChangeComplete(ZONE1.name(), "8"); + created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); + assertEquals(CHANGE_ADD_ZONE1.additions(), created.additions()); + assertNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertEquals("9", created.id()); + assertNull(created.status()); + // finishes with delete otherwise we cannot delete the zone + checkChangeComplete(ZONE1.name(), "9"); + created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); + checkChangeComplete(ZONE1.name(), "10"); + assertEquals(CHANGE_DELETE_ZONE1.deletions(), created.deletions()); + assertNull(created.startTimeMillis()); + assertTrue(created.additions().isEmpty()); + assertEquals("10", created.id()); + assertNull(created.status()); + checkChangeComplete(ZONE1.name(), "10"); + } finally { + clear(); } - // field options - changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), - Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), - Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.ADDITIONS)).iterateAll()); - change = changes.get(1); - assertEquals(CHANGE_ADD_ZONE1.additions(), change.additions()); - assertTrue(change.deletions().isEmpty()); - assertEquals("1", change.id()); - assertNull(change.startTimeMillis()); - assertNull(change.status()); - changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), - Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), - Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.DELETIONS)).iterateAll()); - change = changes.get(2); - assertTrue(change.additions().isEmpty()); - assertNotNull(change.deletions()); - assertEquals("2", change.id()); - assertNull(change.startTimeMillis()); - assertNull(change.status()); - changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), - Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), - Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.ID)).iterateAll()); - change = changes.get(1); - assertTrue(change.additions().isEmpty()); - assertTrue(change.deletions().isEmpty()); - assertEquals("1", change.id()); - assertNull(change.startTimeMillis()); - assertNull(change.status()); - changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), - Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), - Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.START_TIME)).iterateAll()); - change = changes.get(1); - assertTrue(change.additions().isEmpty()); - assertTrue(change.deletions().isEmpty()); - assertEquals("1", change.id()); - assertNotNull(change.startTimeMillis()); - assertNull(change.status()); - changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), - Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), - Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.STATUS)).iterateAll()); - change = changes.get(1); - assertTrue(change.additions().isEmpty()); - assertTrue(change.deletions().isEmpty()); - assertEquals("1", change.id()); - assertNull(change.startTimeMillis()); - assertEquals(ChangeRequest.Status.DONE, change.status()); } @Test - public void testListChangesUsingZoneObject() { - // zone exists but has no changes - Zone created = DNS.create(ZONE1); - ImmutableList changes = ImmutableList.copyOf( - created.listChangeRequests().iterateAll()); - assertEquals(1, changes.size()); // default change creating SOA and NS - // zone has changes - ChangeRequest change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); - checkChangeComplete(ZONE1.name(), change.id()); - change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - checkChangeComplete(ZONE1.name(), change.id()); - change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); - checkChangeComplete(ZONE1.name(), change.id()); - change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - checkChangeComplete(ZONE1.name(), change.id()); - changes = ImmutableList.copyOf(created.listChangeRequests().iterateAll()); - assertEquals(5, changes.size()); - // error in options - try { - created.listChangeRequests(Dns.ChangeRequestListOption.pageSize(0)); - } catch (DnsException ex) { - // expected - assertEquals(400, ex.code()); - // todo(mderka) test retry functionality - } + public void testListChanges() { try { - created.listChangeRequests(Dns.ChangeRequestListOption.pageSize(-1)); - } catch (DnsException ex) { - // expected - assertEquals(400, ex.code()); - // todo(mderka) test retry functionality - } - // sorting order - ImmutableList ascending = ImmutableList.copyOf(created.listChangeRequests( - Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING)).iterateAll()); - ImmutableList descending = ImmutableList.copyOf(created.listChangeRequests( - Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.DESCENDING)).iterateAll()); - int size = 5; - assertEquals(size, descending.size()); - assertEquals(size, ascending.size()); - for (int i = 0; i < size; i++) { - assertEquals(descending.get(i), ascending.get(size - i - 1)); + // no such zone exists + try { + DNS.listChangeRequests(ZONE1.name()); + fail(); + } catch (DnsException ex) { + // expected + assertEquals(404, ex.code()); + // todo(mderka) test retry functionality + } + // zone exists but has no changes + DNS.create(ZONE1); + ImmutableList changes = ImmutableList.copyOf( + DNS.listChangeRequests(ZONE1.name()).iterateAll()); + assertEquals(1, changes.size()); // default change creating SOA and NS + // zone has changes + ChangeRequest change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); + checkChangeComplete(ZONE1.name(), change.id()); + change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + checkChangeComplete(ZONE1.name(), change.id()); + change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); + checkChangeComplete(ZONE1.name(), change.id()); + change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + checkChangeComplete(ZONE1.name(), change.id()); + changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name()).iterateAll()); + assertEquals(5, changes.size()); + // error in options + try { + DNS.listChangeRequests(ZONE1.name(), Dns.ChangeRequestListOption.pageSize(0)); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test retry functionality + } + try { + DNS.listChangeRequests(ZONE1.name(), Dns.ChangeRequestListOption.pageSize(-1)); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test retry functionality + } + // sorting order + ImmutableList ascending = ImmutableList.copyOf(DNS.listChangeRequests( + ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING)).iterateAll()); + ImmutableList descending = ImmutableList.copyOf(DNS.listChangeRequests( + ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.DESCENDING)).iterateAll()); + int size = 5; + assertEquals(size, descending.size()); + assertEquals(size, ascending.size()); + for (int i = 0; i < size; i++) { + assertEquals(descending.get(i), ascending.get(size - i - 1)); + } + // field options + changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.ADDITIONS)).iterateAll()); + change = changes.get(1); + assertEquals(CHANGE_ADD_ZONE1.additions(), change.additions()); + assertTrue(change.deletions().isEmpty()); + assertEquals("1", change.id()); + assertNull(change.startTimeMillis()); + assertNull(change.status()); + changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.DELETIONS)).iterateAll()); + change = changes.get(2); + assertTrue(change.additions().isEmpty()); + assertNotNull(change.deletions()); + assertEquals("2", change.id()); + assertNull(change.startTimeMillis()); + assertNull(change.status()); + changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.ID)).iterateAll()); + change = changes.get(1); + assertTrue(change.additions().isEmpty()); + assertTrue(change.deletions().isEmpty()); + assertEquals("1", change.id()); + assertNull(change.startTimeMillis()); + assertNull(change.status()); + changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.START_TIME)).iterateAll()); + change = changes.get(1); + assertTrue(change.additions().isEmpty()); + assertTrue(change.deletions().isEmpty()); + assertEquals("1", change.id()); + assertNotNull(change.startTimeMillis()); + assertNull(change.status()); + changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.STATUS)).iterateAll()); + change = changes.get(1); + assertTrue(change.additions().isEmpty()); + assertTrue(change.deletions().isEmpty()); + assertEquals("1", change.id()); + assertNull(change.startTimeMillis()); + assertEquals(ChangeRequest.Status.DONE, change.status()); + } finally { + clear(); } - // field options - changes = ImmutableList.copyOf(created.listChangeRequests( - Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), - Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.ADDITIONS)).iterateAll()); - change = changes.get(1); - assertEquals(CHANGE_ADD_ZONE1.additions(), change.additions()); - assertTrue(change.deletions().isEmpty()); - assertEquals("1", change.id()); - assertNull(change.startTimeMillis()); - assertNull(change.status()); - changes = ImmutableList.copyOf(created.listChangeRequests( - Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), - Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.DELETIONS)).iterateAll()); - change = changes.get(2); - assertTrue(change.additions().isEmpty()); - assertNotNull(change.deletions()); - assertEquals("2", change.id()); - assertNull(change.startTimeMillis()); - assertNull(change.status()); - changes = ImmutableList.copyOf(created.listChangeRequests( - Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), - Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.ID)).iterateAll()); - change = changes.get(1); - assertTrue(change.additions().isEmpty()); - assertTrue(change.deletions().isEmpty()); - assertEquals("1", change.id()); - assertNull(change.startTimeMillis()); - assertNull(change.status()); - changes = ImmutableList.copyOf(created.listChangeRequests( - Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), - Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.START_TIME)).iterateAll()); - change = changes.get(1); - assertTrue(change.additions().isEmpty()); - assertTrue(change.deletions().isEmpty()); - assertEquals("1", change.id()); - assertNotNull(change.startTimeMillis()); - assertNull(change.status()); - changes = ImmutableList.copyOf(created.listChangeRequests( - Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), - Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.STATUS)).iterateAll()); - change = changes.get(1); - assertTrue(change.additions().isEmpty()); - assertTrue(change.deletions().isEmpty()); - assertEquals("1", change.id()); - assertNull(change.startTimeMillis()); - assertEquals(ChangeRequest.Status.DONE, change.status()); - } - - @Test - public void testGetChangeUsingZoneObject() { - Zone zone = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); - ChangeRequest created = zone.applyChangeRequest(CHANGE_ADD_ZONE1); - ChangeRequest retrieved = zone.getChangeRequest(created.id()); - assertEqChangesIgnoreStatus(created, retrieved); - checkChangeComplete(ZONE1.name(), "1"); - zone.applyChangeRequest(CHANGE_DELETE_ZONE1); - checkChangeComplete(ZONE1.name(), "2"); - // with options - created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); - retrieved = zone.getChangeRequest(created.id(), - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); - assertEqChangesIgnoreStatus(created, retrieved); - checkChangeComplete(ZONE1.name(), "3"); - zone.applyChangeRequest(CHANGE_DELETE_ZONE1); - checkChangeComplete(ZONE1.name(), "4"); - created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); - retrieved = zone.getChangeRequest(created.id(), - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); - assertEqChangesIgnoreStatus(created, retrieved); - checkChangeComplete(ZONE1.name(), "5"); - zone.applyChangeRequest(CHANGE_DELETE_ZONE1); - checkChangeComplete(ZONE1.name(), "6"); - created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); - retrieved = zone.getChangeRequest(created.id(), - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); - assertEqChangesIgnoreStatus(created, retrieved); - checkChangeComplete(ZONE1.name(), "7"); - zone.applyChangeRequest(CHANGE_DELETE_ZONE1); - checkChangeComplete(ZONE1.name(), "8"); - created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); - retrieved = zone.getChangeRequest(created.id(), - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); - assertEqChangesIgnoreStatus(created, retrieved); - // finishes with delete otherwise we cannot delete the zone - checkChangeComplete(ZONE1.name(), "9"); - created = zone.applyChangeRequest(CHANGE_DELETE_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); - retrieved = zone.getChangeRequest(created.id(), - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); - assertEqChangesIgnoreStatus(created, retrieved); - checkChangeComplete(ZONE1.name(), "10"); } @Test - public void testGetChangeUsingServiceObject() { - Zone zone = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); - ChangeRequest created = zone.applyChangeRequest(CHANGE_ADD_ZONE1); - ChangeRequest retrieved = DNS.getChangeRequest(zone.name(), created.id()); - assertEqChangesIgnoreStatus(created, retrieved); - zone.applyChangeRequest(CHANGE_DELETE_ZONE1); - // with options - created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); - retrieved = DNS.getChangeRequest(zone.name(), created.id(), - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); - assertEqChangesIgnoreStatus(created, retrieved); - zone.applyChangeRequest(CHANGE_DELETE_ZONE1); - created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); - retrieved = DNS.getChangeRequest(zone.name(), created.id(), - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); - assertEqChangesIgnoreStatus(created, retrieved); - zone.applyChangeRequest(CHANGE_DELETE_ZONE1); - created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); - retrieved = DNS.getChangeRequest(zone.name(), created.id(), - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); - assertEqChangesIgnoreStatus(created, retrieved); - zone.applyChangeRequest(CHANGE_DELETE_ZONE1); - created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); - retrieved = DNS.getChangeRequest(zone.name(), created.id(), - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); - assertEqChangesIgnoreStatus(created, retrieved); - // finishes with delete otherwise we cannot delete the zone - created = zone.applyChangeRequest(CHANGE_DELETE_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); - retrieved = DNS.getChangeRequest(zone.name(), created.id(), - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); - assertEqChangesIgnoreStatus(created, retrieved); + public void testGetChange() { + try { + Zone zone = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); + ChangeRequest created = zone.applyChangeRequest(CHANGE_ADD_ZONE1); + ChangeRequest retrieved = DNS.getChangeRequest(zone.name(), created.id()); + assertEqChangesIgnoreStatus(created, retrieved); + zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + // with options + created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); + retrieved = DNS.getChangeRequest(zone.name(), created.id(), + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); + assertEqChangesIgnoreStatus(created, retrieved); + zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); + retrieved = DNS.getChangeRequest(zone.name(), created.id(), + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); + assertEqChangesIgnoreStatus(created, retrieved); + zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); + retrieved = DNS.getChangeRequest(zone.name(), created.id(), + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); + assertEqChangesIgnoreStatus(created, retrieved); + zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); + retrieved = DNS.getChangeRequest(zone.name(), created.id(), + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); + assertEqChangesIgnoreStatus(created, retrieved); + // finishes with delete otherwise we cannot delete the zone + created = zone.applyChangeRequest(CHANGE_DELETE_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); + retrieved = DNS.getChangeRequest(zone.name(), created.id(), + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); + assertEqChangesIgnoreStatus(created, retrieved); + } finally { + clear(); + } } @Test @@ -1027,242 +778,128 @@ public void testGetProject() { } @Test - public void testListDnsRecordsUsingService() { - Zone zone = DNS.create(ZONE1); - ImmutableList dnsRecords = ImmutableList.copyOf( - DNS.listDnsRecords(zone.name()).iterateAll()); - assertEquals(2, dnsRecords.size()); - ImmutableList defaultRecords = - ImmutableList.of(DnsRecord.Type.NS, DnsRecord.Type.SOA); - for (DnsRecord record : dnsRecords) { - assertTrue(defaultRecords.contains(record.type())); - } - // field options - Iterator dnsRecordIterator = DNS.listDnsRecords(zone.name(), - Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TTL)).iterateAll(); - int counter = 0; - while (dnsRecordIterator.hasNext()) { - DnsRecord record = dnsRecordIterator.next(); - assertEquals(dnsRecords.get(counter).ttl(), record.ttl()); - assertEquals(dnsRecords.get(counter).name(), record.name()); - assertEquals(dnsRecords.get(counter).type(), record.type()); - assertTrue(record.records().isEmpty()); - counter++; - } - assertEquals(2, counter); - dnsRecordIterator = DNS.listDnsRecords(zone.name(), - Dns.DnsRecordListOption.fields(Dns.DnsRecordField.NAME)).iterateAll(); - counter = 0; - while (dnsRecordIterator.hasNext()) { - DnsRecord record = dnsRecordIterator.next(); - assertEquals(dnsRecords.get(counter).name(), record.name()); - assertEquals(dnsRecords.get(counter).type(), record.type()); - assertTrue(record.records().isEmpty()); - assertNull(record.ttl()); - counter++; - } - assertEquals(2, counter); - dnsRecordIterator = DNS.listDnsRecords(zone.name(), - Dns.DnsRecordListOption.fields(Dns.DnsRecordField.DNS_RECORDS)).iterateAll(); - counter = 0; - while (dnsRecordIterator.hasNext()) { - DnsRecord record = dnsRecordIterator.next(); - assertEquals(dnsRecords.get(counter).records(), record.records()); - assertEquals(dnsRecords.get(counter).name(), record.name()); - assertEquals(dnsRecords.get(counter).type(), record.type()); - assertNull(record.ttl()); - counter++; - } - assertEquals(2, counter); - dnsRecordIterator = DNS.listDnsRecords(zone.name(), - Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TYPE), - Dns.DnsRecordListOption.pageSize(1)).iterateAll(); // also test paging - counter = 0; - while (dnsRecordIterator.hasNext()) { - DnsRecord record = dnsRecordIterator.next(); - assertEquals(dnsRecords.get(counter).type(), record.type()); - assertEquals(dnsRecords.get(counter).name(), record.name()); - assertTrue(record.records().isEmpty()); - assertNull(record.ttl()); - counter++; - } - assertEquals(2, counter); - // test page size - Page dnsRecordPage = DNS.listDnsRecords(zone.name(), - Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TYPE), - Dns.DnsRecordListOption.pageSize(1)); - assertEquals(1, ImmutableList.copyOf(dnsRecordPage.values().iterator()).size()); - // test name filter - ChangeRequest change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); - checkChangeComplete(ZONE1.name(), change.id()); - dnsRecordIterator = DNS.listDnsRecords(ZONE1.name(), - Dns.DnsRecordListOption.dnsName(A_RECORD_ZONE1.name())).iterateAll(); - counter = 0; - while (dnsRecordIterator.hasNext()) { - DnsRecord record = dnsRecordIterator.next(); - assertTrue(ImmutableList.of(A_RECORD_ZONE1.type(), AAAA_RECORD_ZONE1.type()) - .contains(record.type())); - counter++; - } - assertEquals(2, counter); - // test type filter - checkChangeComplete(ZONE1.name(), change.id()); - dnsRecordIterator = DNS.listDnsRecords(ZONE1.name(), - Dns.DnsRecordListOption.dnsName(A_RECORD_ZONE1.name()), - Dns.DnsRecordListOption.type(A_RECORD_ZONE1.type())) - .iterateAll(); - counter = 0; - while (dnsRecordIterator.hasNext()) { - DnsRecord record = dnsRecordIterator.next(); - assertEquals(A_RECORD_ZONE1, record); - counter++; - } - assertEquals(1, counter); - change = zone.applyChangeRequest(CHANGE_DELETE_ZONE1); - // check wrong arguments - try { - // name is not set - DNS.listDnsRecords(ZONE1.name(), - Dns.DnsRecordListOption.type(A_RECORD_ZONE1.type())); - } catch (DnsException ex) { - // expected - assertEquals(400, ex.code()); - // todo(mderka) test retry functionality when available - } - try { - DNS.listDnsRecords(ZONE1.name(), - Dns.DnsRecordListOption.pageSize(0)); - } catch (DnsException ex) { - // expected - assertEquals(400, ex.code()); - // todo(mderka) test retry functionality when available - } - try { - DNS.listDnsRecords(ZONE1.name(), - Dns.DnsRecordListOption.pageSize(-1)); - } catch (DnsException ex) { - // expected - assertEquals(400, ex.code()); - // todo(mderka) test retry functionality when available - } - checkChangeComplete(ZONE1.name(), change.id()); - } - - @Test - public void testListDnsRecordsUsingZoneObject() { - Zone zone = DNS.create(ZONE1); - ImmutableList dnsRecords = ImmutableList.copyOf( - zone.listDnsRecords().iterateAll()); - assertEquals(2, dnsRecords.size()); - ImmutableList defaultRecords = - ImmutableList.of(DnsRecord.Type.NS, DnsRecord.Type.SOA); - for (DnsRecord record : dnsRecords) { - assertTrue(defaultRecords.contains(record.type())); - } - // field options - Iterator dnsRecordIterator = zone.listDnsRecords( - Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TTL)).iterateAll(); - int counter = 0; - while (dnsRecordIterator.hasNext()) { - DnsRecord record = dnsRecordIterator.next(); - assertEquals(dnsRecords.get(counter).ttl(), record.ttl()); - assertEquals(dnsRecords.get(counter).name(), record.name()); - assertEquals(dnsRecords.get(counter).type(), record.type()); - assertTrue(record.records().isEmpty()); - counter++; - } - assertEquals(2, counter); - dnsRecordIterator = zone.listDnsRecords( - Dns.DnsRecordListOption.fields(Dns.DnsRecordField.NAME)).iterateAll(); - counter = 0; - while (dnsRecordIterator.hasNext()) { - DnsRecord record = dnsRecordIterator.next(); - assertEquals(dnsRecords.get(counter).name(), record.name()); - assertEquals(dnsRecords.get(counter).type(), record.type()); - assertTrue(record.records().isEmpty()); - assertNull(record.ttl()); - counter++; - } - assertEquals(2, counter); - dnsRecordIterator = zone.listDnsRecords( - Dns.DnsRecordListOption.fields(Dns.DnsRecordField.DNS_RECORDS)).iterateAll(); - counter = 0; - while (dnsRecordIterator.hasNext()) { - DnsRecord record = dnsRecordIterator.next(); - assertEquals(dnsRecords.get(counter).records(), record.records()); - assertEquals(dnsRecords.get(counter).name(), record.name()); - assertEquals(dnsRecords.get(counter).type(), record.type()); - assertNull(record.ttl()); - counter++; - } - assertEquals(2, counter); - dnsRecordIterator = zone.listDnsRecords( - Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TYPE), - Dns.DnsRecordListOption.pageSize(1)).iterateAll(); // also test paging - counter = 0; - while (dnsRecordIterator.hasNext()) { - DnsRecord record = dnsRecordIterator.next(); - assertEquals(dnsRecords.get(counter).type(), record.type()); - assertEquals(dnsRecords.get(counter).name(), record.name()); - assertTrue(record.records().isEmpty()); - assertNull(record.ttl()); - counter++; - } - assertEquals(2, counter); - // test page size - Page dnsRecordPage = zone.listDnsRecords( - Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TYPE), - Dns.DnsRecordListOption.pageSize(1)); - assertEquals(1, ImmutableList.copyOf(dnsRecordPage.values().iterator()).size()); - // test name filter - ChangeRequest change = zone.applyChangeRequest(CHANGE_ADD_ZONE1); - checkChangeComplete(ZONE1.name(), change.id()); - dnsRecordIterator = zone.listDnsRecords(Dns.DnsRecordListOption.dnsName(A_RECORD_ZONE1.name())) - .iterateAll(); - counter = 0; - while (dnsRecordIterator.hasNext()) { - DnsRecord record = dnsRecordIterator.next(); - assertTrue(ImmutableList.of(A_RECORD_ZONE1.type(), AAAA_RECORD_ZONE1.type()) - .contains(record.type())); - counter++; - } - assertEquals(2, counter); - // test type filter - checkChangeComplete(ZONE1.name(), change.id()); - dnsRecordIterator = zone.listDnsRecords(Dns.DnsRecordListOption.dnsName(A_RECORD_ZONE1.name()), - Dns.DnsRecordListOption.type(A_RECORD_ZONE1.type())) - .iterateAll(); - counter = 0; - while (dnsRecordIterator.hasNext()) { - DnsRecord record = dnsRecordIterator.next(); - assertEquals(A_RECORD_ZONE1, record); - counter++; - } - assertEquals(1, counter); - change = zone.applyChangeRequest(CHANGE_DELETE_ZONE1); - // check wrong arguments - try { - // name is not set - zone.listDnsRecords(Dns.DnsRecordListOption.type(A_RECORD_ZONE1.type())); - } catch (DnsException ex) { - // expected - assertEquals(400, ex.code()); - // todo(mderka) test retry functionality when available - } + public void testListDnsRecords() { try { - zone.listDnsRecords(Dns.DnsRecordListOption.pageSize(0)); - } catch (DnsException ex) { - // expected - assertEquals(400, ex.code()); - // todo(mderka) test retry functionality when available - } - try { - zone.listDnsRecords(Dns.DnsRecordListOption.pageSize(-1)); - } catch (DnsException ex) { - // expected - assertEquals(400, ex.code()); - // todo(mderka) test retry functionality when available + Zone zone = DNS.create(ZONE1); + ImmutableList dnsRecords = ImmutableList.copyOf( + DNS.listDnsRecords(zone.name()).iterateAll()); + assertEquals(2, dnsRecords.size()); + ImmutableList defaultRecords = + ImmutableList.of(DnsRecord.Type.NS, DnsRecord.Type.SOA); + for (DnsRecord record : dnsRecords) { + assertTrue(defaultRecords.contains(record.type())); + } + // field options + Iterator dnsRecordIterator = DNS.listDnsRecords(zone.name(), + Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TTL)).iterateAll(); + int counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertEquals(dnsRecords.get(counter).ttl(), record.ttl()); + assertEquals(dnsRecords.get(counter).name(), record.name()); + assertEquals(dnsRecords.get(counter).type(), record.type()); + assertTrue(record.records().isEmpty()); + counter++; + } + assertEquals(2, counter); + dnsRecordIterator = DNS.listDnsRecords(zone.name(), + Dns.DnsRecordListOption.fields(Dns.DnsRecordField.NAME)).iterateAll(); + counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertEquals(dnsRecords.get(counter).name(), record.name()); + assertEquals(dnsRecords.get(counter).type(), record.type()); + assertTrue(record.records().isEmpty()); + assertNull(record.ttl()); + counter++; + } + assertEquals(2, counter); + dnsRecordIterator = DNS.listDnsRecords(zone.name(), + Dns.DnsRecordListOption.fields(Dns.DnsRecordField.DNS_RECORDS)).iterateAll(); + counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertEquals(dnsRecords.get(counter).records(), record.records()); + assertEquals(dnsRecords.get(counter).name(), record.name()); + assertEquals(dnsRecords.get(counter).type(), record.type()); + assertNull(record.ttl()); + counter++; + } + assertEquals(2, counter); + dnsRecordIterator = DNS.listDnsRecords(zone.name(), + Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TYPE), + Dns.DnsRecordListOption.pageSize(1)).iterateAll(); // also test paging + counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertEquals(dnsRecords.get(counter).type(), record.type()); + assertEquals(dnsRecords.get(counter).name(), record.name()); + assertTrue(record.records().isEmpty()); + assertNull(record.ttl()); + counter++; + } + assertEquals(2, counter); + // test page size + Page dnsRecordPage = DNS.listDnsRecords(zone.name(), + Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TYPE), + Dns.DnsRecordListOption.pageSize(1)); + assertEquals(1, ImmutableList.copyOf(dnsRecordPage.values().iterator()).size()); + // test name filter + ChangeRequest change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); + checkChangeComplete(ZONE1.name(), change.id()); + dnsRecordIterator = DNS.listDnsRecords(ZONE1.name(), + Dns.DnsRecordListOption.dnsName(A_RECORD_ZONE1.name())).iterateAll(); + counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertTrue(ImmutableList.of(A_RECORD_ZONE1.type(), AAAA_RECORD_ZONE1.type()) + .contains(record.type())); + counter++; + } + assertEquals(2, counter); + // test type filter + checkChangeComplete(ZONE1.name(), change.id()); + dnsRecordIterator = DNS.listDnsRecords(ZONE1.name(), + Dns.DnsRecordListOption.dnsName(A_RECORD_ZONE1.name()), + Dns.DnsRecordListOption.type(A_RECORD_ZONE1.type())) + .iterateAll(); + counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertEquals(A_RECORD_ZONE1, record); + counter++; + } + assertEquals(1, counter); + change = zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + // check wrong arguments + try { + // name is not set + DNS.listDnsRecords(ZONE1.name(), + Dns.DnsRecordListOption.type(A_RECORD_ZONE1.type())); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test retry functionality when available + } + try { + DNS.listDnsRecords(ZONE1.name(), + Dns.DnsRecordListOption.pageSize(0)); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test retry functionality when available + } + try { + DNS.listDnsRecords(ZONE1.name(), + Dns.DnsRecordListOption.pageSize(-1)); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test retry functionality when available + } + checkChangeComplete(ZONE1.name(), change.id()); + } finally { + clear(); } - checkChangeComplete(ZONE1.name(), change.id()); } } From 992a371006c8e723137b57933b72824754e98869 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 29 Feb 2016 19:54:57 +0100 Subject: [PATCH 119/375] Remove tabs from storage and bigquery poms --- gcloud-java-bigquery/pom.xml | 8 ++++---- gcloud-java-storage/pom.xml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/gcloud-java-bigquery/pom.xml b/gcloud-java-bigquery/pom.xml index f7304e276d75..34ddd7679e97 100644 --- a/gcloud-java-bigquery/pom.xml +++ b/gcloud-java-bigquery/pom.xml @@ -33,10 +33,10 @@ v2-rev270-1.21.0 compile - - com.google.guava - guava-jdk5 - + + com.google.guava + guava-jdk5 + diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml index d98fcd2647e2..f18283b70bc8 100644 --- a/gcloud-java-storage/pom.xml +++ b/gcloud-java-storage/pom.xml @@ -27,10 +27,10 @@ v1-rev62-1.21.0 compile - - com.google.guava - guava-jdk5 - + + com.google.guava + guava-jdk5 + com.google.api-client google-api-client From 72b4f44859400fe9e7a1f42ed20bb15b431ca301 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 29 Feb 2016 20:22:36 +0100 Subject: [PATCH 120/375] Fix links to examples javadoc in READMEs --- README.md | 8 ++++---- gcloud-java-bigquery/README.md | 2 +- gcloud-java-datastore/README.md | 2 +- gcloud-java-resourcemanager/README.md | 2 +- gcloud-java-storage/README.md | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index b6c2473f9794..810e8aecbbf2 100644 --- a/README.md +++ b/README.md @@ -45,17 +45,17 @@ Example Applications -------------------- - [`BigQueryExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/BigQueryExample.java) - A simple command line interface providing some of Cloud BigQuery's functionality - - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/BigQueryExample.html). + - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/bigquery/BigQueryExample.html). - [`Bookshelf`](https://github.com/GoogleCloudPlatform/getting-started-java/tree/master/bookshelf) - An App Engine app that manages a virtual bookshelf. - This app uses `gcloud-java` to interface with Cloud Datastore and Cloud Storage. It also uses Cloud SQL, another Google Cloud Platform service. - [`DatastoreExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/DatastoreExample.java) - A simple command line interface for the Cloud Datastore - - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/DatastoreExample.html). + - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/datastore/DatastoreExample.html). - [`ResourceManagerExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/ResourceManagerExample.java) - A simple command line interface providing some of Cloud Resource Manager's functionality - - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/ResourceManagerExample.html). + - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/resourcemanager/ResourceManagerExample.html). - [`SparkDemo`](https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/managed_vms/sparkjava) - An example of using gcloud-java-datastore from within the SparkJava and App Engine Managed VM frameworks. - Read about how it works on the example's [README page](https://github.com/GoogleCloudPlatform/java-docs-samples/tree/master/managed_vms/sparkjava#how-does-it-work). - [`StorageExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java) - A simple command line interface providing some of Cloud Storage's functionality - - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/StorageExample.html). + - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/storage/StorageExample.html). Specifying a Project ID ----------------------- diff --git a/gcloud-java-bigquery/README.md b/gcloud-java-bigquery/README.md index b406fb5496d2..9a1c6e539dae 100644 --- a/gcloud-java-bigquery/README.md +++ b/gcloud-java-bigquery/README.md @@ -37,7 +37,7 @@ libraryDependencies += "com.google.gcloud" % "gcloud-java-bigquery" % "0.1.4" Example Application ------------------- - [`BigQueryExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/BigQueryExample.java) - A simple command line interface providing some of Cloud BigQuery's functionality. -Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/BigQueryExample.html). +Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/bigquery/BigQueryExample.html). Authentication -------------- diff --git a/gcloud-java-datastore/README.md b/gcloud-java-datastore/README.md index a1d024fcc96d..c27aea21e3a8 100644 --- a/gcloud-java-datastore/README.md +++ b/gcloud-java-datastore/README.md @@ -36,7 +36,7 @@ libraryDependencies += "com.google.gcloud" % "gcloud-java-datastore" % "0.1.4" Example Application -------------------- -[`DatastoreExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/DatastoreExample.java) is a simple command line interface for the Cloud Datastore. Read more about using the application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/DatastoreExample.html). +[`DatastoreExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/DatastoreExample.java) is a simple command line interface for the Cloud Datastore. Read more about using the application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/datastore/DatastoreExample.html). Authentication -------------- diff --git a/gcloud-java-resourcemanager/README.md b/gcloud-java-resourcemanager/README.md index 9637b37d3bb8..ab4eb012066b 100644 --- a/gcloud-java-resourcemanager/README.md +++ b/gcloud-java-resourcemanager/README.md @@ -36,7 +36,7 @@ libraryDependencies += "com.google.gcloud" % "gcloud-java-resourcemanager" % "0. Example Application -------------------- -[`ResourceManagerExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/ResourceManagerExample.java) is a simple command line interface for the Cloud Resource Manager. Read more about using the application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/ResourceManagerExample.html). +[`ResourceManagerExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/ResourceManagerExample.java) is a simple command line interface for the Cloud Resource Manager. Read more about using the application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/resourcemanager/ResourceManagerExample.html). Authentication -------------- diff --git a/gcloud-java-storage/README.md b/gcloud-java-storage/README.md index 3b013eb03724..bd7427444c92 100644 --- a/gcloud-java-storage/README.md +++ b/gcloud-java-storage/README.md @@ -37,7 +37,7 @@ libraryDependencies += "com.google.gcloud" % "gcloud-java-storage" % "0.1.4" Example Application ------------------- -[`StorageExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java) is a simple command line interface that provides some of Cloud Storage's functionality. Read more about using the application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/StorageExample.html). +[`StorageExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java) is a simple command line interface that provides some of Cloud Storage's functionality. Read more about using the application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/storage/StorageExample.html). Authentication -------------- From 5c3bd9ff6d19701777cdd09270e62e2ff3c0275b Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 29 Feb 2016 23:05:41 +0100 Subject: [PATCH 121/375] Use better link names for examples javadoc --- README.md | 8 ++++---- gcloud-java-bigquery/README.md | 2 +- gcloud-java-datastore/README.md | 2 +- gcloud-java-resourcemanager/README.md | 2 +- gcloud-java-storage/README.md | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 810e8aecbbf2..32a0f539425e 100644 --- a/README.md +++ b/README.md @@ -45,17 +45,17 @@ Example Applications -------------------- - [`BigQueryExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/BigQueryExample.java) - A simple command line interface providing some of Cloud BigQuery's functionality - - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/bigquery/BigQueryExample.html). + - Read more about using this application on the [`BigQueryExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/bigquery/BigQueryExample.html). - [`Bookshelf`](https://github.com/GoogleCloudPlatform/getting-started-java/tree/master/bookshelf) - An App Engine app that manages a virtual bookshelf. - This app uses `gcloud-java` to interface with Cloud Datastore and Cloud Storage. It also uses Cloud SQL, another Google Cloud Platform service. - [`DatastoreExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/DatastoreExample.java) - A simple command line interface for the Cloud Datastore - - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/datastore/DatastoreExample.html). + - Read more about using this application on the [`DatastoreExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/datastore/DatastoreExample.html). - [`ResourceManagerExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/ResourceManagerExample.java) - A simple command line interface providing some of Cloud Resource Manager's functionality - - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/resourcemanager/ResourceManagerExample.html). + - Read more about using this application on the [`ResourceManagerExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/resourcemanager/ResourceManagerExample.html). - [`SparkDemo`](https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/managed_vms/sparkjava) - An example of using gcloud-java-datastore from within the SparkJava and App Engine Managed VM frameworks. - Read about how it works on the example's [README page](https://github.com/GoogleCloudPlatform/java-docs-samples/tree/master/managed_vms/sparkjava#how-does-it-work). - [`StorageExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java) - A simple command line interface providing some of Cloud Storage's functionality - - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/storage/StorageExample.html). + - Read more about using this application on the [`StorageExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/storage/StorageExample.html). Specifying a Project ID ----------------------- diff --git a/gcloud-java-bigquery/README.md b/gcloud-java-bigquery/README.md index 9a1c6e539dae..58633ba635f9 100644 --- a/gcloud-java-bigquery/README.md +++ b/gcloud-java-bigquery/README.md @@ -37,7 +37,7 @@ libraryDependencies += "com.google.gcloud" % "gcloud-java-bigquery" % "0.1.4" Example Application ------------------- - [`BigQueryExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/BigQueryExample.java) - A simple command line interface providing some of Cloud BigQuery's functionality. -Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/bigquery/BigQueryExample.html). +Read more about using this application on the [`BigQueryExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/bigquery/BigQueryExample.html). Authentication -------------- diff --git a/gcloud-java-datastore/README.md b/gcloud-java-datastore/README.md index c27aea21e3a8..dd341ba244c3 100644 --- a/gcloud-java-datastore/README.md +++ b/gcloud-java-datastore/README.md @@ -36,7 +36,7 @@ libraryDependencies += "com.google.gcloud" % "gcloud-java-datastore" % "0.1.4" Example Application -------------------- -[`DatastoreExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/DatastoreExample.java) is a simple command line interface for the Cloud Datastore. Read more about using the application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/datastore/DatastoreExample.html). +[`DatastoreExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/DatastoreExample.java) is a simple command line interface for the Cloud Datastore. Read more about using the application on the [`DatastoreExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/datastore/DatastoreExample.html). Authentication -------------- diff --git a/gcloud-java-resourcemanager/README.md b/gcloud-java-resourcemanager/README.md index ab4eb012066b..cd48d6699311 100644 --- a/gcloud-java-resourcemanager/README.md +++ b/gcloud-java-resourcemanager/README.md @@ -36,7 +36,7 @@ libraryDependencies += "com.google.gcloud" % "gcloud-java-resourcemanager" % "0. Example Application -------------------- -[`ResourceManagerExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/ResourceManagerExample.java) is a simple command line interface for the Cloud Resource Manager. Read more about using the application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/resourcemanager/ResourceManagerExample.html). +[`ResourceManagerExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/ResourceManagerExample.java) is a simple command line interface for the Cloud Resource Manager. Read more about using the application on the [`ResourceManagerExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/resourcemanager/ResourceManagerExample.html). Authentication -------------- diff --git a/gcloud-java-storage/README.md b/gcloud-java-storage/README.md index bd7427444c92..f7973544bba2 100644 --- a/gcloud-java-storage/README.md +++ b/gcloud-java-storage/README.md @@ -37,7 +37,7 @@ libraryDependencies += "com.google.gcloud" % "gcloud-java-storage" % "0.1.4" Example Application ------------------- -[`StorageExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java) is a simple command line interface that provides some of Cloud Storage's functionality. Read more about using the application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/storage/StorageExample.html). +[`StorageExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java) is a simple command line interface that provides some of Cloud Storage's functionality. Read more about using the application on the [`StorageExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/storage/StorageExample.html). Authentication -------------- From 21e68cce2c133463fcc4d74e06e3114c5e25ef65 Mon Sep 17 00:00:00 2001 From: aozarov Date: Mon, 29 Feb 2016 15:10:12 -0800 Subject: [PATCH 122/375] Add a versions option to BlobListOption --- .../main/java/com/google/gcloud/storage/Storage.java | 10 ++++++++++ .../com/google/gcloud/storage/StorageImplTest.java | 8 ++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index 4acc1dbcad07..4fa4ba3658be 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -700,6 +700,16 @@ public static BlobListOption recursive(boolean recursive) { return new BlobListOption(StorageRpc.Option.DELIMITER, recursive); } + /** + * If set to {@code true}, lists all versions of a blob. + * The default is {@code false}. + * + * @see Object Versioning + */ + public static BlobListOption versions(boolean versions) { + return new BlobListOption(StorageRpc.Option.VERSIONS, versions); + } + /** * Returns an option to specify the blob's fields to be returned by the RPC call. If this option * is not provided all blob's fields are returned. {@code BlobListOption.fields}) can be used to diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java index b14dcd057438..612664de14ae 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java @@ -200,11 +200,14 @@ public class StorageImplTest { Storage.BlobListOption.prefix("prefix"); private static final Storage.BlobListOption BLOB_LIST_FIELDS = Storage.BlobListOption.fields(Storage.BlobField.CONTENT_TYPE, Storage.BlobField.MD5HASH); + private static final Storage.BlobListOption BLOB_LIST_VERSIONS = + Storage.BlobListOption.versions(false); private static final Storage.BlobListOption BLOB_LIST_EMPTY_FIELDS = Storage.BlobListOption.fields(); private static final Map BLOB_LIST_OPTIONS = ImmutableMap.of( StorageRpc.Option.MAX_RESULTS, BLOB_LIST_MAX_RESULT.value(), - StorageRpc.Option.PREFIX, BLOB_LIST_PREFIX.value()); + StorageRpc.Option.PREFIX, BLOB_LIST_PREFIX.value(), + StorageRpc.Option.VERSIONS, BLOB_LIST_VERSIONS.value()); private static final String PRIVATE_KEY_STRING = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoG" + "BAL2xolH1zrISQ8+GzOV29BNjjzq4/HIP8Psd1+cZb81vDklSF+95wB250MSE0BDc81pvIMwj5OmIfLg1NY6uB" @@ -650,7 +653,8 @@ public void testListBlobsWithOptions() { EasyMock.replay(storageRpcMock); initializeService(); ImmutableList blobList = ImmutableList.of(expectedBlob1, expectedBlob2); - Page page = storage.list(BUCKET_NAME1, BLOB_LIST_MAX_RESULT, BLOB_LIST_PREFIX); + Page page = + storage.list(BUCKET_NAME1, BLOB_LIST_MAX_RESULT, BLOB_LIST_PREFIX, BLOB_LIST_VERSIONS); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(blobList.toArray(), Iterables.toArray(page.values(), Blob.class)); } From 7e498c1ef6ef00a29ba17714e732bf58e6cace83 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 29 Feb 2016 18:20:11 -0800 Subject: [PATCH 123/375] Remove userinfo scope from DatastoreOptions --- .../java/com/google/gcloud/datastore/DatastoreOptions.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java index 112d0e8d2602..d47aa5fa2915 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java @@ -35,8 +35,7 @@ public class DatastoreOptions extends ServiceOptions SCOPES = ImmutableSet.of(DATASTORE_SCOPE, USERINFO_SCOPE); + private static final Set SCOPES = ImmutableSet.of(DATASTORE_SCOPE); private final String namespace; private final boolean normalizeDataset; From c95e5e7dbecaeb613e77385f62258f9c43b32af2 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Thu, 18 Feb 2016 08:10:00 -0800 Subject: [PATCH 124/375] Allow eventual consistency for Datastore reads --- gcloud-java-datastore/pom.xml | 12 ---- .../google/gcloud/datastore/Datastore.java | 39 ++++++++++- .../gcloud/datastore/DatastoreHelper.java | 31 ++++++-- .../gcloud/datastore/DatastoreImpl.java | 39 +++++++++++ .../gcloud/datastore/DatastoreReader.java | 10 +-- .../google/gcloud/datastore/ReadOption.java | 66 +++++++++++++++++ .../gcloud/datastore/TransactionImpl.java | 8 +-- .../gcloud/datastore/DatastoreHelperTest.java | 65 ++++++++++++++--- .../gcloud/datastore/DatastoreTest.java | 70 +++++++++++++++++++ 9 files changed, 303 insertions(+), 37 deletions(-) create mode 100644 gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index b33f66a19682..ee633fd57883 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -42,18 +42,6 @@ datastore-v1beta3-proto-client 0.0.1-SNAPSHOT - - com.google.apis - google-api-services-datastore-protobuf - v1beta2-rev1-2.1.2 - compile - - - com.google.api-client - google-api-client - - - junit junit diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java index b49db1cacdfe..00b914a36678 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java @@ -18,6 +18,7 @@ import com.google.gcloud.Service; +import java.util.Iterator; import java.util.List; /** @@ -32,7 +33,6 @@ public interface Datastore extends Service, DatastoreReaderWri */ Transaction newTransaction(); - /** * A callback for running with a transactional * {@link com.google.gcloud.datastore.DatastoreReaderWriter}. @@ -45,7 +45,6 @@ interface TransactionCallable { T run(DatastoreReaderWriter readerWriter) throws Exception; } - /** * Invokes the callback's {@link Datastore.TransactionCallable#run} method with a * {@link DatastoreReaderWriter} that is associated with a new transaction. @@ -105,4 +104,40 @@ interface TransactionCallable { * Returns a new KeyFactory for this service */ KeyFactory newKeyFactory(); + + /** + * Returns an {@link Entity} for the given {@link Key} or {@code null} if it doesn't exist. + * {@link ReadOption}s can be specified if desired. + * + * @throws DatastoreException upon failure + */ + Entity get(Key key, ReadOption... options); + + /** + * Returns an {@link Entity} for each given {@link Key} that exists in the Datastore. + * The order of the result is unspecified. + * Results are loaded lazily, so it is possible to get a {@code DatastoreException} + * from the returned {@code Iterator}'s {@link Iterator#hasNext hasNext} or + * {@link Iterator#next next} methods. {@link ReadOption}s can be specified if desired. + * + * @throws DatastoreException upon failure + * @see #get(Key) + */ + Iterator get(Iterable keys, ReadOption... options); + + /** + * Returns a list with a value for each given key (ordered by input). + * {@code null} values are returned for nonexistent keys. + * When possible prefer using {@link #get(Key...)} to avoid eagerly loading the results. + * {@link ReadOption}s can be specified if desired. + */ + List fetch(Iterable keys, ReadOption... options); + + /** + * Submits a {@link Query} and returns its result. + * {@link ReadOption}s can be specified if desired. + * + * @throws DatastoreException upon failure + */ + QueryResults run(Query query, ReadOption... options); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java index 5ea0f755d2f8..2873e2f8aafa 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java @@ -20,6 +20,8 @@ import com.google.common.collect.Maps; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -33,13 +35,16 @@ class DatastoreHelper { private DatastoreHelper() { } - static Key allocateId(Datastore service, IncompleteKey key) { return service.allocateId(new IncompleteKey[]{key}).get(0); } - static Entity get(DatastoreReader reader, Key key) { - return Iterators.getNext(reader.get(new Key[]{key}), null); + static Entity get(Transaction reader, Key key) { + return Iterators.getNext(reader.get(new Key[] {key}), null); + } + + static Entity get(Datastore reader, Key key, ReadOption... options) { + return Iterators.getNext(reader.get(Collections.singletonList(key), options), null); } static Entity add(DatastoreWriter writer, FullEntity entity) { @@ -52,10 +57,24 @@ static KeyFactory newKeyFactory(DatastoreOptions options) { /** * Returns a list with a value for each given key (ordered by input). - * A {@code null} would be returned for non-existing keys. + * {@code null} values are returned for nonexistent keys. */ - static List fetch(DatastoreReader reader, Key... keys) { + static List fetch(Transaction reader, Key... keys) { Iterator entities = reader.get(keys); + return compileEntities(keys, entities); + } + + /** + * Returns a list with a value for each given key (ordered by input). + * {@code null} values are returned for nonexistent keys. + */ + static List fetch(Datastore reader, Key[] keys, ReadOption... options) { + Iterator entities; + entities = reader.get(Arrays.asList(keys), options); + return compileEntities(keys, entities); + } + + private static List compileEntities(Key[] keys, Iterator entities) { Map map = Maps.newHashMapWithExpectedSize(keys.length); while (entities.hasNext()) { Entity entity = entities.next(); @@ -63,7 +82,7 @@ static List fetch(DatastoreReader reader, Key... keys) { } List list = new ArrayList<>(keys.length); for (Key key : keys) { - // this will include nulls for non-existing keys + // this will include nulls for nonexistent keys list.add(map.get(key)); } return list; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java index df4e22149fd5..73d25ab140d7 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java @@ -20,11 +20,14 @@ import com.google.common.base.Preconditions; import com.google.common.collect.AbstractIterator; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; import com.google.common.collect.Sets; +import com.google.datastore.v1beta3.ReadOptions.ReadConsistency; import com.google.gcloud.BaseService; import com.google.gcloud.RetryHelper; import com.google.gcloud.RetryHelper.RetryHelperException; import com.google.gcloud.RetryParams; +import com.google.gcloud.datastore.ReadOption.EventualConsistency; import com.google.gcloud.spi.DatastoreRpc; import com.google.protobuf.ByteString; @@ -70,6 +73,11 @@ public QueryResults run(Query query) { return run(null, query); } + @Override + public QueryResults run(Query query, ReadOption... options) { + return run(toReadOptionsPb(options), query); + } + QueryResults run(com.google.datastore.v1beta3.ReadOptions readOptionsPb, Query query) { return new QueryResultsImpl<>(this, readOptionsPb, query); } @@ -185,16 +193,47 @@ public Entity get(Key key) { return DatastoreHelper.get(this, key); } + @Override + public Entity get(Key key, ReadOption... options) { + return DatastoreHelper.get(this, key, options); + } + @Override public Iterator get(Key... keys) { return get(null, keys); } + @Override + public Iterator get(Iterable keys, ReadOption... options) { + return get(toReadOptionsPb(options), Iterables.toArray(keys, Key.class)); + } + + private static com.google.datastore.v1beta3.ReadOptions toReadOptionsPb(ReadOption... options) { + com.google.datastore.v1beta3.ReadOptions readOptionsPb = null; + if (options != null) { + Map, ReadOption> optionsMap = ReadOption.asImmutableMap(options); + EventualConsistency eventualConsistency = + (EventualConsistency) optionsMap.get(EventualConsistency.class); + if (eventualConsistency != null) { + readOptionsPb = + com.google.datastore.v1beta3.ReadOptions.newBuilder() + .setReadConsistency(ReadConsistency.EVENTUAL) + .build(); + } + } + return readOptionsPb; + } + @Override public List fetch(Key... keys) { return DatastoreHelper.fetch(this, keys); } + @Override + public List fetch(Iterable keys, ReadOption... options) { + return DatastoreHelper.fetch(this, Iterables.toArray(keys, Key.class), options); + } + Iterator get(com.google.datastore.v1beta3.ReadOptions readOptionsPb, final Key... keys) { if (keys.length == 0) { return Collections.emptyIterator(); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReader.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReader.java index 4852dd53e16c..7ba5089ae4eb 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReader.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReader.java @@ -25,7 +25,7 @@ public interface DatastoreReader { /** - * Returns an {@link Entity} for the given {@link Key} or {@code null} if does not exists. + * Returns an {@link Entity} for the given {@link Key} or {@code null} if it doesn't exist. * * @throws DatastoreException upon failure */ @@ -34,7 +34,7 @@ public interface DatastoreReader { /** * Returns an {@link Entity} for each given {@link Key} that exists in the Datastore. * The order of the result is unspecified. - * Results are loaded lazily therefore it is possible to get a {@code DatastoreException} + * Results are loaded lazily, so it is possible to get a {@code DatastoreException} * from the returned {@code Iterator}'s {@link Iterator#hasNext hasNext} or * {@link Iterator#next next} methods. * @@ -45,13 +45,13 @@ public interface DatastoreReader { /** * Returns a list with a value for each given key (ordered by input). - * A {@code null} would be returned for non-existing keys. - * When possible prefer using {@link #get(Key...)} which does not eagerly loads the results. + * {@code null} values are returned for nonexistent keys. + * When possible prefer using {@link #get(Key...)} to avoid eagerly loading the results. */ List fetch(Key... keys); /** - * Submit a {@link Query} and returns its result. + * Submits a {@link Query} and returns its result. * * @throws DatastoreException upon failure */ diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java new file mode 100644 index 000000000000..86214fddbf02 --- /dev/null +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java @@ -0,0 +1,66 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.datastore; + +import com.google.common.collect.ImmutableMap; + +import java.io.Serializable; +import java.util.Map; + +/** + * Specifies options for read operations in Datastore, namely getting/fetching entities and running + * queries. + */ +public abstract class ReadOption implements Serializable { + + private static final long serialVersionUID = -4406964829189800528L; + + /** + * Specifies eventual consistency for reads from Datastore. + */ + public static final class EventualConsistency extends ReadOption { + + private static final long serialVersionUID = -6959530217724666172L; + + private final boolean eventualConsistency; + + private EventualConsistency(boolean eventualConsistency) { + this.eventualConsistency = eventualConsistency; + } + + public boolean isEventual() { + return eventualConsistency; + } + } + + ReadOption() {} + + /** + * Returns a {@code ReadOption} that specifies eventual consistency. + */ + public static EventualConsistency eventualConsistency() { + return new EventualConsistency(true); + } + + static Map, ReadOption> asImmutableMap(ReadOption... options) { + ImmutableMap.Builder, ReadOption> builder = ImmutableMap.builder(); + for (ReadOption option : options) { + builder.put(option.getClass(), option); + } + return builder.build(); + } +} diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java index 5a422927005a..469c14e1c78a 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java @@ -40,7 +40,7 @@ static class ResponseImpl implements Transaction.Response { @Override public List generatedKeys() { - Iterator results = + Iterator results = response.getMutationResultsList().iterator(); List generated = new ArrayList<>(numAutoAllocatedIds); for (int i = 0; i < numAutoAllocatedIds; i++) { @@ -66,7 +66,7 @@ public Entity get(Key key) { @Override public Iterator get(Key... keys) { validateActive(); - com.google.datastore.v1beta3.ReadOptions.Builder readOptionsPb = + com.google.datastore.v1beta3.ReadOptions.Builder readOptionsPb = com.google.datastore.v1beta3.ReadOptions.newBuilder(); readOptionsPb.setTransaction(transaction); return datastore.get(readOptionsPb.build(), keys); @@ -81,7 +81,7 @@ public List fetch(Key... keys) { @Override public QueryResults run(Query query) { validateActive(); - com.google.datastore.v1beta3.ReadOptions.Builder readOptionsPb = + com.google.datastore.v1beta3.ReadOptions.Builder readOptionsPb = com.google.datastore.v1beta3.ReadOptions.newBuilder(); readOptionsPb.setTransaction(transaction); return datastore.run(readOptionsPb.build(), query); @@ -91,7 +91,7 @@ public QueryResults run(Query query) { public Transaction.Response commit() { validateActive(); List mutationsPb = toMutationPbList(); - com.google.datastore.v1beta3.CommitRequest.Builder requestPb = + com.google.datastore.v1beta3.CommitRequest.Builder requestPb = com.google.datastore.v1beta3.CommitRequest.newBuilder(); requestPb.setMode(com.google.datastore.v1beta3.CommitRequest.Mode.TRANSACTIONAL); requestPb.setTransaction(transaction); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreHelperTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreHelperTest.java index 55c8d0cf3ce6..61b266a9abc2 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreHelperTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreHelperTest.java @@ -27,6 +27,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterators; import com.google.gcloud.datastore.Datastore.TransactionCallable; @@ -66,52 +67,100 @@ public void testAllocateId() throws Exception { } @Test - public void testGet() throws Exception { + public void testGetWithDatastore() throws Exception { Datastore datastore = createStrictMock(Datastore.class); IncompleteKey pKey1 = IncompleteKey.builder("ds", "k").build(); Key key1 = Key.builder(pKey1, 1).build(); Entity entity1 = Entity.builder(key1).build(); Key key2 = Key.builder(pKey1, 2).build(); - expect(datastore.get(new Key[]{key1})) + ReadOption eventualConsistency = ReadOption.eventualConsistency(); + expect(datastore.get(Collections.singletonList(key1))) .andReturn(Collections.singletonList(entity1).iterator()); - expect(datastore.get(new Key[]{key2})) + expect(datastore.get(Collections.singletonList(key2))) .andReturn(Collections.emptyIterator()); + expect(datastore.get(Collections.singletonList(key1), eventualConsistency)) + .andReturn(Collections.singletonList(entity1).iterator()); replay(datastore); assertEquals(entity1, DatastoreHelper.get(datastore, key1)); assertNull(DatastoreHelper.get(datastore, key2)); + assertEquals(entity1, DatastoreHelper.get(datastore, key1, eventualConsistency)); verify(datastore); } + @Test + public void testGetWithTransaction() throws Exception { + Transaction transaction = createStrictMock(Transaction.class); + IncompleteKey pKey1 = IncompleteKey.builder("ds", "k").build(); + Key key1 = Key.builder(pKey1, 1).build(); + Entity entity1 = Entity.builder(key1).build(); + Key key2 = Key.builder(pKey1, 2).build(); + expect(transaction.get(new Key[] {key1})) + .andReturn(Collections.singletonList(entity1).iterator()); + expect(transaction.get(new Key[] {key2})).andReturn(Collections.emptyIterator()); + replay(transaction); + assertEquals(entity1, DatastoreHelper.get(transaction, key1)); + assertNull(DatastoreHelper.get(transaction, key2)); + verify(transaction); + } + @Test public void testAdd() throws Exception { Datastore datastore = createStrictMock(Datastore.class); IncompleteKey pKey = IncompleteKey.builder("ds", "k").build(); Key key = Key.builder(pKey, 1).build(); Entity entity = Entity.builder(key).build(); - expect(datastore.add(new Entity[]{entity})) - .andReturn(Collections.singletonList(entity)); + expect(datastore.add(new Entity[] {entity})).andReturn(Collections.singletonList(entity)); replay(datastore); assertEquals(entity, DatastoreHelper.add(datastore, entity)); verify(datastore); } @Test - public void testFetch() throws Exception { + public void testFetchWithDatastore() throws Exception { Datastore datastore = createStrictMock(Datastore.class); IncompleteKey pKey1 = IncompleteKey.builder("ds", "k").build(); Key key1 = Key.builder(pKey1, 1).build(); Key key2 = Key.builder(pKey1, "a").build(); Entity entity1 = Entity.builder(key1).build(); Entity entity2 = Entity.builder(key2).build(); - expect(datastore.get(key1, key2)).andReturn(Iterators.forArray(entity1, entity2)).once(); + ReadOption eventualConsistency = ReadOption.eventualConsistency(); + expect(datastore.get(ImmutableList.of(key1, key2))) + .andReturn(Iterators.forArray(entity1, entity2)) + .once(); + expect(datastore.get(ImmutableList.of(key1, key2), eventualConsistency)) + .andReturn(Iterators.forArray(entity1, entity2)) + .once(); replay(datastore); - List values = DatastoreHelper.fetch(datastore, key1, key2); + List values = DatastoreHelper.fetch(datastore, new Key[] {key1, key2}); + assertEquals(2, values.size()); + assertEquals(entity1, values.get(0)); + assertEquals(entity2, values.get(1)); + values = DatastoreHelper.fetch(datastore, new Key[] {key1, key2}, eventualConsistency); assertEquals(2, values.size()); assertEquals(entity1, values.get(0)); assertEquals(entity2, values.get(1)); verify(datastore); } + @Test + public void testFetchWithTransaction() throws Exception { + Transaction transaction = createStrictMock(Transaction.class); + IncompleteKey pKey1 = IncompleteKey.builder("ds", "k").build(); + Key key1 = Key.builder(pKey1, 1).build(); + Key key2 = Key.builder(pKey1, "a").build(); + Entity entity1 = Entity.builder(key1).build(); + Entity entity2 = Entity.builder(key2).build(); + expect(transaction.get(new Key[] {key1, key2})) + .andReturn(Iterators.forArray(entity1, entity2)) + .once(); + replay(transaction); + List values = DatastoreHelper.fetch(transaction, new Key[] {key1, key2}); + assertEquals(2, values.size()); + assertEquals(entity1, values.get(0)); + assertEquals(entity2, values.get(1)); + verify(transaction); + } + @Test public void testRunInTransaction() throws Exception { final Datastore datastore = createStrictMock(Datastore.class); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index 002e5f6df04f..957ab881e7c4 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -25,7 +25,12 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterators; +import com.google.datastore.v1beta3.LookupResponse; +import com.google.datastore.v1beta3.PartitionId; +import com.google.datastore.v1beta3.ReadOptions.ReadConsistency; +import com.google.datastore.v1beta3.RunQueryResponse; import com.google.gcloud.RetryParams; import com.google.gcloud.datastore.Query.ResultType; import com.google.gcloud.datastore.StructuredQuery.OrderBy; @@ -690,6 +695,37 @@ public void testQueryPaginationWithLimit() throws DatastoreException { return responses; } + @Test + public void testEventuallyConsistentQuery() { + DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); + DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); + EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) + .andReturn(rpcMock); + com.google.datastore.v1beta3.ReadOptions readOption = + com.google.datastore.v1beta3.ReadOptions.newBuilder() + .setReadConsistencyValue(ReadConsistency.EVENTUAL_VALUE) + .build(); + com.google.datastore.v1beta3.GqlQuery query = + com.google.datastore.v1beta3.GqlQuery.newBuilder() + .setQueryString("FROM * SELECT *") + .build(); + com.google.datastore.v1beta3.RunQueryRequest.Builder expectedRequest = + com.google.datastore.v1beta3.RunQueryRequest.newBuilder() + .setReadOptions(readOption) + .setGqlQuery(query) + .setPartitionId(PartitionId.newBuilder().setProjectId(PROJECT_ID).build()); + EasyMock.expect(rpcMock.runQuery(expectedRequest.build())) + .andReturn(RunQueryResponse.newBuilder().build()); + EasyMock.replay(rpcFactoryMock, rpcMock); + Datastore mockDatastore = options.toBuilder() + .retryParams(RetryParams.defaultInstance()) + .serviceRpcFactory(rpcFactoryMock) + .build() + .service(); + mockDatastore.run( + Query.gqlQueryBuilder("FROM * SELECT *").build(), ReadOption.eventualConsistency()); + } + @Test public void testToUrlSafe() { byte[][] invalidUtf8 = @@ -765,6 +801,40 @@ public void testGet() { assertFalse(entity.contains("bla")); } + @Test + public void testLookupEventualConsistency() { + DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); + DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); + EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) + .andReturn(rpcMock); + com.google.datastore.v1beta3.ReadOptions readOption = + com.google.datastore.v1beta3.ReadOptions.newBuilder() + .setReadConsistencyValue(ReadConsistency.EVENTUAL_VALUE) + .build(); + com.google.datastore.v1beta3.Key key = com.google.datastore.v1beta3.Key.newBuilder() + .setPartitionId(PartitionId.newBuilder().setProjectId(PROJECT_ID).build()) + .addPath(com.google.datastore.v1beta3.Key.PathElement.newBuilder() + .setKind("kind1").setName("name").build()) + .build(); + com.google.datastore.v1beta3.LookupRequest lookupRequest = + com.google.datastore.v1beta3.LookupRequest.newBuilder() + .setReadOptions(readOption) + .addKeys(key) + .build(); + EasyMock.expect(rpcMock.lookup(lookupRequest)) + .andReturn(LookupResponse.newBuilder().build()) + .times(3); + EasyMock.replay(rpcFactoryMock, rpcMock); + Datastore mockDatastore = options.toBuilder() + .retryParams(RetryParams.defaultInstance()) + .serviceRpcFactory(rpcFactoryMock) + .build() + .service(); + mockDatastore.get(KEY1, ReadOption.eventualConsistency()); + mockDatastore.get(ImmutableList.of(KEY1), ReadOption.eventualConsistency()); + mockDatastore.fetch(ImmutableList.of(KEY1), ReadOption.eventualConsistency()); + } + @Test public void testGetArrayNoDeferredResults() { datastore.put(ENTITY3); From 438896b96ded6829c3fe869a145ab3cf2c9bcaf9 Mon Sep 17 00:00:00 2001 From: Arie Ozarov Date: Mon, 29 Feb 2016 20:12:00 -0800 Subject: [PATCH 125/375] add list versioned blobs to integration tests --- .../storage/testing/RemoteGcsHelper.java | 5 +- .../gcloud/storage/RemoteGcsHelperTest.java | 23 +++++--- .../gcloud/storage/it/ITStorageTest.java | 55 ++++++++++++++----- 3 files changed, 57 insertions(+), 26 deletions(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/RemoteGcsHelper.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/RemoteGcsHelper.java index 024aa04eba1b..1287ede746d5 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/RemoteGcsHelper.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/RemoteGcsHelper.java @@ -20,6 +20,7 @@ import com.google.gcloud.RetryParams; import com.google.gcloud.storage.BlobInfo; import com.google.gcloud.storage.Storage; +import com.google.gcloud.storage.Storage.BlobListOption; import com.google.gcloud.storage.StorageException; import com.google.gcloud.storage.StorageOptions; @@ -173,8 +174,8 @@ public DeleteBucketTask(Storage storage, String bucket) { @Override public Boolean call() { while (true) { - for (BlobInfo info : storage.list(bucket).values()) { - storage.delete(bucket, info.name()); + for (BlobInfo info : storage.list(bucket, BlobListOption.versions(true)).values()) { + storage.delete(info.blobId()); } try { storage.delete(bucket); diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteGcsHelperTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteGcsHelperTest.java index 2f56bbda7bd9..154554a029fe 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteGcsHelperTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteGcsHelperTest.java @@ -21,6 +21,7 @@ import com.google.common.collect.ImmutableList; import com.google.gcloud.Page; +import com.google.gcloud.storage.Storage.BlobListOption; import com.google.gcloud.storage.testing.RemoteGcsHelper; import org.easymock.EasyMock; @@ -117,9 +118,10 @@ public Iterator iterateAll() { @Test public void testForceDelete() throws InterruptedException, ExecutionException { Storage storageMock = EasyMock.createMock(Storage.class); - EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(blobPage); + EasyMock.expect(storageMock.list(BUCKET_NAME, BlobListOption.versions(true))) + .andReturn(blobPage); for (BlobInfo info : blobList) { - EasyMock.expect(storageMock.delete(BUCKET_NAME, info.name())).andReturn(true); + EasyMock.expect(storageMock.delete(info.blobId())).andReturn(true); } EasyMock.expect(storageMock.delete(BUCKET_NAME)).andReturn(true); EasyMock.replay(storageMock); @@ -132,7 +134,7 @@ public void testForceDeleteTimeout() throws InterruptedException, ExecutionExcep Storage storageMock = EasyMock.createMock(Storage.class); EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(blobPage).anyTimes(); for (BlobInfo info : blobList) { - EasyMock.expect(storageMock.delete(BUCKET_NAME, info.name())).andReturn(true).anyTimes(); + EasyMock.expect(storageMock.delete(info.blobId())).andReturn(true).anyTimes(); } EasyMock.expect(storageMock.delete(BUCKET_NAME)).andThrow(RETRYABLE_EXCEPTION).anyTimes(); EasyMock.replay(storageMock); @@ -143,9 +145,10 @@ public void testForceDeleteTimeout() throws InterruptedException, ExecutionExcep @Test public void testForceDeleteFail() throws InterruptedException, ExecutionException { Storage storageMock = EasyMock.createMock(Storage.class); - EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(blobPage); + EasyMock.expect(storageMock.list(BUCKET_NAME, BlobListOption.versions(true))) + .andReturn(blobPage); for (BlobInfo info : blobList) { - EasyMock.expect(storageMock.delete(BUCKET_NAME, info.name())).andReturn(true); + EasyMock.expect(storageMock.delete(info.blobId())).andReturn(true); } EasyMock.expect(storageMock.delete(BUCKET_NAME)).andThrow(FATAL_EXCEPTION); EasyMock.replay(storageMock); @@ -160,9 +163,10 @@ public void testForceDeleteFail() throws InterruptedException, ExecutionExceptio @Test public void testForceDeleteNoTimeout() { Storage storageMock = EasyMock.createMock(Storage.class); - EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(blobPage); + EasyMock.expect(storageMock.list(BUCKET_NAME, BlobListOption.versions(true))) + .andReturn(blobPage); for (BlobInfo info : blobList) { - EasyMock.expect(storageMock.delete(BUCKET_NAME, info.name())).andReturn(true); + EasyMock.expect(storageMock.delete(info.blobId())).andReturn(true); } EasyMock.expect(storageMock.delete(BUCKET_NAME)).andReturn(true); EasyMock.replay(storageMock); @@ -173,9 +177,10 @@ public void testForceDeleteNoTimeout() { @Test public void testForceDeleteNoTimeoutFail() { Storage storageMock = EasyMock.createMock(Storage.class); - EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(blobPage); + EasyMock.expect(storageMock.list(BUCKET_NAME, BlobListOption.versions(true))) + .andReturn(blobPage); for (BlobInfo info : blobList) { - EasyMock.expect(storageMock.delete(BUCKET_NAME, info.name())).andReturn(true); + EasyMock.expect(storageMock.delete(info.blobId())).andReturn(true); } EasyMock.expect(storageMock.delete(BUCKET_NAME)).andThrow(FATAL_EXCEPTION); EasyMock.replay(storageMock); diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java index 43c2cf6d372b..1adf48a6cf68 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java @@ -28,23 +28,14 @@ import com.google.api.client.util.Lists; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import com.google.gcloud.Page; import com.google.gcloud.ReadChannel; import com.google.gcloud.RestorableState; import com.google.gcloud.WriteChannel; -import com.google.gcloud.storage.BatchRequest; -import com.google.gcloud.storage.BatchResponse; -import com.google.gcloud.storage.Blob; -import com.google.gcloud.storage.BlobId; -import com.google.gcloud.storage.BlobInfo; -import com.google.gcloud.storage.Bucket; -import com.google.gcloud.storage.BucketInfo; -import com.google.gcloud.storage.CopyWriter; -import com.google.gcloud.storage.HttpMethod; -import com.google.gcloud.storage.Storage; +import com.google.gcloud.storage.*; import com.google.gcloud.storage.Storage.BlobField; import com.google.gcloud.storage.Storage.BucketField; -import com.google.gcloud.storage.StorageException; import com.google.gcloud.storage.testing.RemoteGcsHelper; import org.junit.AfterClass; @@ -63,6 +54,7 @@ import java.util.List; import java.util.Map; import java.util.Random; +import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.logging.Level; @@ -302,8 +294,7 @@ public void testListBlobsSelectedFields() { Blob remoteBlob2 = storage.create(blob2); assertNotNull(remoteBlob1); assertNotNull(remoteBlob2); - Page page = - storage.list(BUCKET, + Page page = storage.list(BUCKET, Storage.BlobListOption.prefix("test-list-blobs-selected-fields-blob"), Storage.BlobListOption.fields(BlobField.METADATA)); int index = 0; @@ -331,8 +322,7 @@ public void testListBlobsEmptySelectedFields() { Blob remoteBlob2 = storage.create(blob2); assertNotNull(remoteBlob1); assertNotNull(remoteBlob2); - Page page = storage.list( - BUCKET, + Page page = storage.list(BUCKET, Storage.BlobListOption.prefix("test-list-blobs-empty-selected-fields-blob"), Storage.BlobListOption.fields()); int index = 0; @@ -345,6 +335,41 @@ public void testListBlobsEmptySelectedFields() { assertTrue(remoteBlob2.delete()); } + @Test + public void testListBlobsVersioned() throws ExecutionException, InterruptedException { + String bucketName = RemoteGcsHelper.generateBucketName(); + Bucket bucket = storage.create(BucketInfo.builder(bucketName).versioningEnabled(true).build()); + try { + String[] blobNames = {"test-list-blobs-versioned-blob1", "test-list-blobs-versioned-blob2"}; + BlobInfo blob1 = BlobInfo.builder(bucket, blobNames[0]) + .contentType(CONTENT_TYPE) + .build(); + BlobInfo blob2 = BlobInfo.builder(bucket, blobNames[1]) + .contentType(CONTENT_TYPE) + .build(); + Blob remoteBlob1 = storage.create(blob1); + Blob remoteBlob2 = storage.create(blob2); + Blob remoteBlob3 = storage.create(blob2); + assertNotNull(remoteBlob1); + assertNotNull(remoteBlob2); + assertNotNull(remoteBlob3); + Page page = storage.list(bucketName, + Storage.BlobListOption.prefix("test-list-blobs-versioned-blob"), + Storage.BlobListOption.versions(true)); + Set blobSet = ImmutableSet.of(blobNames[0], blobNames[1]); + for (Blob remoteBlob : page.values()) { + assertEquals(bucketName, remoteBlob.bucket()); + assertTrue(blobSet.contains(remoteBlob.name())); + assertNotNull(remoteBlob.generation()); + } + assertTrue(remoteBlob1.delete()); + assertTrue(remoteBlob2.delete()); + assertTrue(remoteBlob3.delete()); + } finally { + RemoteGcsHelper.forceDelete(storage, bucketName, 5, TimeUnit.SECONDS); + } + } + @Test public void testUpdateBlob() { String blobName = "test-update-blob"; From e66c9a48fc3dc6e952922d01375a2943161f7fca Mon Sep 17 00:00:00 2001 From: Arie Ozarov Date: Tue, 1 Mar 2016 07:13:29 -0800 Subject: [PATCH 126/375] fix style and formatting issue --- .../main/java/com/google/gcloud/storage/Storage.java | 3 +-- .../com/google/gcloud/storage/it/ITStorageTest.java | 12 +++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index 4fa4ba3658be..98f3450b7f10 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -701,8 +701,7 @@ public static BlobListOption recursive(boolean recursive) { } /** - * If set to {@code true}, lists all versions of a blob. - * The default is {@code false}. + * If set to {@code true}, lists all versions of a blob. The default is {@code false}. * * @see Object Versioning */ diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java index 1adf48a6cf68..d239e40246d8 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java @@ -33,9 +33,19 @@ import com.google.gcloud.ReadChannel; import com.google.gcloud.RestorableState; import com.google.gcloud.WriteChannel; -import com.google.gcloud.storage.*; +import com.google.gcloud.storage.BatchRequest; +import com.google.gcloud.storage.BatchResponse; +import com.google.gcloud.storage.Blob; +import com.google.gcloud.storage.BlobId; +import com.google.gcloud.storage.BlobInfo; +import com.google.gcloud.storage.Bucket; +import com.google.gcloud.storage.BucketInfo; +import com.google.gcloud.storage.CopyWriter; +import com.google.gcloud.storage.HttpMethod; +import com.google.gcloud.storage.Storage; import com.google.gcloud.storage.Storage.BlobField; import com.google.gcloud.storage.Storage.BucketField; +import com.google.gcloud.storage.StorageException; import com.google.gcloud.storage.testing.RemoteGcsHelper; import org.junit.AfterClass; From 93810ca74ca1ff26fc86dc03125fb9381076576b Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 1 Mar 2016 16:50:29 +0100 Subject: [PATCH 127/375] Replace com.google.api.client.util.Lists with Guava's Lists --- .../src/main/java/com/google/gcloud/bigquery/FieldValue.java | 2 +- .../test/java/com/google/gcloud/storage/it/ITStorageTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/FieldValue.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/FieldValue.java index 24c4b28b7613..8b27c70db782 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/FieldValue.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/FieldValue.java @@ -20,9 +20,9 @@ import static com.google.common.base.Preconditions.checkState; import com.google.api.client.util.Data; -import com.google.api.client.util.Lists; import com.google.common.base.Function; import com.google.common.base.MoreObjects; +import com.google.common.collect.Lists; import java.io.Serializable; import java.util.List; diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java index d239e40246d8..8e954de57e68 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java @@ -25,10 +25,10 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import com.google.api.client.util.Lists; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; import com.google.gcloud.Page; import com.google.gcloud.ReadChannel; import com.google.gcloud.RestorableState; From 8a3d5d8122496d6a5fe492a3052e49feb3ba60ae Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 1 Mar 2016 17:33:06 +0100 Subject: [PATCH 128/375] Replace repackaged checkNotNull inclusion with Guava's --- .../src/main/java/com/google/gcloud/storage/BucketInfo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BucketInfo.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BucketInfo.java index bf34413f417f..a1de1a07e03e 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BucketInfo.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BucketInfo.java @@ -16,8 +16,8 @@ package com.google.gcloud.storage; -import static com.google.api.client.repackaged.com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.MoreObjects.firstNonNull; +import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.Lists.transform; import com.google.api.client.json.jackson2.JacksonFactory; From 76e3b3ef5ead06e8741d887ca8c337451470692a Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 1 Mar 2016 08:13:53 -0800 Subject: [PATCH 129/375] Clean up test code and javadoc formatting --- .../google/gcloud/datastore/Datastore.java | 21 +- .../gcloud/datastore/DatastoreHelper.java | 15 +- .../gcloud/datastore/DatastoreImpl.java | 15 +- .../gcloud/datastore/DatastoreReader.java | 15 +- .../google/gcloud/datastore/ReadOption.java | 2 +- .../gcloud/datastore/DatastoreTest.java | 452 +++++++----------- 6 files changed, 190 insertions(+), 330 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java index 00b914a36678..c0efaa52b4e8 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java @@ -114,11 +114,11 @@ interface TransactionCallable { Entity get(Key key, ReadOption... options); /** - * Returns an {@link Entity} for each given {@link Key} that exists in the Datastore. - * The order of the result is unspecified. - * Results are loaded lazily, so it is possible to get a {@code DatastoreException} - * from the returned {@code Iterator}'s {@link Iterator#hasNext hasNext} or - * {@link Iterator#next next} methods. {@link ReadOption}s can be specified if desired. + * Returns an {@link Entity} for each given {@link Key} that exists in the Datastore. The order of + * the result is unspecified. Results are loaded lazily, so it is possible to get a + * {@code DatastoreException} from the returned {@code Iterator}'s + * {@link Iterator#hasNext hasNext} or {@link Iterator#next next} methods. {@link ReadOption}s can + * be specified if desired. * * @throws DatastoreException upon failure * @see #get(Key) @@ -126,16 +126,15 @@ interface TransactionCallable { Iterator get(Iterable keys, ReadOption... options); /** - * Returns a list with a value for each given key (ordered by input). - * {@code null} values are returned for nonexistent keys. - * When possible prefer using {@link #get(Key...)} to avoid eagerly loading the results. - * {@link ReadOption}s can be specified if desired. + * Returns a list with a value for each given key (ordered by input). {@code null} values are + * returned for nonexistent keys. When possible prefer using {@link #get(Key...)} to avoid eagerly + * loading the results. {@link ReadOption}s can be specified if desired. */ List fetch(Iterable keys, ReadOption... options); /** - * Submits a {@link Query} and returns its result. - * {@link ReadOption}s can be specified if desired. + * Submits a {@link Query} and returns its result. {@link ReadOption}s can be specified if + * desired. * * @throws DatastoreException upon failure */ diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java index 2873e2f8aafa..e3cf9c055576 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java @@ -56,22 +56,19 @@ static KeyFactory newKeyFactory(DatastoreOptions options) { } /** - * Returns a list with a value for each given key (ordered by input). - * {@code null} values are returned for nonexistent keys. + * Returns a list with a value for each given key (ordered by input). {@code null} values are + * returned for nonexistent keys. */ static List fetch(Transaction reader, Key... keys) { - Iterator entities = reader.get(keys); - return compileEntities(keys, entities); + return compileEntities(keys, reader.get(keys)); } /** - * Returns a list with a value for each given key (ordered by input). - * {@code null} values are returned for nonexistent keys. + * Returns a list with a value for each given key (ordered by input). {@code null} values are + * returned for nonexistent keys. */ static List fetch(Datastore reader, Key[] keys, ReadOption... options) { - Iterator entities; - entities = reader.get(Arrays.asList(keys), options); - return compileEntities(keys, entities); + return compileEntities(keys, reader.get(Arrays.asList(keys), options)); } private static List compileEntities(Key[] keys, Iterator entities) { diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java index 73d25ab140d7..80cf59980de1 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java @@ -210,16 +210,11 @@ public Iterator get(Iterable keys, ReadOption... options) { private static com.google.datastore.v1beta3.ReadOptions toReadOptionsPb(ReadOption... options) { com.google.datastore.v1beta3.ReadOptions readOptionsPb = null; - if (options != null) { - Map, ReadOption> optionsMap = ReadOption.asImmutableMap(options); - EventualConsistency eventualConsistency = - (EventualConsistency) optionsMap.get(EventualConsistency.class); - if (eventualConsistency != null) { - readOptionsPb = - com.google.datastore.v1beta3.ReadOptions.newBuilder() - .setReadConsistency(ReadConsistency.EVENTUAL) - .build(); - } + if (options != null + && ReadOption.asImmutableMap(options).containsKey(EventualConsistency.class)) { + readOptionsPb = com.google.datastore.v1beta3.ReadOptions.newBuilder() + .setReadConsistency(ReadConsistency.EVENTUAL) + .build(); } return readOptionsPb; } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReader.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReader.java index 7ba5089ae4eb..3d6e5ec73243 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReader.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReader.java @@ -32,11 +32,10 @@ public interface DatastoreReader { Entity get(Key key); /** - * Returns an {@link Entity} for each given {@link Key} that exists in the Datastore. - * The order of the result is unspecified. - * Results are loaded lazily, so it is possible to get a {@code DatastoreException} - * from the returned {@code Iterator}'s {@link Iterator#hasNext hasNext} or - * {@link Iterator#next next} methods. + * Returns an {@link Entity} for each given {@link Key} that exists in the Datastore. The order of + * the result is unspecified. Results are loaded lazily, so it is possible to get a + * {@code DatastoreException} from the returned {@code Iterator}'s + * {@link Iterator#hasNext hasNext} or {@link Iterator#next next} methods. * * @throws DatastoreException upon failure * @see #get(Key) @@ -44,9 +43,9 @@ public interface DatastoreReader { Iterator get(Key... key); /** - * Returns a list with a value for each given key (ordered by input). - * {@code null} values are returned for nonexistent keys. - * When possible prefer using {@link #get(Key...)} to avoid eagerly loading the results. + * Returns a list with a value for each given key (ordered by input). {@code null} values are + * returned for nonexistent keys. When possible prefer using {@link #get(Key...)} to avoid eagerly + * loading the results. */ List fetch(Key... keys); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java index 86214fddbf02..f8905716e564 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java @@ -47,7 +47,7 @@ public boolean isEventual() { } } - ReadOption() {} + private ReadOption() {} /** * Returns a {@code ReadOption} that specifies eventual consistency. diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index 957ab881e7c4..23c22ac4f645 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -27,9 +27,14 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterators; +import com.google.datastore.v1beta3.EntityResult; +import com.google.datastore.v1beta3.LookupRequest; import com.google.datastore.v1beta3.LookupResponse; import com.google.datastore.v1beta3.PartitionId; +import com.google.datastore.v1beta3.QueryResultBatch; +import com.google.datastore.v1beta3.ReadOptions; import com.google.datastore.v1beta3.ReadOptions.ReadConsistency; +import com.google.datastore.v1beta3.RunQueryRequest; import com.google.datastore.v1beta3.RunQueryResponse; import com.google.gcloud.RetryParams; import com.google.gcloud.datastore.Query.ResultType; @@ -96,22 +101,24 @@ public class DatastoreTest { private static final FullEntity PARTIAL_ENTITY3 = FullEntity.builder(PARTIAL_ENTITY1).key(IncompleteKey.builder(PROJECT_ID, KIND3).build()) .build(); - private static final Entity ENTITY1 = - Entity.builder(KEY1) - .set("str", STR_VALUE) - .set("date", DATE_TIME_VALUE) - .set("latLng", LAT_LNG_VALUE) - .set("bool", BOOL_VALUE) - .set("partial1", EntityValue.of(PARTIAL_ENTITY1)) - .set("list", LIST_VALUE2) - .build(); + private static final Entity ENTITY1 = Entity.builder(KEY1) + .set("str", STR_VALUE) + .set("date", DATE_TIME_VALUE) + .set("latLng", LAT_LNG_VALUE) + .set("bool", BOOL_VALUE) + .set("partial1", EntityValue.of(PARTIAL_ENTITY1)) + .set("list", LIST_VALUE2) + .build(); private static final Entity ENTITY2 = Entity.builder(ENTITY1).key(KEY2).remove("str") .set("name", "Dan").setNull("null").set("age", 20).build(); private static final Entity ENTITY3 = Entity.builder(ENTITY1).key(KEY3).remove("str") .set("null", NULL_VALUE).set("partial1", PARTIAL_ENTITY2).set("partial2", ENTITY2).build(); private DatastoreOptions options; + private DatastoreOptions rpcMockOptions; private Datastore datastore; + private DatastoreRpcFactory rpcFactoryMock; + private DatastoreRpc rpcMock; private static LocalGcdHelper gcdHelper; private static final int PORT = LocalGcdHelper.findAvailablePort(LocalGcdHelper.DEFAULT_PORT); @@ -134,6 +141,14 @@ public void setUp() { .retryParams(RetryParams.noRetries()) .build(); datastore = options.service(); + rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); + rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); + rpcMockOptions = options + .toBuilder() + .retryParams(RetryParams.defaultInstance()) + .serviceRpcFactory(rpcFactoryMock) + .build(); + EasyMock.expect(rpcFactoryMock.create(rpcMockOptions)).andReturn(rpcMock); StructuredQuery query = Query.keyQueryBuilder().build(); QueryResults result = datastore.run(query); datastore.delete(Iterators.toArray(result, Key.class)); @@ -426,24 +441,13 @@ public void testRunGqlQueryWithCasting() { @Test public void testGqlQueryPagination() throws DatastoreException { - DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); - DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); - EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) - .andReturn(rpcMock); - List responses = - buildResponsesForQueryPagination(); + List responses = buildResponsesForQueryPagination(); for (int i = 0; i < responses.size(); i++) { - EasyMock - .expect(rpcMock.runQuery( - EasyMock.anyObject(com.google.datastore.v1beta3.RunQueryRequest.class))) - .andReturn(responses.get(i)); + EasyMock.expect(rpcMock.runQuery(EasyMock.anyObject(RunQueryRequest.class))) + .andReturn(responses.get(i)); } EasyMock.replay(rpcFactoryMock, rpcMock); - DatastoreOptions options = this.options.toBuilder() - .retryParams(RetryParams.defaultInstance()) - .serviceRpcFactory(rpcFactoryMock) - .build(); - Datastore mockDatastore = options.service(); + Datastore mockDatastore = rpcMockOptions.service(); QueryResults results = mockDatastore.run(Query.gqlQueryBuilder(ResultType.KEY, "select __key__ from *").build()); int count = 0; @@ -480,15 +484,14 @@ public void testRunStructuredQuery() { assertTrue(projectionEntity.names().isEmpty()); assertFalse(results2.hasNext()); - StructuredQuery projectionQuery = - Query.projectionEntityQueryBuilder() - .kind(KIND2) - .projection("age") - .filter(PropertyFilter.gt("age", 18)) - .distinctOn("age") - .orderBy(OrderBy.asc("age")) - .limit(10) - .build(); + StructuredQuery projectionQuery = Query.projectionEntityQueryBuilder() + .kind(KIND2) + .projection("age") + .filter(PropertyFilter.gt("age", 18)) + .distinctOn("age") + .orderBy(OrderBy.asc("age")) + .limit(10) + .build(); QueryResults results4 = datastore.run(projectionQuery); assertTrue(results4.hasNext()); @@ -501,25 +504,14 @@ public void testRunStructuredQuery() { @Test public void testStructuredQueryPagination() throws DatastoreException { - DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); - DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); - EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) - .andReturn(rpcMock); - List responses = - buildResponsesForQueryPagination(); + List responses = buildResponsesForQueryPagination(); for (int i = 0; i < responses.size(); i++) { - EasyMock - .expect(rpcMock.runQuery( - EasyMock.anyObject(com.google.datastore.v1beta3.RunQueryRequest.class))) - .andReturn(responses.get(i)); + EasyMock.expect(rpcMock.runQuery(EasyMock.anyObject(RunQueryRequest.class))) + .andReturn(responses.get(i)); } EasyMock.replay(rpcFactoryMock, rpcMock); - DatastoreOptions options = this.options.toBuilder() - .retryParams(RetryParams.defaultInstance()) - .serviceRpcFactory(rpcFactoryMock) - .build(); - Datastore mockDatastore = options.service(); - QueryResults results = mockDatastore.run(Query.keyQueryBuilder().build()); + Datastore datastore = rpcMockOptions.service(); + QueryResults results = datastore.run(Query.keyQueryBuilder().build()); int count = 0; while (results.hasNext()) { count += 1; @@ -529,85 +521,57 @@ public void testStructuredQueryPagination() throws DatastoreException { EasyMock.verify(rpcFactoryMock, rpcMock); } - private List buildResponsesForQueryPagination() { + private List buildResponsesForQueryPagination() { Entity entity4 = Entity.builder(KEY4).set("value", StringValue.of("value")).build(); Entity entity5 = Entity.builder(KEY5).set("value", "value").build(); datastore.add(ENTITY3, entity4, entity5); - List responses = new ArrayList<>(); + List responses = new ArrayList<>(); Query query = Query.keyQueryBuilder().build(); - com.google.datastore.v1beta3.RunQueryRequest.Builder requestPb = - com.google.datastore.v1beta3.RunQueryRequest.newBuilder(); + RunQueryRequest.Builder requestPb = RunQueryRequest.newBuilder(); query.populatePb(requestPb); - com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb = - com.google.datastore.v1beta3.RunQueryResponse.newBuilder() - .mergeFrom(((DatastoreImpl) datastore).runQuery(requestPb.build())) - .getBatch(); - com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb1 = - com.google.datastore.v1beta3.QueryResultBatch.newBuilder() - .mergeFrom(queryResultBatchPb) - .setMoreResults( - com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType.NOT_FINISHED) - .clearEntityResults() - .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(0, 1)) - .setEndCursor(queryResultBatchPb.getEntityResultsList().get(0).getCursor()) - .build(); - responses.add( - com.google.datastore.v1beta3.RunQueryResponse.newBuilder() - .setBatch(queryResultBatchPb1) - .build()); - com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb2 = - com.google.datastore.v1beta3.QueryResultBatch.newBuilder() - .mergeFrom(queryResultBatchPb) - .setMoreResults( - com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType.NOT_FINISHED) - .clearEntityResults() - .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(1, 3)) - .setEndCursor(queryResultBatchPb.getEntityResultsList().get(2).getCursor()) - .build(); - responses.add( - com.google.datastore.v1beta3.RunQueryResponse.newBuilder() - .setBatch(queryResultBatchPb2) - .build()); - com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb3 = - com.google.datastore.v1beta3.QueryResultBatch.newBuilder() - .mergeFrom(queryResultBatchPb) - .setMoreResults( - com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType.NO_MORE_RESULTS) - .clearEntityResults() - .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(3, 5)) - .setEndCursor(queryResultBatchPb.getEntityResultsList().get(4).getCursor()) - .build(); - responses.add( - com.google.datastore.v1beta3.RunQueryResponse.newBuilder() - .setBatch(queryResultBatchPb3) - .build()); + QueryResultBatch queryResultBatchPb = RunQueryResponse.newBuilder() + .mergeFrom(((DatastoreImpl) datastore).runQuery(requestPb.build())) + .getBatch(); + QueryResultBatch queryResultBatchPb1 = QueryResultBatch.newBuilder() + .mergeFrom(queryResultBatchPb) + .setMoreResults(QueryResultBatch.MoreResultsType.NOT_FINISHED) + .clearEntityResults() + .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(0, 1)) + .setEndCursor(queryResultBatchPb.getEntityResultsList().get(0).getCursor()) + .build(); + responses.add(RunQueryResponse.newBuilder().setBatch(queryResultBatchPb1).build()); + QueryResultBatch queryResultBatchPb2 = QueryResultBatch.newBuilder() + .mergeFrom(queryResultBatchPb) + .setMoreResults(QueryResultBatch.MoreResultsType.NOT_FINISHED) + .clearEntityResults() + .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(1, 3)) + .setEndCursor(queryResultBatchPb.getEntityResultsList().get(2).getCursor()) + .build(); + responses.add(RunQueryResponse.newBuilder().setBatch(queryResultBatchPb2).build()); + QueryResultBatch queryResultBatchPb3 = QueryResultBatch.newBuilder() + .mergeFrom(queryResultBatchPb) + .setMoreResults(QueryResultBatch.MoreResultsType.NO_MORE_RESULTS) + .clearEntityResults() + .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(3, 5)) + .setEndCursor(queryResultBatchPb.getEntityResultsList().get(4).getCursor()) + .build(); + responses.add(RunQueryResponse.newBuilder().setBatch(queryResultBatchPb3).build()); return responses; } public void testQueryPaginationWithLimit() throws DatastoreException { - DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); - DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); - EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) - .andReturn(rpcMock); - List responses = - buildResponsesForQueryPaginationWithLimit(); + List responses = buildResponsesForQueryPaginationWithLimit(); for (int i = 0; i < responses.size(); i++) { - EasyMock.expect( - rpcMock.runQuery( - EasyMock.anyObject(com.google.datastore.v1beta3.RunQueryRequest.class))) + EasyMock.expect(rpcMock.runQuery(EasyMock.anyObject(RunQueryRequest.class))) .andReturn(responses.get(i)); } EasyMock.replay(rpcFactoryMock, rpcMock); - Datastore mockDatastore = options.toBuilder() - .retryParams(RetryParams.defaultInstance()) - .serviceRpcFactory(rpcFactoryMock) - .build() - .service(); + Datastore datastore = rpcMockOptions.service(); int limit = 2; int totalCount = 0; StructuredQuery query = Query.entityQueryBuilder().limit(limit).build(); while (true) { - QueryResults results = mockDatastore.run(query); + QueryResults results = datastore.run(query); int resultCount = 0; while (results.hasNext()) { results.next(); @@ -623,107 +587,72 @@ public void testQueryPaginationWithLimit() throws DatastoreException { EasyMock.verify(rpcFactoryMock, rpcMock); } - private List - buildResponsesForQueryPaginationWithLimit() { + private List buildResponsesForQueryPaginationWithLimit() { Entity entity4 = Entity.builder(KEY4).set("value", StringValue.of("value")).build(); Entity entity5 = Entity.builder(KEY5).set("value", "value").build(); datastore.add(ENTITY3, entity4, entity5); - List responses = new ArrayList<>(); + List responses = new ArrayList<>(); Query query = Query.entityQueryBuilder().build(); - com.google.datastore.v1beta3.RunQueryRequest.Builder requestPb = - com.google.datastore.v1beta3.RunQueryRequest.newBuilder(); + RunQueryRequest.Builder requestPb = RunQueryRequest.newBuilder(); query.populatePb(requestPb); - com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb = - com.google.datastore.v1beta3.RunQueryResponse.newBuilder() - .mergeFrom(((DatastoreImpl) datastore).runQuery(requestPb.build())) - .getBatch(); - com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb1 = - com.google.datastore.v1beta3.QueryResultBatch.newBuilder() - .mergeFrom(queryResultBatchPb) - .setMoreResults( - com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType.NOT_FINISHED) - .clearEntityResults() - .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(0, 1)) - .setEndCursor(queryResultBatchPb.getEntityResultsList().get(0).getCursor()) - .build(); - responses.add( - com.google.datastore.v1beta3.RunQueryResponse.newBuilder() - .setBatch(queryResultBatchPb1) - .build()); - com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb2 = - com.google.datastore.v1beta3.QueryResultBatch.newBuilder() - .mergeFrom(queryResultBatchPb) - .setMoreResults( - com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType - .MORE_RESULTS_AFTER_LIMIT) - .clearEntityResults() - .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(1, 2)) - .setEndCursor( - ByteString.copyFrom(new byte[] {(byte) 0x80})) // test invalid UTF-8 string - .build(); - responses.add( - com.google.datastore.v1beta3.RunQueryResponse.newBuilder() - .setBatch(queryResultBatchPb2) - .build()); - com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb3 = - com.google.datastore.v1beta3.QueryResultBatch.newBuilder() - .mergeFrom(queryResultBatchPb) - .setMoreResults( - com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType - .MORE_RESULTS_AFTER_LIMIT) - .clearEntityResults() - .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(2, 4)) - .setEndCursor(queryResultBatchPb.getEntityResultsList().get(3).getCursor()) - .build(); - responses.add( - com.google.datastore.v1beta3.RunQueryResponse.newBuilder() - .setBatch(queryResultBatchPb3) - .build()); - com.google.datastore.v1beta3.QueryResultBatch queryResultBatchPb4 = - com.google.datastore.v1beta3.QueryResultBatch.newBuilder() - .mergeFrom(queryResultBatchPb) - .setMoreResults( - com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType.NO_MORE_RESULTS) - .clearEntityResults() - .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(4, 5)) - .setEndCursor(queryResultBatchPb.getEntityResultsList().get(4).getCursor()) - .build(); - responses.add( - com.google.datastore.v1beta3.RunQueryResponse.newBuilder() - .setBatch(queryResultBatchPb4) - .build()); + QueryResultBatch queryResultBatchPb = RunQueryResponse.newBuilder() + .mergeFrom(((DatastoreImpl) datastore).runQuery(requestPb.build())) + .getBatch(); + QueryResultBatch queryResultBatchPb1 = QueryResultBatch.newBuilder() + .mergeFrom(queryResultBatchPb) + .setMoreResults(QueryResultBatch.MoreResultsType.NOT_FINISHED) + .clearEntityResults() + .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(0, 1)) + .setEndCursor(queryResultBatchPb.getEntityResultsList().get(0).getCursor()) + .build(); + responses.add(RunQueryResponse.newBuilder().setBatch(queryResultBatchPb1).build()); + QueryResultBatch queryResultBatchPb2 = QueryResultBatch.newBuilder() + .mergeFrom(queryResultBatchPb) + .setMoreResults(QueryResultBatch.MoreResultsType.MORE_RESULTS_AFTER_LIMIT) + .clearEntityResults() + .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(1, 2)) + .setEndCursor( + ByteString.copyFrom(new byte[] {(byte) 0x80})) // test invalid UTF-8 string + .build(); + responses.add(RunQueryResponse.newBuilder().setBatch(queryResultBatchPb2).build()); + QueryResultBatch queryResultBatchPb3 = QueryResultBatch.newBuilder() + .mergeFrom(queryResultBatchPb) + .setMoreResults(QueryResultBatch.MoreResultsType.MORE_RESULTS_AFTER_LIMIT) + .clearEntityResults() + .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(2, 4)) + .setEndCursor(queryResultBatchPb.getEntityResultsList().get(3).getCursor()) + .build(); + responses.add(RunQueryResponse.newBuilder().setBatch(queryResultBatchPb3).build()); + QueryResultBatch queryResultBatchPb4 = QueryResultBatch.newBuilder() + .mergeFrom(queryResultBatchPb) + .setMoreResults(QueryResultBatch.MoreResultsType.NO_MORE_RESULTS) + .clearEntityResults() + .addAllEntityResults(queryResultBatchPb.getEntityResultsList().subList(4, 5)) + .setEndCursor(queryResultBatchPb.getEntityResultsList().get(4).getCursor()) + .build(); + responses.add(RunQueryResponse.newBuilder().setBatch(queryResultBatchPb4).build()); return responses; } @Test - public void testEventuallyConsistentQuery() { - DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); - DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); - EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) - .andReturn(rpcMock); - com.google.datastore.v1beta3.ReadOptions readOption = - com.google.datastore.v1beta3.ReadOptions.newBuilder() - .setReadConsistencyValue(ReadConsistency.EVENTUAL_VALUE) - .build(); - com.google.datastore.v1beta3.GqlQuery query = - com.google.datastore.v1beta3.GqlQuery.newBuilder() - .setQueryString("FROM * SELECT *") - .build(); - com.google.datastore.v1beta3.RunQueryRequest.Builder expectedRequest = - com.google.datastore.v1beta3.RunQueryRequest.newBuilder() - .setReadOptions(readOption) - .setGqlQuery(query) - .setPartitionId(PartitionId.newBuilder().setProjectId(PROJECT_ID).build()); + public void testEventualConsistencyQuery() { + ReadOptions readOption = + ReadOptions.newBuilder().setReadConsistencyValue(ReadConsistency.EVENTUAL_VALUE).build(); + com.google.datastore.v1beta3.GqlQuery query = com.google.datastore.v1beta3.GqlQuery.newBuilder() + .setQueryString("FROM * SELECT *") + .build(); + RunQueryRequest.Builder expectedRequest = RunQueryRequest.newBuilder() + .setReadOptions(readOption) + .setGqlQuery(query) + .setPartitionId(PartitionId.newBuilder().setProjectId(PROJECT_ID) + .build()); EasyMock.expect(rpcMock.runQuery(expectedRequest.build())) .andReturn(RunQueryResponse.newBuilder().build()); EasyMock.replay(rpcFactoryMock, rpcMock); - Datastore mockDatastore = options.toBuilder() - .retryParams(RetryParams.defaultInstance()) - .serviceRpcFactory(rpcFactoryMock) - .build() - .service(); - mockDatastore.run( + Datastore datastore = rpcMockOptions.service(); + datastore.run( Query.gqlQueryBuilder("FROM * SELECT *").build(), ReadOption.eventualConsistency()); + EasyMock.verify(rpcFactoryMock, rpcMock); } @Test @@ -803,36 +732,24 @@ public void testGet() { @Test public void testLookupEventualConsistency() { - DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); - DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); - EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) - .andReturn(rpcMock); - com.google.datastore.v1beta3.ReadOptions readOption = - com.google.datastore.v1beta3.ReadOptions.newBuilder() - .setReadConsistencyValue(ReadConsistency.EVENTUAL_VALUE) - .build(); + ReadOptions readOption = + ReadOptions.newBuilder().setReadConsistencyValue(ReadConsistency.EVENTUAL_VALUE).build(); com.google.datastore.v1beta3.Key key = com.google.datastore.v1beta3.Key.newBuilder() .setPartitionId(PartitionId.newBuilder().setProjectId(PROJECT_ID).build()) .addPath(com.google.datastore.v1beta3.Key.PathElement.newBuilder() .setKind("kind1").setName("name").build()) .build(); - com.google.datastore.v1beta3.LookupRequest lookupRequest = - com.google.datastore.v1beta3.LookupRequest.newBuilder() - .setReadOptions(readOption) - .addKeys(key) - .build(); + LookupRequest lookupRequest = + LookupRequest.newBuilder().setReadOptions(readOption).addKeys(key).build(); EasyMock.expect(rpcMock.lookup(lookupRequest)) .andReturn(LookupResponse.newBuilder().build()) .times(3); EasyMock.replay(rpcFactoryMock, rpcMock); - Datastore mockDatastore = options.toBuilder() - .retryParams(RetryParams.defaultInstance()) - .serviceRpcFactory(rpcFactoryMock) - .build() - .service(); - mockDatastore.get(KEY1, ReadOption.eventualConsistency()); - mockDatastore.get(ImmutableList.of(KEY1), ReadOption.eventualConsistency()); - mockDatastore.fetch(ImmutableList.of(KEY1), ReadOption.eventualConsistency()); + Datastore datastore = rpcMockOptions.service(); + datastore.get(KEY1, ReadOption.eventualConsistency()); + datastore.get(ImmutableList.of(KEY1), ReadOption.eventualConsistency()); + datastore.fetch(ImmutableList.of(KEY1), ReadOption.eventualConsistency()); + EasyMock.verify(rpcFactoryMock, rpcMock); } @Test @@ -898,57 +815,41 @@ private Datastore createDatastoreForDeferredLookup() throws DatastoreException { keysPb.add(KEY3.toPb()); keysPb.add(KEY4.toPb()); keysPb.add(KEY5.toPb()); - List lookupRequests = new ArrayList<>(); + List lookupRequests = new ArrayList<>(); + lookupRequests.add(LookupRequest.newBuilder().addAllKeys(keysPb).build()); lookupRequests.add( - com.google.datastore.v1beta3.LookupRequest.newBuilder().addAllKeys(keysPb).build()); - lookupRequests.add( - com.google.datastore.v1beta3.LookupRequest.newBuilder() + LookupRequest.newBuilder() .addKeys(keysPb.get(2)) .addKeys(keysPb.get(3)) .addKeys(keysPb.get(5)) .build()); - lookupRequests.add( - com.google.datastore.v1beta3.LookupRequest.newBuilder().addKeys(keysPb.get(5)).build()); + lookupRequests.add(LookupRequest.newBuilder().addKeys(keysPb.get(5)).build()); Entity entity4 = Entity.builder(KEY4).set("value", StringValue.of("value")).build(); Entity entity5 = Entity.builder(KEY5).set("value", "value").build(); - List lookupResponses = new ArrayList<>(); + List lookupResponses = new ArrayList<>(); lookupResponses.add( - com.google.datastore.v1beta3.LookupResponse.newBuilder() - .addFound( - com.google.datastore.v1beta3.EntityResult.newBuilder().setEntity(ENTITY1.toPb())) - .addFound( - com.google.datastore.v1beta3.EntityResult.newBuilder().setEntity(entity4.toPb())) + LookupResponse.newBuilder() + .addFound(EntityResult.newBuilder().setEntity(ENTITY1.toPb())) + .addFound(EntityResult.newBuilder().setEntity(entity4.toPb())) .addDeferred(keysPb.get(2)) .addDeferred(keysPb.get(3)) .addDeferred(keysPb.get(5)) .build()); lookupResponses.add( - com.google.datastore.v1beta3.LookupResponse.newBuilder() - .addFound( - com.google.datastore.v1beta3.EntityResult.newBuilder().setEntity(ENTITY3.toPb())) - .addFound( - com.google.datastore.v1beta3.EntityResult.newBuilder().setEntity(entity4.toPb())) + LookupResponse.newBuilder() + .addFound(EntityResult.newBuilder().setEntity(ENTITY3.toPb())) + .addFound(EntityResult.newBuilder().setEntity(entity4.toPb())) .addDeferred(keysPb.get(5)) .build()); lookupResponses.add( - com.google.datastore.v1beta3.LookupResponse.newBuilder() - .addFound( - com.google.datastore.v1beta3.EntityResult.newBuilder().setEntity(entity5.toPb())) + LookupResponse.newBuilder() + .addFound(EntityResult.newBuilder().setEntity(entity5.toPb())) .build()); - DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); - DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); - EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) - .andReturn(rpcMock); for (int i = 0; i < lookupRequests.size(); i++) { EasyMock.expect(rpcMock.lookup(lookupRequests.get(i))).andReturn(lookupResponses.get(i)); } EasyMock.replay(rpcFactoryMock, rpcMock); - DatastoreOptions options = - this.options.toBuilder() - .retryParams(RetryParams.defaultInstance()) - .serviceRpcFactory(rpcFactoryMock) - .build(); - return options.service(); + return rpcMockOptions.service(); } @Test @@ -1044,26 +945,15 @@ public void testKeyFactory() { @Test public void testRetryableException() throws Exception { - com.google.datastore.v1beta3.LookupRequest requestPb = - com.google.datastore.v1beta3.LookupRequest.newBuilder().addKeys(KEY1.toPb()).build(); - com.google.datastore.v1beta3.LookupResponse responsePb = - com.google.datastore.v1beta3.LookupResponse.newBuilder() - .addFound( - com.google.datastore.v1beta3.EntityResult.newBuilder().setEntity(ENTITY1.toPb())) - .build(); - DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); - DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); - EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) - .andReturn(rpcMock); + LookupRequest requestPb = LookupRequest.newBuilder().addKeys(KEY1.toPb()).build(); + LookupResponse responsePb = LookupResponse.newBuilder() + .addFound(EntityResult.newBuilder().setEntity(ENTITY1.toPb())) + .build(); EasyMock.expect(rpcMock.lookup(requestPb)) .andThrow(new DatastoreException(14, "UNAVAILABLE", "UNAVAILABLE", null)) .andReturn(responsePb); EasyMock.replay(rpcFactoryMock, rpcMock); - DatastoreOptions options = this.options.toBuilder() - .retryParams(RetryParams.defaultInstance()) - .serviceRpcFactory(rpcFactoryMock) - .build(); - Datastore datastore = options.service(); + Datastore datastore = rpcMockOptions.service(); Entity entity = datastore.get(KEY1); assertEquals(ENTITY1, entity); EasyMock.verify(rpcFactoryMock, rpcMock); @@ -1071,23 +961,13 @@ public void testRetryableException() throws Exception { @Test public void testNonRetryableException() throws Exception { - com.google.datastore.v1beta3.LookupRequest requestPb = - com.google.datastore.v1beta3.LookupRequest.newBuilder().addKeys(KEY1.toPb()).build(); - DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); - DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); - EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) - .andReturn(rpcMock); + LookupRequest requestPb = LookupRequest.newBuilder().addKeys(KEY1.toPb()).build(); EasyMock.expect(rpcMock.lookup(requestPb)) .andThrow( new DatastoreException(DatastoreException.UNKNOWN_CODE, "denied", "PERMISSION_DENIED")) .times(1); EasyMock.replay(rpcFactoryMock, rpcMock); - RetryParams retryParams = RetryParams.builder().retryMinAttempts(2).build(); - DatastoreOptions options = this.options.toBuilder() - .retryParams(retryParams) - .serviceRpcFactory(rpcFactoryMock) - .build(); - Datastore datastore = options.service(); + Datastore datastore = rpcMockOptions.service(); thrown.expect(DatastoreException.class); thrown.expectMessage("denied"); datastore.get(KEY1); @@ -1096,21 +976,11 @@ public void testNonRetryableException() throws Exception { @Test public void testRuntimeException() throws Exception { - com.google.datastore.v1beta3.LookupRequest requestPb = - com.google.datastore.v1beta3.LookupRequest.newBuilder().addKeys(KEY1.toPb()).build(); - DatastoreRpcFactory rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); - DatastoreRpc rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); - EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(DatastoreOptions.class))) - .andReturn(rpcMock); + LookupRequest requestPb = LookupRequest.newBuilder().addKeys(KEY1.toPb()).build(); String exceptionMessage = "Artificial runtime exception"; - EasyMock.expect(rpcMock.lookup(requestPb)) - .andThrow(new RuntimeException(exceptionMessage)); + EasyMock.expect(rpcMock.lookup(requestPb)).andThrow(new RuntimeException(exceptionMessage)); EasyMock.replay(rpcFactoryMock, rpcMock); - DatastoreOptions options = this.options.toBuilder() - .retryParams(RetryParams.defaultInstance()) - .serviceRpcFactory(rpcFactoryMock) - .build(); - Datastore datastore = options.service(); + Datastore datastore = rpcMockOptions.service(); thrown.expect(DatastoreException.class); thrown.expectMessage(exceptionMessage); datastore.get(KEY1); From 0d794eaf55f61ad3156d3ecbce9b64562e870868 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 1 Mar 2016 10:08:37 -0800 Subject: [PATCH 130/375] Improve eventual consistency javadoc --- .../main/java/com/google/gcloud/datastore/ReadOption.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java index f8905716e564..f0de06d1651d 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java @@ -30,7 +30,8 @@ public abstract class ReadOption implements Serializable { private static final long serialVersionUID = -4406964829189800528L; /** - * Specifies eventual consistency for reads from Datastore. + * Specifies eventual consistency for reads from Datastore. Lookups and ancestor queries using + * this option permit Datastore to return stale results. */ public static final class EventualConsistency extends ReadOption { @@ -50,7 +51,8 @@ public boolean isEventual() { private ReadOption() {} /** - * Returns a {@code ReadOption} that specifies eventual consistency. + * Returns a {@code ReadOption} that specifies eventual consistency, allowing Datastore to return + * stale results from gets, fetches, and ancestor queries. */ public static EventualConsistency eventualConsistency() { return new EventualConsistency(true); From 9b6929bbfdc9dc376fd52464f1df0cda4b5da7e3 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Tue, 1 Mar 2016 11:57:36 -0800 Subject: [PATCH 131/375] Added retryable errors. --- .../java/com/google/gcloud/dns/DnsException.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java index 2092d5909d37..70d7254e9502 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java @@ -16,27 +16,39 @@ package com.google.gcloud.dns; +import com.google.common.collect.ImmutableSet; import com.google.gcloud.BaseServiceException; import com.google.gcloud.RetryHelper.RetryHelperException; import com.google.gcloud.RetryHelper.RetryInterruptedException; import java.io.IOException; +import java.util.Set; /** * DNS service exception. */ public class DnsException extends BaseServiceException { + // see: https://cloud.google.com/dns/troubleshooting + private static final Set RETRYABLE_ERRORS = ImmutableSet.of( + new Error(500, null), + new Error(502, null), + new Error(503, null)); private static final long serialVersionUID = 490302380416260252L; public DnsException(IOException exception) { super(exception, true); } - public DnsException(int code, String message) { + private DnsException(int code, String message) { super(code, message, null, true); } + @Override + protected Set retryableErrors() { + return RETRYABLE_ERRORS; + } + /** * Translate RetryHelperException to the DnsException that caused the error. This method will * always throw an exception. @@ -48,6 +60,4 @@ static DnsException translateAndThrow(RetryHelperException ex) { BaseServiceException.translateAndPropagateIfPossible(ex); throw new DnsException(UNKNOWN_CODE, ex.getMessage()); } - - //TODO(mderka) Add translation and retry functionality. Created issue #593. } From 452e27495dfae67fb43adc96b020fc1bbaa10961 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 2 Mar 2016 15:52:06 +0100 Subject: [PATCH 132/375] Handle eventally consistent blob lists in storage ITs --- .../gcloud/storage/it/ITStorageTest.java | 43 +++++++++++++++---- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java index 8e954de57e68..1bdd14dd79f8 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java @@ -28,6 +28,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterators; import com.google.common.collect.Lists; import com.google.gcloud.Page; import com.google.gcloud.ReadChannel; @@ -287,8 +288,8 @@ public void testGetBlobFailNonExistingGeneration() { assertTrue(remoteBlob.delete()); } - @Test - public void testListBlobsSelectedFields() { + @Test(timeout = 5000) + public void testListBlobsSelectedFields() throws InterruptedException { String[] blobNames = {"test-list-blobs-selected-fields-blob1", "test-list-blobs-selected-fields-blob2"}; ImmutableMap metadata = ImmutableMap.of("k", "v"); @@ -307,10 +308,18 @@ public void testListBlobsSelectedFields() { Page page = storage.list(BUCKET, Storage.BlobListOption.prefix("test-list-blobs-selected-fields-blob"), Storage.BlobListOption.fields(BlobField.METADATA)); - int index = 0; + // Listing blobs is eventually consistent, we loop until the list is of the expected size. The + // test fails if timeout is reached. + while (Iterators.size(page.values().iterator()) != 2) { + Thread.sleep(500); + page = storage.list(BUCKET, + Storage.BlobListOption.prefix("test-list-blobs-selected-fields-blob"), + Storage.BlobListOption.fields(BlobField.METADATA)); + } + Set blobSet = ImmutableSet.of(blobNames[0], blobNames[1]); for (Blob remoteBlob : page.values()) { assertEquals(BUCKET, remoteBlob.bucket()); - assertEquals(blobNames[index++], remoteBlob.name()); + assertTrue(blobSet.contains(remoteBlob.name())); assertEquals(metadata, remoteBlob.metadata()); assertNull(remoteBlob.contentType()); } @@ -318,8 +327,8 @@ public void testListBlobsSelectedFields() { assertTrue(remoteBlob2.delete()); } - @Test - public void testListBlobsEmptySelectedFields() { + @Test(timeout = 5000) + public void testListBlobsEmptySelectedFields() throws InterruptedException { String[] blobNames = {"test-list-blobs-empty-selected-fields-blob1", "test-list-blobs-empty-selected-fields-blob2"}; BlobInfo blob1 = BlobInfo.builder(BUCKET, blobNames[0]) @@ -335,17 +344,25 @@ public void testListBlobsEmptySelectedFields() { Page page = storage.list(BUCKET, Storage.BlobListOption.prefix("test-list-blobs-empty-selected-fields-blob"), Storage.BlobListOption.fields()); - int index = 0; + // Listing blobs is eventually consistent, we loop until the list is of the expected size. The + // test fails if timeout is reached. + while (Iterators.size(page.values().iterator()) != 2) { + Thread.sleep(500); + page = storage.list(BUCKET, + Storage.BlobListOption.prefix("test-list-blobs-empty-selected-fields-blob"), + Storage.BlobListOption.fields()); + } + Set blobSet = ImmutableSet.of(blobNames[0], blobNames[1]); for (Blob remoteBlob : page.values()) { assertEquals(BUCKET, remoteBlob.bucket()); - assertEquals(blobNames[index++], remoteBlob.name()); + assertTrue(blobSet.contains(remoteBlob.name())); assertNull(remoteBlob.contentType()); } assertTrue(remoteBlob1.delete()); assertTrue(remoteBlob2.delete()); } - @Test + @Test(timeout = 10000) public void testListBlobsVersioned() throws ExecutionException, InterruptedException { String bucketName = RemoteGcsHelper.generateBucketName(); Bucket bucket = storage.create(BucketInfo.builder(bucketName).versioningEnabled(true).build()); @@ -366,6 +383,14 @@ public void testListBlobsVersioned() throws ExecutionException, InterruptedExcep Page page = storage.list(bucketName, Storage.BlobListOption.prefix("test-list-blobs-versioned-blob"), Storage.BlobListOption.versions(true)); + // Listing blobs is eventually consistent, we loop until the list is of the expected size. The + // test fails if timeout is reached. + while (Iterators.size(page.values().iterator()) != 3) { + Thread.sleep(500); + page = storage.list(bucketName, + Storage.BlobListOption.prefix("test-list-blobs-versioned-blob"), + Storage.BlobListOption.versions(true)); + } Set blobSet = ImmutableSet.of(blobNames[0], blobNames[1]); for (Blob remoteBlob : page.values()) { assertEquals(bucketName, remoteBlob.bucket()); From 22153aa90264ef13758435b541ec6ee8f17cd620 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Tue, 1 Mar 2016 10:17:19 -0800 Subject: [PATCH 133/375] Added sleep and renamed change completion check. Moved integration test to a separate package and adjusted accordingly. Added missing fails. --- .../google/gcloud/dns/{ => it}/ITDnsTest.java | 125 +++++++++--------- 1 file changed, 64 insertions(+), 61 deletions(-) rename gcloud-java-dns/src/test/java/com/google/gcloud/dns/{ => it}/ITDnsTest.java (92%) diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ITDnsTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java similarity index 92% rename from gcloud-java-dns/src/test/java/com/google/gcloud/dns/ITDnsTest.java rename to gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java index e473d1c4912c..ae721e742ae8 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ITDnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.dns; +package com.google.gcloud.dns.it; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -25,6 +25,14 @@ import com.google.common.collect.ImmutableList; import com.google.gcloud.Page; +import com.google.gcloud.dns.ChangeRequest; +import com.google.gcloud.dns.Dns; +import com.google.gcloud.dns.DnsException; +import com.google.gcloud.dns.DnsOptions; +import com.google.gcloud.dns.DnsRecord; +import com.google.gcloud.dns.ProjectInfo; +import com.google.gcloud.dns.Zone; +import com.google.gcloud.dns.ZoneInfo; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -62,24 +70,20 @@ public class ITDnsTest { .description(ZONE_DESCRIPTION1) .dnsName(ZONE_DNS_NAME1) .build(); - public static final ZoneInfo ZONE_NAME_ERROR = - ZoneInfo.builder(ZONE_NAME_TOO_LONG) - .description(ZONE_DESCRIPTION1) - .dnsName(ZONE_DNS_NAME1) - .build(); - public static final ZoneInfo ZONE_MISSING_DESCRIPTION = - ZoneInfo.builder(ZONE_NAME1) - .dnsName(ZONE_DNS_NAME1) - .build(); - public static final ZoneInfo ZONE_MISSING_DNS_NAME = - ZoneInfo.builder(ZONE_NAME1) - .description(ZONE_DESCRIPTION1) - .build(); - public static final ZoneInfo ZONE_DNS_NO_PERIOD = - ZoneInfo.builder(ZONE_NAME1) - .description(ZONE_DESCRIPTION1) - .dnsName(ZONE_DNS_NAME_NO_PERIOD) - .build(); + public static final ZoneInfo ZONE_NAME_ERROR = ZoneInfo.builder(ZONE_NAME_TOO_LONG) + .description(ZONE_DESCRIPTION1) + .dnsName(ZONE_DNS_NAME1) + .build(); + public static final ZoneInfo ZONE_MISSING_DESCRIPTION = ZoneInfo.builder(ZONE_NAME1) + .dnsName(ZONE_DNS_NAME1) + .build(); + public static final ZoneInfo ZONE_MISSING_DNS_NAME = ZoneInfo.builder(ZONE_NAME1) + .description(ZONE_DESCRIPTION1) + .build(); + public static final ZoneInfo ZONE_DNS_NO_PERIOD = ZoneInfo.builder(ZONE_NAME1) + .description(ZONE_DESCRIPTION1) + .dnsName(ZONE_DNS_NAME_NO_PERIOD) + .build(); public static final DnsRecord A_RECORD_ZONE1 = DnsRecord.builder("www." + ZONE1.dnsName(), DnsRecord.Type.A) .records(ImmutableList.of("123.123.55.1")) @@ -116,7 +120,7 @@ public static void clear() { if (!toDelete.isEmpty()) { ChangeRequest deletion = zone.applyChangeRequest(ChangeRequest.builder().deletions(toDelete).build()); - checkChangeComplete(zone.name(), deletion.id()); + waitUntilComplete(zone.name(), deletion.id()); } zone.delete(); } @@ -145,17 +149,23 @@ public static void after() { } private static void assertEqChangesIgnoreStatus(ChangeRequest expected, ChangeRequest actual) { - ChangeRequest unifiedEx = ChangeRequest.fromPb(expected.toPb().setStatus("pending")); - ChangeRequest unifiedAct = ChangeRequest.fromPb(actual.toPb().setStatus("pending")); - assertEquals(unifiedEx, unifiedAct); + assertEquals(expected.additions(), actual.additions()); + assertEquals(expected.deletions(), actual.deletions()); + assertEquals(expected.id(), actual.id()); + assertEquals(expected.startTimeMillis(), actual.startTimeMillis()); } - private static void checkChangeComplete(String zoneName, String changeId) { + private static void waitUntilComplete(String zoneName, String changeId) { while (true) { ChangeRequest changeRequest = DNS.getChangeRequest(zoneName, changeId, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); if (ChangeRequest.Status.DONE.equals(changeRequest.status())) { - break; + return; + } + try { + Thread.sleep(500); + } catch (InterruptedException e) { + fail("Thread was interrupted while waiting for change processing."); } } } @@ -404,6 +414,7 @@ public void testListZones() { // error in options try { DNS.listZones(Dns.ZoneListOption.pageSize(0)); + fail(); } catch (DnsException ex) { // expected assertEquals(400, ex.code()); @@ -411,6 +422,7 @@ public void testListZones() { } try { DNS.listZones(Dns.ZoneListOption.pageSize(-1)); + fail(); } catch (DnsException ex) { // expected assertEquals(400, ex.code()); @@ -422,6 +434,7 @@ public void testListZones() { // dns name problems try { DNS.listZones(Dns.ZoneListOption.dnsName("aaaaa")); + fail(); } catch (DnsException ex) { // expected assertEquals(400, ex.code()); @@ -529,7 +542,6 @@ public void testDeleteZone() { } } - @Test public void testCreateChange() { try { @@ -542,9 +554,9 @@ public void testCreateChange() { assertTrue(ImmutableList.of(ChangeRequest.Status.PENDING, ChangeRequest.Status.DONE) .contains(created.status())); assertEqChangesIgnoreStatus(created, DNS.getChangeRequest(ZONE1.name(), "1")); - checkChangeComplete(ZONE1.name(), "1"); + waitUntilComplete(ZONE1.name(), "1"); DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - checkChangeComplete(ZONE1.name(), "2"); + waitUntilComplete(ZONE1.name(), "2"); // with options created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); @@ -553,9 +565,9 @@ public void testCreateChange() { assertTrue(created.deletions().isEmpty()); assertEquals("3", created.id()); assertNull(created.status()); - checkChangeComplete(ZONE1.name(), "3"); + waitUntilComplete(ZONE1.name(), "3"); DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - checkChangeComplete(ZONE1.name(), "4"); + waitUntilComplete(ZONE1.name(), "4"); created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); assertTrue(created.additions().isEmpty()); @@ -563,9 +575,9 @@ public void testCreateChange() { assertTrue(created.deletions().isEmpty()); assertEquals("5", created.id()); assertNotNull(created.status()); - checkChangeComplete(ZONE1.name(), "5"); + waitUntilComplete(ZONE1.name(), "5"); DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - checkChangeComplete(ZONE1.name(), "6"); + waitUntilComplete(ZONE1.name(), "6"); created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); assertTrue(created.additions().isEmpty()); @@ -573,9 +585,9 @@ public void testCreateChange() { assertTrue(created.deletions().isEmpty()); assertEquals("7", created.id()); assertNull(created.status()); - checkChangeComplete(ZONE1.name(), "7"); + waitUntilComplete(ZONE1.name(), "7"); DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - checkChangeComplete(ZONE1.name(), "8"); + waitUntilComplete(ZONE1.name(), "8"); created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); assertEquals(CHANGE_ADD_ZONE1.additions(), created.additions()); @@ -584,16 +596,16 @@ public void testCreateChange() { assertEquals("9", created.id()); assertNull(created.status()); // finishes with delete otherwise we cannot delete the zone - checkChangeComplete(ZONE1.name(), "9"); + waitUntilComplete(ZONE1.name(), "9"); created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); - checkChangeComplete(ZONE1.name(), "10"); + waitUntilComplete(ZONE1.name(), "10"); assertEquals(CHANGE_DELETE_ZONE1.deletions(), created.deletions()); assertNull(created.startTimeMillis()); assertTrue(created.additions().isEmpty()); assertEquals("10", created.id()); assertNull(created.status()); - checkChangeComplete(ZONE1.name(), "10"); + waitUntilComplete(ZONE1.name(), "10"); } finally { clear(); } @@ -618,18 +630,19 @@ public void testListChanges() { assertEquals(1, changes.size()); // default change creating SOA and NS // zone has changes ChangeRequest change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); - checkChangeComplete(ZONE1.name(), change.id()); + waitUntilComplete(ZONE1.name(), change.id()); change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - checkChangeComplete(ZONE1.name(), change.id()); + waitUntilComplete(ZONE1.name(), change.id()); change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); - checkChangeComplete(ZONE1.name(), change.id()); + waitUntilComplete(ZONE1.name(), change.id()); change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - checkChangeComplete(ZONE1.name(), change.id()); + waitUntilComplete(ZONE1.name(), change.id()); changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name()).iterateAll()); assertEquals(5, changes.size()); // error in options try { DNS.listChangeRequests(ZONE1.name(), Dns.ChangeRequestListOption.pageSize(0)); + fail(); } catch (DnsException ex) { // expected assertEquals(400, ex.code()); @@ -637,6 +650,7 @@ public void testListChanges() { } try { DNS.listChangeRequests(ZONE1.name(), Dns.ChangeRequestListOption.pageSize(-1)); + fail(); } catch (DnsException ex) { // expected assertEquals(400, ex.code()); @@ -754,27 +768,16 @@ public void testGetProject() { // fetches all fields ProjectInfo project = DNS.getProject(); assertNotNull(project.quota()); - assertNotNull(project.number()); - assertNotNull(project.id()); - assertEquals(PROJECT_ID, project.id()); // options project = DNS.getProject(Dns.ProjectOption.fields(Dns.ProjectField.QUOTA)); assertNotNull(project.quota()); - assertNull(project.number()); - assertNotNull(project.id()); // id is always returned project = DNS.getProject(Dns.ProjectOption.fields(Dns.ProjectField.PROJECT_ID)); assertNull(project.quota()); - assertNull(project.number()); - assertNotNull(project.id()); project = DNS.getProject(Dns.ProjectOption.fields(Dns.ProjectField.PROJECT_NUMBER)); assertNull(project.quota()); - assertNotNull(project.number()); - assertNotNull(project.id()); project = DNS.getProject(Dns.ProjectOption.fields(Dns.ProjectField.PROJECT_NUMBER, Dns.ProjectField.QUOTA, Dns.ProjectField.PROJECT_ID)); assertNotNull(project.quota()); - assertNotNull(project.number()); - assertNotNull(project.id()); } @Test @@ -846,7 +849,7 @@ public void testListDnsRecords() { assertEquals(1, ImmutableList.copyOf(dnsRecordPage.values().iterator()).size()); // test name filter ChangeRequest change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); - checkChangeComplete(ZONE1.name(), change.id()); + waitUntilComplete(ZONE1.name(), change.id()); dnsRecordIterator = DNS.listDnsRecords(ZONE1.name(), Dns.DnsRecordListOption.dnsName(A_RECORD_ZONE1.name())).iterateAll(); counter = 0; @@ -858,7 +861,7 @@ public void testListDnsRecords() { } assertEquals(2, counter); // test type filter - checkChangeComplete(ZONE1.name(), change.id()); + waitUntilComplete(ZONE1.name(), change.id()); dnsRecordIterator = DNS.listDnsRecords(ZONE1.name(), Dns.DnsRecordListOption.dnsName(A_RECORD_ZONE1.name()), Dns.DnsRecordListOption.type(A_RECORD_ZONE1.type())) @@ -874,30 +877,30 @@ public void testListDnsRecords() { // check wrong arguments try { // name is not set - DNS.listDnsRecords(ZONE1.name(), - Dns.DnsRecordListOption.type(A_RECORD_ZONE1.type())); + DNS.listDnsRecords(ZONE1.name(), Dns.DnsRecordListOption.type(A_RECORD_ZONE1.type())); + fail(); } catch (DnsException ex) { // expected assertEquals(400, ex.code()); // todo(mderka) test retry functionality when available } try { - DNS.listDnsRecords(ZONE1.name(), - Dns.DnsRecordListOption.pageSize(0)); + DNS.listDnsRecords(ZONE1.name(), Dns.DnsRecordListOption.pageSize(0)); + fail(); } catch (DnsException ex) { // expected assertEquals(400, ex.code()); // todo(mderka) test retry functionality when available } try { - DNS.listDnsRecords(ZONE1.name(), - Dns.DnsRecordListOption.pageSize(-1)); + DNS.listDnsRecords(ZONE1.name(), Dns.DnsRecordListOption.pageSize(-1)); + fail(); } catch (DnsException ex) { // expected assertEquals(400, ex.code()); // todo(mderka) test retry functionality when available } - checkChangeComplete(ZONE1.name(), change.id()); + waitUntilComplete(ZONE1.name(), change.id()); } finally { clear(); } From 4f2810143b17838a75c59bc5615ec44b86a58cab Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Tue, 1 Mar 2016 16:09:49 -0800 Subject: [PATCH 134/375] Added retries for userRateLimitExceeded and rateLimitExceeded. --- .../src/main/java/com/google/gcloud/dns/DnsException.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java index 70d7254e9502..1ecb98a3fdc6 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java @@ -31,9 +31,12 @@ public class DnsException extends BaseServiceException { // see: https://cloud.google.com/dns/troubleshooting private static final Set RETRYABLE_ERRORS = ImmutableSet.of( + new Error(429, null), new Error(500, null), new Error(502, null), - new Error(503, null)); + new Error(503, null), + new Error(null, "userRateLimitExceeded"), + new Error(null, "rateLimitExceeded")); private static final long serialVersionUID = 490302380416260252L; public DnsException(IOException exception) { From a3fdbbc697b5923848f6d3609b82232994a2433f Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 2 Mar 2016 21:41:08 +0100 Subject: [PATCH 135/375] Add BlobTargetOption and BlobWriteOption classes to Bucket --- .../com/google/gcloud/storage/Bucket.java | 301 +++++++++++++++++- .../com/google/gcloud/storage/BucketTest.java | 145 +++++++++ 2 files changed, 440 insertions(+), 6 deletions(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java index c438f497730e..db255e23db57 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java @@ -16,26 +16,30 @@ package com.google.gcloud.storage; +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.gcloud.storage.Bucket.BucketSourceOption.toGetOptions; import static com.google.gcloud.storage.Bucket.BucketSourceOption.toSourceOptions; +import com.google.common.base.Function; import com.google.common.base.MoreObjects; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import com.google.gcloud.Page; import com.google.gcloud.spi.StorageRpc; import com.google.gcloud.storage.Storage.BlobGetOption; -import com.google.gcloud.storage.Storage.BlobTargetOption; -import com.google.gcloud.storage.Storage.BlobWriteOption; import com.google.gcloud.storage.Storage.BucketTargetOption; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; +import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.Set; /** * A Google cloud storage bucket. @@ -64,7 +68,7 @@ private BucketSourceOption(StorageRpc.Option rpcOption) { super(rpcOption, null); } - private Storage.BucketSourceOption toSourceOptions(BucketInfo bucketInfo) { + private Storage.BucketSourceOption toSourceOption(BucketInfo bucketInfo) { switch (rpcOption()) { case IF_METAGENERATION_MATCH: return Storage.BucketSourceOption.metagenerationMatch(bucketInfo.metageneration()); @@ -108,7 +112,7 @@ static Storage.BucketSourceOption[] toSourceOptions(BucketInfo bucketInfo, new Storage.BucketSourceOption[options.length]; int index = 0; for (BucketSourceOption option : options) { - convertedOptions[index++] = option.toSourceOptions(bucketInfo); + convertedOptions[index++] = option.toSourceOption(bucketInfo); } return convertedOptions; } @@ -124,6 +128,287 @@ static Storage.BucketGetOption[] toGetOptions(BucketInfo bucketInfo, } } + /** + * Class for specifying blob target options when {@code Bucket} methods are used. + */ + public static class BlobTargetOption extends Option { + + private static final Function TO_ENUM = + new Function() { + @Override + public StorageRpc.Option apply(BlobTargetOption blobTargetOption) { + return blobTargetOption.rpcOption(); + } + }; + private static final long serialVersionUID = 8345296337342509425L; + + private BlobTargetOption(StorageRpc.Option rpcOption, Object value) { + super(rpcOption, value); + } + + private StorageRpc.Tuple toTargetOption(BlobInfo blobInfo) { + BlobId blobId = blobInfo.blobId(); + switch (rpcOption()) { + case PREDEFINED_ACL: + return StorageRpc.Tuple.of(blobInfo, + Storage.BlobTargetOption.predefinedAcl((Storage.PredefinedAcl) value())); + case IF_GENERATION_MATCH: + blobId = BlobId.of(blobId.bucket(), blobId.name(), (Long) value()); + return StorageRpc.Tuple.of(blobInfo.toBuilder().blobId(blobId).build(), + Storage.BlobTargetOption.generationMatch()); + case IF_GENERATION_NOT_MATCH: + blobId = BlobId.of(blobId.bucket(), blobId.name(), (Long) value()); + return StorageRpc.Tuple.of(blobInfo.toBuilder().blobId(blobId).build(), + Storage.BlobTargetOption.generationNotMatch()); + case IF_METAGENERATION_MATCH: + return StorageRpc.Tuple.of(blobInfo.toBuilder().metageneration((Long) value()).build(), + Storage.BlobTargetOption.metagenerationMatch()); + case IF_METAGENERATION_NOT_MATCH: + return StorageRpc.Tuple.of(blobInfo.toBuilder().metageneration((Long) value()).build(), + Storage.BlobTargetOption.metagenerationNotMatch()); + default: + throw new AssertionError("Unexpected enum value"); + } + } + + /** + * Returns an option for specifying blob's predefined ACL configuration. + */ + public static BlobTargetOption predefinedAcl(Storage.PredefinedAcl acl) { + return new BlobTargetOption(StorageRpc.Option.PREDEFINED_ACL, acl); + } + + /** + * Returns an option that causes an operation to succeed only if the target blob does not exist. + * This option can not be provided together with {@link #generationMatch(long)} or + * {@link #generationNotMatch(long)}. + */ + public static BlobTargetOption doesNotExist() { + return new BlobTargetOption(StorageRpc.Option.IF_GENERATION_MATCH, 0L); + } + + /** + * Returns an option for blob's data generation match. If this option is used the request will + * fail if generation does not match the provided value. This option can not be provided + * together with {@link #generationNotMatch(long)} or {@link #doesNotExist()}. + */ + public static BlobTargetOption generationMatch(long generation) { + return new BlobTargetOption(StorageRpc.Option.IF_GENERATION_MATCH, generation); + } + + /** + * Returns an option for blob's data generation mismatch. If this option is used the request + * will fail if blob's generation matches the provided value. This option can not be provided + * together with {@link #generationMatch(long)} or {@link #doesNotExist()}. + */ + public static BlobTargetOption generationNotMatch(long generation) { + return new BlobTargetOption(StorageRpc.Option.IF_GENERATION_NOT_MATCH, generation); + } + + /** + * Returns an option for blob's metageneration match. If this option is used the request will + * fail if metageneration does not match the provided value. Either this option or + * {@link #metagenerationNotMatch(long)} can be provided at the same time. + */ + public static BlobTargetOption metagenerationMatch(long metageneration) { + return new BlobTargetOption(StorageRpc.Option.IF_METAGENERATION_MATCH, metageneration); + } + + /** + * Returns an option for blob's metageneration mismatch. If this option is used the request will + * fail if metageneration matches the provided value. Either this option or + * {@link #metagenerationMatch(long)} can be provided at the same time. + */ + public static BlobTargetOption metagenerationNotMatch(long metageneration) { + return new BlobTargetOption(StorageRpc.Option.IF_METAGENERATION_NOT_MATCH, metageneration); + } + + static StorageRpc.Tuple toTargetOptions( + BlobInfo info, BlobTargetOption... options) { + Set optionSet = + Sets.immutableEnumSet(Lists.transform(Arrays.asList(options), TO_ENUM)); + checkArgument(!(optionSet.contains(StorageRpc.Option.IF_METAGENERATION_NOT_MATCH) + && optionSet.contains(StorageRpc.Option.IF_METAGENERATION_MATCH)), + "metagenerationMatch and metagenerationNotMatch options can not be both provided"); + checkArgument(!(optionSet.contains(StorageRpc.Option.IF_GENERATION_NOT_MATCH) + && optionSet.contains(StorageRpc.Option.IF_GENERATION_MATCH)), + "Only one option of generationMatch, doesNotExist or generationNotMatch can be provided"); + Storage.BlobTargetOption[] convertedOptions = new Storage.BlobTargetOption[options.length]; + BlobInfo targetInfo = info; + int index = 0; + for (BlobTargetOption option : options) { + StorageRpc.Tuple target = + option.toTargetOption(targetInfo); + targetInfo = target.x(); + convertedOptions[index++] = target.y(); + } + return StorageRpc.Tuple.of(targetInfo, convertedOptions); + } + } + + /** + * Class for specifying blob write options when {@code Bucket} methods are used. + */ + public static class BlobWriteOption implements Serializable { + + private static final Function TO_ENUM = + new Function() { + @Override + public Storage.BlobWriteOption.Option apply(BlobWriteOption blobWriteOption) { + return blobWriteOption.option; + } + }; + private static final long serialVersionUID = 4722190734541993114L; + + private final Storage.BlobWriteOption.Option option; + private final Object value; + + private StorageRpc.Tuple toWriteOption(BlobInfo blobInfo) { + BlobId blobId = blobInfo.blobId(); + switch (option) { + case PREDEFINED_ACL: + return StorageRpc.Tuple.of(blobInfo, + Storage.BlobWriteOption.predefinedAcl((Storage.PredefinedAcl) value)); + case IF_GENERATION_MATCH: + blobId = BlobId.of(blobId.bucket(), blobId.name(), (Long) value); + return StorageRpc.Tuple.of(blobInfo.toBuilder().blobId(blobId).build(), + Storage.BlobWriteOption.generationMatch()); + case IF_GENERATION_NOT_MATCH: + blobId = BlobId.of(blobId.bucket(), blobId.name(), (Long) value); + return StorageRpc.Tuple.of(blobInfo.toBuilder().blobId(blobId).build(), + Storage.BlobWriteOption.generationNotMatch()); + case IF_METAGENERATION_MATCH: + return StorageRpc.Tuple.of(blobInfo.toBuilder().metageneration((Long) value).build(), + Storage.BlobWriteOption.metagenerationMatch()); + case IF_METAGENERATION_NOT_MATCH: + return StorageRpc.Tuple.of(blobInfo.toBuilder().metageneration((Long) value).build(), + Storage.BlobWriteOption.metagenerationNotMatch()); + case IF_MD5_MATCH: + return StorageRpc.Tuple.of(blobInfo.toBuilder().md5((String) value).build(), + Storage.BlobWriteOption.md5Match()); + case IF_CRC32C_MATCH: + return StorageRpc.Tuple.of(blobInfo.toBuilder().crc32c((String) value).build(), + Storage.BlobWriteOption.crc32cMatch()); + default: + throw new AssertionError("Unexpected enum value"); + } + } + + private BlobWriteOption(Storage.BlobWriteOption.Option option, Object value) { + this.option = option; + this.value = value; + } + + @Override + public int hashCode() { + return Objects.hash(option, value); + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (!(obj instanceof BlobWriteOption)) { + return false; + } + final BlobWriteOption other = (BlobWriteOption) obj; + return this.option == other.option && Objects.equals(this.value, other.value); + } + + /** + * Returns an option for specifying blob's predefined ACL configuration. + */ + public static BlobWriteOption predefinedAcl(Storage.PredefinedAcl acl) { + return new BlobWriteOption(Storage.BlobWriteOption.Option.PREDEFINED_ACL, acl); + } + + /** + * Returns an option that causes an operation to succeed only if the target blob does not exist. + * This option can not be provided together with {@link #generationMatch(long)} or + * {@link #generationNotMatch(long)}. + */ + public static BlobWriteOption doesNotExist() { + return new BlobWriteOption(Storage.BlobWriteOption.Option.IF_GENERATION_MATCH, 0L); + } + + /** + * Returns an option for blob's data generation match. If this option is used the request will + * fail if generation does not match the provided value. This option can not be provided + * together with {@link #generationNotMatch(long)} or {@link #doesNotExist()}. + */ + public static BlobWriteOption generationMatch(long generation) { + return new BlobWriteOption(Storage.BlobWriteOption.Option.IF_GENERATION_MATCH, generation); + } + + /** + * Returns an option for blob's data generation mismatch. If this option is used the request + * will fail if generation matches the provided value. This option can not be provided + * together with {@link #generationMatch(long)} or {@link #doesNotExist()}. + */ + public static BlobWriteOption generationNotMatch(long generation) { + return new BlobWriteOption(Storage.BlobWriteOption.Option.IF_GENERATION_NOT_MATCH, + generation); + } + + /** + * Returns an option for blob's metageneration match. If this option is used the request will + * fail if metageneration does not match the provided value. Either this option or + * {@link #metagenerationNotMatch(long)} can be provided at the same time. + */ + public static BlobWriteOption metagenerationMatch(long metageneration) { + return new BlobWriteOption(Storage.BlobWriteOption.Option.IF_METAGENERATION_MATCH, + metageneration); + } + + /** + * Returns an option for blob's metageneration mismatch. If this option is used the request will + * fail if metageneration matches the provided value. Either this option or + * {@link #metagenerationMatch(long)} can be provided at the same time. + */ + public static BlobWriteOption metagenerationNotMatch(long metageneration) { + return new BlobWriteOption(Storage.BlobWriteOption.Option.IF_METAGENERATION_NOT_MATCH, + metageneration); + } + + /** + * Returns an option for blob's data MD5 hash match. If this option is used the request will + * fail if blobs' data MD5 hash does not match the provided value. + */ + public static BlobWriteOption md5Match(String md5) { + return new BlobWriteOption(Storage.BlobWriteOption.Option.IF_MD5_MATCH, md5); + } + + /** + * Returns an option for blob's data CRC32C checksum match. If this option is used the request + * will fail if blobs' data CRC32C checksum does not match the provided value. + */ + public static BlobWriteOption crc32cMatch(String crc32c) { + return new BlobWriteOption(Storage.BlobWriteOption.Option.IF_CRC32C_MATCH, crc32c); + } + + static StorageRpc.Tuple toWriteOptions( + BlobInfo info, BlobWriteOption... options) { + Set optionSet = + Sets.immutableEnumSet(Lists.transform(Arrays.asList(options), TO_ENUM)); + checkArgument(!(optionSet.contains(Storage.BlobWriteOption.Option.IF_METAGENERATION_NOT_MATCH) + && optionSet.contains(Storage.BlobWriteOption.Option.IF_METAGENERATION_MATCH)), + "metagenerationMatch and metagenerationNotMatch options can not be both provided"); + checkArgument(!(optionSet.contains(Storage.BlobWriteOption.Option.IF_GENERATION_NOT_MATCH) + && optionSet.contains(Storage.BlobWriteOption.Option.IF_GENERATION_MATCH)), + "Only one option of generationMatch, doesNotExist or generationNotMatch can be provided"); + Storage.BlobWriteOption[] convertedOptions = new Storage.BlobWriteOption[options.length]; + BlobInfo writeInfo = info; + int index = 0; + for (BlobWriteOption option : options) { + StorageRpc.Tuple write = option.toWriteOption(writeInfo); + writeInfo = write.x(); + convertedOptions[index++] = write.y(); + } + return StorageRpc.Tuple.of(writeInfo, convertedOptions); + } + } + /** * Builder for {@code Bucket}. */ @@ -357,7 +642,9 @@ public List get(String blobName1, String blobName2, String... blobNames) { public Blob create(String blob, byte[] content, String contentType, BlobTargetOption... options) { BlobInfo blobInfo = BlobInfo.builder(BlobId.of(name(), blob)) .contentType(MoreObjects.firstNonNull(contentType, Storage.DEFAULT_CONTENT_TYPE)).build(); - return storage.create(blobInfo, content, options); + StorageRpc.Tuple target = + BlobTargetOption.toTargetOptions(blobInfo, options); + return storage.create(target.x(), content, target.y()); } /** @@ -377,7 +664,9 @@ public Blob create(String blob, InputStream content, String contentType, BlobWriteOption... options) { BlobInfo blobInfo = BlobInfo.builder(BlobId.of(name(), blob)) .contentType(MoreObjects.firstNonNull(contentType, Storage.DEFAULT_CONTENT_TYPE)).build(); - return storage.create(blobInfo, content, options); + StorageRpc.Tuple write = + BlobWriteOption.toWriteOptions(blobInfo, options); + return storage.create(write.x(), content, write.y()); } /** diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java index aac8a79d3a47..236411e0c2d8 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java @@ -42,7 +42,9 @@ import org.easymock.Capture; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import java.io.ByteArrayInputStream; import java.io.InputStream; @@ -99,6 +101,9 @@ public class BucketTest { private Bucket expectedBucket; private Iterable blobResults; + @Rule + public ExpectedException thrown = ExpectedException.none(); + @Before public void setUp() { storage = createStrictMock(Storage.class); @@ -301,6 +306,72 @@ public void testCreateNullContentType() throws Exception { assertEquals(expectedBlob, blob); } + @Test + public void testCreateWithOptions() throws Exception { + initializeExpectedBucket(5); + BlobInfo info = BlobInfo.builder(BlobId.of("b", "n", 42L)) + .contentType(CONTENT_TYPE) + .metageneration(24L) + .build(); + Blob expectedBlob = new Blob(serviceMockReturnsOptions, new BlobInfo.BuilderImpl(info)); + byte[] content = {0xD, 0xE, 0xA, 0xD}; + Storage.PredefinedAcl acl = Storage.PredefinedAcl.ALL_AUTHENTICATED_USERS; + expect(storage.options()).andReturn(mockOptions); + expect(storage.create(info, content, Storage.BlobTargetOption.generationMatch(), + Storage.BlobTargetOption.metagenerationMatch(), + Storage.BlobTargetOption.predefinedAcl(acl))).andReturn(expectedBlob); + replay(storage); + initializeBucket(); + Blob blob = bucket.create("n", content, CONTENT_TYPE, + Bucket.BlobTargetOption.generationMatch(42L), + Bucket.BlobTargetOption.metagenerationMatch(24L), + Bucket.BlobTargetOption.predefinedAcl(acl)); + assertEquals(expectedBlob, blob); + } + + @Test + public void testCreateNotExists() throws Exception { + initializeExpectedBucket(5); + BlobInfo info = BlobInfo.builder(BlobId.of("b", "n", 0L)).contentType(CONTENT_TYPE).build(); + Blob expectedBlob = new Blob(serviceMockReturnsOptions, new BlobInfo.BuilderImpl(info)); + byte[] content = {0xD, 0xE, 0xA, 0xD}; + expect(storage.options()).andReturn(mockOptions); + expect(storage.create(info, content, Storage.BlobTargetOption.generationMatch())) + .andReturn(expectedBlob); + replay(storage); + initializeBucket(); + Blob blob = bucket.create("n", content, CONTENT_TYPE, Bucket.BlobTargetOption.doesNotExist()); + assertEquals(expectedBlob, blob); + } + + @Test + public void testCreateWithWrongGenerationOptions() throws Exception { + initializeExpectedBucket(4); + expect(storage.options()).andReturn(mockOptions); + replay(storage); + initializeBucket(); + byte[] content = {0xD, 0xE, 0xA, 0xD}; + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage( + "Only one option of generationMatch, doesNotExist or generationNotMatch can be provided"); + bucket.create("n", content, CONTENT_TYPE, Bucket.BlobTargetOption.generationMatch(42L), + Bucket.BlobTargetOption.generationNotMatch(24L)); + } + + @Test + public void testCreateWithWrongMetagenerationOptions() throws Exception { + initializeExpectedBucket(4); + expect(storage.options()).andReturn(mockOptions); + replay(storage); + initializeBucket(); + byte[] content = {0xD, 0xE, 0xA, 0xD}; + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage( + "metagenerationMatch and metagenerationNotMatch options can not be both provided"); + bucket.create("n", content, CONTENT_TYPE, Bucket.BlobTargetOption.metagenerationMatch(42L), + Bucket.BlobTargetOption.metagenerationNotMatch(24L)); + } + @Test public void testCreateFromStream() throws Exception { initializeExpectedBucket(5); @@ -331,6 +402,80 @@ public void testCreateFromStreamNullContentType() throws Exception { assertEquals(expectedBlob, blob); } + @Test + public void testCreateFromStreamWithOptions() throws Exception { + initializeExpectedBucket(5); + BlobInfo info = BlobInfo.builder(BlobId.of("b", "n", 42L)) + .contentType(CONTENT_TYPE) + .metageneration(24L) + .crc32c("crc") + .md5("md5") + .build(); + Blob expectedBlob = new Blob(serviceMockReturnsOptions, new BlobInfo.BuilderImpl(info)); + byte[] content = {0xD, 0xE, 0xA, 0xD}; + Storage.PredefinedAcl acl = Storage.PredefinedAcl.ALL_AUTHENTICATED_USERS; + InputStream streamContent = new ByteArrayInputStream(content); + expect(storage.options()).andReturn(mockOptions); + expect(storage.create(info, streamContent, Storage.BlobWriteOption.generationMatch(), + Storage.BlobWriteOption.metagenerationMatch(), Storage.BlobWriteOption.predefinedAcl(acl), + Storage.BlobWriteOption.crc32cMatch(), Storage.BlobWriteOption.md5Match())) + .andReturn(expectedBlob); + replay(storage); + initializeBucket(); + Blob blob = bucket.create("n", streamContent, CONTENT_TYPE, + Bucket.BlobWriteOption.generationMatch(42L), + Bucket.BlobWriteOption.metagenerationMatch(24L), Bucket.BlobWriteOption.predefinedAcl(acl), + Bucket.BlobWriteOption.crc32cMatch("crc"), Bucket.BlobWriteOption.md5Match("md5")); + assertEquals(expectedBlob, blob); + } + + @Test + public void testCreateFromStreamNotExists() throws Exception { + initializeExpectedBucket(5); + BlobInfo info = BlobInfo.builder(BlobId.of("b", "n", 0L)).contentType(CONTENT_TYPE).build(); + Blob expectedBlob = new Blob(serviceMockReturnsOptions, new BlobInfo.BuilderImpl(info)); + byte[] content = {0xD, 0xE, 0xA, 0xD}; + InputStream streamContent = new ByteArrayInputStream(content); + expect(storage.options()).andReturn(mockOptions); + expect(storage.create(info, streamContent, Storage.BlobWriteOption.generationMatch())) + .andReturn(expectedBlob); + replay(storage); + initializeBucket(); + Blob blob = + bucket.create("n", streamContent, CONTENT_TYPE, Bucket.BlobWriteOption.doesNotExist()); + assertEquals(expectedBlob, blob); + } + + @Test + public void testCreateFromStreamWithWrongGenerationOptions() throws Exception { + initializeExpectedBucket(4); + expect(storage.options()).andReturn(mockOptions); + replay(storage); + initializeBucket(); + byte[] content = {0xD, 0xE, 0xA, 0xD}; + InputStream streamContent = new ByteArrayInputStream(content); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage( + "Only one option of generationMatch, doesNotExist or generationNotMatch can be provided"); + bucket.create("n", streamContent, CONTENT_TYPE, Bucket.BlobWriteOption.generationMatch(42L), + Bucket.BlobWriteOption.generationNotMatch(24L)); + } + + @Test + public void testCreateFromStreamWithWrongMetagenerationOptions() throws Exception { + initializeExpectedBucket(4); + expect(storage.options()).andReturn(mockOptions); + replay(storage); + initializeBucket(); + byte[] content = {0xD, 0xE, 0xA, 0xD}; + InputStream streamContent = new ByteArrayInputStream(content); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage( + "metagenerationMatch and metagenerationNotMatch options can not be both provided"); + bucket.create("n", streamContent, CONTENT_TYPE, Bucket.BlobWriteOption.metagenerationMatch(42L), + Bucket.BlobWriteOption.metagenerationNotMatch(24L)); + } + @Test public void testToBuilder() { expect(storage.options()).andReturn(mockOptions).times(4); From 36003385f3fb321a52af6533374fa7b3489b1ec7 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 3 Mar 2016 00:32:08 +0100 Subject: [PATCH 136/375] Reword javadoc in BlobTargetOption and BlobWriteOption --- .../java/com/google/gcloud/storage/Bucket.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java index db255e23db57..d318626f4207 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java @@ -207,8 +207,8 @@ public static BlobTargetOption generationNotMatch(long generation) { /** * Returns an option for blob's metageneration match. If this option is used the request will - * fail if metageneration does not match the provided value. Either this option or - * {@link #metagenerationNotMatch(long)} can be provided at the same time. + * fail if metageneration does not match the provided value. This option can not be provided + * together with {@link #metagenerationNotMatch(long)}. */ public static BlobTargetOption metagenerationMatch(long metageneration) { return new BlobTargetOption(StorageRpc.Option.IF_METAGENERATION_MATCH, metageneration); @@ -216,8 +216,8 @@ public static BlobTargetOption metagenerationMatch(long metageneration) { /** * Returns an option for blob's metageneration mismatch. If this option is used the request will - * fail if metageneration matches the provided value. Either this option or - * {@link #metagenerationMatch(long)} can be provided at the same time. + * fail if metageneration matches the provided value. This option can not be provided together + * with {@link #metagenerationMatch(long)}. */ public static BlobTargetOption metagenerationNotMatch(long metageneration) { return new BlobTargetOption(StorageRpc.Option.IF_METAGENERATION_NOT_MATCH, metageneration); @@ -353,8 +353,8 @@ public static BlobWriteOption generationNotMatch(long generation) { /** * Returns an option for blob's metageneration match. If this option is used the request will - * fail if metageneration does not match the provided value. Either this option or - * {@link #metagenerationNotMatch(long)} can be provided at the same time. + * fail if metageneration does not match the provided value. This option can not be provided + * together with {@link #metagenerationNotMatch(long)}. */ public static BlobWriteOption metagenerationMatch(long metageneration) { return new BlobWriteOption(Storage.BlobWriteOption.Option.IF_METAGENERATION_MATCH, @@ -363,8 +363,8 @@ public static BlobWriteOption metagenerationMatch(long metageneration) { /** * Returns an option for blob's metageneration mismatch. If this option is used the request will - * fail if metageneration matches the provided value. Either this option or - * {@link #metagenerationMatch(long)} can be provided at the same time. + * fail if metageneration matches the provided value. This option can not be provided together + * with {@link #metagenerationMatch(long)}. */ public static BlobWriteOption metagenerationNotMatch(long metageneration) { return new BlobWriteOption(Storage.BlobWriteOption.Option.IF_METAGENERATION_NOT_MATCH, From 5858809c9eee2c561f9496552328e6ab1b4bdb40 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Wed, 2 Mar 2016 17:32:17 -0800 Subject: [PATCH 137/375] pom.xml version edit --- gcloud-java-dns/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcloud-java-dns/pom.xml b/gcloud-java-dns/pom.xml index 5f04f261d500..1a559473cc82 100644 --- a/gcloud-java-dns/pom.xml +++ b/gcloud-java-dns/pom.xml @@ -13,7 +13,7 @@ com.google.gcloud gcloud-java-pom - 0.1.3-SNAPSHOT + 0.1.5-SNAPSHOT gcloud-java-dns From 622dcc9055f082b44ed32abfda9e585c7e76ce8e Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 3 Mar 2016 10:13:17 +0100 Subject: [PATCH 138/375] Replace values().iterator() with iterateAll() in blob list ITs --- .../gcloud/storage/it/ITStorageTest.java | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java index 1bdd14dd79f8..38521ae5e137 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java @@ -101,13 +101,12 @@ public static void afterClass() throws ExecutionException, InterruptedException @Test(timeout = 5000) public void testListBuckets() throws InterruptedException { - Iterator bucketIterator = - storage.list(Storage.BucketListOption.prefix(BUCKET), - Storage.BucketListOption.fields()).values().iterator(); + Iterator bucketIterator = storage.list(Storage.BucketListOption.prefix(BUCKET), + Storage.BucketListOption.fields()).iterateAll(); while (!bucketIterator.hasNext()) { Thread.sleep(500); bucketIterator = storage.list(Storage.BucketListOption.prefix(BUCKET), - Storage.BucketListOption.fields()).values().iterator(); + Storage.BucketListOption.fields()).iterateAll(); } while (bucketIterator.hasNext()) { Bucket remoteBucket = bucketIterator.next(); @@ -310,14 +309,16 @@ public void testListBlobsSelectedFields() throws InterruptedException { Storage.BlobListOption.fields(BlobField.METADATA)); // Listing blobs is eventually consistent, we loop until the list is of the expected size. The // test fails if timeout is reached. - while (Iterators.size(page.values().iterator()) != 2) { + while (Iterators.size(page.iterateAll()) != 2) { Thread.sleep(500); page = storage.list(BUCKET, Storage.BlobListOption.prefix("test-list-blobs-selected-fields-blob"), Storage.BlobListOption.fields(BlobField.METADATA)); } Set blobSet = ImmutableSet.of(blobNames[0], blobNames[1]); - for (Blob remoteBlob : page.values()) { + Iterator iterator = page.iterateAll(); + while (iterator.hasNext()) { + Blob remoteBlob = iterator.next(); assertEquals(BUCKET, remoteBlob.bucket()); assertTrue(blobSet.contains(remoteBlob.name())); assertEquals(metadata, remoteBlob.metadata()); @@ -346,14 +347,16 @@ public void testListBlobsEmptySelectedFields() throws InterruptedException { Storage.BlobListOption.fields()); // Listing blobs is eventually consistent, we loop until the list is of the expected size. The // test fails if timeout is reached. - while (Iterators.size(page.values().iterator()) != 2) { + while (Iterators.size(page.iterateAll()) != 2) { Thread.sleep(500); page = storage.list(BUCKET, Storage.BlobListOption.prefix("test-list-blobs-empty-selected-fields-blob"), Storage.BlobListOption.fields()); } Set blobSet = ImmutableSet.of(blobNames[0], blobNames[1]); - for (Blob remoteBlob : page.values()) { + Iterator iterator = page.iterateAll(); + while (iterator.hasNext()) { + Blob remoteBlob = iterator.next(); assertEquals(BUCKET, remoteBlob.bucket()); assertTrue(blobSet.contains(remoteBlob.name())); assertNull(remoteBlob.contentType()); @@ -362,7 +365,7 @@ public void testListBlobsEmptySelectedFields() throws InterruptedException { assertTrue(remoteBlob2.delete()); } - @Test(timeout = 10000) + @Test(timeout = 15000) public void testListBlobsVersioned() throws ExecutionException, InterruptedException { String bucketName = RemoteGcsHelper.generateBucketName(); Bucket bucket = storage.create(BucketInfo.builder(bucketName).versioningEnabled(true).build()); @@ -385,14 +388,16 @@ public void testListBlobsVersioned() throws ExecutionException, InterruptedExcep Storage.BlobListOption.versions(true)); // Listing blobs is eventually consistent, we loop until the list is of the expected size. The // test fails if timeout is reached. - while (Iterators.size(page.values().iterator()) != 3) { + while (Iterators.size(page.iterateAll()) != 3) { Thread.sleep(500); page = storage.list(bucketName, Storage.BlobListOption.prefix("test-list-blobs-versioned-blob"), Storage.BlobListOption.versions(true)); } Set blobSet = ImmutableSet.of(blobNames[0], blobNames[1]); - for (Blob remoteBlob : page.values()) { + Iterator iterator = page.iterateAll(); + while (iterator.hasNext()) { + Blob remoteBlob = iterator.next(); assertEquals(bucketName, remoteBlob.bucket()); assertTrue(blobSet.contains(remoteBlob.name())); assertNotNull(remoteBlob.generation()); From 86845061f481d0125ba18ce044cd242e396f40af Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Thu, 3 Mar 2016 09:48:50 -0800 Subject: [PATCH 139/375] Added missing waits for change completion. --- .../test/java/com/google/gcloud/dns/it/ITDnsTest.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java index ae721e742ae8..fd257c681225 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java @@ -52,11 +52,10 @@ public class ITDnsTest { public static final String PREFIX = "gcldjvit-"; public static final Dns DNS = DnsOptions.builder().build().service(); - public static final String PROJECT_ID = DNS.options().projectId(); public static final String ZONE_NAME1 = (PREFIX + UUID.randomUUID()).substring(0, 32); public static final String ZONE_NAME_EMPTY_DESCRIPTION = - ("gcldjvit-" + UUID.randomUUID()).substring(0, 32); - public static final String ZONE_NAME_TOO_LONG = (PREFIX + UUID.randomUUID()); + (PREFIX + UUID.randomUUID()).substring(0, 32); + public static final String ZONE_NAME_TOO_LONG = PREFIX + UUID.randomUUID(); public static final String ZONE_DESCRIPTION1 = "first zone"; public static final String ZONE_DNS_NAME1 = ZONE_NAME1 + ".com."; public static final String ZONE_DNS_EMPTY_DESCRIPTION = ZONE_NAME_EMPTY_DESCRIPTION + ".com."; @@ -727,6 +726,7 @@ public void testGetChange() { ChangeRequest created = zone.applyChangeRequest(CHANGE_ADD_ZONE1); ChangeRequest retrieved = DNS.getChangeRequest(zone.name(), created.id()); assertEqChangesIgnoreStatus(created, retrieved); + waitUntilComplete(zone.name(), created.id()); zone.applyChangeRequest(CHANGE_DELETE_ZONE1); // with options created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, @@ -734,30 +734,35 @@ public void testGetChange() { retrieved = DNS.getChangeRequest(zone.name(), created.id(), Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); assertEqChangesIgnoreStatus(created, retrieved); + waitUntilComplete(zone.name(), created.id()); zone.applyChangeRequest(CHANGE_DELETE_ZONE1); created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); retrieved = DNS.getChangeRequest(zone.name(), created.id(), Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); assertEqChangesIgnoreStatus(created, retrieved); + waitUntilComplete(zone.name(), created.id()); zone.applyChangeRequest(CHANGE_DELETE_ZONE1); created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); retrieved = DNS.getChangeRequest(zone.name(), created.id(), Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); assertEqChangesIgnoreStatus(created, retrieved); + waitUntilComplete(zone.name(), created.id()); zone.applyChangeRequest(CHANGE_DELETE_ZONE1); created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); retrieved = DNS.getChangeRequest(zone.name(), created.id(), Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); assertEqChangesIgnoreStatus(created, retrieved); + waitUntilComplete(zone.name(), created.id()); // finishes with delete otherwise we cannot delete the zone created = zone.applyChangeRequest(CHANGE_DELETE_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); retrieved = DNS.getChangeRequest(zone.name(), created.id(), Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); assertEqChangesIgnoreStatus(created, retrieved); + waitUntilComplete(zone.name(), created.id()); } finally { clear(); } From 8dd8786a5e9a38c7738889a2a6bca23848d3a3ee Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 4 Mar 2016 15:32:20 +0100 Subject: [PATCH 140/375] Remove redundant throws from services method signatures --- .../com/google/gcloud/bigquery/BigQuery.java | 53 ++++---- .../google/gcloud/bigquery/BigQueryImpl.java | 59 ++++----- .../com/google/gcloud/spi/BigQueryRpc.java | 87 +++++++++--- .../google/gcloud/spi/DefaultBigQueryRpc.java | 45 +++---- .../com/google/gcloud/spi/DatastoreRpc.java | 40 +++++- .../gcloud/spi/DefaultDatastoreRpc.java | 14 +- .../resourcemanager/ResourceManager.java | 2 +- .../gcloud/spi/DefaultResourceManagerRpc.java | 13 +- .../google/gcloud/spi/ResourceManagerRpc.java | 56 ++++++-- .../google/gcloud/spi/DefaultStorageRpc.java | 24 ++-- .../com/google/gcloud/spi/StorageRpc.java | 125 ++++++++++++++---- .../com/google/gcloud/storage/Storage.java | 44 +++--- 12 files changed, 364 insertions(+), 198 deletions(-) diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java index 4b5d3ef0c81a..986c595e350d 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java @@ -457,35 +457,35 @@ public static QueryResultsOption maxWaitTime(long maxWaitTime) { * * @throws BigQueryException upon failure */ - Dataset create(DatasetInfo dataset, DatasetOption... options) throws BigQueryException; + Dataset create(DatasetInfo dataset, DatasetOption... options); /** * Creates a new table. * * @throws BigQueryException upon failure */ - Table create(TableInfo table, TableOption... options) throws BigQueryException; + Table create(TableInfo table, TableOption... options); /** * Creates a new job. * * @throws BigQueryException upon failure */ - Job create(JobInfo job, JobOption... options) throws BigQueryException; + Job create(JobInfo job, JobOption... options); /** * Returns the requested dataset or {@code null} if not found. * * @throws BigQueryException upon failure */ - Dataset getDataset(String datasetId, DatasetOption... options) throws BigQueryException; + Dataset getDataset(String datasetId, DatasetOption... options); /** * Returns the requested dataset or {@code null} if not found. * * @throws BigQueryException upon failure */ - Dataset getDataset(DatasetId datasetId, DatasetOption... options) throws BigQueryException; + Dataset getDataset(DatasetId datasetId, DatasetOption... options); /** * Lists the project's datasets. This method returns partial information on each dataset @@ -495,7 +495,7 @@ public static QueryResultsOption maxWaitTime(long maxWaitTime) { * * @throws BigQueryException upon failure */ - Page listDatasets(DatasetListOption... options) throws BigQueryException; + Page listDatasets(DatasetListOption... options); /** * Deletes the requested dataset. @@ -503,7 +503,7 @@ public static QueryResultsOption maxWaitTime(long maxWaitTime) { * @return {@code true} if dataset was deleted, {@code false} if it was not found * @throws BigQueryException upon failure */ - boolean delete(String datasetId, DatasetDeleteOption... options) throws BigQueryException; + boolean delete(String datasetId, DatasetDeleteOption... options); /** * Deletes the requested dataset. @@ -511,7 +511,7 @@ public static QueryResultsOption maxWaitTime(long maxWaitTime) { * @return {@code true} if dataset was deleted, {@code false} if it was not found * @throws BigQueryException upon failure */ - boolean delete(DatasetId datasetId, DatasetDeleteOption... options) throws BigQueryException; + boolean delete(DatasetId datasetId, DatasetDeleteOption... options); /** * Deletes the requested table. @@ -519,7 +519,7 @@ public static QueryResultsOption maxWaitTime(long maxWaitTime) { * @return {@code true} if table was deleted, {@code false} if it was not found * @throws BigQueryException upon failure */ - boolean delete(String datasetId, String tableId) throws BigQueryException; + boolean delete(String datasetId, String tableId); /** * Deletes the requested table. @@ -527,35 +527,35 @@ public static QueryResultsOption maxWaitTime(long maxWaitTime) { * @return {@code true} if table was deleted, {@code false} if it was not found * @throws BigQueryException upon failure */ - boolean delete(TableId tableId) throws BigQueryException; + boolean delete(TableId tableId); /** * Updates dataset information. * * @throws BigQueryException upon failure */ - Dataset update(DatasetInfo dataset, DatasetOption... options) throws BigQueryException; + Dataset update(DatasetInfo dataset, DatasetOption... options); /** * Updates table information. * * @throws BigQueryException upon failure */ - Table update(TableInfo table, TableOption... options) throws BigQueryException; + Table update(TableInfo table, TableOption... options); /** * Returns the requested table or {@code null} if not found. * * @throws BigQueryException upon failure */ - Table getTable(String datasetId, String tableId, TableOption... options) throws BigQueryException; + Table getTable(String datasetId, String tableId, TableOption... options); /** * Returns the requested table or {@code null} if not found. * * @throws BigQueryException upon failure */ - Table getTable(TableId tableId, TableOption... options) throws BigQueryException; + Table getTable(TableId tableId, TableOption... options); /** * Lists the tables in the dataset. This method returns partial information on each table @@ -566,7 +566,7 @@ public static QueryResultsOption maxWaitTime(long maxWaitTime) { * * @throws BigQueryException upon failure */ - Page listTables(String datasetId, TableListOption... options) throws BigQueryException; + Page
    listTables(String datasetId, TableListOption... options); /** * Lists the tables in the dataset. This method returns partial information on each table @@ -577,14 +577,14 @@ public static QueryResultsOption maxWaitTime(long maxWaitTime) { * * @throws BigQueryException upon failure */ - Page
    listTables(DatasetId datasetId, TableListOption... options) throws BigQueryException; + Page
    listTables(DatasetId datasetId, TableListOption... options); /** * Sends an insert all request. * * @throws BigQueryException upon failure */ - InsertAllResponse insertAll(InsertAllRequest request) throws BigQueryException; + InsertAllResponse insertAll(InsertAllRequest request); /** * Lists the table's rows. @@ -592,36 +592,35 @@ public static QueryResultsOption maxWaitTime(long maxWaitTime) { * @throws BigQueryException upon failure */ Page> listTableData(String datasetId, String tableId, - TableDataListOption... options) throws BigQueryException; + TableDataListOption... options); /** * Lists the table's rows. * * @throws BigQueryException upon failure */ - Page> listTableData(TableId tableId, TableDataListOption... options) - throws BigQueryException; + Page> listTableData(TableId tableId, TableDataListOption... options); /** * Returns the requested job or {@code null} if not found. * * @throws BigQueryException upon failure */ - Job getJob(String jobId, JobOption... options) throws BigQueryException; + Job getJob(String jobId, JobOption... options); /** * Returns the requested job or {@code null} if not found. * * @throws BigQueryException upon failure */ - Job getJob(JobId jobId, JobOption... options) throws BigQueryException; + Job getJob(JobId jobId, JobOption... options); /** * Lists the jobs. * * @throws BigQueryException upon failure */ - Page listJobs(JobListOption... options) throws BigQueryException; + Page listJobs(JobListOption... options); /** * Sends a job cancel request. This call will return immediately. The job status can then be @@ -632,7 +631,7 @@ Page> listTableData(TableId tableId, TableDataListOption... opt * found * @throws BigQueryException upon failure */ - boolean cancel(String jobId) throws BigQueryException; + boolean cancel(String jobId); /** * Sends a job cancel request. This call will return immediately. The job status can then be @@ -643,21 +642,21 @@ Page> listTableData(TableId tableId, TableDataListOption... opt * found * @throws BigQueryException upon failure */ - boolean cancel(JobId tableId) throws BigQueryException; + boolean cancel(JobId tableId); /** * Runs the query associated with the request. * * @throws BigQueryException upon failure */ - QueryResponse query(QueryRequest request) throws BigQueryException; + QueryResponse query(QueryRequest request); /** * Returns results of the query associated with the provided job. * * @throws BigQueryException upon failure */ - QueryResponse getQueryResults(JobId job, QueryResultsOption... options) throws BigQueryException; + QueryResponse getQueryResults(JobId job, QueryResultsOption... options); /** * Returns a channel to write data to be inserted into a BigQuery table. Data format and other diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryImpl.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryImpl.java index 1158dd86c83d..ce881c6ea079 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryImpl.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryImpl.java @@ -153,7 +153,7 @@ public QueryResult nextPage() { } @Override - public Dataset create(DatasetInfo dataset, DatasetOption... options) throws BigQueryException { + public Dataset create(DatasetInfo dataset, DatasetOption... options) { final com.google.api.services.bigquery.model.Dataset datasetPb = dataset.setProjectId(options().projectId()).toPb(); final Map optionsMap = optionMap(options); @@ -171,7 +171,7 @@ public com.google.api.services.bigquery.model.Dataset call() { } @Override - public Table create(TableInfo table, TableOption... options) throws BigQueryException { + public Table create(TableInfo table, TableOption... options) { final com.google.api.services.bigquery.model.Table tablePb = table.setProjectId(options().projectId()).toPb(); final Map optionsMap = optionMap(options); @@ -189,7 +189,7 @@ public com.google.api.services.bigquery.model.Table call() { } @Override - public Job create(JobInfo job, JobOption... options) throws BigQueryException { + public Job create(JobInfo job, JobOption... options) { final com.google.api.services.bigquery.model.Job jobPb = job.setProjectId(options().projectId()).toPb(); final Map optionsMap = optionMap(options); @@ -207,13 +207,12 @@ public com.google.api.services.bigquery.model.Job call() { } @Override - public Dataset getDataset(String datasetId, DatasetOption... options) throws BigQueryException { + public Dataset getDataset(String datasetId, DatasetOption... options) { return getDataset(DatasetId.of(datasetId), options); } @Override - public Dataset getDataset(final DatasetId datasetId, DatasetOption... options) - throws BigQueryException { + public Dataset getDataset(final DatasetId datasetId, DatasetOption... options) { final Map optionsMap = optionMap(options); try { com.google.api.services.bigquery.model.Dataset answer = @@ -230,7 +229,7 @@ public com.google.api.services.bigquery.model.Dataset call() { } @Override - public Page listDatasets(DatasetListOption... options) throws BigQueryException { + public Page listDatasets(DatasetListOption... options) { return listDatasets(options(), optionMap(options)); } @@ -261,13 +260,12 @@ public Dataset apply(com.google.api.services.bigquery.model.Dataset dataset) { } @Override - public boolean delete(String datasetId, DatasetDeleteOption... options) throws BigQueryException { + public boolean delete(String datasetId, DatasetDeleteOption... options) { return delete(DatasetId.of(datasetId), options); } @Override - public boolean delete(final DatasetId datasetId, DatasetDeleteOption... options) - throws BigQueryException { + public boolean delete(final DatasetId datasetId, DatasetDeleteOption... options) { final Map optionsMap = optionMap(options); try { return runWithRetries(new Callable() { @@ -282,12 +280,12 @@ public Boolean call() { } @Override - public boolean delete(String datasetId, String tableId) throws BigQueryException { + public boolean delete(String datasetId, String tableId) { return delete(TableId.of(datasetId, tableId)); } @Override - public boolean delete(final TableId tableId) throws BigQueryException { + public boolean delete(final TableId tableId) { try { return runWithRetries(new Callable() { @Override @@ -301,7 +299,7 @@ public Boolean call() { } @Override - public Dataset update(DatasetInfo dataset, DatasetOption... options) throws BigQueryException { + public Dataset update(DatasetInfo dataset, DatasetOption... options) { final com.google.api.services.bigquery.model.Dataset datasetPb = dataset.setProjectId(options().projectId()).toPb(); final Map optionsMap = optionMap(options); @@ -319,7 +317,7 @@ public com.google.api.services.bigquery.model.Dataset call() { } @Override - public Table update(TableInfo table, TableOption... options) throws BigQueryException { + public Table update(TableInfo table, TableOption... options) { final com.google.api.services.bigquery.model.Table tablePb = table.setProjectId(options().projectId()).toPb(); final Map optionsMap = optionMap(options); @@ -337,13 +335,12 @@ public com.google.api.services.bigquery.model.Table call() { } @Override - public Table getTable(final String datasetId, final String tableId, TableOption... options) - throws BigQueryException { + public Table getTable(final String datasetId, final String tableId, TableOption... options) { return getTable(TableId.of(datasetId, tableId), options); } @Override - public Table getTable(final TableId tableId, TableOption... options) throws BigQueryException { + public Table getTable(final TableId tableId, TableOption... options) { final Map optionsMap = optionMap(options); try { com.google.api.services.bigquery.model.Table answer = @@ -360,14 +357,12 @@ public com.google.api.services.bigquery.model.Table call() { } @Override - public Page
    listTables(String datasetId, TableListOption... options) - throws BigQueryException { + public Page
    listTables(String datasetId, TableListOption... options) { return listTables(datasetId, options(), optionMap(options)); } @Override - public Page
    listTables(DatasetId datasetId, TableListOption... options) - throws BigQueryException { + public Page
    listTables(DatasetId datasetId, TableListOption... options) { return listTables(datasetId.dataset(), options(), optionMap(options)); } @@ -399,7 +394,7 @@ public Table apply(com.google.api.services.bigquery.model.Table table) { } @Override - public InsertAllResponse insertAll(InsertAllRequest request) throws BigQueryException { + public InsertAllResponse insertAll(InsertAllRequest request) { final TableId tableId = request.table(); final TableDataInsertAllRequest requestPb = new TableDataInsertAllRequest(); requestPb.setIgnoreUnknownValues(request.ignoreUnknownValues()); @@ -418,13 +413,12 @@ public Rows apply(RowToInsert rowToInsert) { @Override public Page> listTableData(String datasetId, String tableId, - TableDataListOption... options) throws BigQueryException { + TableDataListOption... options) { return listTableData(TableId.of(datasetId, tableId), options(), optionMap(options)); } @Override - public Page> listTableData(TableId tableId, TableDataListOption... options) - throws BigQueryException { + public Page> listTableData(TableId tableId, TableDataListOption... options) { return listTableData(tableId, options(), optionMap(options)); } @@ -459,12 +453,12 @@ public List apply(TableRow rowPb) { } @Override - public Job getJob(String jobId, JobOption... options) throws BigQueryException { + public Job getJob(String jobId, JobOption... options) { return getJob(JobId.of(jobId), options); } @Override - public Job getJob(final JobId jobId, JobOption... options) throws BigQueryException { + public Job getJob(final JobId jobId, JobOption... options) { final Map optionsMap = optionMap(options); try { com.google.api.services.bigquery.model.Job answer = @@ -481,7 +475,7 @@ public com.google.api.services.bigquery.model.Job call() { } @Override - public Page listJobs(JobListOption... options) throws BigQueryException { + public Page listJobs(JobListOption... options) { return listJobs(options(), optionMap(options)); } @@ -508,12 +502,12 @@ public Job apply(com.google.api.services.bigquery.model.Job job) { } @Override - public boolean cancel(String jobId) throws BigQueryException { + public boolean cancel(String jobId) { return cancel(JobId.of(jobId)); } @Override - public boolean cancel(final JobId jobId) throws BigQueryException { + public boolean cancel(final JobId jobId) { try { return runWithRetries(new Callable() { @Override @@ -527,7 +521,7 @@ public Boolean call() { } @Override - public QueryResponse query(final QueryRequest request) throws BigQueryException { + public QueryResponse query(final QueryRequest request) { try { com.google.api.services.bigquery.model.QueryResponse results = runWithRetries(new Callable() { @@ -566,8 +560,7 @@ public com.google.api.services.bigquery.model.QueryResponse call() { } @Override - public QueryResponse getQueryResults(JobId job, QueryResultsOption... options) - throws BigQueryException { + public QueryResponse getQueryResults(JobId job, QueryResultsOption... options) { Map optionsMap = optionMap(options); return getQueryResults(job, options(), optionsMap); } diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/spi/BigQueryRpc.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/spi/BigQueryRpc.java index 6062e19950e0..a1935e5ab136 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/spi/BigQueryRpc.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/spi/BigQueryRpc.java @@ -100,7 +100,7 @@ public Y y() { * * @throws BigQueryException upon failure */ - Dataset getDataset(String datasetId, Map options) throws BigQueryException; + Dataset getDataset(String datasetId, Map options); /** * Lists the project's datasets. Partial information is returned on a dataset (datasetReference, @@ -108,13 +108,28 @@ public Y y() { * * @throws BigQueryException upon failure */ - Tuple> listDatasets(Map options) throws BigQueryException; + Tuple> listDatasets(Map options); - Dataset create(Dataset dataset, Map options) throws BigQueryException; + /** + * Creates a new dataset. + * + * @throws BigQueryException upon failure + */ + Dataset create(Dataset dataset, Map options); - Table create(Table table, Map options) throws BigQueryException; + /** + * Creates a new table. + * + * @throws BigQueryException upon failure + */ + Table create(Table table, Map options); - Job create(Job job, Map options) throws BigQueryException; + /** + * Creates a new job. + * + * @throws BigQueryException upon failure + */ + Job create(Job job, Map options); /** * Delete the requested dataset. @@ -122,18 +137,28 @@ public Y y() { * @return {@code true} if dataset was deleted, {@code false} if it was not found * @throws BigQueryException upon failure */ - boolean deleteDataset(String datasetId, Map options) throws BigQueryException; + boolean deleteDataset(String datasetId, Map options); - Dataset patch(Dataset dataset, Map options) throws BigQueryException; + /** + * Updates dataset information. + * + * @throws BigQueryException upon failure + */ + Dataset patch(Dataset dataset, Map options); - Table patch(Table table, Map options) throws BigQueryException; + /** + * Updates table information. + * + * @throws BigQueryException upon failure + */ + Table patch(Table table, Map options); /** * Returns the requested table or {@code null} if not found. * * @throws BigQueryException upon failure */ - Table getTable(String datasetId, String tableId, Map options) throws BigQueryException; + Table getTable(String datasetId, String tableId, Map options); /** * Lists the dataset's tables. Partial information is returned on a table (tableReference, @@ -141,8 +166,7 @@ public Y y() { * * @throws BigQueryException upon failure */ - Tuple> listTables(String dataset, Map options) - throws BigQueryException; + Tuple> listTables(String dataset, Map options); /** * Delete the requested table. @@ -150,27 +174,37 @@ Tuple> listTables(String dataset, Map options * @return {@code true} if table was deleted, {@code false} if it was not found * @throws BigQueryException upon failure */ - boolean deleteTable(String datasetId, String tableId) throws BigQueryException; + boolean deleteTable(String datasetId, String tableId); + /** + * Sends an insert all request. + * + * @throws BigQueryException upon failure + */ TableDataInsertAllResponse insertAll(String datasetId, String tableId, - TableDataInsertAllRequest request) throws BigQueryException; + TableDataInsertAllRequest request); + /** + * Lists the table's rows. + * + * @throws BigQueryException upon failure + */ Tuple> listTableData(String datasetId, String tableId, - Map options) throws BigQueryException; + Map options); /** * Returns the requested job or {@code null} if not found. * * @throws BigQueryException upon failure */ - Job getJob(String jobId, Map options) throws BigQueryException; + Job getJob(String jobId, Map options); /** * Lists the project's jobs. * * @throws BigQueryException upon failure */ - Tuple> listJobs(Map options) throws BigQueryException; + Tuple> listJobs(Map options); /** * Sends a job cancel request. This call will return immediately, and the client will need to poll @@ -180,12 +214,21 @@ Tuple> listTableData(String datasetId, String tableId * found * @throws BigQueryException upon failure */ - boolean cancel(String jobId) throws BigQueryException; + boolean cancel(String jobId); - GetQueryResultsResponse getQueryResults(String jobId, Map options) - throws BigQueryException; + /** + * Returns results of the query associated with the provided job. + * + * @throws BigQueryException upon failure + */ + GetQueryResultsResponse getQueryResults(String jobId, Map options); - QueryResponse query(QueryRequest request) throws BigQueryException; + /** + * Runs the query associated with the request. + * + * @throws BigQueryException upon failure + */ + QueryResponse query(QueryRequest request); /** * Opens a resumable upload session to load data into a BigQuery table and returns an upload URI. @@ -193,7 +236,7 @@ GetQueryResultsResponse getQueryResults(String jobId, Map options) * @param configuration load configuration * @throws BigQueryException upon failure */ - String open(JobConfiguration configuration) throws BigQueryException; + String open(JobConfiguration configuration); /** * Uploads the provided data to the resumable upload session at the specified position. @@ -207,5 +250,5 @@ GetQueryResultsResponse getQueryResults(String jobId, Map options) * @throws BigQueryException upon failure */ void write(String uploadId, byte[] toWrite, int toWriteOffset, long destOffset, int length, - boolean last) throws BigQueryException; + boolean last); } diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/spi/DefaultBigQueryRpc.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/spi/DefaultBigQueryRpc.java index b57f1dc8a128..a5c44129955a 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/spi/DefaultBigQueryRpc.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/spi/DefaultBigQueryRpc.java @@ -90,7 +90,7 @@ private static BigQueryException translate(IOException exception) { } @Override - public Dataset getDataset(String datasetId, Map options) throws BigQueryException { + public Dataset getDataset(String datasetId, Map options) { try { return bigquery.datasets() .get(this.options.projectId(), datasetId) @@ -106,8 +106,7 @@ public Dataset getDataset(String datasetId, Map options) throws BigQu } @Override - public Tuple> listDatasets(Map options) - throws BigQueryException { + public Tuple> listDatasets(Map options) { try { DatasetList datasetsList = bigquery.datasets() .list(this.options.projectId()) @@ -135,7 +134,7 @@ public Dataset apply(DatasetList.Datasets datasetPb) { } @Override - public Dataset create(Dataset dataset, Map options) throws BigQueryException { + public Dataset create(Dataset dataset, Map options) { try { return bigquery.datasets().insert(this.options.projectId(), dataset) .setFields(FIELDS.getString(options)) @@ -146,8 +145,7 @@ public Dataset create(Dataset dataset, Map options) throws BigQueryEx } @Override - public Table create(Table table, Map options) - throws BigQueryException { + public Table create(Table table, Map options) { try { // unset the type, as it is output only table.setType(null); @@ -161,7 +159,7 @@ public Table create(Table table, Map options) } @Override - public Job create(Job job, Map options) throws BigQueryException { + public Job create(Job job, Map options) { try { return bigquery.jobs() .insert(this.options.projectId(), job) @@ -173,7 +171,7 @@ public Job create(Job job, Map options) throws BigQueryException { } @Override - public boolean deleteDataset(String datasetId, Map options) throws BigQueryException { + public boolean deleteDataset(String datasetId, Map options) { try { bigquery.datasets().delete(this.options.projectId(), datasetId) .setDeleteContents(DELETE_CONTENTS.getBoolean(options)) @@ -189,7 +187,7 @@ public boolean deleteDataset(String datasetId, Map options) throws Bi } @Override - public Dataset patch(Dataset dataset, Map options) throws BigQueryException { + public Dataset patch(Dataset dataset, Map options) { try { DatasetReference reference = dataset.getDatasetReference(); return bigquery.datasets() @@ -202,7 +200,7 @@ public Dataset patch(Dataset dataset, Map options) throws BigQueryExc } @Override - public Table patch(Table table, Map options) throws BigQueryException { + public Table patch(Table table, Map options) { try { // unset the type, as it is output only table.setType(null); @@ -217,8 +215,7 @@ public Table patch(Table table, Map options) throws BigQueryException } @Override - public Table getTable(String datasetId, String tableId, Map options) - throws BigQueryException { + public Table getTable(String datasetId, String tableId, Map options) { try { return bigquery.tables() .get(this.options.projectId(), datasetId, tableId) @@ -234,8 +231,7 @@ public Table getTable(String datasetId, String tableId, Map options) } @Override - public Tuple> listTables(String datasetId, Map options) - throws BigQueryException { + public Tuple> listTables(String datasetId, Map options) { try { TableList tableList = bigquery.tables() .list(this.options.projectId(), datasetId) @@ -262,7 +258,7 @@ public Table apply(TableList.Tables tablePb) { } @Override - public boolean deleteTable(String datasetId, String tableId) throws BigQueryException { + public boolean deleteTable(String datasetId, String tableId) { try { bigquery.tables().delete(this.options.projectId(), datasetId, tableId).execute(); return true; @@ -277,7 +273,7 @@ public boolean deleteTable(String datasetId, String tableId) throws BigQueryExce @Override public TableDataInsertAllResponse insertAll(String datasetId, String tableId, - TableDataInsertAllRequest request) throws BigQueryException { + TableDataInsertAllRequest request) { try { return bigquery.tabledata() .insertAll(this.options.projectId(), datasetId, tableId, request) @@ -289,7 +285,7 @@ public TableDataInsertAllResponse insertAll(String datasetId, String tableId, @Override public Tuple> listTableData(String datasetId, String tableId, - Map options) throws BigQueryException { + Map options) { try { TableDataList tableDataList = bigquery.tabledata() .list(this.options.projectId(), datasetId, tableId) @@ -306,7 +302,7 @@ public Tuple> listTableData(String datasetId, String } @Override - public Job getJob(String jobId, Map options) throws BigQueryException { + public Job getJob(String jobId, Map options) { try { return bigquery.jobs() .get(this.options.projectId(), jobId) @@ -322,7 +318,7 @@ public Job getJob(String jobId, Map options) throws BigQueryException } @Override - public Tuple> listJobs(Map options) throws BigQueryException { + public Tuple> listJobs(Map options) { try { JobList jobsList = bigquery.jobs() .list(this.options.projectId()) @@ -363,7 +359,7 @@ public Job apply(JobList.Jobs jobPb) { } @Override - public boolean cancel(String jobId) throws BigQueryException { + public boolean cancel(String jobId) { try { bigquery.jobs().cancel(this.options.projectId(), jobId).execute(); return true; @@ -377,8 +373,7 @@ public boolean cancel(String jobId) throws BigQueryException { } @Override - public GetQueryResultsResponse getQueryResults(String jobId, Map options) - throws BigQueryException { + public GetQueryResultsResponse getQueryResults(String jobId, Map options) { try { return bigquery.jobs().getQueryResults(this.options.projectId(), jobId) .setMaxResults(MAX_RESULTS.getLong(options)) @@ -397,7 +392,7 @@ public GetQueryResultsResponse getQueryResults(String jobId, Map opti } @Override - public QueryResponse query(QueryRequest request) throws BigQueryException { + public QueryResponse query(QueryRequest request) { try { return bigquery.jobs().query(this.options.projectId(), request).execute(); } catch (IOException ex) { @@ -406,7 +401,7 @@ public QueryResponse query(QueryRequest request) throws BigQueryException { } @Override - public String open(JobConfiguration configuration) throws BigQueryException { + public String open(JobConfiguration configuration) { try { Job loadJob = new Job().setConfiguration(configuration); StringBuilder builder = new StringBuilder() @@ -429,7 +424,7 @@ public String open(JobConfiguration configuration) throws BigQueryException { @Override public void write(String uploadId, byte[] toWrite, int toWriteOffset, long destOffset, int length, - boolean last) throws BigQueryException { + boolean last) { try { GenericUrl url = new GenericUrl(uploadId); HttpRequest httpRequest = bigquery.getRequestFactory().buildPutRequest(url, diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DatastoreRpc.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DatastoreRpc.java index fd916e0a1c87..4d4540c70196 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DatastoreRpc.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DatastoreRpc.java @@ -35,16 +35,46 @@ */ public interface DatastoreRpc { - AllocateIdsResponse allocateIds(AllocateIdsRequest request) throws DatastoreException; + /** + * Sends an allocate IDs request. + * + * @throws DatastoreException upon failure + */ + AllocateIdsResponse allocateIds(AllocateIdsRequest request); + /** + * Sends a begin transaction request. + * + * @throws DatastoreException upon failure + */ BeginTransactionResponse beginTransaction(BeginTransactionRequest request) throws DatastoreException; - CommitResponse commit(CommitRequest request) throws DatastoreException; + /** + * Sends a commit request. + * + * @throws DatastoreException upon failure + */ + CommitResponse commit(CommitRequest request); - LookupResponse lookup(LookupRequest request) throws DatastoreException; + /** + * Sends a lookup request. + * + * @throws DatastoreException upon failure + */ + LookupResponse lookup(LookupRequest request); - RollbackResponse rollback(RollbackRequest request) throws DatastoreException; + /** + * Sends a rollback request. + * + * @throws DatastoreException upon failure + */ + RollbackResponse rollback(RollbackRequest request); - RunQueryResponse runQuery(RunQueryRequest request) throws DatastoreException; + /** + * Sends a request to run a query. + * + * @throws DatastoreException upon failure + */ + RunQueryResponse runQuery(RunQueryRequest request); } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java index c82ff9689f68..f679cc0d5826 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java @@ -111,8 +111,7 @@ private static DatastoreException translate( } @Override - public AllocateIdsResponse allocateIds(AllocateIdsRequest request) - throws DatastoreException { + public AllocateIdsResponse allocateIds(AllocateIdsRequest request) { try { return client.allocateIds(request); } catch (com.google.api.services.datastore.client.DatastoreException ex) { @@ -121,8 +120,7 @@ public AllocateIdsResponse allocateIds(AllocateIdsRequest request) } @Override - public BeginTransactionResponse beginTransaction(BeginTransactionRequest request) - throws DatastoreException { + public BeginTransactionResponse beginTransaction(BeginTransactionRequest request) { try { return client.beginTransaction(request); } catch (com.google.api.services.datastore.client.DatastoreException ex) { @@ -131,7 +129,7 @@ public BeginTransactionResponse beginTransaction(BeginTransactionRequest request } @Override - public CommitResponse commit(CommitRequest request) throws DatastoreException { + public CommitResponse commit(CommitRequest request) { try { return client.commit(request); } catch (com.google.api.services.datastore.client.DatastoreException ex) { @@ -140,7 +138,7 @@ public CommitResponse commit(CommitRequest request) throws DatastoreException { } @Override - public LookupResponse lookup(LookupRequest request) throws DatastoreException { + public LookupResponse lookup(LookupRequest request) { try { return client.lookup(request); } catch (com.google.api.services.datastore.client.DatastoreException ex) { @@ -149,7 +147,7 @@ public LookupResponse lookup(LookupRequest request) throws DatastoreException { } @Override - public RollbackResponse rollback(RollbackRequest request) throws DatastoreException { + public RollbackResponse rollback(RollbackRequest request) { try { return client.rollback(request); } catch (com.google.api.services.datastore.client.DatastoreException ex) { @@ -158,7 +156,7 @@ public RollbackResponse rollback(RollbackRequest request) throws DatastoreExcept } @Override - public RunQueryResponse runQuery(RunQueryRequest request) throws DatastoreException { + public RunQueryResponse runQuery(RunQueryRequest request) { try { return client.runQuery(request); } catch (com.google.api.services.datastore.client.DatastoreException ex) { diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java index 3d27f2a33ac8..f9ddf6872414 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java @@ -168,7 +168,7 @@ public static ProjectListOption fields(ProjectField... fields) { } /** - * Create a new project. + * Creates a new project. * *

    Initially, the project resource is owned by its creator exclusively. The creator can later * grant permission to others to read or update the project. Several APIs are activated diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/DefaultResourceManagerRpc.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/DefaultResourceManagerRpc.java index 61c622fa0c33..d30cd2df3627 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/DefaultResourceManagerRpc.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/DefaultResourceManagerRpc.java @@ -38,7 +38,7 @@ private static ResourceManagerException translate(IOException exception) { } @Override - public Project create(Project project) throws ResourceManagerException { + public Project create(Project project) { try { return resourceManager.projects().create(project).execute(); } catch (IOException ex) { @@ -47,7 +47,7 @@ public Project create(Project project) throws ResourceManagerException { } @Override - public void delete(String projectId) throws ResourceManagerException { + public void delete(String projectId) { try { resourceManager.projects().delete(projectId).execute(); } catch (IOException ex) { @@ -56,7 +56,7 @@ public void delete(String projectId) throws ResourceManagerException { } @Override - public Project get(String projectId, Map options) throws ResourceManagerException { + public Project get(String projectId, Map options) { try { return resourceManager.projects() .get(projectId) @@ -74,8 +74,7 @@ public Project get(String projectId, Map options) throws ResourceMana } @Override - public Tuple> list(Map options) - throws ResourceManagerException { + public Tuple> list(Map options) { try { ListProjectsResponse response = resourceManager.projects() .list() @@ -92,7 +91,7 @@ public Tuple> list(Map options) } @Override - public void undelete(String projectId) throws ResourceManagerException { + public void undelete(String projectId) { try { resourceManager.projects().undelete(projectId).execute(); } catch (IOException ex) { @@ -101,7 +100,7 @@ public void undelete(String projectId) throws ResourceManagerException { } @Override - public Project replace(Project project) throws ResourceManagerException { + public Project replace(Project project) { try { return resourceManager.projects().update(project.getProjectId(), project).execute(); } catch (IOException ex) { diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/ResourceManagerRpc.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/ResourceManagerRpc.java index 52dfc2d2368e..e1d72a6a373e 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/ResourceManagerRpc.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/ResourceManagerRpc.java @@ -75,17 +75,51 @@ public Y y() { } } - Project create(Project project) throws ResourceManagerException; - - void delete(String projectId) throws ResourceManagerException; - - Project get(String projectId, Map options) throws ResourceManagerException; - - Tuple> list(Map options) throws ResourceManagerException; - - void undelete(String projectId) throws ResourceManagerException; - - Project replace(Project project) throws ResourceManagerException; + /** + * Creates a new project. + * + * @throws ResourceManagerException upon failure + */ + Project create(Project project); + + /** + * Marks the project identified by the specified project ID for deletion. + * + * @throws ResourceManagerException upon failure + */ + void delete(String projectId); + + /** + * Retrieves the project identified by the specified project ID. Returns {@code null} if the + * project is not found or if the user doesn't have read permissions for the project. + * + * @throws ResourceManagerException upon failure + */ + Project get(String projectId, Map options); + + /** + * Lists the projects visible to the current user. + * + * @throws ResourceManagerException upon failure + */ + Tuple> list(Map options); + + /** + * Restores the project identified by the specified project ID. Undelete will only succeed if the + * project has a lifecycle state of {@code DELETE_REQUESTED} state. The caller must have modify + * permissions for this project. + * + * @throws ResourceManagerException upon failure + */ + void undelete(String projectId); + + /** + * Replaces the attributes of the project. The caller must have modify permissions for this + * project. + * + * @throws ResourceManagerException upon failure + */ + Project replace(Project project); // TODO(ajaykannan): implement "Organization" functionality when available (issue #319) } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java b/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java index dc84a1de5559..3d7febfd556b 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java @@ -99,7 +99,7 @@ private static StorageException translate(GoogleJsonError exception) { } @Override - public Bucket create(Bucket bucket, Map options) throws StorageException { + public Bucket create(Bucket bucket, Map options) { try { return storage.buckets() .insert(this.options.projectId(), bucket) @@ -114,7 +114,7 @@ public Bucket create(Bucket bucket, Map options) throws StorageExcept @Override public StorageObject create(StorageObject storageObject, final InputStream content, - Map options) throws StorageException { + Map options) { try { Storage.Objects.Insert insert = storage.objects() .insert(storageObject.getBucket(), storageObject, @@ -296,7 +296,7 @@ private Storage.Objects.Delete deleteRequest(StorageObject blob, Map @Override public StorageObject compose(Iterable sources, StorageObject target, - Map targetOptions) throws StorageException { + Map targetOptions) { ComposeRequest request = new ComposeRequest(); if (target.getContentType() == null) { target.setContentType("application/octet-stream"); @@ -327,8 +327,7 @@ public StorageObject compose(Iterable sources, StorageObject targ } @Override - public byte[] load(StorageObject from, Map options) - throws StorageException { + public byte[] load(StorageObject from, Map options) { try { Storage.Objects.Get getRequest = storage.objects() .get(from.getBucket(), from.getName()) @@ -347,7 +346,7 @@ public byte[] load(StorageObject from, Map options) } @Override - public BatchResponse batch(BatchRequest request) throws StorageException { + public BatchResponse batch(BatchRequest request) { List>>> partitionedToDelete = Lists.partition(request.toDelete, MAX_BATCH_DELETES); Iterator>>> iterator = partitionedToDelete.iterator(); @@ -437,7 +436,7 @@ public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) { @Override public Tuple read(StorageObject from, Map options, long position, - int bytes) throws StorageException { + int bytes) { try { Get req = storage.objects() .get(from.getBucket(), from.getName()) @@ -460,7 +459,7 @@ public Tuple read(StorageObject from, Map options, lo @Override public void write(String uploadId, byte[] toWrite, int toWriteOffset, long destOffset, int length, - boolean last) throws StorageException { + boolean last) { try { GenericUrl url = new GenericUrl(uploadId); HttpRequest httpRequest = storage.getRequestFactory().buildPutRequest(url, @@ -501,8 +500,7 @@ public void write(String uploadId, byte[] toWrite, int toWriteOffset, long destO } @Override - public String open(StorageObject object, Map options) - throws StorageException { + public String open(StorageObject object, Map options) { try { Insert req = storage.objects().insert(object.getBucket(), object); GenericUrl url = req.buildHttpRequest().getUrl(); @@ -538,16 +536,16 @@ public String open(StorageObject object, Map options) } @Override - public RewriteResponse openRewrite(RewriteRequest rewriteRequest) throws StorageException { + public RewriteResponse openRewrite(RewriteRequest rewriteRequest) { return rewrite(rewriteRequest, null); } @Override - public RewriteResponse continueRewrite(RewriteResponse previousResponse) throws StorageException { + public RewriteResponse continueRewrite(RewriteResponse previousResponse) { return rewrite(previousResponse.rewriteRequest, previousResponse.rewriteToken); } - private RewriteResponse rewrite(RewriteRequest req, String token) throws StorageException { + private RewriteResponse rewrite(RewriteRequest req, String token) { try { Long maxBytesRewrittenPerCall = req.megabytesRewrittenPerCall != null ? req.megabytesRewrittenPerCall * MEGABYTE : null; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/StorageRpc.java b/gcloud-java-storage/src/main/java/com/google/gcloud/spi/StorageRpc.java index e15a27114810..c76fc0f2d3b8 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/StorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/spi/StorageRpc.java @@ -217,57 +217,134 @@ public int hashCode() { } } - Bucket create(Bucket bucket, Map options) throws StorageException; + /** + * Creates a new bucket. + * + * @throws StorageException upon failure + */ + Bucket create(Bucket bucket, Map options); - StorageObject create(StorageObject object, InputStream content, Map options) - throws StorageException; + /** + * Creates a new storage object. + * + * @throws StorageException upon failure + */ + StorageObject create(StorageObject object, InputStream content, Map options); - Tuple> list(Map options) throws StorageException; + /** + * Lists the project's buckets. + * + * @throws StorageException upon failure + */ + Tuple> list(Map options); - Tuple> list(String bucket, Map options) - throws StorageException; + /** + * Lists the bucket's blobs. + * + * @throws StorageException upon failure + */ + Tuple> list(String bucket, Map options); /** * Returns the requested bucket or {@code null} if not found. * * @throws StorageException upon failure */ - Bucket get(Bucket bucket, Map options) throws StorageException; + Bucket get(Bucket bucket, Map options); /** * Returns the requested storage object or {@code null} if not found. * * @throws StorageException upon failure */ - StorageObject get(StorageObject object, Map options) - throws StorageException; + StorageObject get(StorageObject object, Map options); - Bucket patch(Bucket bucket, Map options) throws StorageException; + /** + * Updates bucket information. + * + * @throws StorageException upon failure + */ + Bucket patch(Bucket bucket, Map options); - StorageObject patch(StorageObject storageObject, Map options) - throws StorageException; + /** + * Updates the storage object's information. Original metadata are merged with metadata in the + * provided {@code storageObject}. + * + * @throws StorageException upon failure + */ + StorageObject patch(StorageObject storageObject, Map options); - boolean delete(Bucket bucket, Map options) throws StorageException; + /** + * Deletes the requested bucket. + * + * @return {@code true} if the bucket was deleted, {@code false} if it was not found + * @throws StorageException upon failure + */ + boolean delete(Bucket bucket, Map options); - boolean delete(StorageObject object, Map options) throws StorageException; + /** + * Deletes the requested storage object. + * + * @return {@code true} if the storage object was deleted, {@code false} if it was not found + * @throws StorageException upon failure + */ + boolean delete(StorageObject object, Map options); - BatchResponse batch(BatchRequest request) throws StorageException; + /** + * Sends a batch request. + * + * @throws StorageException upon failure + */ + BatchResponse batch(BatchRequest request); + /** + * Sends a compose request. + * + * @throws StorageException upon failure + */ StorageObject compose(Iterable sources, StorageObject target, - Map targetOptions) throws StorageException; + Map targetOptions); - byte[] load(StorageObject storageObject, Map options) - throws StorageException; + /** + * Reads all the bytes from a storage object. + * + * @throws StorageException upon failure + */ + byte[] load(StorageObject storageObject, Map options); - Tuple read(StorageObject from, Map options, long position, int bytes) - throws StorageException; + /** + * Reads the given amount of bytes from a storage object at the given position. + * + * @throws StorageException upon failure + */ + Tuple read(StorageObject from, Map options, long position, int bytes); - String open(StorageObject object, Map options) throws StorageException; + /** + * Opens a resumable upload channel for a given storage object. + * + * @throws StorageException upon failure + */ + String open(StorageObject object, Map options); + /** + * Writes the provided bytes to a storage object at the provided location. + * + * @throws StorageException upon failure + */ void write(String uploadId, byte[] toWrite, int toWriteOffset, long destOffset, int length, - boolean last) throws StorageException; + boolean last); - RewriteResponse openRewrite(RewriteRequest rewriteRequest) throws StorageException; + /** + * Sends a rewrite request to open a rewrite channel. + * + * @throws StorageException upon failure + */ + RewriteResponse openRewrite(RewriteRequest rewriteRequest); - RewriteResponse continueRewrite(RewriteResponse previousResponse) throws StorageException; + /** + * Continues rewriting on an already open rewrite channel. + * + * @throws StorageException + */ + RewriteResponse continueRewrite(RewriteResponse previousResponse); } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index 98f3450b7f10..065bcca7c9e8 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -1215,7 +1215,7 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx } /** - * Create a new bucket. + * Creates a new bucket. * * @return a complete bucket * @throws StorageException upon failure @@ -1223,7 +1223,7 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx Bucket create(BucketInfo bucketInfo, BucketTargetOption... options); /** - * Create a new blob with no content. + * Creates a new blob with no content. * * @return a [@code Blob} with complete information * @throws StorageException upon failure @@ -1231,7 +1231,7 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx Blob create(BlobInfo blobInfo, BlobTargetOption... options); /** - * Create a new blob. Direct upload is used to upload {@code content}. For large content, + * Creates a new blob. Direct upload is used to upload {@code content}. For large content, * {@link #writer} is recommended as it uses resumable upload. MD5 and CRC32C hashes of * {@code content} are computed and used for validating transferred data. * @@ -1242,7 +1242,7 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx Blob create(BlobInfo blobInfo, byte[] content, BlobTargetOption... options); /** - * Create a new blob. Direct upload is used to upload {@code content}. For large content, + * Creates a new blob. Direct upload is used to upload {@code content}. For large content, * {@link #writer} is recommended as it uses resumable upload. By default any md5 and crc32c * values in the given {@code blobInfo} are ignored unless requested via the * {@code BlobWriteOption.md5Match} and {@code BlobWriteOption.crc32cMatch} options. The given @@ -1254,49 +1254,49 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx Blob create(BlobInfo blobInfo, InputStream content, BlobWriteOption... options); /** - * Return the requested bucket or {@code null} if not found. + * Returns the requested bucket or {@code null} if not found. * * @throws StorageException upon failure */ Bucket get(String bucket, BucketGetOption... options); /** - * Return the requested blob or {@code null} if not found. + * Returns the requested blob or {@code null} if not found. * * @throws StorageException upon failure */ Blob get(String bucket, String blob, BlobGetOption... options); /** - * Return the requested blob or {@code null} if not found. + * Returns the requested blob or {@code null} if not found. * * @throws StorageException upon failure */ Blob get(BlobId blob, BlobGetOption... options); /** - * Return the requested blob or {@code null} if not found. + * Returns the requested blob or {@code null} if not found. * * @throws StorageException upon failure */ Blob get(BlobId blob); /** - * List the project's buckets. + * Lists the project's buckets. * * @throws StorageException upon failure */ Page list(BucketListOption... options); /** - * List the bucket's blobs. + * Lists the bucket's blobs. * * @throws StorageException upon failure */ Page list(String bucket, BlobListOption... options); /** - * Update bucket information. + * Updates bucket information. * * @return the updated bucket * @throws StorageException upon failure @@ -1304,7 +1304,7 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx Bucket update(BucketInfo bucketInfo, BucketTargetOption... options); /** - * Update blob information. Original metadata are merged with metadata in the provided + * Updates blob information. Original metadata are merged with metadata in the provided * {@code blobInfo}. To replace metadata instead you first have to unset them. Unsetting metadata * can be done by setting the provided {@code blobInfo}'s metadata to {@code null}. * @@ -1321,7 +1321,7 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx Blob update(BlobInfo blobInfo, BlobTargetOption... options); /** - * Update blob information. Original metadata are merged with metadata in the provided + * Updates blob information. Original metadata are merged with metadata in the provided * {@code blobInfo}. To replace metadata instead you first have to unset them. Unsetting metadata * can be done by setting the provided {@code blobInfo}'s metadata to {@code null}. * @@ -1338,7 +1338,7 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx Blob update(BlobInfo blobInfo); /** - * Delete the requested bucket. + * Deletes the requested bucket. * * @return {@code true} if bucket was deleted, {@code false} if it was not found * @throws StorageException upon failure @@ -1346,7 +1346,7 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx boolean delete(String bucket, BucketSourceOption... options); /** - * Delete the requested blob. + * Deletes the requested blob. * * @return {@code true} if blob was deleted, {@code false} if it was not found * @throws StorageException upon failure @@ -1354,7 +1354,7 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx boolean delete(String bucket, String blob, BlobSourceOption... options); /** - * Delete the requested blob. + * Deletes the requested blob. * * @return {@code true} if blob was deleted, {@code false} if it was not found * @throws StorageException upon failure @@ -1362,7 +1362,7 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx boolean delete(BlobId blob, BlobSourceOption... options); /** - * Delete the requested blob. + * Deletes the requested blob. * * @return {@code true} if blob was deleted, {@code false} if it was not found * @throws StorageException upon failure @@ -1370,7 +1370,7 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx boolean delete(BlobId blob); /** - * Send a compose request. + * Sends a compose request. * * @return the composed blob * @throws StorageException upon failure @@ -1422,7 +1422,7 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx byte[] readAllBytes(BlobId blob, BlobSourceOption... options); /** - * Send a batch request. + * Sends a batch request. * * @return the batch response * @throws StorageException upon failure @@ -1430,7 +1430,7 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx BatchResponse submit(BatchRequest batchRequest); /** - * Return a channel for reading the blob's content. The blob's latest generation is read. If the + * Returns a channel for reading the blob's content. The blob's latest generation is read. If the * blob changes while reading (i.e. {@link BlobInfo#etag()} changes), subsequent calls to * {@code blobReadChannel.read(ByteBuffer)} may throw {@link StorageException}. * @@ -1443,7 +1443,7 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx ReadChannel reader(String bucket, String blob, BlobSourceOption... options); /** - * Return a channel for reading the blob's content. If {@code blob.generation()} is set + * Returns a channel for reading the blob's content. If {@code blob.generation()} is set * data corresponding to that generation is read. If {@code blob.generation()} is {@code null} * the blob's latest generation is read. If the blob changes while reading (i.e. * {@link BlobInfo#etag()} changes), subsequent calls to {@code blobReadChannel.read(ByteBuffer)} @@ -1459,7 +1459,7 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx ReadChannel reader(BlobId blob, BlobSourceOption... options); /** - * Create a blob and return a channel for writing its content. By default any md5 and crc32c + * Creates a blob and return a channel for writing its content. By default any md5 and crc32c * values in the given {@code blobInfo} are ignored unless requested via the * {@code BlobWriteOption.md5Match} and {@code BlobWriteOption.crc32cMatch} options. * From b8031e1d1c5068f6bf9f1a5bf180de9aa94fc1d8 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Fri, 4 Mar 2016 09:29:18 -0800 Subject: [PATCH 141/375] Adjusted clear not to collide when parallel test are running. --- .../com/google/gcloud/dns/it/ITDnsTest.java | 119 +++++++++--------- 1 file changed, 63 insertions(+), 56 deletions(-) diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java index fd257c681225..fda579a4a94b 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java @@ -50,68 +50,75 @@ public class ITDnsTest { // todo(mderka) Implement test for creating invalid change when DnsException is finished. #673 - public static final String PREFIX = "gcldjvit-"; - public static final Dns DNS = DnsOptions.builder().build().service(); - public static final String ZONE_NAME1 = (PREFIX + UUID.randomUUID()).substring(0, 32); - public static final String ZONE_NAME_EMPTY_DESCRIPTION = + private static final String PREFIX = "gcldjvit-"; + private static final Dns DNS = DnsOptions.builder().build().service(); + private static final String ZONE_NAME1 = (PREFIX + UUID.randomUUID()).substring(0, 32); + private static final String ZONE_NAME_EMPTY_DESCRIPTION = (PREFIX + UUID.randomUUID()).substring(0, 32); - public static final String ZONE_NAME_TOO_LONG = PREFIX + UUID.randomUUID(); - public static final String ZONE_DESCRIPTION1 = "first zone"; - public static final String ZONE_DNS_NAME1 = ZONE_NAME1 + ".com."; - public static final String ZONE_DNS_EMPTY_DESCRIPTION = ZONE_NAME_EMPTY_DESCRIPTION + ".com."; - public static final String ZONE_DNS_NAME_NO_PERIOD = ZONE_NAME1 + ".com"; - public static final ZoneInfo ZONE1 = ZoneInfo.builder(ZONE_NAME1) + private static final String ZONE_NAME_TOO_LONG = PREFIX + UUID.randomUUID(); + private static final String ZONE_DESCRIPTION1 = "first zone"; + private static final String ZONE_DNS_NAME1 = ZONE_NAME1 + ".com."; + private static final String ZONE_DNS_EMPTY_DESCRIPTION = ZONE_NAME_EMPTY_DESCRIPTION + ".com."; + private static final String ZONE_DNS_NAME_NO_PERIOD = ZONE_NAME1 + ".com"; + private static final ZoneInfo ZONE1 = ZoneInfo.builder(ZONE_NAME1) .description(ZONE_DESCRIPTION1) .dnsName(ZONE_DNS_EMPTY_DESCRIPTION) .build(); - public static final ZoneInfo ZONE_EMPTY_DESCRIPTION = + private static final ZoneInfo ZONE_EMPTY_DESCRIPTION = ZoneInfo.builder(ZONE_NAME_EMPTY_DESCRIPTION) .description(ZONE_DESCRIPTION1) .dnsName(ZONE_DNS_NAME1) .build(); - public static final ZoneInfo ZONE_NAME_ERROR = ZoneInfo.builder(ZONE_NAME_TOO_LONG) + private static final ZoneInfo ZONE_NAME_ERROR = ZoneInfo.builder(ZONE_NAME_TOO_LONG) .description(ZONE_DESCRIPTION1) .dnsName(ZONE_DNS_NAME1) .build(); - public static final ZoneInfo ZONE_MISSING_DESCRIPTION = ZoneInfo.builder(ZONE_NAME1) + private static final ZoneInfo ZONE_MISSING_DESCRIPTION = ZoneInfo.builder(ZONE_NAME1) .dnsName(ZONE_DNS_NAME1) .build(); - public static final ZoneInfo ZONE_MISSING_DNS_NAME = ZoneInfo.builder(ZONE_NAME1) + private static final ZoneInfo ZONE_MISSING_DNS_NAME = ZoneInfo.builder(ZONE_NAME1) .description(ZONE_DESCRIPTION1) .build(); - public static final ZoneInfo ZONE_DNS_NO_PERIOD = ZoneInfo.builder(ZONE_NAME1) + private static final ZoneInfo ZONE_DNS_NO_PERIOD = ZoneInfo.builder(ZONE_NAME1) .description(ZONE_DESCRIPTION1) .dnsName(ZONE_DNS_NAME_NO_PERIOD) .build(); - public static final DnsRecord A_RECORD_ZONE1 = + private static final DnsRecord A_RECORD_ZONE1 = DnsRecord.builder("www." + ZONE1.dnsName(), DnsRecord.Type.A) .records(ImmutableList.of("123.123.55.1")) .ttl(25, TimeUnit.SECONDS) .build(); - public static final DnsRecord AAAA_RECORD_ZONE1 = + private static final DnsRecord AAAA_RECORD_ZONE1 = DnsRecord.builder("www." + ZONE1.dnsName(), DnsRecord.Type.AAAA) .records(ImmutableList.of("ed:ed:12:aa:36:3:3:105")) .ttl(25, TimeUnit.SECONDS) .build(); - public static final ChangeRequest CHANGE_ADD_ZONE1 = ChangeRequest.builder() + private static final ChangeRequest CHANGE_ADD_ZONE1 = ChangeRequest.builder() .add(A_RECORD_ZONE1) .add(AAAA_RECORD_ZONE1) .build(); - public static final ChangeRequest CHANGE_DELETE_ZONE1 = ChangeRequest.builder() + private static final ChangeRequest CHANGE_DELETE_ZONE1 = ChangeRequest.builder() .delete(A_RECORD_ZONE1) .delete(AAAA_RECORD_ZONE1) .build(); + private static final List ZONE_NAMES = ImmutableList.of(ZONE_NAME1, + ZONE_NAME_EMPTY_DESCRIPTION); - public static void clear() { - Page zones = DNS.listZones(); - Iterator zoneIterator = zones.iterateAll(); - while (zoneIterator.hasNext()) { - Zone zone = zoneIterator.next(); - List toDelete = new LinkedList<>(); - if (zone.name().startsWith(PREFIX)) { - Iterator dnsRecordIterator = zone.listDnsRecords().iterateAll(); - while (dnsRecordIterator.hasNext()) { - DnsRecord record = dnsRecordIterator.next(); + private static void clear() { + for (String zoneName : ZONE_NAMES) { + Zone zone = DNS.getZone(zoneName); + if (zone != null) { + /* We wait for all changes to complete before retrieving a list of DNS records to be + deleted. Waiting is necessary as changes potentially might create more records between + when the list has been retrieved and executing the subsequent delete operation. */ + Iterator iterator = zone.listChangeRequests().iterateAll(); + while (iterator.hasNext()) { + waitForChangeToComplete(zoneName, iterator.next().id()); + } + Iterator recordIterator = zone.listDnsRecords().iterateAll(); + List toDelete = new LinkedList<>(); + while (recordIterator.hasNext()) { + DnsRecord record = recordIterator.next(); if (!ImmutableList.of(DnsRecord.Type.NS, DnsRecord.Type.SOA).contains(record.type())) { toDelete.add(record); } @@ -119,7 +126,7 @@ public static void clear() { if (!toDelete.isEmpty()) { ChangeRequest deletion = zone.applyChangeRequest(ChangeRequest.builder().deletions(toDelete).build()); - waitUntilComplete(zone.name(), deletion.id()); + waitForChangeToComplete(zone.name(), deletion.id()); } zone.delete(); } @@ -130,7 +137,7 @@ private static List filter(Iterator iterator) { List result = new LinkedList<>(); while (iterator.hasNext()) { Zone zone = iterator.next(); - if (zone.name().startsWith(PREFIX)) { + if (ZONE_NAMES.contains(zone.name())) { result.add(zone); } } @@ -154,7 +161,7 @@ private static void assertEqChangesIgnoreStatus(ChangeRequest expected, ChangeRe assertEquals(expected.startTimeMillis(), actual.startTimeMillis()); } - private static void waitUntilComplete(String zoneName, String changeId) { + private static void waitForChangeToComplete(String zoneName, String changeId) { while (true) { ChangeRequest changeRequest = DNS.getChangeRequest(zoneName, changeId, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); @@ -553,9 +560,9 @@ public void testCreateChange() { assertTrue(ImmutableList.of(ChangeRequest.Status.PENDING, ChangeRequest.Status.DONE) .contains(created.status())); assertEqChangesIgnoreStatus(created, DNS.getChangeRequest(ZONE1.name(), "1")); - waitUntilComplete(ZONE1.name(), "1"); + waitForChangeToComplete(ZONE1.name(), "1"); DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - waitUntilComplete(ZONE1.name(), "2"); + waitForChangeToComplete(ZONE1.name(), "2"); // with options created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); @@ -564,9 +571,9 @@ public void testCreateChange() { assertTrue(created.deletions().isEmpty()); assertEquals("3", created.id()); assertNull(created.status()); - waitUntilComplete(ZONE1.name(), "3"); + waitForChangeToComplete(ZONE1.name(), "3"); DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - waitUntilComplete(ZONE1.name(), "4"); + waitForChangeToComplete(ZONE1.name(), "4"); created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); assertTrue(created.additions().isEmpty()); @@ -574,9 +581,9 @@ public void testCreateChange() { assertTrue(created.deletions().isEmpty()); assertEquals("5", created.id()); assertNotNull(created.status()); - waitUntilComplete(ZONE1.name(), "5"); + waitForChangeToComplete(ZONE1.name(), "5"); DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - waitUntilComplete(ZONE1.name(), "6"); + waitForChangeToComplete(ZONE1.name(), "6"); created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); assertTrue(created.additions().isEmpty()); @@ -584,9 +591,9 @@ public void testCreateChange() { assertTrue(created.deletions().isEmpty()); assertEquals("7", created.id()); assertNull(created.status()); - waitUntilComplete(ZONE1.name(), "7"); + waitForChangeToComplete(ZONE1.name(), "7"); DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - waitUntilComplete(ZONE1.name(), "8"); + waitForChangeToComplete(ZONE1.name(), "8"); created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); assertEquals(CHANGE_ADD_ZONE1.additions(), created.additions()); @@ -595,16 +602,16 @@ public void testCreateChange() { assertEquals("9", created.id()); assertNull(created.status()); // finishes with delete otherwise we cannot delete the zone - waitUntilComplete(ZONE1.name(), "9"); + waitForChangeToComplete(ZONE1.name(), "9"); created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); - waitUntilComplete(ZONE1.name(), "10"); + waitForChangeToComplete(ZONE1.name(), "10"); assertEquals(CHANGE_DELETE_ZONE1.deletions(), created.deletions()); assertNull(created.startTimeMillis()); assertTrue(created.additions().isEmpty()); assertEquals("10", created.id()); assertNull(created.status()); - waitUntilComplete(ZONE1.name(), "10"); + waitForChangeToComplete(ZONE1.name(), "10"); } finally { clear(); } @@ -629,13 +636,13 @@ public void testListChanges() { assertEquals(1, changes.size()); // default change creating SOA and NS // zone has changes ChangeRequest change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); - waitUntilComplete(ZONE1.name(), change.id()); + waitForChangeToComplete(ZONE1.name(), change.id()); change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - waitUntilComplete(ZONE1.name(), change.id()); + waitForChangeToComplete(ZONE1.name(), change.id()); change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); - waitUntilComplete(ZONE1.name(), change.id()); + waitForChangeToComplete(ZONE1.name(), change.id()); change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - waitUntilComplete(ZONE1.name(), change.id()); + waitForChangeToComplete(ZONE1.name(), change.id()); changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name()).iterateAll()); assertEquals(5, changes.size()); // error in options @@ -726,7 +733,7 @@ public void testGetChange() { ChangeRequest created = zone.applyChangeRequest(CHANGE_ADD_ZONE1); ChangeRequest retrieved = DNS.getChangeRequest(zone.name(), created.id()); assertEqChangesIgnoreStatus(created, retrieved); - waitUntilComplete(zone.name(), created.id()); + waitForChangeToComplete(zone.name(), created.id()); zone.applyChangeRequest(CHANGE_DELETE_ZONE1); // with options created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, @@ -734,35 +741,35 @@ public void testGetChange() { retrieved = DNS.getChangeRequest(zone.name(), created.id(), Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); assertEqChangesIgnoreStatus(created, retrieved); - waitUntilComplete(zone.name(), created.id()); + waitForChangeToComplete(zone.name(), created.id()); zone.applyChangeRequest(CHANGE_DELETE_ZONE1); created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); retrieved = DNS.getChangeRequest(zone.name(), created.id(), Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); assertEqChangesIgnoreStatus(created, retrieved); - waitUntilComplete(zone.name(), created.id()); + waitForChangeToComplete(zone.name(), created.id()); zone.applyChangeRequest(CHANGE_DELETE_ZONE1); created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); retrieved = DNS.getChangeRequest(zone.name(), created.id(), Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); assertEqChangesIgnoreStatus(created, retrieved); - waitUntilComplete(zone.name(), created.id()); + waitForChangeToComplete(zone.name(), created.id()); zone.applyChangeRequest(CHANGE_DELETE_ZONE1); created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); retrieved = DNS.getChangeRequest(zone.name(), created.id(), Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); assertEqChangesIgnoreStatus(created, retrieved); - waitUntilComplete(zone.name(), created.id()); + waitForChangeToComplete(zone.name(), created.id()); // finishes with delete otherwise we cannot delete the zone created = zone.applyChangeRequest(CHANGE_DELETE_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); retrieved = DNS.getChangeRequest(zone.name(), created.id(), Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); assertEqChangesIgnoreStatus(created, retrieved); - waitUntilComplete(zone.name(), created.id()); + waitForChangeToComplete(zone.name(), created.id()); } finally { clear(); } @@ -854,7 +861,7 @@ public void testListDnsRecords() { assertEquals(1, ImmutableList.copyOf(dnsRecordPage.values().iterator()).size()); // test name filter ChangeRequest change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); - waitUntilComplete(ZONE1.name(), change.id()); + waitForChangeToComplete(ZONE1.name(), change.id()); dnsRecordIterator = DNS.listDnsRecords(ZONE1.name(), Dns.DnsRecordListOption.dnsName(A_RECORD_ZONE1.name())).iterateAll(); counter = 0; @@ -866,7 +873,7 @@ public void testListDnsRecords() { } assertEquals(2, counter); // test type filter - waitUntilComplete(ZONE1.name(), change.id()); + waitForChangeToComplete(ZONE1.name(), change.id()); dnsRecordIterator = DNS.listDnsRecords(ZONE1.name(), Dns.DnsRecordListOption.dnsName(A_RECORD_ZONE1.name()), Dns.DnsRecordListOption.type(A_RECORD_ZONE1.type())) @@ -905,7 +912,7 @@ public void testListDnsRecords() { assertEquals(400, ex.code()); // todo(mderka) test retry functionality when available } - waitUntilComplete(ZONE1.name(), change.id()); + waitForChangeToComplete(ZONE1.name(), change.id()); } finally { clear(); } From c486452b4c81da7f077e2573b1f29dee3994bd86 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Sun, 6 Mar 2016 08:54:43 -0800 Subject: [PATCH 142/375] Add NoAuthCredentials --- .../com/google/gcloud/AuthCredentials.java | 34 +++++++++++++++++++ .../com/google/gcloud/ServiceOptions.java | 7 ++-- .../gcloud/datastore/DatastoreTest.java | 2 ++ .../testing/LocalResourceManagerHelper.java | 11 ++++-- 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java index fc5d74d0896c..f4f6b6938531 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java @@ -243,6 +243,33 @@ public RestorableState capture() { } } + public static class NoAuthCredentials extends AuthCredentials { + + private static final AuthCredentials INSTANCE = new NoAuthCredentials(); + private static final NoAuthCredentialsState STATE = new NoAuthCredentialsState(); + + private static class NoAuthCredentialsState + implements RestorableState, Serializable { + + private static final long serialVersionUID = -4022100563954640465L; + + @Override + public AuthCredentials restore() { + return INSTANCE; + } + } + + @Override + public GoogleCredentials credentials() { + return null; + } + + @Override + public RestorableState capture() { + return STATE; + } + } + public abstract GoogleCredentials credentials(); public static AuthCredentials createForAppEngine() { @@ -281,6 +308,13 @@ public static ServiceAccountAuthCredentials createFor(String account, PrivateKey return new ServiceAccountAuthCredentials(account, privateKey); } + /** + * Creates a placeholder denoting that no credentials should be used. + */ + public static AuthCredentials noAuth() { + return NoAuthCredentials.INSTANCE; + } + /** * Creates Service Account Credentials given a stream for credentials in JSON format. * diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java index 31e543809464..d45069434a26 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java @@ -523,9 +523,10 @@ public RetryParams retryParams() { * options. */ public HttpRequestInitializer httpRequestInitializer() { - final HttpRequestInitializer delegate = authCredentials() != null - ? new HttpCredentialsAdapter(authCredentials().credentials().createScoped(scopes())) - : null; + final HttpRequestInitializer delegate = + authCredentials() != null && authCredentials.credentials() != null + ? new HttpCredentialsAdapter(authCredentials().credentials().createScoped(scopes())) + : null; return new HttpRequestInitializer() { @Override public void initialize(HttpRequest httpRequest) throws IOException { diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index a289610fe841..5d106fc7d31d 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -32,6 +32,7 @@ import com.google.api.services.datastore.DatastoreV1.RunQueryResponse; import com.google.common.collect.Iterators; import com.google.common.collect.Lists; +import com.google.gcloud.AuthCredentials; import com.google.gcloud.RetryParams; import com.google.gcloud.datastore.Query.ResultType; import com.google.gcloud.datastore.StructuredQuery.OrderBy; @@ -128,6 +129,7 @@ public void setUp() { options = DatastoreOptions.builder() .projectId(PROJECT_ID) .host("http://localhost:" + PORT) + .authCredentials(AuthCredentials.noAuth()) .retryParams(RetryParams.noRetries()) .build(); datastore = options.service(); diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java index a077eb6144a5..cda2dd1e00ea 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java @@ -12,6 +12,7 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.io.ByteStreams; +import com.google.gcloud.AuthCredentials; import com.google.gcloud.resourcemanager.ResourceManagerOptions; import com.sun.net.httpserver.Headers; @@ -550,17 +551,21 @@ private LocalResourceManagerHelper() { } /** - * Creates a LocalResourceManagerHelper object that listens to requests on the local machine. + * Creates a {@code LocalResourceManagerHelper} object that listens to requests on the local + * machine. */ public static LocalResourceManagerHelper create() { return new LocalResourceManagerHelper(); } /** - * Returns a ResourceManagerOptions instance that sets the host to use the mock server. + * Returns a {@link ResourceManagerOptions} instance that sets the host to use the mock server. */ public ResourceManagerOptions options() { - return ResourceManagerOptions.builder().host("http://localhost:" + port).build(); + return ResourceManagerOptions.builder() + .host("http://localhost:" + port) + .authCredentials(AuthCredentials.noAuth()) + .build(); } /** From 8c353ecbc62a9f8d7784ba8f99ee2f3cf15a4c00 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 7 Mar 2016 08:27:49 -0800 Subject: [PATCH 143/375] Add javadoc --- .../com/google/gcloud/AuthCredentials.java | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java index f4f6b6938531..1f8a56f8e68c 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java @@ -132,6 +132,12 @@ public RestorableState capture() { } } + /** + * Represents service account credentials. + * + * @see + * User accounts and service accounts + */ public static class ServiceAccountAuthCredentials extends AuthCredentials { private final String account; @@ -195,6 +201,14 @@ public RestorableState capture() { } } + /** + * Represents Application Default Credentials, which are credentials that are inferred from the + * runtime environment. + * + * @see + * Google Application Default Credentials + */ public static class ApplicationDefaultAuthCredentials extends AuthCredentials { private GoogleCredentials googleCredentials; @@ -243,6 +257,11 @@ public RestorableState capture() { } } + /** + * Represents that requests sent to the server should not be authenticated. This is typically + * useful when using the local service emulators, such as {@code LocalGcdHelper} and + * {@code LocalResourceManagerHelper}. + */ public static class NoAuthCredentials extends AuthCredentials { private static final AuthCredentials INSTANCE = new NoAuthCredentials(); @@ -309,7 +328,9 @@ public static ServiceAccountAuthCredentials createFor(String account, PrivateKey } /** - * Creates a placeholder denoting that no credentials should be used. + * Creates a placeholder denoting that no credentials should be used. This is typically useful + * when using the local service emulators, such as {@code LocalGcdHelper} and + * {@code LocalResourceManagerHelper}. */ public static AuthCredentials noAuth() { return NoAuthCredentials.INSTANCE; From 0c4af89295be8709d63776ee4c65d4d64fa282ce Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 7 Mar 2016 08:50:26 -0800 Subject: [PATCH 144/375] change NoAuthCredentials javadoc wording --- .../src/main/java/com/google/gcloud/AuthCredentials.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java index 1f8a56f8e68c..6f9e09ca04bc 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java @@ -258,9 +258,9 @@ public RestorableState capture() { } /** - * Represents that requests sent to the server should not be authenticated. This is typically - * useful when using the local service emulators, such as {@code LocalGcdHelper} and - * {@code LocalResourceManagerHelper}. + * A placeholder for credentials to signify that requests sent to the server should not be + * authenticated. This is typically useful when using the local service emulators, such as + * {@code LocalGcdHelper} and {@code LocalResourceManagerHelper}. */ public static class NoAuthCredentials extends AuthCredentials { From cded23436465bb5fb1233eb5cd6740b4561357f9 Mon Sep 17 00:00:00 2001 From: aozarov Date: Mon, 7 Mar 2016 15:28:21 -0800 Subject: [PATCH 145/375] Fix writes with 0 length --- .../google/gcloud/spi/DefaultStorageRpc.java | 10 +++++++- .../gcloud/storage/it/ITStorageTest.java | 23 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java b/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java index 3d7febfd556b..4d9214ef5929 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java @@ -461,12 +461,20 @@ public Tuple read(StorageObject from, Map options, lo public void write(String uploadId, byte[] toWrite, int toWriteOffset, long destOffset, int length, boolean last) { try { + if (length == 0 && !last) { + return; + } GenericUrl url = new GenericUrl(uploadId); HttpRequest httpRequest = storage.getRequestFactory().buildPutRequest(url, new ByteArrayContent(null, toWrite, toWriteOffset, length)); long limit = destOffset + length; StringBuilder range = new StringBuilder("bytes "); - range.append(destOffset).append('-').append(limit - 1).append('/'); + if (length == 0) { + range.append('*'); + } else { + range.append(destOffset).append('-').append(limit - 1); + } + range.append('/'); if (last) { range.append(limit); } else { diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java index 38521ae5e137..a411cdd60bfb 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java @@ -823,6 +823,29 @@ public void testReadAndWriteChannels() throws IOException { assertTrue(storage.delete(BUCKET, blobName)); } + @Test + public void testReadAndWriteChannelsWithDifferentFileSize() throws IOException { + String blobNamePrefix = "test-read-and-write-channels-blob-"; + int[] blobSizes = {0, 700, 1024 * 256, 2 * 1024 * 1024, 4 * 1024 * 1024, 4 * 1024 * 1024 + 1}; + Random rnd = new Random(); + for (int blobSize : blobSizes) { + String blobName = blobNamePrefix + blobSize; + BlobInfo blob = BlobInfo.builder(BUCKET, blobName).build(); + byte[] bytes = new byte[blobSize]; + rnd.nextBytes(bytes); + try (WriteChannel writer = storage.writer(blob)) { + writer.write(ByteBuffer.wrap(BLOB_BYTE_CONTENT)); + } + ByteBuffer readBytes; + try (ReadChannel reader = storage.reader(blob.blobId())) { + readBytes = ByteBuffer.allocate(BLOB_BYTE_CONTENT.length); + reader.read(readBytes); + } + assertArrayEquals(BLOB_BYTE_CONTENT, readBytes.array()); + assertTrue(storage.delete(BUCKET, blobName)); + } + } + @Test public void testReadAndWriteCaptureChannels() throws IOException { String blobName = "test-read-and-write-capture-channels-blob"; From 36ebabda8ae8f075e5b83128344c5a92c84c3715 Mon Sep 17 00:00:00 2001 From: aozarov Date: Mon, 7 Mar 2016 17:00:03 -0800 Subject: [PATCH 146/375] Fix test and issue #723 --- .../google/gcloud/BaseServiceException.java | 23 ++++++++++++------- .../google/gcloud/spi/DefaultStorageRpc.java | 7 +++++- .../gcloud/storage/BlobReadChannel.java | 2 +- .../gcloud/storage/it/ITStorageTest.java | 15 ++++++++---- 4 files changed, 32 insertions(+), 15 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/BaseServiceException.java b/gcloud-java-core/src/main/java/com/google/gcloud/BaseServiceException.java index 579340f1256e..365243904436 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/BaseServiceException.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/BaseServiceException.java @@ -97,13 +97,17 @@ public BaseServiceException(IOException exception, boolean idempotent) { String debugInfo = null; if (exception instanceof GoogleJsonResponseException) { GoogleJsonError jsonError = ((GoogleJsonResponseException) exception).getDetails(); - Error error = error(jsonError); - code = error.code; - reason = error.reason; - if (reason != null) { - GoogleJsonError.ErrorInfo errorInfo = jsonError.getErrors().get(0); - location = errorInfo.getLocation(); - debugInfo = (String) errorInfo.get("debugInfo"); + if (jsonError != null) { + Error error = error(jsonError); + code = error.code; + reason = error.reason; + if (reason != null) { + GoogleJsonError.ErrorInfo errorInfo = jsonError.getErrors().get(0); + location = errorInfo.getLocation(); + debugInfo = (String) errorInfo.get("debugInfo"); + } + } else { + code = ((GoogleJsonResponseException) exception).getStatusCode(); } } this.code = code; @@ -207,7 +211,10 @@ protected static Error error(GoogleJsonError error) { protected static String message(IOException exception) { if (exception instanceof GoogleJsonResponseException) { - return ((GoogleJsonResponseException) exception).getDetails().getMessage(); + GoogleJsonError details = ((GoogleJsonResponseException) exception).getDetails(); + if (details != null) { + return details.getMessage(); + } } return exception.getMessage(); } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java b/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java index 4d9214ef5929..cac47b4bd248 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java @@ -31,6 +31,7 @@ import static com.google.gcloud.spi.StorageRpc.Option.PREFIX; import static com.google.gcloud.spi.StorageRpc.Option.VERSIONS; import static java.net.HttpURLConnection.HTTP_NOT_FOUND; +import static javax.servlet.http.HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE; import com.google.api.client.googleapis.batch.json.JsonBatchCallback; import com.google.api.client.googleapis.json.GoogleJsonError; @@ -453,7 +454,11 @@ public Tuple read(StorageObject from, Map options, lo String etag = req.getLastResponseHeaders().getETag(); return Tuple.of(etag, output.toByteArray()); } catch (IOException ex) { - throw translate(ex); + StorageException serviceException = translate(ex); + if (serviceException.code() == SC_REQUESTED_RANGE_NOT_SATISFIABLE) { + return Tuple.of(null, new byte[0]); + } + throw serviceException; } } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobReadChannel.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobReadChannel.java index 2b9643434ecc..52b8c39321da 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobReadChannel.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobReadChannel.java @@ -127,7 +127,7 @@ public Tuple call() { return storageRpc.read(storageObject, requestOptions, position, toRead); } }, serviceOptions.retryParams(), StorageImpl.EXCEPTION_HANDLER); - if (lastEtag != null && !Objects.equals(result.x(), lastEtag)) { + if (result.y().length > 0 && lastEtag != null && !Objects.equals(result.x(), lastEtag)) { StringBuilder messageBuilder = new StringBuilder(); messageBuilder.append("Blob ").append(blob).append(" was updated while reading"); throw new StorageException(0, messageBuilder.toString()); diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java index a411cdd60bfb..b62a54aff818 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java @@ -54,6 +54,7 @@ import org.junit.Test; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; @@ -834,14 +835,18 @@ public void testReadAndWriteChannelsWithDifferentFileSize() throws IOException { byte[] bytes = new byte[blobSize]; rnd.nextBytes(bytes); try (WriteChannel writer = storage.writer(blob)) { - writer.write(ByteBuffer.wrap(BLOB_BYTE_CONTENT)); + writer.write(ByteBuffer.wrap(bytes)); } - ByteBuffer readBytes; + ByteArrayOutputStream output = new ByteArrayOutputStream(); try (ReadChannel reader = storage.reader(blob.blobId())) { - readBytes = ByteBuffer.allocate(BLOB_BYTE_CONTENT.length); - reader.read(readBytes); + ByteBuffer buffer = ByteBuffer.allocate(64 * 1024); + while (reader.read(buffer) > 0) { + buffer.flip(); + output.write(buffer.array(), 0, buffer.limit()); + buffer.clear(); + } } - assertArrayEquals(BLOB_BYTE_CONTENT, readBytes.array()); + assertArrayEquals(bytes, output.toByteArray()); assertTrue(storage.delete(BUCKET, blobName)); } } From d930b4bbc2833d82ce84c13e3c6704695aebd91c Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 8 Mar 2016 12:29:17 +0100 Subject: [PATCH 147/375] Remove BlobListOption.recursive option and fix delimiter handling - Add BlobListOption.currentDirectory option that sets the '/' delimiter - Add isDirectory method to BlobInfo objects - Change StorageRpc.list(bucket) method to add prefixes to the list of storage objects - Add unit and integration tests --- .../google/gcloud/spi/DefaultStorageRpc.java | 21 ++++++- .../com/google/gcloud/spi/StorageRpc.java | 2 +- .../java/com/google/gcloud/storage/Blob.java | 6 ++ .../com/google/gcloud/storage/BlobInfo.java | 27 ++++++++ .../com/google/gcloud/storage/Storage.java | 16 +++-- .../google/gcloud/storage/StorageImpl.java | 3 +- .../google/gcloud/storage/StorageOptions.java | 31 +--------- .../google/gcloud/storage/BlobInfoTest.java | 62 +++++++++++++++++++ .../com/google/gcloud/storage/BlobTest.java | 38 +++++++++++- .../gcloud/storage/SerializationTest.java | 1 - .../gcloud/storage/StorageImplTest.java | 16 +++++ .../gcloud/storage/it/ITStorageTest.java | 46 ++++++++++++++ 12 files changed, 228 insertions(+), 41 deletions(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java b/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java index cac47b4bd248..fcbfe5514d1e 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java @@ -57,8 +57,10 @@ import com.google.api.services.storage.model.ComposeRequest.SourceObjects.ObjectPreconditions; import com.google.api.services.storage.model.Objects; import com.google.api.services.storage.model.StorageObject; +import com.google.common.base.Function; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.gcloud.storage.StorageException; @@ -67,6 +69,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.math.BigInteger; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -151,7 +154,7 @@ public Tuple> list(Map options) { } @Override - public Tuple> list(String bucket, Map options) { + public Tuple> list(final String bucket, Map options) { try { Objects objects = storage.objects() .list(bucket) @@ -163,8 +166,20 @@ public Tuple> list(String bucket, Map .setPageToken(PAGE_TOKEN.getString(options)) .setFields(FIELDS.getString(options)) .execute(); - return Tuple.>of( - objects.getNextPageToken(), objects.getItems()); + Iterable storageObjects = Iterables.concat( + objects.getItems() != null ? objects.getItems() : ImmutableList.of(), + objects.getPrefixes() != null + ? Lists.transform(objects.getPrefixes(), new Function() { + @Override + public StorageObject apply(String prefix) { + return new StorageObject() + .set("isDirectory", true) + .setBucket(bucket) + .setName(prefix) + .setSize(BigInteger.ZERO); + } + }) : ImmutableList.of()); + return Tuple.of(objects.getNextPageToken(), storageObjects); } catch (IOException ex) { throw translate(ex); } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/StorageRpc.java b/gcloud-java-storage/src/main/java/com/google/gcloud/spi/StorageRpc.java index c76fc0f2d3b8..ab4a7a9d0acb 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/StorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/spi/StorageRpc.java @@ -344,7 +344,7 @@ void write(String uploadId, byte[] toWrite, int toWriteOffset, long destOffset, /** * Continues rewriting on an already open rewrite channel. * - * @throws StorageException + * @throws StorageException upon failure */ RewriteResponse continueRewrite(RewriteResponse previousResponse); } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java index aea424ca4063..79ad3804faf0 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java @@ -290,6 +290,12 @@ Builder updateTime(Long updateTime) { return this; } + @Override + Builder isDirectory(boolean isDirectory) { + infoBuilder.isDirectory(isDirectory); + return this; + } + @Override public Blob build() { return new Blob(storage, infoBuilder); diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobInfo.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobInfo.java index 54fabe87d766..9d981aeeafda 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobInfo.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobInfo.java @@ -78,6 +78,7 @@ public StorageObject apply(BlobInfo blobInfo) { private final String contentDisposition; private final String contentLanguage; private final Integer componentCount; + private final boolean isDirectory; /** * This class is meant for internal use only. Users are discouraged from using this class. @@ -187,6 +188,8 @@ public abstract static class Builder { abstract Builder updateTime(Long updateTime); + abstract Builder isDirectory(boolean isDirectory); + /** * Creates a {@code BlobInfo} object. */ @@ -215,6 +218,7 @@ static final class BuilderImpl extends Builder { private Long metageneration; private Long deleteTime; private Long updateTime; + private Boolean isDirectory; BuilderImpl(BlobId blobId) { this.blobId = blobId; @@ -241,6 +245,7 @@ static final class BuilderImpl extends Builder { metageneration = blobInfo.metageneration; deleteTime = blobInfo.deleteTime; updateTime = blobInfo.updateTime; + isDirectory = blobInfo.isDirectory; } @Override @@ -364,6 +369,12 @@ Builder updateTime(Long updateTime) { return this; } + @Override + Builder isDirectory(boolean isDirectory) { + this.isDirectory = isDirectory; + return this; + } + @Override public BlobInfo build() { checkNotNull(blobId); @@ -392,6 +403,7 @@ public BlobInfo build() { metageneration = builder.metageneration; deleteTime = builder.deleteTime; updateTime = builder.updateTime; + isDirectory = firstNonNull(builder.isDirectory, Boolean.FALSE); } /** @@ -588,6 +600,18 @@ public Long updateTime() { return updateTime; } + /** + * Returns {@code true} if the current blob represents a directory. This can only happen if the + * blob is returned by {@link Storage#list(String, Storage.BlobListOption...)} when the + * {@link Storage.BlobListOption#currentDirectory()} option is used. If {@code true} only + * {@link #blobId()} and {@link #size()} are set for the current blob: {@link BlobId#name()} ends + * with the '/' character, {@link BlobId#generation()} returns {@code null} and {@link #size()} is + * {@code 0}. + */ + public boolean isDirectory() { + return isDirectory; + } + /** * Returns a builder for the current blob. */ @@ -761,6 +785,9 @@ public Acl apply(ObjectAccessControl objectAccessControl) { } })); } + if (storageObject.get("isDirectory") != null) { + builder.isDirectory(Boolean.TRUE); + } return builder.build(); } } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index 065bcca7c9e8..e1ab337cdbdf 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -694,10 +694,17 @@ public static BlobListOption prefix(String prefix) { } /** - * Returns an option to specify whether blob listing should include subdirectories or not. + * If specified, results are returned in a directory-like mode. Blobs whose names, aside from + * a possible {@link #prefix(String)}, do not contain the '/' delimiter are returned as is. + * Blobs whose names, aside from a possible {@link #prefix(String)}, contain the '/' delimiter, + * will have their name truncated after the delimiter and will be returned as {@link Blob} + * objects where only {@link Blob#blobId()}, {@link Blob#size()} and {@link Blob#isDirectory()} + * are set. For such directory blobs, ({@link BlobId#generation()} returns {@code null}), + * {@link Blob#size()} returns {@code 0} while {@link Blob#isDirectory()} returns {@code true}. + * Duplicate directory blobs are omitted. */ - public static BlobListOption recursive(boolean recursive) { - return new BlobListOption(StorageRpc.Option.DELIMITER, recursive); + public static BlobListOption currentDirectory() { + return new BlobListOption(StorageRpc.Option.DELIMITER, true); } /** @@ -1289,7 +1296,8 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx Page list(BucketListOption... options); /** - * Lists the bucket's blobs. + * Lists the bucket's blobs. If the {@link BlobListOption#currentDirectory()} option is provided, + * results are returned in a directory-like mode. * * @throws StorageException upon failure */ diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java index de77cba021a1..788072905871 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java @@ -76,6 +76,7 @@ final class StorageImpl extends BaseService implements Storage { private static final byte[] EMPTY_BYTE_ARRAY = {}; private static final String EMPTY_BYTE_ARRAY_MD5 = "1B2M2Y8AsgTpgAmY7PhCfg=="; private static final String EMPTY_BYTE_ARRAY_CRC32C = "AAAAAA=="; + private static final String PATH_DELIMITER = "/"; private static final Function, Boolean> DELETE_FUNCTION = new Function, Boolean>() { @@ -669,7 +670,7 @@ private static void addToOptionMap(StorageRpc.Option getOption, StorageRpc.O } Boolean value = (Boolean) temp.remove(DELIMITER); if (Boolean.TRUE.equals(value)) { - temp.put(DELIMITER, options().pathDelimiter()); + temp.put(DELIMITER, PATH_DELIMITER); } if (useAsSource) { addToOptionMap(IF_GENERATION_MATCH, IF_SOURCE_GENERATION_MATCH, generation, temp); diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageOptions.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageOptions.java index bd30cb173366..ca9b8944ea8b 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageOptions.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageOptions.java @@ -16,14 +16,12 @@ package com.google.gcloud.storage; -import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableSet; import com.google.gcloud.ServiceOptions; import com.google.gcloud.spi.DefaultStorageRpc; import com.google.gcloud.spi.StorageRpc; import com.google.gcloud.spi.StorageRpcFactory; -import java.util.Objects; import java.util.Set; public class StorageOptions extends ServiceOptions { @@ -31,9 +29,6 @@ public class StorageOptions extends ServiceOptions SCOPES = ImmutableSet.of(GCS_SCOPE); - private static final String DEFAULT_PATH_DELIMITER = "/"; - - private final String pathDelimiter; public static class DefaultStorageFactory implements StorageFactory { @@ -58,24 +53,10 @@ public StorageRpc create(StorageOptions options) { public static class Builder extends ServiceOptions.Builder { - private String pathDelimiter; - private Builder() {} private Builder(StorageOptions options) { super(options); - pathDelimiter = options.pathDelimiter; - } - - /** - * Sets the path delimiter for the storage service. - * - * @param pathDelimiter the path delimiter to set - * @return the builder - */ - public Builder pathDelimiter(String pathDelimiter) { - this.pathDelimiter = pathDelimiter; - return this; } @Override @@ -86,7 +67,6 @@ public StorageOptions build() { private StorageOptions(Builder builder) { super(StorageFactory.class, StorageRpcFactory.class, builder); - pathDelimiter = MoreObjects.firstNonNull(builder.pathDelimiter, DEFAULT_PATH_DELIMITER); } @SuppressWarnings("unchecked") @@ -106,13 +86,6 @@ protected Set scopes() { return SCOPES; } - /** - * Returns the storage service's path delimiter. - */ - public String pathDelimiter() { - return pathDelimiter; - } - /** * Returns a default {@code StorageOptions} instance. */ @@ -128,7 +101,7 @@ public Builder toBuilder() { @Override public int hashCode() { - return baseHashCode() ^ Objects.hash(pathDelimiter); + return baseHashCode(); } @Override @@ -137,7 +110,7 @@ public boolean equals(Object obj) { return false; } StorageOptions other = (StorageOptions) obj; - return baseEquals(other) && Objects.equals(pathDelimiter, other.pathDelimiter); + return baseEquals(other); } public static Builder builder() { diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobInfoTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobInfoTest.java index a1cc01f4287c..029181c6c07b 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobInfoTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobInfoTest.java @@ -20,7 +20,11 @@ import static com.google.gcloud.storage.Acl.Role.READER; import static com.google.gcloud.storage.Acl.Role.WRITER; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import com.google.api.services.storage.model.StorageObject; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.gcloud.storage.Acl.Project; @@ -28,6 +32,7 @@ import org.junit.Test; +import java.math.BigInteger; import java.util.List; import java.util.Map; @@ -76,6 +81,10 @@ public class BlobInfoTest { .size(SIZE) .updateTime(UPDATE_TIME) .build(); + private static final BlobInfo DIRECTORY_INFO = BlobInfo.builder("b", "n/") + .size(0L) + .isDirectory(true) + .build(); @Test public void testToBuilder() { @@ -118,6 +127,30 @@ public void testBuilder() { assertEquals(SELF_LINK, BLOB_INFO.selfLink()); assertEquals(SIZE, BLOB_INFO.size()); assertEquals(UPDATE_TIME, BLOB_INFO.updateTime()); + assertFalse(BLOB_INFO.isDirectory()); + assertEquals("b", DIRECTORY_INFO.bucket()); + assertEquals("n/", DIRECTORY_INFO.name()); + assertNull(DIRECTORY_INFO.acl()); + assertNull(DIRECTORY_INFO.componentCount()); + assertNull(DIRECTORY_INFO.contentType()); + assertNull(DIRECTORY_INFO.cacheControl()); + assertNull(DIRECTORY_INFO.contentDisposition()); + assertNull(DIRECTORY_INFO.contentEncoding()); + assertNull(DIRECTORY_INFO.contentLanguage()); + assertNull(DIRECTORY_INFO.crc32c()); + assertNull(DIRECTORY_INFO.deleteTime()); + assertNull(DIRECTORY_INFO.etag()); + assertNull(DIRECTORY_INFO.generation()); + assertNull(DIRECTORY_INFO.id()); + assertNull(DIRECTORY_INFO.md5()); + assertNull(DIRECTORY_INFO.mediaLink()); + assertNull(DIRECTORY_INFO.metadata()); + assertNull(DIRECTORY_INFO.metageneration()); + assertNull(DIRECTORY_INFO.owner()); + assertNull(DIRECTORY_INFO.selfLink()); + assertEquals(0L, (long) DIRECTORY_INFO.size()); + assertNull(DIRECTORY_INFO.updateTime()); + assertTrue(DIRECTORY_INFO.isDirectory()); } private void compareBlobs(BlobInfo expected, BlobInfo value) { @@ -151,6 +184,35 @@ public void testToPbAndFromPb() { compareBlobs(BLOB_INFO, BlobInfo.fromPb(BLOB_INFO.toPb())); BlobInfo blobInfo = BlobInfo.builder(BlobId.of("b", "n")).build(); compareBlobs(blobInfo, BlobInfo.fromPb(blobInfo.toPb())); + StorageObject object = new StorageObject() + .setName("n/") + .setBucket("b") + .setSize(BigInteger.ZERO) + .set("isDirectory", true); + blobInfo = BlobInfo.fromPb(object); + assertEquals("b", blobInfo.bucket()); + assertEquals("n/", blobInfo.name()); + assertNull(blobInfo.acl()); + assertNull(blobInfo.componentCount()); + assertNull(blobInfo.contentType()); + assertNull(blobInfo.cacheControl()); + assertNull(blobInfo.contentDisposition()); + assertNull(blobInfo.contentEncoding()); + assertNull(blobInfo.contentLanguage()); + assertNull(blobInfo.crc32c()); + assertNull(blobInfo.deleteTime()); + assertNull(blobInfo.etag()); + assertNull(blobInfo.generation()); + assertNull(blobInfo.id()); + assertNull(blobInfo.md5()); + assertNull(blobInfo.mediaLink()); + assertNull(blobInfo.metadata()); + assertNull(blobInfo.metageneration()); + assertNull(blobInfo.owner()); + assertNull(blobInfo.selfLink()); + assertEquals(0L, (long) blobInfo.size()); + assertNull(blobInfo.updateTime()); + assertTrue(blobInfo.isDirectory()); } @Test diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java index c7508593f8c9..5a6173c08199 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java @@ -95,6 +95,10 @@ public class BlobTest { .updateTime(UPDATE_TIME) .build(); private static final BlobInfo BLOB_INFO = BlobInfo.builder("b", "n").metageneration(42L).build(); + private static final BlobInfo DIRECTORY_INFO = BlobInfo.builder("b", "n/") + .size(0L) + .isDirectory(true) + .build(); private Storage storage; private Blob blob; @@ -305,18 +309,20 @@ public void testSignUrl() throws Exception { @Test public void testToBuilder() { - expect(storage.options()).andReturn(mockOptions).times(4); + expect(storage.options()).andReturn(mockOptions).times(6); replay(storage); Blob fullBlob = new Blob(storage, new BlobInfo.BuilderImpl(FULL_BLOB_INFO)); assertEquals(fullBlob, fullBlob.toBuilder().build()); Blob simpleBlob = new Blob(storage, new BlobInfo.BuilderImpl(BLOB_INFO)); assertEquals(simpleBlob, simpleBlob.toBuilder().build()); + Blob directory = new Blob(storage, new BlobInfo.BuilderImpl(DIRECTORY_INFO)); + assertEquals(directory, directory.toBuilder().build()); } @Test public void testBuilder() { initializeExpectedBlob(4); - expect(storage.options()).andReturn(mockOptions).times(2); + expect(storage.options()).andReturn(mockOptions).times(4); replay(storage); Blob.Builder builder = new Blob.Builder(new Blob(storage, new BlobInfo.BuilderImpl(BLOB_INFO))); Blob blob = builder.acl(ACL) @@ -360,5 +366,33 @@ public void testBuilder() { assertEquals(SELF_LINK, blob.selfLink()); assertEquals(SIZE, blob.size()); assertEquals(UPDATE_TIME, blob.updateTime()); + assertFalse(blob.isDirectory()); + builder = new Blob.Builder(new Blob(storage, new BlobInfo.BuilderImpl(DIRECTORY_INFO))); + blob = builder.blobId(BlobId.of("b", "n/")) + .isDirectory(true) + .size(0L) + .build(); + assertEquals("b", blob.bucket()); + assertEquals("n/", blob.name()); + assertNull(blob.acl()); + assertNull(blob.componentCount()); + assertNull(blob.contentType()); + assertNull(blob.cacheControl()); + assertNull(blob.contentDisposition()); + assertNull(blob.contentEncoding()); + assertNull(blob.contentLanguage()); + assertNull(blob.crc32c()); + assertNull(blob.deleteTime()); + assertNull(blob.etag()); + assertNull(blob.id()); + assertNull(blob.md5()); + assertNull(blob.mediaLink()); + assertNull(blob.metadata()); + assertNull(blob.metageneration()); + assertNull(blob.owner()); + assertNull(blob.selfLink()); + assertEquals(0L, (long) blob.size()); + assertNull(blob.updateTime()); + assertTrue(blob.isDirectory()); } } diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java index c9b957bb936a..ac096375b120 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java @@ -90,7 +90,6 @@ public void testServiceOptions() throws Exception { .projectId("p2") .retryParams(RetryParams.defaultInstance()) .authCredentials(null) - .pathDelimiter(":") .build(); serializedCopy = serializeAndDeserialize(options); assertEquals(options, serializedCopy); diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java index 612664de14ae..4050e7d6267b 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java @@ -719,6 +719,22 @@ public void testListBlobsWithEmptyFields() { assertArrayEquals(blobList.toArray(), Iterables.toArray(page.values(), Blob.class)); } + @Test + public void testListBlobsCurrentDirectory() { + String cursor = "cursor"; + Map options = ImmutableMap.of(StorageRpc.Option.DELIMITER, "/"); + ImmutableList blobInfoList = ImmutableList.of(BLOB_INFO1, BLOB_INFO2); + Tuple> result = + Tuple.of(cursor, Iterables.transform(blobInfoList, BlobInfo.INFO_TO_PB_FUNCTION)); + EasyMock.expect(storageRpcMock.list(BUCKET_NAME1, options)).andReturn(result); + EasyMock.replay(storageRpcMock); + initializeService(); + ImmutableList blobList = ImmutableList.of(expectedBlob1, expectedBlob2); + Page page = storage.list(BUCKET_NAME1, Storage.BlobListOption.currentDirectory()); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(blobList.toArray(), Iterables.toArray(page.values(), Blob.class)); + } + @Test public void testUpdateBucket() { BucketInfo updatedBucketInfo = BUCKET_INFO1.toBuilder().indexPage("some-page").build(); diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java index b62a54aff818..563a621c48fb 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java @@ -411,6 +411,52 @@ public void testListBlobsVersioned() throws ExecutionException, InterruptedExcep } } + @Test(timeout = 5000) + public void testListBlobsCurrentDirectory() throws InterruptedException { + String directoryName = "test-list-blobs-current-directory/"; + String subdirectoryName = "subdirectory/"; + String[] blobNames = {directoryName + subdirectoryName + "blob1", + directoryName + "blob2"}; + BlobInfo blob1 = BlobInfo.builder(BUCKET, blobNames[0]) + .contentType(CONTENT_TYPE) + .build(); + BlobInfo blob2 = BlobInfo.builder(BUCKET, blobNames[1]) + .contentType(CONTENT_TYPE) + .build(); + Blob remoteBlob1 = storage.create(blob1, BLOB_BYTE_CONTENT); + Blob remoteBlob2 = storage.create(blob2, BLOB_BYTE_CONTENT); + assertNotNull(remoteBlob1); + assertNotNull(remoteBlob2); + Page page = storage.list(BUCKET, + Storage.BlobListOption.prefix("test-list-blobs-current-directory/"), + Storage.BlobListOption.currentDirectory()); + // Listing blobs is eventually consistent, we loop until the list is of the expected size. The + // test fails if timeout is reached. + while (Iterators.size(page.iterateAll()) != 2) { + Thread.sleep(500); + page = storage.list(BUCKET, + Storage.BlobListOption.prefix("test-list-blobs-current-directory/"), + Storage.BlobListOption.currentDirectory()); + } + Iterator iterator = page.iterateAll(); + while (iterator.hasNext()) { + Blob remoteBlob = iterator.next(); + assertEquals(BUCKET, remoteBlob.bucket()); + if (remoteBlob.name().equals(blobNames[1])) { + assertEquals(CONTENT_TYPE, remoteBlob.contentType()); + assertEquals(BLOB_BYTE_CONTENT.length, (long) remoteBlob.size()); + assertFalse(remoteBlob.isDirectory()); + } else if (remoteBlob.name().equals(directoryName + subdirectoryName)) { + assertEquals(0L, (long) remoteBlob.size()); + assertTrue(remoteBlob.isDirectory()); + } else { + fail("Unexpected blob with name " + remoteBlob.name()); + } + } + assertTrue(remoteBlob1.delete()); + assertTrue(remoteBlob2.delete()); + } + @Test public void testUpdateBlob() { String blobName = "test-update-blob"; From 0f4a7a0fd9d2927fd35c09712e7f531411322739 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 8 Mar 2016 18:41:22 +0100 Subject: [PATCH 148/375] Release version 0.1.5 --- gcloud-java-bigquery/pom.xml | 2 +- gcloud-java-contrib/pom.xml | 2 +- gcloud-java-core/pom.xml | 2 +- gcloud-java-datastore/pom.xml | 2 +- gcloud-java-examples/pom.xml | 2 +- gcloud-java-resourcemanager/pom.xml | 2 +- gcloud-java-storage/pom.xml | 2 +- gcloud-java/pom.xml | 2 +- pom.xml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/gcloud-java-bigquery/pom.xml b/gcloud-java-bigquery/pom.xml index 34ddd7679e97..ac42c839bdb7 100644 --- a/gcloud-java-bigquery/pom.xml +++ b/gcloud-java-bigquery/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.5-SNAPSHOT + 0.1.5 gcloud-java-bigquery diff --git a/gcloud-java-contrib/pom.xml b/gcloud-java-contrib/pom.xml index dd976991e2af..78e7670d3ae8 100644 --- a/gcloud-java-contrib/pom.xml +++ b/gcloud-java-contrib/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.5-SNAPSHOT + 0.1.5 gcloud-java-contrib diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml index d07a567b7e5a..8525fde68174 100644 --- a/gcloud-java-core/pom.xml +++ b/gcloud-java-core/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.5-SNAPSHOT + 0.1.5 gcloud-java-core diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index 452986ba5ea3..67e72245df25 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.5-SNAPSHOT + 0.1.5 gcloud-java-datastore diff --git a/gcloud-java-examples/pom.xml b/gcloud-java-examples/pom.xml index 862d48c89eaa..9586536e3624 100644 --- a/gcloud-java-examples/pom.xml +++ b/gcloud-java-examples/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.5-SNAPSHOT + 0.1.5 gcloud-java-examples diff --git a/gcloud-java-resourcemanager/pom.xml b/gcloud-java-resourcemanager/pom.xml index 40a865f4db68..513da0b67b7e 100644 --- a/gcloud-java-resourcemanager/pom.xml +++ b/gcloud-java-resourcemanager/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.5-SNAPSHOT + 0.1.5 gcloud-java-resourcemanager diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml index f18283b70bc8..01b8f5e01c3f 100644 --- a/gcloud-java-storage/pom.xml +++ b/gcloud-java-storage/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.5-SNAPSHOT + 0.1.5 gcloud-java-storage diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml index adfa716fe27b..927455dfb159 100644 --- a/gcloud-java/pom.xml +++ b/gcloud-java/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.5-SNAPSHOT + 0.1.5 diff --git a/pom.xml b/pom.xml index 28bcba708f7f..b656f5853972 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.gcloud gcloud-java-pom pom - 0.1.5-SNAPSHOT + 0.1.5 GCloud Java https://github.com/GoogleCloudPlatform/gcloud-java From 1f1f4b05c8a5073bcf91da1160da5aac16cab96a Mon Sep 17 00:00:00 2001 From: travis-ci Date: Tue, 8 Mar 2016 18:26:13 +0000 Subject: [PATCH 149/375] Updating version in README files. [ci skip] --- README.md | 6 +++--- gcloud-java-bigquery/README.md | 6 +++--- gcloud-java-contrib/README.md | 6 +++--- gcloud-java-core/README.md | 6 +++--- gcloud-java-datastore/README.md | 6 +++--- gcloud-java-examples/README.md | 6 +++--- gcloud-java-resourcemanager/README.md | 6 +++--- gcloud-java-storage/README.md | 6 +++--- gcloud-java/README.md | 6 +++--- 9 files changed, 27 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 32a0f539425e..68c624c37489 100644 --- a/README.md +++ b/README.md @@ -29,16 +29,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java - 0.1.4 + 0.1.5 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java:0.1.4' +compile 'com.google.gcloud:gcloud-java:0.1.5' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java" % "0.1.4" +libraryDependencies += "com.google.gcloud" % "gcloud-java" % "0.1.5" ``` Example Applications diff --git a/gcloud-java-bigquery/README.md b/gcloud-java-bigquery/README.md index 58633ba635f9..3387cd8c4f41 100644 --- a/gcloud-java-bigquery/README.md +++ b/gcloud-java-bigquery/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-bigquery - 0.1.4 + 0.1.5 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-bigquery:0.1.4' +compile 'com.google.gcloud:gcloud-java-bigquery:0.1.5' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-bigquery" % "0.1.4" +libraryDependencies += "com.google.gcloud" % "gcloud-java-bigquery" % "0.1.5" ``` Example Application diff --git a/gcloud-java-contrib/README.md b/gcloud-java-contrib/README.md index 7a935192891d..426417d54e87 100644 --- a/gcloud-java-contrib/README.md +++ b/gcloud-java-contrib/README.md @@ -16,16 +16,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-contrib - 0.1.4 + 0.1.5 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-contrib:0.1.4' +compile 'com.google.gcloud:gcloud-java-contrib:0.1.5' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-contrib" % "0.1.4" +libraryDependencies += "com.google.gcloud" % "gcloud-java-contrib" % "0.1.5" ``` Java Versions diff --git a/gcloud-java-core/README.md b/gcloud-java-core/README.md index bc9463b9cc2b..fc5f481f8ec3 100644 --- a/gcloud-java-core/README.md +++ b/gcloud-java-core/README.md @@ -19,16 +19,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-core - 0.1.4 + 0.1.5 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-core:0.1.4' +compile 'com.google.gcloud:gcloud-java-core:0.1.5' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-core" % "0.1.4" +libraryDependencies += "com.google.gcloud" % "gcloud-java-core" % "0.1.5" ``` Troubleshooting diff --git a/gcloud-java-datastore/README.md b/gcloud-java-datastore/README.md index dd341ba244c3..0d89a0a07e3e 100644 --- a/gcloud-java-datastore/README.md +++ b/gcloud-java-datastore/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-datastore - 0.1.4 + 0.1.5 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-datastore:0.1.4' +compile 'com.google.gcloud:gcloud-java-datastore:0.1.5' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-datastore" % "0.1.4" +libraryDependencies += "com.google.gcloud" % "gcloud-java-datastore" % "0.1.5" ``` Example Application diff --git a/gcloud-java-examples/README.md b/gcloud-java-examples/README.md index 59fbca11e219..7d54b8f3e1a9 100644 --- a/gcloud-java-examples/README.md +++ b/gcloud-java-examples/README.md @@ -19,16 +19,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-examples - 0.1.4 + 0.1.5 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-examples:0.1.4' +compile 'com.google.gcloud:gcloud-java-examples:0.1.5' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-examples" % "0.1.4" +libraryDependencies += "com.google.gcloud" % "gcloud-java-examples" % "0.1.5" ``` To run examples from your command line: diff --git a/gcloud-java-resourcemanager/README.md b/gcloud-java-resourcemanager/README.md index cd48d6699311..94037e27a709 100644 --- a/gcloud-java-resourcemanager/README.md +++ b/gcloud-java-resourcemanager/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-resourcemanager - 0.1.4 + 0.1.5 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-resourcemanager:0.1.4' +compile 'com.google.gcloud:gcloud-java-resourcemanager:0.1.5' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-resourcemanager" % "0.1.4" +libraryDependencies += "com.google.gcloud" % "gcloud-java-resourcemanager" % "0.1.5" ``` Example Application diff --git a/gcloud-java-storage/README.md b/gcloud-java-storage/README.md index f7973544bba2..0ee05b31c10c 100644 --- a/gcloud-java-storage/README.md +++ b/gcloud-java-storage/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-storage - 0.1.4 + 0.1.5 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-storage:0.1.4' +compile 'com.google.gcloud:gcloud-java-storage:0.1.5' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-storage" % "0.1.4" +libraryDependencies += "com.google.gcloud" % "gcloud-java-storage" % "0.1.5" ``` Example Application diff --git a/gcloud-java/README.md b/gcloud-java/README.md index c51b4e8fe7bc..e296d0c0c565 100644 --- a/gcloud-java/README.md +++ b/gcloud-java/README.md @@ -27,16 +27,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java - 0.1.4 + 0.1.5 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java:0.1.4' +compile 'com.google.gcloud:gcloud-java:0.1.5' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java" % "0.1.4" +libraryDependencies += "com.google.gcloud" % "gcloud-java" % "0.1.5" ``` Troubleshooting From aa6c173871113775725082517ba113fc0306a619 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 8 Mar 2016 20:27:32 +0100 Subject: [PATCH 150/375] Update version to 0.1.6-SNAPSHOT --- gcloud-java-bigquery/pom.xml | 2 +- gcloud-java-contrib/pom.xml | 2 +- gcloud-java-core/pom.xml | 2 +- gcloud-java-datastore/pom.xml | 2 +- gcloud-java-examples/pom.xml | 2 +- gcloud-java-resourcemanager/pom.xml | 2 +- gcloud-java-storage/pom.xml | 2 +- gcloud-java/pom.xml | 2 +- pom.xml | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/gcloud-java-bigquery/pom.xml b/gcloud-java-bigquery/pom.xml index ac42c839bdb7..9a2137cb987d 100644 --- a/gcloud-java-bigquery/pom.xml +++ b/gcloud-java-bigquery/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.5 + 0.1.6-SNAPSHOT gcloud-java-bigquery diff --git a/gcloud-java-contrib/pom.xml b/gcloud-java-contrib/pom.xml index 78e7670d3ae8..bd4a6458dc38 100644 --- a/gcloud-java-contrib/pom.xml +++ b/gcloud-java-contrib/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.5 + 0.1.6-SNAPSHOT gcloud-java-contrib diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml index 8525fde68174..6d0ed675b423 100644 --- a/gcloud-java-core/pom.xml +++ b/gcloud-java-core/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.5 + 0.1.6-SNAPSHOT gcloud-java-core diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index 67e72245df25..977b6db22b14 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.5 + 0.1.6-SNAPSHOT gcloud-java-datastore diff --git a/gcloud-java-examples/pom.xml b/gcloud-java-examples/pom.xml index 9586536e3624..111308658c2e 100644 --- a/gcloud-java-examples/pom.xml +++ b/gcloud-java-examples/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.5 + 0.1.6-SNAPSHOT gcloud-java-examples diff --git a/gcloud-java-resourcemanager/pom.xml b/gcloud-java-resourcemanager/pom.xml index 513da0b67b7e..c10691d3b07d 100644 --- a/gcloud-java-resourcemanager/pom.xml +++ b/gcloud-java-resourcemanager/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.5 + 0.1.6-SNAPSHOT gcloud-java-resourcemanager diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml index 01b8f5e01c3f..d5f0f6d98660 100644 --- a/gcloud-java-storage/pom.xml +++ b/gcloud-java-storage/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.5 + 0.1.6-SNAPSHOT gcloud-java-storage diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml index 927455dfb159..19536faa8c8d 100644 --- a/gcloud-java/pom.xml +++ b/gcloud-java/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.5 + 0.1.6-SNAPSHOT diff --git a/pom.xml b/pom.xml index b656f5853972..b9d979c4d467 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.gcloud gcloud-java-pom pom - 0.1.5 + 0.1.6-SNAPSHOT GCloud Java https://github.com/GoogleCloudPlatform/gcloud-java From de9b0d60eee8079223feb6f1f30b069e91e67431 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 9 Mar 2016 12:34:48 +0100 Subject: [PATCH 151/375] Refactor Storage's delimiter support - Minor fixes to javadoc - Favor firstNonNull over ternary operator when possible - Move prefix-object transformer to static function - Simplify StorageOptions equals method --- .../google/gcloud/spi/DefaultStorageRpc.java | 31 +++++++++++-------- .../com/google/gcloud/storage/BlobInfo.java | 4 +-- .../com/google/gcloud/storage/Storage.java | 16 +++++----- .../google/gcloud/storage/StorageOptions.java | 6 +--- 4 files changed, 29 insertions(+), 28 deletions(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java b/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java index fcbfe5514d1e..ec4447d406cb 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java @@ -14,6 +14,7 @@ package com.google.gcloud.spi; +import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.gcloud.spi.StorageRpc.Option.DELIMITER; import static com.google.gcloud.spi.StorageRpc.Option.FIELDS; import static com.google.gcloud.spi.StorageRpc.Option.IF_GENERATION_MATCH; @@ -58,7 +59,6 @@ import com.google.api.services.storage.model.Objects; import com.google.api.services.storage.model.StorageObject; import com.google.common.base.Function; -import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; @@ -167,24 +167,29 @@ public Tuple> list(final String bucket, Map storageObjects = Iterables.concat( - objects.getItems() != null ? objects.getItems() : ImmutableList.of(), + firstNonNull(objects.getItems(), ImmutableList.of()), objects.getPrefixes() != null - ? Lists.transform(objects.getPrefixes(), new Function() { - @Override - public StorageObject apply(String prefix) { - return new StorageObject() - .set("isDirectory", true) - .setBucket(bucket) - .setName(prefix) - .setSize(BigInteger.ZERO); - } - }) : ImmutableList.of()); + ? Lists.transform(objects.getPrefixes(), objectFromPrefix(bucket)) + : ImmutableList.of()); return Tuple.of(objects.getNextPageToken(), storageObjects); } catch (IOException ex) { throw translate(ex); } } + private static Function objectFromPrefix(final String bucket) { + return new Function() { + @Override + public StorageObject apply(String prefix) { + return new StorageObject() + .set("isDirectory", true) + .setBucket(bucket) + .setName(prefix) + .setSize(BigInteger.ZERO); + } + }; + } + @Override public Bucket get(Bucket bucket, Map options) { try { @@ -549,7 +554,7 @@ public String open(StorageObject object, Map options) { HttpRequest httpRequest = requestFactory.buildPostRequest(url, new JsonHttpContent(jsonFactory, object)); httpRequest.getHeaders().set("X-Upload-Content-Type", - MoreObjects.firstNonNull(object.getContentType(), "application/octet-stream")); + firstNonNull(object.getContentType(), "application/octet-stream")); HttpResponse response = httpRequest.execute(); if (response.getStatusCode() != 200) { GoogleJsonError error = new GoogleJsonError(); diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobInfo.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobInfo.java index 9d981aeeafda..cf509c8f0961 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobInfo.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobInfo.java @@ -603,7 +603,7 @@ public Long updateTime() { /** * Returns {@code true} if the current blob represents a directory. This can only happen if the * blob is returned by {@link Storage#list(String, Storage.BlobListOption...)} when the - * {@link Storage.BlobListOption#currentDirectory()} option is used. If {@code true} only + * {@link Storage.BlobListOption#currentDirectory()} option is used. When this is the case only * {@link #blobId()} and {@link #size()} are set for the current blob: {@link BlobId#name()} ends * with the '/' character, {@link BlobId#generation()} returns {@code null} and {@link #size()} is * {@code 0}. @@ -785,7 +785,7 @@ public Acl apply(ObjectAccessControl objectAccessControl) { } })); } - if (storageObject.get("isDirectory") != null) { + if (storageObject.containsKey("isDirectory")) { builder.isDirectory(Boolean.TRUE); } return builder.build(); diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index e1ab337cdbdf..0ee18f541284 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -694,14 +694,14 @@ public static BlobListOption prefix(String prefix) { } /** - * If specified, results are returned in a directory-like mode. Blobs whose names, aside from - * a possible {@link #prefix(String)}, do not contain the '/' delimiter are returned as is. - * Blobs whose names, aside from a possible {@link #prefix(String)}, contain the '/' delimiter, - * will have their name truncated after the delimiter and will be returned as {@link Blob} - * objects where only {@link Blob#blobId()}, {@link Blob#size()} and {@link Blob#isDirectory()} - * are set. For such directory blobs, ({@link BlobId#generation()} returns {@code null}), - * {@link Blob#size()} returns {@code 0} while {@link Blob#isDirectory()} returns {@code true}. - * Duplicate directory blobs are omitted. + * If specified, results are returned in a directory-like mode. Blobs whose names, after a + * possible {@link #prefix(String)}, do not contain the '/' delimiter are returned as is. Blobs + * whose names, after a possible {@link #prefix(String)}, contain the '/' delimiter, will have + * their name truncated after the delimiter and will be returned as {@link Blob} objects where + * only {@link Blob#blobId()}, {@link Blob#size()} and {@link Blob#isDirectory()} are set. For + * such directory blobs, ({@link BlobId#generation()} returns {@code null}), {@link Blob#size()} + * returns {@code 0} while {@link Blob#isDirectory()} returns {@code true}. Duplicate directory + * blobs are omitted. */ public static BlobListOption currentDirectory() { return new BlobListOption(StorageRpc.Option.DELIMITER, true); diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageOptions.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageOptions.java index ca9b8944ea8b..86ce18eb71ec 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageOptions.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageOptions.java @@ -106,11 +106,7 @@ public int hashCode() { @Override public boolean equals(Object obj) { - if (!(obj instanceof StorageOptions)) { - return false; - } - StorageOptions other = (StorageOptions) obj; - return baseEquals(other); + return obj instanceof StorageOptions && baseEquals((StorageOptions) obj); } public static Builder builder() { From 1f06caf21d73921280ce6e724cbaebb6f22169d4 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Wed, 24 Feb 2016 10:11:02 -0800 Subject: [PATCH 152/375] The following has been done within multiple iterations: Refactored URL parsing and removed unnecessary doc in local helper. Refactored to use AtomicReference instead of singleton Map. Adjusted tests of paging to test that pages contain expected objects. Added check and test for deleting non-empy zone. Removed RrsetWapper and used tailMap in listing. Added @VisibleForTesting annotations. Added fails to expected exceptions. Added error message checks. Addressed codacy suggestions. Assigned project ID to the helper and test. Added pool of executors instead of spawning one threads. Reduced number of threads. --- .../{ => dns}/testing/LocalDnsHelper.java | 719 ++++------- .../testing/OptionParsers.java} | 63 +- .../com/google/gcloud/spi/DefaultDnsRpc.java | 6 +- .../{ => dns}/testing/LocalDnsHelperTest.java | 1116 ++++++----------- 4 files changed, 678 insertions(+), 1226 deletions(-) rename gcloud-java-dns/src/main/java/com/google/gcloud/{ => dns}/testing/LocalDnsHelper.java (63%) rename gcloud-java-dns/src/main/java/com/google/gcloud/{testing/OptionParsersAndExtractors.java => dns/testing/OptionParsers.java} (80%) rename gcloud-java-dns/src/test/java/com/google/gcloud/{ => dns}/testing/LocalDnsHelperTest.java (63%) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/testing/LocalDnsHelper.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/LocalDnsHelper.java similarity index 63% rename from gcloud-java-dns/src/main/java/com/google/gcloud/testing/LocalDnsHelper.java rename to gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/LocalDnsHelper.java index b8483bc4fcd7..f9cd1a11281e 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/testing/LocalDnsHelper.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/LocalDnsHelper.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package com.google.gcloud.testing; +package com.google.gcloud.dns.testing; -import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.net.InetAddresses.isInetAddress; import static java.net.HttpURLConnection.HTTP_NO_CONTENT; import static java.net.HttpURLConnection.HTTP_OK; @@ -27,12 +27,12 @@ import com.google.api.services.dns.model.Project; import com.google.api.services.dns.model.Quota; import com.google.api.services.dns.model.ResourceRecordSet; -import com.google.common.base.Function; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Joiner; -import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableSortedMap; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.google.common.io.ByteStreams; @@ -54,26 +54,32 @@ import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.NavigableMap; import java.util.NavigableSet; -import java.util.Objects; import java.util.Random; import java.util.Set; +import java.util.SortedMap; import java.util.TreeMap; import java.util.TreeSet; import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.ConcurrentNavigableMap; import java.util.concurrent.ConcurrentSkipListMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.regex.Pattern; import java.util.zip.GZIPInputStream; -import javax.annotation.Nullable; - /** - * A utility to create local Google Cloud DNS mock. + * A local Google Cloud DNS mock. * *

    The mock runs in a separate thread, listening for HTTP requests on the local machine at an * ephemeral port. @@ -81,7 +87,7 @@ *

    While the mock attempts to simulate the service, there are some differences in the behaviour. * The mock will accept any project ID and never returns a notFound or another error because of * project ID. It assumes that all project IDs exist and that the user has all the necessary - * privileges to manipulate any project. Similarly, the local simulation does not work with any + * privileges to manipulate any project. Similarly, the local simulation does not require * verification of domain name ownership. Any request for creating a managed zone will be approved. * The mock does not track quota and will allow the user to exceed it. The mock provides only basic * validation of the DNS data for records of type A and AAAA. It does not validate any other record @@ -97,16 +103,21 @@ public class LocalDnsHelper { private static final Random ID_GENERATOR = new Random(); private static final String VERSION = "v1"; private static final String CONTEXT = "/dns/" + VERSION + "/projects"; - private static final Set SUPPORTED_COMPRESSION_ENCODINGS = - ImmutableSet.of("gzip", "x-gzip"); + private static final Set ENCODINGS = ImmutableSet.of("gzip", "x-gzip"); private static final List TYPES = ImmutableList.of("A", "AAAA", "CNAME", "MX", "NAPTR", "NS", "PTR", "SOA", "SPF", "SRV", "TXT"); + private static final TreeSet FORBIDDEN = Sets.newTreeSet( + ImmutableList.of("google.com.", "com.", "example.com.", "net.", "org.")); + private static final Pattern ZONE_NAME_RE = Pattern.compile("[a-z][a-z0-9-]*"); + private static final ScheduledExecutorService EXECUTORS = + Executors.newScheduledThreadPool(2, Executors.defaultThreadFactory()); + private static final String PROJECT_ID = "dummyprojectid"; static { try { BASE_CONTEXT = new URI(CONTEXT); } catch (URISyntaxException e) { - throw new RuntimeException( + throw new IllegalArgumentException( "Could not initialize LocalDnsHelper due to URISyntaxException.", e); } } @@ -139,67 +150,7 @@ private enum CallRegex { } /** - * Wraps DNS data by adding a timestamp and id which is used for paging and listing. - */ - static class RrsetWrapper { - static final Function WRAP_FUNCTION = - new Function() { - @Nullable - @Override - public RrsetWrapper apply(@Nullable ResourceRecordSet input) { - return new RrsetWrapper(input); - } - }; - private final ResourceRecordSet rrset; - private final Long timestamp = System.currentTimeMillis(); - private String id; - - RrsetWrapper(ResourceRecordSet rrset) { - // The constructor creates a copy in order to prevent side effects. - this.rrset = new ResourceRecordSet(); - this.rrset.setName(rrset.getName()); - this.rrset.setTtl(rrset.getTtl()); - this.rrset.setRrdatas(ImmutableList.copyOf(rrset.getRrdatas())); - this.rrset.setType(rrset.getType()); - } - - void setId(String id) { - this.id = id; - } - - String id() { - return id; - } - - /** - * Equals does not care about the listing id and timestamp metadata, just the rrset. - */ - @Override - public boolean equals(Object other) { - return (other instanceof RrsetWrapper) && Objects.equals(rrset, ((RrsetWrapper) other).rrset); - } - - @Override - public int hashCode() { - return Objects.hash(rrset); - } - - ResourceRecordSet rrset() { - return rrset; - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("rrset", rrset) - .add("timestamp", timestamp) - .add("id", id) - .toString(); - } - } - - /** - * Associates a project with a collection of ManagedZones. Thread safe. + * Associates a project with a collection of ManagedZones. */ static class ProjectContainer { private final Project project; @@ -220,29 +171,24 @@ ConcurrentSkipListMap zones() { } /** - * Associates a zone with a collection of changes and dns records. Thread safe. + * Associates a zone with a collection of changes and dns records. */ static class ZoneContainer { private final ManagedZone zone; - /** - * DNS records are held in a map to allow for atomic replacement of record sets when applying - * changes. The key for the map is always the zone name. The collection of records is immutable - * and must always exist, i.e., dnsRecords.get(zone.getName()) is never {@code null}. - */ - private final ConcurrentSkipListMap> - dnsRecords = new ConcurrentSkipListMap<>(); + private final AtomicReference> + dnsRecords = new AtomicReference<>(ImmutableSortedMap.of()); private final ConcurrentLinkedQueue changes = new ConcurrentLinkedQueue<>(); ZoneContainer(ManagedZone zone) { this.zone = zone; - this.dnsRecords.put(zone.getName(), ImmutableList.of()); + this.dnsRecords.set(ImmutableSortedMap.of()); } ManagedZone zone() { return zone; } - ConcurrentSkipListMap> dnsRecords() { + AtomicReference> dnsRecords() { return dnsRecords; } @@ -283,6 +229,7 @@ private enum Error { INTERNAL_ERROR(500, "global", "internalError", "INTERNAL_ERROR"), BAD_REQUEST(400, "global", "badRequest", "BAD_REQUEST"), INVALID(400, "global", "invalid", "INVALID"), + CONTAINER_NOT_EMPTY(400, "global", "containerNotEmpty", "CONTAINER_NOT_EMPTY"), NOT_AVAILABLE(400, "global", "managedZoneDnsNameNotAvailable", "NOT_AVAILABLE"), NOT_FOUND(404, "global", "notFound", "NOT_FOUND"), ALREADY_EXISTS(409, "global", "alreadyExists", "ALREADY_EXISTS"), @@ -325,34 +272,38 @@ private String toJson(String message) throws IOException { private class RequestHandler implements HttpHandler { - /** - * Chooses the proper handler for a request. - */ private Response pickHandler(HttpExchange exchange, CallRegex regex) { + URI relative = BASE_CONTEXT.relativize(exchange.getRequestURI()); + String path = relative.getPath(); + String[] tokens = path.split("/"); + String projectId = tokens.length > 0 ? tokens[0] : null; + String zoneName = tokens.length > 2 ? tokens[2] : null; + String changeId = tokens.length > 4 ? tokens[4] : null; + String query = relative.getQuery(); switch (regex) { case CHANGE_GET: - return handleChangeGet(exchange); + return getChange(projectId, zoneName, changeId, query); case CHANGE_LIST: - return handleChangeList(exchange); + return listChanges(projectId, zoneName, query); case ZONE_GET: - return handleZoneGet(exchange); + return getZone(projectId, zoneName, query); case ZONE_DELETE: - return handleZoneDelete(exchange); + return deleteZone(projectId, zoneName); case ZONE_LIST: - return handleZoneList(exchange); + return listZones(projectId, query); case PROJECT_GET: - return handleProjectGet(exchange); + return getProject(projectId, query); case RECORD_LIST: - return handleDnsRecordList(exchange); + return listDnsRecords(projectId, zoneName, query); case ZONE_CREATE: try { - return handleZoneCreate(exchange); + return handleZoneCreate(exchange, projectId, query); } catch (IOException ex) { return Error.BAD_REQUEST.response(ex.getMessage()); } case CHANGE_CREATE: try { - return handleChangeCreate(exchange); + return handleChangeCreate(exchange, projectId, zoneName, query); } catch (IOException ex) { return Error.BAD_REQUEST.response(ex.getMessage()); } @@ -367,122 +318,53 @@ public void handle(HttpExchange exchange) throws IOException { String rawPath = exchange.getRequestURI().getRawPath(); for (CallRegex regex : CallRegex.values()) { if (requestMethod.equals(regex.method) && rawPath.matches(regex.pathRegex)) { - // there is a match, pass the handling accordingly Response response = pickHandler(exchange, regex); writeResponse(exchange, response); - return; // only one match is possible + return; } } - // could not be matched, the service returns 404 page not found here - writeResponse(exchange, Error.NOT_FOUND.response("The url does not match any API call.")); - } - - private Response handleZoneDelete(HttpExchange exchange) { - String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); - String[] tokens = path.split("/"); - String projectId = tokens[0]; - String zoneName = tokens[2]; - return deleteZone(projectId, zoneName); - } - - private Response handleZoneGet(HttpExchange exchange) { - String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); - String[] tokens = path.split("/"); - String projectId = tokens[0]; - String zoneName = tokens[2]; - String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); - String[] fields = OptionParsersAndExtractors.parseGetOptions(query); - return getZone(projectId, zoneName, fields); - } - - private Response handleZoneList(HttpExchange exchange) { - String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); - String[] tokens = path.split("/"); - String projectId = tokens[0]; - String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); - Map options = OptionParsersAndExtractors.parseListZonesOptions(query); - return listZones(projectId, options); - } - - private Response handleProjectGet(HttpExchange exchange) { - String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); - String[] tokens = path.split("/"); - String projectId = tokens[0]; - String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); - String[] fields = OptionParsersAndExtractors.parseGetOptions(query); - return getProject(projectId, fields); + writeResponse(exchange, Error.NOT_FOUND.response(String.format( + "The url %s for %s method does not match any API call.", + requestMethod, exchange.getRequestURI()))); } /** * @throws IOException if the request cannot be parsed. */ - private Response handleChangeCreate(HttpExchange exchange) throws IOException { - String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); - String[] tokens = path.split("/"); - String projectId = tokens[0]; - String zoneName = tokens[2]; - String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); - String[] fields = OptionParsersAndExtractors.parseGetOptions(query); + private Response handleChangeCreate(HttpExchange exchange, String projectId, String zoneName, + String query) throws IOException { String requestBody = decodeContent(exchange.getRequestHeaders(), exchange.getRequestBody()); - Change change = jsonFactory.fromString(requestBody, Change.class); + Change change; + try { + change = jsonFactory.fromString(requestBody, Change.class); + } catch (IllegalArgumentException ex) { + return Error.REQUIRED.response( + "The 'entity.change' parameter is required but was missing."); + } + String[] fields = OptionParsers.parseGetOptions(query); return createChange(projectId, zoneName, change, fields); } - private Response handleChangeGet(HttpExchange exchange) { - String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); - String[] tokens = path.split("/"); - String projectId = tokens[0]; - String zoneName = tokens[2]; - String changeId = tokens[4]; - String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); - String[] fields = OptionParsersAndExtractors.parseGetOptions(query); - return getChange(projectId, zoneName, changeId, fields); - } - - private Response handleChangeList(HttpExchange exchange) { - String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); - String[] tokens = path.split("/"); - String projectId = tokens[0]; - String zoneName = tokens[2]; - String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); - Map options = OptionParsersAndExtractors.parseListChangesOptions(query); - return listChanges(projectId, zoneName, options); - } - - private Response handleDnsRecordList(HttpExchange exchange) { - String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); - String[] tokens = path.split("/"); - String projectId = tokens[0]; - String zoneName = tokens[2]; - String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); - Map options = OptionParsersAndExtractors.parseListDnsRecordsOptions(query); - return listDnsRecords(projectId, zoneName, options); - } - /** * @throws IOException if the request cannot be parsed. */ - private Response handleZoneCreate(HttpExchange exchange) throws IOException { - String path = BASE_CONTEXT.relativize(exchange.getRequestURI()).getPath(); - String[] tokens = path.split("/"); - String projectId = tokens[0]; - String query = BASE_CONTEXT.relativize(exchange.getRequestURI()).getQuery(); - String[] options = OptionParsersAndExtractors.parseGetOptions(query); + private Response handleZoneCreate(HttpExchange exchange, String projectId, String query) + throws IOException { String requestBody = decodeContent(exchange.getRequestHeaders(), exchange.getRequestBody()); ManagedZone zone; try { - // IllegalArgumentException if the request body is an empty string zone = jsonFactory.fromString(requestBody, ManagedZone.class); } catch (IllegalArgumentException ex) { return Error.REQUIRED.response( "The 'entity.managedZone' parameter is required but was missing."); } + String[] options = OptionParsers.parseGetOptions(query); return createZone(projectId, zone, options); } } private LocalDnsHelper(long delay) { - this.delayChange = delay; // 0 makes this synchronous + this.delayChange = delay; try { server = HttpServer.create(new InetSocketAddress(0), 0); port = server.getAddress().getPort(); @@ -501,9 +383,9 @@ ConcurrentSkipListMap projects() { /** * Creates new {@link LocalDnsHelper} instance that listens to requests on the local machine. This - * instance processes changes separate threads. The parameter determines how long a thread should - * wait before processing a change. If it is set to 0, the threading is turned off and the mock - * will behave synchronously. + * instance processes changes in separate thread. The parameter determines how long a thread + * should wait before processing a change. If it is set to 0, the threading is turned off and the + * mock will behave synchronously. * * @param delay delay for processing changes in ms or 0 for synchronous processing */ @@ -512,10 +394,10 @@ public static LocalDnsHelper create(Long delay) { } /** - * Returns a DnsOptions instance that sets the host to use the mock server. + * Returns a {@link DnsOptions} instance that sets the host to use the mock server. */ public DnsOptions options() { - return DnsOptions.builder().host("http://localhost:" + port).build(); + return DnsOptions.builder().projectId(PROJECT_ID).host("http://localhost:" + port).build(); } /** @@ -539,6 +421,7 @@ private static void writeResponse(HttpExchange exchange, Response response) { exchange.getResponseHeaders().add("Connection", "close"); exchange.sendResponseHeaders(response.code(), response.body().length()); if (response.code() != 204) { + // the server automatically sends headers and closes output stream when 204 is returned outputStream.write(response.body().getBytes(StandardCharsets.UTF_8)); } outputStream.close(); @@ -547,18 +430,15 @@ private static void writeResponse(HttpExchange exchange, Response response) { } } - /** - * Decodes content of the HttpRequest. - */ private static String decodeContent(Headers headers, InputStream inputStream) throws IOException { List contentEncoding = headers.get("Content-encoding"); InputStream input = inputStream; try { if (contentEncoding != null && !contentEncoding.isEmpty()) { String encoding = contentEncoding.get(0); - if (SUPPORTED_COMPRESSION_ENCODINGS.contains(encoding)) { + if (ENCODINGS.contains(encoding)) { input = new GZIPInputStream(inputStream); - } else if (!encoding.equals("identity")) { + } else if (!"identity".equals(encoding)) { throw new IOException( "The request has the following unsupported HTTP content encoding: " + encoding); } @@ -574,25 +454,25 @@ private static String decodeContent(Headers headers, InputStream inputStream) th * * @param context managedZones | projects | rrsets | changes */ + @VisibleForTesting static Response toListResponse(List serializedObjects, String context, String pageToken, boolean includePageToken) { - // start building response StringBuilder responseBody = new StringBuilder(); responseBody.append("{\"").append(context).append("\": ["); Joiner.on(",").appendTo(responseBody, serializedObjects); - responseBody.append("]"); - // add page token only if exists and is asked for + responseBody.append(']'); + // add page token only if it exists and is asked for if (pageToken != null && includePageToken) { - responseBody.append(",\"nextPageToken\": \"").append(pageToken).append("\""); + responseBody.append(",\"nextPageToken\": \"").append(pageToken).append('"'); } - responseBody.append("}"); + responseBody.append('}'); return new Response(HTTP_OK, responseBody.toString()); } /** * Prepares DNS records that are created by default for each zone. */ - private static ImmutableList defaultRecords(ManagedZone zone) { + private static ImmutableSortedMap defaultRecords(ManagedZone zone) { ResourceRecordSet soa = new ResourceRecordSet(); soa.setTtl(21600); soa.setName(zone.getDnsName()); @@ -606,17 +486,15 @@ private static ImmutableList defaultRecords(ManagedZone zone) { ns.setName(zone.getDnsName()); ns.setRrdatas(zone.getNameServers()); ns.setType("NS"); - RrsetWrapper nsWrapper = new RrsetWrapper(ns); - RrsetWrapper soaWrapper = new RrsetWrapper(soa); - ImmutableList results = ImmutableList.of(nsWrapper, soaWrapper); - nsWrapper.setId(getUniqueId(results)); - soaWrapper.setId(getUniqueId(results)); - return results; + String nsId = getUniqueId(ImmutableSet.of()); + String soaId = getUniqueId(ImmutableSet.of(nsId)); + return ImmutableSortedMap.of(nsId, ns, soaId, soa); } /** * Returns a list of four nameservers randomly chosen from the predefined set. */ + @VisibleForTesting static List randomNameservers() { ArrayList nameservers = Lists.newArrayList( "dns1.googlecloud.com", "dns2.googlecloud.com", "dns3.googlecloud.com", @@ -630,23 +508,14 @@ static List randomNameservers() { } /** - * Returns a hex string id (used for a dns record) unique within the set of wrappers. + * Returns a hex string id (used for a dns record) unique within the set of ids. */ - static String getUniqueId(List wrappers) { - TreeSet ids = Sets.newTreeSet(Lists.transform(wrappers, - new Function() { - @Override - public String apply(RrsetWrapper input) { - return input.id() == null ? "null" : input.id(); - } - })); + @VisibleForTesting + static String getUniqueId(Set ids) { String id; do { id = Long.toHexString(System.currentTimeMillis()) + Long.toHexString(Math.abs(ID_GENERATOR.nextLong())); - if (!ids.contains(id)) { - return id; - } } while (ids.contains(id)); return id; } @@ -654,21 +523,19 @@ public String apply(RrsetWrapper input) { /** * Tests if a DNS record matches name and type (if provided). Used for filtering. */ + @VisibleForTesting static boolean matchesCriteria(ResourceRecordSet record, String name, String type) { if (type != null && !record.getType().equals(type)) { return false; } - if (name != null && !record.getName().equals(name)) { - return false; - } - return true; + return name == null || record.getName().equals(name); } /** * Returns a project container. Never returns {@code null} because we assume that all projects * exists. */ - ProjectContainer findProject(String projectId) { + private ProjectContainer findProject(String projectId) { ProjectContainer defaultProject = createProject(projectId); projects.putIfAbsent(projectId, defaultProject); return projects.get(projectId); @@ -677,6 +544,7 @@ ProjectContainer findProject(String projectId) { /** * Returns a zone container. Returns {@code null} if zone does not exist within project. */ + @VisibleForTesting ZoneContainer findZone(String projectId, String zoneName) { ProjectContainer projectContainer = findProject(projectId); // never null return projectContainer.zones().get(zoneName); @@ -685,6 +553,7 @@ ZoneContainer findZone(String projectId, String zoneName) { /** * Returns a change found by its id. Returns {@code null} if such a change does not exist. */ + @VisibleForTesting Change findChange(String projectId, String zoneName, String changeId) { ZoneContainer wrapper = findZone(projectId, zoneName); return wrapper == null ? null : wrapper.findChange(changeId); @@ -693,20 +562,20 @@ Change findChange(String projectId, String zoneName, String changeId) { /** * Returns a response to getChange service call. */ - Response getChange(String projectId, String zoneName, String changeId, String[] fields) { + @VisibleForTesting + Response getChange(String projectId, String zoneName, String changeId, String query) { Change change = findChange(projectId, zoneName, changeId); if (change == null) { ZoneContainer zone = findZone(projectId, zoneName); if (zone == null) { - // zone does not exist return Error.NOT_FOUND.response(String.format( "The 'parameters.managedZone' resource named '%s' does not exist.", zoneName)); } - // zone exists but change does not return Error.NOT_FOUND.response(String.format( "The 'parameters.changeId' resource named '%s' does not exist.", changeId)); } - Change result = OptionParsersAndExtractors.extractFields(change, fields); + String[] fields = OptionParsers.parseGetOptions(query); + Change result = OptionParsers.extractFields(change, fields); try { return new Response(HTTP_OK, jsonFactory.toString(result)); } catch (IOException e) { @@ -719,13 +588,15 @@ Response getChange(String projectId, String zoneName, String changeId, String[] /** * Returns a response to getZone service call. */ - Response getZone(String projectId, String zoneName, String[] fields) { + @VisibleForTesting + Response getZone(String projectId, String zoneName, String query) { ZoneContainer container = findZone(projectId, zoneName); if (container == null) { return Error.NOT_FOUND.response(String.format( "The 'parameters.managedZone' resource named '%s' does not exist.", zoneName)); } - ManagedZone result = OptionParsersAndExtractors.extractFields(container.zone(), fields); + String[] fields = OptionParsers.parseGetOptions(query); + ManagedZone result = OptionParsers.extractFields(container.zone(), fields); try { return new Response(HTTP_OK, jsonFactory.toString(result)); } catch (IOException e) { @@ -738,11 +609,11 @@ Response getZone(String projectId, String zoneName, String[] fields) { * We assume that every project exists. If we do not have it in the collection yet, we just create * a new default project instance with default quota. */ - Response getProject(String projectId, String[] fields) { - ProjectContainer defaultProject = createProject(projectId); - projects.putIfAbsent(projectId, defaultProject); - Project project = projects.get(projectId).project(); // project is now guaranteed to exist - Project result = OptionParsersAndExtractors.extractFields(project, fields); + @VisibleForTesting + Response getProject(String projectId, String query) { + String[] fields = OptionParsers.parseGetOptions(query); + Project project = findProject(projectId).project(); // creates project if needed + Project result = OptionParsers.extractFields(project, fields); try { return new Response(HTTP_OK, jsonFactory.toString(result)); } catch (IOException e) { @@ -752,8 +623,7 @@ Response getProject(String projectId, String[] fields) { } /** - * Creates a project. It generates a project number randomly (we do not have project numbers - * available). + * Creates a project. It generates a project number randomly. */ private ProjectContainer createProject(String projectId) { Quota quota = new Quota(); @@ -771,14 +641,21 @@ private ProjectContainer createProject(String projectId) { return new ProjectContainer(project); } - /** - * Deletes a zone. - */ + @VisibleForTesting Response deleteZone(String projectId, String zoneName) { + ZoneContainer zone = findZone(projectId, zoneName); + ImmutableSortedMap rrsets = zone == null + ? ImmutableSortedMap.of() : zone.dnsRecords().get(); + ImmutableList defaults = ImmutableList.of("NS", "SOA"); + for (ResourceRecordSet current : rrsets.values()) { + if (!defaults.contains(current.getType())) { + return Error.CONTAINER_NOT_EMPTY.response(String.format( + "The resource named '%s' cannot be deleted because it is not empty", zoneName)); + } + } ProjectContainer projectContainer = projects.get(projectId); ZoneContainer previous = projectContainer.zones.remove(zoneName); return previous == null - // map was not in the collection ? Error.NOT_FOUND.response(String.format( "The 'parameters.managedZone' resource named '%s' does not exist.", zoneName)) : new Response(HTTP_NO_CONTENT, "{}"); @@ -787,14 +664,12 @@ Response deleteZone(String projectId, String zoneName) { /** * Creates new managed zone and stores it in the collection. Assumes that project exists. */ - Response createZone(String projectId, ManagedZone zone, String[] fields) { - checkNotNull(zone, "Zone to create cannot be null"); - // check if the provided data is valid + @VisibleForTesting + Response createZone(String projectId, ManagedZone zone, String... fields) { Response errorResponse = checkZone(zone); if (errorResponse != null) { return errorResponse; } - // create a copy of the managed zone in order to avoid side effects ManagedZone completeZone = new ManagedZone(); completeZone.setName(zone.getName()); completeZone.setDnsName(zone.getDnsName()); @@ -802,13 +677,10 @@ Response createZone(String projectId, ManagedZone zone, String[] fields) { completeZone.setNameServerSet(zone.getNameServerSet()); completeZone.setCreationTime(ISODateTimeFormat.dateTime().withZoneUTC() .print(System.currentTimeMillis())); - completeZone.setId( - new BigInteger(String.valueOf(Math.abs(ID_GENERATOR.nextLong() % Long.MAX_VALUE)))); + completeZone.setId(BigInteger.valueOf(Math.abs(ID_GENERATOR.nextLong() % Long.MAX_VALUE))); completeZone.setNameServers(randomNameservers()); ZoneContainer zoneContainer = new ZoneContainer(completeZone); - // create the default NS and SOA records - zoneContainer.dnsRecords().put(zone.getName(), defaultRecords(completeZone)); - // place the zone in the data collection + zoneContainer.dnsRecords().set(defaultRecords(completeZone)); ProjectContainer projectContainer = findProject(projectId); ZoneContainer oldValue = projectContainer.zones().putIfAbsent( completeZone.getName(), zoneContainer); @@ -816,8 +688,7 @@ Response createZone(String projectId, ManagedZone zone, String[] fields) { return Error.ALREADY_EXISTS.response(String.format( "The resource 'entity.managedZone' named '%s' already exists", completeZone.getName())); } - // now return the desired attributes - ManagedZone result = OptionParsersAndExtractors.extractFields(completeZone, fields); + ManagedZone result = OptionParsers.extractFields(completeZone, fields); try { return new Response(HTTP_OK, jsonFactory.toString(result)); } catch (IOException e) { @@ -827,30 +698,28 @@ Response createZone(String projectId, ManagedZone zone, String[] fields) { } /** - * Creates a new change, stores it, and invokes processing in a new thread. + * Creates a new change, stores it, and if delayChange > 0, invokes processing in a new thread. */ - Response createChange(String projectId, String zoneName, Change change, String[] fields) { + Response createChange(String projectId, String zoneName, Change change, String... fields) { ZoneContainer zoneContainer = findZone(projectId, zoneName); if (zoneContainer == null) { return Error.NOT_FOUND.response(String.format( "The 'parameters.managedZone' resource named %s does not exist.", zoneName)); } - // check that the change to be applied is valid Response response = checkChange(change, zoneContainer); if (response != null) { return response; } - // start applying - Change completeChange = new Change(); // copy to avoid side effects + Change completeChange = new Change(); if (change.getAdditions() != null) { completeChange.setAdditions(ImmutableList.copyOf(change.getAdditions())); } if (change.getDeletions() != null) { completeChange.setDeletions(ImmutableList.copyOf(change.getDeletions())); } - /* we need to get the proper ID in concurrent environment - the element fell on an index between 0 and maxId - we will reset all IDs in this range (all of them are valid) */ + /* We need to set ID for the change. We are working in concurrent environment. We know that the + element fell on an index between 0 and maxId, so we will reset all IDs in this range (all of + them are valid for the respective objects). */ ConcurrentLinkedQueue changeSequence = zoneContainer.changes(); changeSequence.add(completeChange); int maxId = changeSequence.size(); @@ -859,13 +728,13 @@ we will reset all IDs in this range (all of them are valid) */ if (index == maxId) { break; } - c.setId(String.valueOf(++index)); // indexing from 1 + c.setId(String.valueOf(++index)); } - completeChange.setStatus("pending"); // not finished yet + completeChange.setStatus("pending"); completeChange.setStartTime(ISODateTimeFormat.dateTime().withZoneUTC() - .print(System.currentTimeMillis())); // accepted + .print(System.currentTimeMillis())); invokeChange(projectId, zoneName, completeChange.getId()); - Change result = OptionParsersAndExtractors.extractFields(completeChange, fields); + Change result = OptionParsers.extractFields(completeChange, fields); try { return new Response(HTTP_OK, jsonFactory.toString(result)); } catch (IOException e) { @@ -876,28 +745,20 @@ we will reset all IDs in this range (all of them are valid) */ } /** - * Applies change. Uses a new thread which applies the change only if DELAY_CHANGE is > 0. + * Applies change. Uses a different pooled thread which applies the change only if {@code + * delayChange} is > 0. */ - private Thread invokeChange(final String projectId, final String zoneName, + private void invokeChange(final String projectId, final String zoneName, final String changeId) { if (delayChange > 0) { - Thread thread = new Thread() { + EXECUTORS.schedule(new Runnable() { @Override public void run() { - try { - Thread.sleep(delayChange); // simulate delayed execution - } catch (InterruptedException ex) { - log.log(Level.WARNING, "Thread was interrupted while sleeping.", ex); - } - // start applying the changes applyExistingChange(projectId, zoneName, changeId); } - }; - thread.start(); - return thread; + }, delayChange, TimeUnit.MILLISECONDS); } else { applyExistingChange(projectId, zoneName, changeId); - return null; } } @@ -910,44 +771,55 @@ private void applyExistingChange(String projectId, String zoneName, String chang return; // no such change exists, nothing to do } ZoneContainer wrapper = findZone(projectId, zoneName); - ConcurrentSkipListMap> dnsRecords = wrapper.dnsRecords(); + if (wrapper == null) { + return; // no such zone exists; it might have been deleted by another thread + } + AtomicReference> dnsRecords = + wrapper.dnsRecords(); while (true) { // managed zone must have a set of records which is not null - ImmutableList original = dnsRecords.get(zoneName); - assert original != null; - List copy = Lists.newLinkedList(original); + ImmutableSortedMap original = dnsRecords.get(); + // the copy will be populated when handling deletions + SortedMap copy = new TreeMap<>(); // apply deletions first List deletions = change.getDeletions(); if (deletions != null) { - List transformedDeletions = Lists.transform(deletions, - RrsetWrapper.WRAP_FUNCTION); - copy.removeAll(transformedDeletions); + for (Map.Entry entry : original.entrySet()) { + if (!deletions.contains(entry.getValue())) { + copy.put(entry.getKey(), entry.getValue()); + } + } + } else { + copy.putAll(original); } // apply additions List additions = change.getAdditions(); if (additions != null) { for (ResourceRecordSet addition : additions) { - String id = getUniqueId(copy); - RrsetWrapper rrsetWrapper = new RrsetWrapper(addition); - rrsetWrapper.setId(id); - copy.add(rrsetWrapper); + ResourceRecordSet rrset = new ResourceRecordSet(); + rrset.setName(addition.getName()); + rrset.setRrdatas(ImmutableList.copyOf(addition.getRrdatas())); + rrset.setTtl(addition.getTtl()); + rrset.setType(addition.getType()); + String id = getUniqueId(copy.keySet()); + copy.put(id, rrset); } } - // make it immutable and replace - boolean success = dnsRecords.replace(zoneName, original, ImmutableList.copyOf(copy)); + boolean success = dnsRecords.compareAndSet(original, ImmutableSortedMap.copyOf(copy)); if (success) { break; // success if no other thread modified the value in the meantime } } - // set status to done change.setStatus("done"); } /** * Lists zones. Next page token is the last listed zone name and is returned only of there is more - * to list. + * to list and if the user does not exclude nextPageToken from field options. */ - Response listZones(String projectId, Map options) { + @VisibleForTesting + Response listZones(String projectId, String query) { + Map options = OptionParsers.parseListZonesOptions(query); Response response = checkListOptions(options); if (response != null) { return response; @@ -958,46 +830,43 @@ Response listZones(String projectId, Map options) { String pageToken = (String) options.get("pageToken"); Integer maxResults = options.get("maxResults") == null ? null : Integer.valueOf((String) options.get("maxResults")); - // matches will be included in the result if true - boolean listing = (pageToken == null || !containers.containsKey(pageToken)); - boolean sizeReached = false; // maximum result size was reached, we should not return more - boolean hasMorePages = false; // should next page token be included in the response? + boolean sizeReached = false; + boolean hasMorePages = false; LinkedList serializedZones = new LinkedList<>(); String lastZoneName = null; - for (ZoneContainer zoneContainer : containers.values()) { + ConcurrentNavigableMap fragment = + pageToken != null ? containers.tailMap(pageToken, false) : containers; + for (ZoneContainer zoneContainer : fragment.values()) { ManagedZone zone = zoneContainer.zone(); - if (listing) { - if (dnsName == null || zone.getDnsName().equals(dnsName)) { - if (sizeReached) { - // we do not add this, just note that there would be more and there should be a token - hasMorePages = true; - break; - } else { - try { - lastZoneName = zone.getName(); - serializedZones.addLast(jsonFactory.toString( - OptionParsersAndExtractors.extractFields(zone, fields))); - } catch (IOException e) { - return Error.INTERNAL_ERROR.response(String.format( - "Error when serializing managed zone %s in project %s", zone.getName(), - projectId)); - } + if (dnsName == null || zone.getDnsName().equals(dnsName)) { + if (sizeReached) { + // we do not add this, just note that there would be more and there should be a token + hasMorePages = true; + break; + } else { + try { + lastZoneName = zone.getName(); + serializedZones.addLast(jsonFactory.toString( + OptionParsers.extractFields(zone, fields))); + } catch (IOException e) { + return Error.INTERNAL_ERROR.response(String.format( + "Error when serializing managed zone %s in project %s", lastZoneName, projectId)); } } } - // either we are listing already, or we check if we should start in the next iteration - listing = zone.getName().equals(pageToken) || listing; - sizeReached = (maxResults != null) && maxResults.equals(serializedZones.size()); + sizeReached = maxResults != null && maxResults.equals(serializedZones.size()); } boolean includePageToken = - hasMorePages && (fields == null || ImmutableList.copyOf(fields).contains("nextPageToken")); + hasMorePages && (fields == null || Arrays.asList(fields).contains("nextPageToken")); return toListResponse(serializedZones, "managedZones", lastZoneName, includePageToken); } /** - * Lists DNS records for a zone. Next page token is ID of the last record listed. + * Lists DNS records for a zone. Next page token is the ID of the last record listed. */ - Response listDnsRecords(String projectId, String zoneName, Map options) { + @VisibleForTesting + Response listDnsRecords(String projectId, String zoneName, String query) { + Map options = OptionParsers.parseListDnsRecordsOptions(query); Response response = checkListOptions(options); if (response != null) { return response; @@ -1007,52 +876,51 @@ Response listDnsRecords(String projectId, String zoneName, Map o return Error.NOT_FOUND.response(String.format( "The 'parameters.managedZone' resource named '%s' does not exist.", zoneName)); } - List dnsRecords = zoneContainer.dnsRecords().get(zoneName); + ImmutableSortedMap dnsRecords = zoneContainer.dnsRecords().get(); String[] fields = (String[]) options.get("fields"); String name = (String) options.get("name"); String type = (String) options.get("type"); String pageToken = (String) options.get("pageToken"); + ImmutableSortedMap fragment = + pageToken != null ? dnsRecords.tailMap(pageToken, false) : dnsRecords; Integer maxResults = options.get("maxResults") == null ? null : Integer.valueOf((String) options.get("maxResults")); - boolean listing = (pageToken == null); // matches will be included in the result if true - boolean sizeReached = false; // maximum result size was reached, we should not return more - boolean hasMorePages = false; // should next page token be included in the response? + boolean sizeReached = false; + boolean hasMorePages = false; LinkedList serializedRrsets = new LinkedList<>(); String lastRecordId = null; - for (RrsetWrapper recordWrapper : dnsRecords) { - ResourceRecordSet record = recordWrapper.rrset(); - if (listing) { - if (matchesCriteria(record, name, type)) { - if (sizeReached) { - // we do not add this, just note that there would be more and there should be a token - hasMorePages = true; - break; - } else { - lastRecordId = recordWrapper.id(); - try { - serializedRrsets.addLast(jsonFactory.toString( - OptionParsersAndExtractors.extractFields(record, fields))); - } catch (IOException e) { - return Error.INTERNAL_ERROR.response(String.format( - "Error when serializing resource record set in managed zone %s in project %s", - zoneName, projectId)); - } + for (String recordId : fragment.keySet()) { + ResourceRecordSet record = fragment.get(recordId); + if (matchesCriteria(record, name, type)) { + if (sizeReached) { + // we do not add this, just note that there would be more and there should be a token + hasMorePages = true; + break; + } else { + lastRecordId = recordId; + try { + serializedRrsets.addLast(jsonFactory.toString( + OptionParsers.extractFields(record, fields))); + } catch (IOException e) { + return Error.INTERNAL_ERROR.response(String.format( + "Error when serializing resource record set in managed zone %s in project %s", + zoneName, projectId)); } } } - // either we are listing already, or we check if we should start in the next iteration - listing = recordWrapper.id().equals(pageToken) || listing; - sizeReached = (maxResults != null) && maxResults.equals(serializedRrsets.size()); + sizeReached = maxResults != null && maxResults.equals(serializedRrsets.size()); } boolean includePageToken = - hasMorePages && (fields == null || ImmutableList.copyOf(fields).contains("nextPageToken")); + hasMorePages && (fields == null || Arrays.asList(fields).contains("nextPageToken")); return toListResponse(serializedRrsets, "rrsets", lastRecordId, includePageToken); } /** - * Lists changes. Next page token is ID of the last change listed. + * Lists changes. Next page token is the ID of the last change listed. */ - Response listChanges(String projectId, String zoneName, Map options) { + @VisibleForTesting + Response listChanges(String projectId, String zoneName, String query) { + Map options = OptionParsers.parseListChangesOptions(query); Response response = checkListOptions(options); if (response != null) { return response; @@ -1063,7 +931,7 @@ Response listChanges(String projectId, String zoneName, Map opti "The 'parameters.managedZone' resource named '%s' does not exist", zoneName)); } // take a sorted snapshot of the current change list - TreeMap changes = new TreeMap<>(); + NavigableMap changes = new TreeMap<>(); for (Change c : zoneContainer.changes()) { if (c.getId() != null) { changes.put(Integer.valueOf(c.getId()), c); @@ -1074,51 +942,54 @@ Response listChanges(String projectId, String zoneName, Map opti String pageToken = (String) options.get("pageToken"); Integer maxResults = options.get("maxResults") == null ? null : Integer.valueOf((String) options.get("maxResults")); - // we are not reading sort by as it the only key is the change sequence + // as the only supported field is change sequence, we are not reading sortBy NavigableSet keys; if ("descending".equals(sortOrder)) { keys = changes.descendingKeySet(); } else { keys = changes.navigableKeySet(); } - boolean listing = (pageToken == null); // matches will be included in the result if true - boolean sizeReached = false; // maximum result size was reached, we should not return more - boolean hasMorePages = false; // should next page token be included in the response? + Integer from = null; + try { + from = Integer.valueOf(pageToken); + } catch (NumberFormatException ex) { + // ignore page token + } + keys = from != null ? keys.tailSet(from, false) : keys; + NavigableMap fragment = + from != null && changes.containsKey(from) ? changes.tailMap(from, false) : changes; + boolean sizeReached = false; + boolean hasMorePages = false; LinkedList serializedResults = new LinkedList<>(); String lastChangeId = null; for (Integer key : keys) { - Change change = changes.get(key); - if (listing) { - if (sizeReached) { - // we do not add this, just note that there would be more and there should be a token - hasMorePages = true; - break; - } else { - lastChangeId = change.getId(); - try { - serializedResults.addLast(jsonFactory.toString( - OptionParsersAndExtractors.extractFields(change, fields))); - } catch (IOException e) { - return Error.INTERNAL_ERROR.response(String.format( - "Error when serializing change %s in managed zone %s in project %s", - change.getId(), zoneName, projectId)); - } + Change change = fragment.get(key); + if (sizeReached) { + // we do not add this, just note that there would be more and there should be a token + hasMorePages = true; + break; + } else { + lastChangeId = change.getId(); + try { + serializedResults.addLast(jsonFactory.toString( + OptionParsers.extractFields(change, fields))); + } catch (IOException e) { + return Error.INTERNAL_ERROR.response(String.format( + "Error when serializing change %s in managed zone %s in project %s", + lastChangeId, zoneName, projectId)); } } - - // either we are listing already, or we check if we should start in the next iteration - listing = change.getId().equals(pageToken) || listing; - sizeReached = (maxResults != null) && maxResults.equals(serializedResults.size()); + sizeReached = maxResults != null && maxResults.equals(serializedResults.size()); } boolean includePageToken = - hasMorePages && (fields == null || ImmutableList.copyOf(fields).contains("nextPageToken")); + hasMorePages && (fields == null || Arrays.asList(fields).contains("nextPageToken")); return toListResponse(serializedResults, "changes", lastChangeId, includePageToken); } /** * Validates a zone to be created. */ - static Response checkZone(ManagedZone zone) { + private static Response checkZone(ManagedZone zone) { if (zone.getName() == null) { return Error.REQUIRED.response( "The 'entity.managedZone.name' parameter is required but was missing."); @@ -1138,7 +1009,8 @@ static Response checkZone(ManagedZone zone) { } catch (NumberFormatException ex) { // expected } - if (zone.getName().isEmpty()) { + if (zone.getName().isEmpty() || zone.getName().length() > 32 + || !ZONE_NAME_RE.matcher(zone.getName()).matches()) { return Error.INVALID.response( String.format("Invalid value for 'entity.managedZone.name': '%s'", zone.getName())); } @@ -1146,9 +1018,7 @@ static Response checkZone(ManagedZone zone) { return Error.INVALID.response( String.format("Invalid value for 'entity.managedZone.dnsName': '%s'", zone.getDnsName())); } - TreeSet forbidden = Sets.newTreeSet( - ImmutableList.of("google.com.", "com.", "example.com.", "net.", "org.")); - if (forbidden.contains(zone.getDnsName())) { + if (FORBIDDEN.contains(zone.getDnsName())) { return Error.NOT_AVAILABLE.response(String.format( "The '%s' managed zone is not available to be created.", zone.getDnsName())); } @@ -1158,12 +1028,10 @@ static Response checkZone(ManagedZone zone) { /** * Validates a change to be created. */ + @VisibleForTesting static Response checkChange(Change change, ZoneContainer zone) { - checkNotNull(zone); - if ((change.getDeletions() != null && change.getDeletions().size() > 0) - || (change.getAdditions() != null && change.getAdditions().size() > 0)) { - // ok, this is what we want - } else { + if ((change.getDeletions() == null || change.getDeletions().size() <= 0) + && (change.getAdditions() == null || change.getAdditions().size() <= 0)) { return Error.REQUIRED.response("The 'entity.change' parameter is required but was missing."); } if (change.getAdditions() != null) { @@ -1186,7 +1054,7 @@ static Response checkChange(Change change, ZoneContainer zone) { counter++; } } - return additionsMeetDeletions(change.getAdditions(), change.getDeletions(), zone); + return checkAdditionsDeletions(change.getAdditions(), change.getDeletions(), zone); // null if everything is ok } @@ -1197,6 +1065,7 @@ static Response checkChange(Change change, ZoneContainer zone) { * @param index the index or addition or deletion in the list * @param zone the zone that this change is applied to */ + @VisibleForTesting static Response checkRrset(ResourceRecordSet rrset, ZoneContainer zone, int index, String type) { if (rrset.getName() == null || !rrset.getName().endsWith(zone.zone().getDnsName())) { return Error.INVALID.response(String.format( @@ -1226,8 +1095,7 @@ static Response checkRrset(ResourceRecordSet rrset, ZoneContainer zone, int inde if ("deletions".equals(type)) { // check that deletion has a match by name and type boolean found = false; - for (RrsetWrapper rrsetWrapper : zone.dnsRecords().get(zone.zone().getName())) { - ResourceRecordSet wrappedRrset = rrsetWrapper.rrset(); + for (ResourceRecordSet wrappedRrset : zone.dnsRecords().get().values()) { if (rrset.getName().equals(wrappedRrset.getName()) && rrset.getType().equals(wrappedRrset.getType())) { found = true; @@ -1241,7 +1109,7 @@ static Response checkRrset(ResourceRecordSet rrset, ZoneContainer zone, int inde } // if found, we still need an exact match if ("deletions".equals(type) - && !zone.dnsRecords().get(zone.zone().getName()).contains(new RrsetWrapper(rrset))) { + && !zone.dnsRecords().get().containsValue(rrset)) { // such a record does not exist return Error.CONDITION_NOT_MET.response(String.format( "Precondition not met for 'entity.change.deletions[%s]", index)); @@ -1251,24 +1119,22 @@ static Response checkRrset(ResourceRecordSet rrset, ZoneContainer zone, int inde } /** - * Checks that for each record that already exists, we have a matching deletion. Furthermore, - * check that mandatory SOA and NS records stay. + * Checks against duplicate additions (for each record to be added that already exists, we must + * have a matching deletion. Furthermore, check that mandatory SOA and NS records stay. */ - static Response additionsMeetDeletions(List additions, + static Response checkAdditionsDeletions(List additions, List deletions, ZoneContainer zone) { if (additions != null) { int index = 0; for (ResourceRecordSet rrset : additions) { - for (RrsetWrapper wrapper : zone.dnsRecords().get(zone.zone().getName())) { - ResourceRecordSet wrappedRrset = wrapper.rrset(); + for (ResourceRecordSet wrappedRrset : zone.dnsRecords().get().values()) { if (rrset.getName().equals(wrappedRrset.getName()) - && rrset.getType().equals(wrappedRrset.getType())) { - // such a record exist and we must have a deletion - if (deletions == null || !deletions.contains(wrappedRrset)) { - return Error.ALREADY_EXISTS.response(String.format( - "The 'entity.change.additions[%s]' resource named '%s (%s)' already exists.", - index, rrset.getName(), rrset.getType())); - } + && rrset.getType().equals(wrappedRrset.getType()) + // such a record exist and we must have a deletion + && (deletions == null || !deletions.contains(wrappedRrset))) { + return Error.ALREADY_EXISTS.response(String.format( + "The 'entity.change.additions[%s]' resource named '%s (%s)' already exists.", + index, rrset.getName(), rrset.getType())); } } if (rrset.getType().equals("SOA") && findByNameAndType(deletions, null, "SOA") == null) { @@ -1323,44 +1189,11 @@ private static ResourceRecordSet findByNameAndType(Iterable r * We only provide the most basic validation for A and AAAA records. */ static boolean checkRrData(String data, String type) { - // todo add validation for other records - String[] tokens; switch (type) { case "A": - tokens = data.split("\\."); - if (tokens.length != 4) { - return false; - } - for (String token : tokens) { - try { - Integer number = Integer.valueOf(token); - if (number < 0 || number > 255) { - return false; - } - } catch (NumberFormatException ex) { - return false; - } - } - return true; + return !data.contains(":") && isInetAddress(data); case "AAAA": - tokens = data.split(":", -1); - if (tokens.length != 8) { - return false; - } - for (String token : tokens) { - try { - if (!token.isEmpty()) { - // empty is ok - Long number = Long.parseLong(token, 16); - if (number < 0 || number > 0xFFFF) { - return false; - } - } - } catch (NumberFormatException ex) { - return false; - } - } - return true; + return data.contains(":") && isInetAddress(data); default: return true; } @@ -1369,11 +1202,12 @@ static boolean checkRrData(String data, String type) { /** * Check supplied listing options. */ + @VisibleForTesting static Response checkListOptions(Map options) { // for general listing String maxResultsString = (String) options.get("maxResults"); if (maxResultsString != null) { - Integer maxResults = null; + Integer maxResults; try { maxResults = Integer.valueOf(maxResultsString); } catch (NumberFormatException ex) { @@ -1386,24 +1220,21 @@ static Response checkListOptions(Map options) { } } String dnsName = (String) options.get("dnsName"); - if (dnsName != null) { - if (!dnsName.endsWith(".")) { - return Error.INVALID.response(String.format( - "Invalid value for 'parameters.dnsName': '%s'", dnsName)); - } + if (dnsName != null && !dnsName.endsWith(".")) { + return Error.INVALID.response(String.format( + "Invalid value for 'parameters.dnsName': '%s'", dnsName)); } // for listing dns records, name must be fully qualified String name = (String) options.get("name"); - if (name != null) { - if (!name.endsWith(".")) { - return Error.INVALID.response(String.format( - "Invalid value for 'parameters.name': '%s'", name)); - } + if (name != null && !name.endsWith(".")) { + return Error.INVALID.response(String.format( + "Invalid value for 'parameters.name': '%s'", name)); } String type = (String) options.get("type"); // must be provided with name if (type != null) { if (name == null) { - return Error.INVALID.response("Invalid value for 'parameters.name': ''"); + return Error.INVALID.response("Invalid value for 'parameters.name': '' " + + "(name must be specified if type is specified)"); } if (!TYPES.contains(type)) { return Error.INVALID.response(String.format( diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/testing/OptionParsersAndExtractors.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/OptionParsers.java similarity index 80% rename from gcloud-java-dns/src/main/java/com/google/gcloud/testing/OptionParsersAndExtractors.java rename to gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/OptionParsers.java index 26759f7e3ccc..ecd7e8179efe 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/testing/OptionParsersAndExtractors.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/OptionParsers.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.testing; +package com.google.gcloud.dns.testing; import com.google.api.services.dns.model.Change; import com.google.api.services.dns.model.ManagedZone; @@ -27,12 +27,8 @@ /** * Utility helpers for LocalDnsHelper. */ -class OptionParsersAndExtractors { +class OptionParsers { - /** - * Makes a map of list options. Expects query to be only query part of the url (i.e., what follows - * the '?'). - */ static Map parseListZonesOptions(String query) { Map options = new HashMap<>(); if (query != null) { @@ -41,20 +37,15 @@ static Map parseListZonesOptions(String query) { String[] argEntry = arg.split("="); switch (argEntry[0]) { case "fields": - // List fields are in the form "managedZones(field1, field2, ...)" + // List fields are in the form "managedZones(field1, field2, ...),nextPageToken" String replaced = argEntry[1].replace("managedZones(", ","); replaced = replaced.replace(")", ","); // we will get empty strings, but it does not matter, they will be ignored - options.put( - "fields", - replaced.split(",")); + options.put("fields", replaced.split(",")); break; case "dnsName": options.put("dnsName", argEntry[1]); break; - case "nextPageToken": - options.put("nextPageToken", argEntry[1]); - break; case "pageToken": options.put("pageToken", argEntry[1]); break; @@ -70,10 +61,6 @@ static Map parseListZonesOptions(String query) { return options; } - /** - * Makes a map of list options. Expects query to be only query part of the url (i.e., what follows - * the '?'). This format is common for all of zone, change and project. - */ static String[] parseGetOptions(String query) { if (query != null) { String[] args = query.split("&"); @@ -85,14 +72,11 @@ static String[] parseGetOptions(String query) { } } } - return null; + return new String[0]; } - /** - * Extracts only request fields. - */ - static ManagedZone extractFields(ManagedZone fullZone, String[] fields) { - if (fields == null) { + static ManagedZone extractFields(ManagedZone fullZone, String... fields) { + if (fields == null || fields.length == 0) { return fullZone; } ManagedZone managedZone = new ManagedZone(); @@ -126,22 +110,17 @@ static ManagedZone extractFields(ManagedZone fullZone, String[] fields) { return managedZone; } - /** - * Extracts only request fields. - */ - static Change extractFields(Change fullChange, String[] fields) { - if (fields == null) { + static Change extractFields(Change fullChange, String... fields) { + if (fields == null || fields.length == 0) { return fullChange; } Change change = new Change(); for (String field : fields) { switch (field) { case "additions": - // todo the fragmentation is ignored here as our api does not support it change.setAdditions(fullChange.getAdditions()); break; case "deletions": - // todo the fragmentation is ignored here as our api does not support it change.setDeletions(fullChange.getDeletions()); break; case "id": @@ -160,11 +139,8 @@ static Change extractFields(Change fullChange, String[] fields) { return change; } - /** - * Extracts only request fields. - */ - static Project extractFields(Project fullProject, String[] fields) { - if (fields == null) { + static Project extractFields(Project fullProject, String... fields) { + if (fields == null || fields.length == 0) { return fullProject; } Project project = new Project(); @@ -186,11 +162,8 @@ static Project extractFields(Project fullProject, String[] fields) { return project; } - /** - * Extracts only request fields. - */ - static ResourceRecordSet extractFields(ResourceRecordSet fullRecord, String[] fields) { - if (fields == null) { + static ResourceRecordSet extractFields(ResourceRecordSet fullRecord, String... fields) { + if (fields == null || fields.length == 0) { return fullRecord; } ResourceRecordSet record = new ResourceRecordSet(); @@ -223,16 +196,9 @@ static Map parseListChangesOptions(String query) { String[] argEntry = arg.split("="); switch (argEntry[0]) { case "fields": - // todo we do not support fragmentation in deletions and additions in the library String replaced = argEntry[1].replace("changes(", ",").replace(")", ","); options.put("fields", replaced.split(",")); // empty strings will be ignored break; - case "name": - options.put("name", argEntry[1]); - break; - case "nextPageToken": - options.put("nextPageToken", argEntry[1]); - break; case "pageToken": options.put("pageToken", argEntry[1]); break; @@ -275,9 +241,6 @@ static Map parseListDnsRecordsOptions(String query) { case "pageToken": options.put("pageToken", argEntry[1]); break; - case "nextPageToken": - options.put("nextPageToken", argEntry[1]); - break; case "maxResults": // parsing to int is done while handling options.put("maxResults", argEntry[1]); diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java index b72a21445a80..1df0a8a2f831 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java @@ -162,9 +162,9 @@ public Change getChangeRequest(String zoneName, String changeRequestId, Map EMPTY_RPC_OPTIONS = ImmutableMap.of(); - private static final DnsRpc RPC = - new DefaultDnsRpc(LOCAL_DNS_HELPER.options()); + private static final DnsRpc RPC = new DefaultDnsRpc(LOCAL_DNS_HELPER.options()); private static final String REAL_PROJECT_ID = LOCAL_DNS_HELPER.options().projectId(); private Map optionsMap; - private ManagedZone minimalZone = new ManagedZone(); // to be adjusted as needed - @BeforeClass public static void before() { - RRSET1.setName(DNS_NAME); - RRSET1.setType(RRSET_TYPE); - RRSET1.setRrdatas(ImmutableList.of("1.1.1.1")); ZONE1.setName(ZONE_NAME1); ZONE1.setDescription(""); ZONE1.setDnsName(DNS_NAME); - ZONE1.setNameServerSet("somenameserveset"); + ZONE1.setNameServerSet("somenameserverset"); ZONE2.setName(ZONE_NAME2); ZONE2.setDescription(""); ZONE2.setDnsName(DNS_NAME); - ZONE2.setNameServerSet("somenameserveset"); + ZONE2.setNameServerSet("somenameserverset"); + RRSET1.setName(DNS_NAME); + RRSET1.setType(RRSET_TYPE); + RRSET1.setRrdatas(ImmutableList.of("1.1.1.1")); RRSET2.setName(DNS_NAME); RRSET2.setType(RRSET_TYPE); + RRSET2.setRrdatas(ImmutableList.of("123.132.153.156")); RRSET_KEEP.setName(DNS_NAME); RRSET_KEEP.setType("MX"); RRSET_KEEP.setRrdatas(ImmutableList.of("255.255.255.254")); - RRSET2.setRrdatas(ImmutableList.of("123.132.153.156")); CHANGE1.setAdditions(ImmutableList.of(RRSET1, RRSET2)); CHANGE2.setDeletions(ImmutableList.of(RRSET2)); CHANGE_KEEP.setAdditions(ImmutableList.of(RRSET_KEEP)); @@ -98,17 +99,13 @@ public static void before() { LOCAL_DNS_HELPER.start(); } + @Rule + public Timeout globalTimeout = Timeout.seconds(60); + @Before public void setUp() { resetProjects(); optionsMap = new HashMap<>(); - minimalZone = copyZone(ZONE1); - } - - private static void resetProjects() { - for (String project : LOCAL_DNS_HELPER.projects().keySet()) { - LOCAL_DNS_HELPER.projects().remove(project); - } } @AfterClass @@ -116,279 +113,55 @@ public static void after() { LOCAL_DNS_HELPER.stop(); } - @Test - public void testMatchesCriteria() { - assertTrue(LocalDnsHelper.matchesCriteria(RRSET1, RRSET1.getName(), RRSET1.getType())); - assertFalse(LocalDnsHelper.matchesCriteria(RRSET1, RRSET1.getName(), "anothertype")); - assertTrue(LocalDnsHelper.matchesCriteria(RRSET1, null, RRSET1.getType())); - assertTrue(LocalDnsHelper.matchesCriteria(RRSET1, RRSET1.getName(), null)); - assertFalse(LocalDnsHelper.matchesCriteria(RRSET1, "anothername", RRSET1.getType())); - } - - @Test - public void testGetUniqueId() { - assertNotNull(LocalDnsHelper.getUniqueId(Lists.newLinkedList())); - } - - @Test - public void testFindProject() { - assertEquals(0, LOCAL_DNS_HELPER.projects().size()); - LocalDnsHelper.ProjectContainer project = LOCAL_DNS_HELPER.findProject(PROJECT_ID1); - assertNotNull(project); - assertTrue(LOCAL_DNS_HELPER.projects().containsKey(PROJECT_ID1)); - assertNotNull(LOCAL_DNS_HELPER.findProject(PROJECT_ID2)); - assertTrue(LOCAL_DNS_HELPER.projects().containsKey(PROJECT_ID2)); - assertTrue(LOCAL_DNS_HELPER.projects().containsKey(PROJECT_ID1)); - assertNotNull(project.zones()); - assertEquals(0, project.zones().size()); - assertNotNull(project.project()); - assertNotNull(project.project().getQuota()); + private static void resetProjects() { + for (String project : LOCAL_DNS_HELPER.projects().keySet()) { + LOCAL_DNS_HELPER.projects().remove(project); + } } - @Test - public void testCreateAndFindZone() { - LocalDnsHelper.ZoneContainer zone1 = LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE_NAME1); - assertTrue(LOCAL_DNS_HELPER.projects().containsKey(PROJECT_ID1)); - assertNull(zone1); - LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); // we do not care about options - zone1 = LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE1.getName()); - assertNotNull(zone1); - // cannot call equals because id and timestamp got assigned - assertEquals(ZONE_NAME1, zone1.zone().getName()); - assertNotNull(zone1.changes()); - assertTrue(zone1.changes().isEmpty()); - assertNotNull(zone1.dnsRecords()); - assertEquals(2, zone1.dnsRecords().get(ZONE_NAME1).size()); // default SOA and NS - LOCAL_DNS_HELPER.createZone(PROJECT_ID2, ZONE1, null); // project does not exits yet - assertEquals(ZONE1.getName(), - LOCAL_DNS_HELPER.findZone(PROJECT_ID2, ZONE_NAME1).zone().getName()); + private static void assertEqChangesIgnoreStatus(Change expected, Change actual) { + assertEquals(expected.getAdditions(), actual.getAdditions()); + assertEquals(expected.getDeletions(), actual.getDeletions()); + assertEquals(expected.getId(), actual.getId()); + assertEquals(expected.getStartTime(), actual.getStartTime()); } @Test - public void testCreateAndFindZoneUsingRpc() { - // zone does not exist yet - ManagedZone zone1 = RPC.getZone(ZONE_NAME1, EMPTY_RPC_OPTIONS); - assertTrue(LOCAL_DNS_HELPER.projects().containsKey(REAL_PROJECT_ID)); // check internal state - assertNull(zone1); - // create zone - ManagedZone createdZone = RPC.create(ZONE1, EMPTY_RPC_OPTIONS); - assertEquals(ZONE1.getName(), createdZone.getName()); - assertEquals(ZONE1.getDescription(), createdZone.getDescription()); - assertEquals(ZONE1.getDnsName(), createdZone.getDnsName()); - assertEquals(4, createdZone.getNameServers().size()); - // get the same zone zone - ManagedZone zone = RPC.getZone(ZONE1.getName(), EMPTY_RPC_OPTIONS); - assertEquals(createdZone, zone); + public void testCreateZone() { + ManagedZone created = RPC.create(ZONE1, EMPTY_RPC_OPTIONS); // check that default records were created - DnsRpc.ListResult resourceRecordSetListResult + DnsRpc.ListResult listResult = RPC.listDnsRecords(ZONE1.getName(), EMPTY_RPC_OPTIONS); - assertEquals(2, Lists.newLinkedList(resourceRecordSetListResult.results()).size()); - } - - @Test - public void testDeleteZone() { - LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); - LocalDnsHelper.Response response = LOCAL_DNS_HELPER.deleteZone(PROJECT_ID1, ZONE1.getName()); - assertEquals(204, response.code()); - // deleting non-existent zone - response = LOCAL_DNS_HELPER.deleteZone(PROJECT_ID1, ZONE1.getName()); - assertEquals(404, response.code()); - assertNull(LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE1.getName())); - LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); - LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE2, null); - assertNotNull(LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE1.getName())); - assertNotNull(LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE2.getName())); - // delete in reverse order - response = LOCAL_DNS_HELPER.deleteZone(PROJECT_ID1, ZONE1.getName()); - assertEquals(204, response.code()); - assertNull(LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE1.getName())); - assertNotNull(LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE2.getName())); - LOCAL_DNS_HELPER.deleteZone(PROJECT_ID1, ZONE2.getName()); - assertEquals(204, response.code()); - assertNull(LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE1.getName())); - assertNull(LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE2.getName())); - } - - @Test - public void testDeleteZoneUsingRpc() { - RPC.create(ZONE1, EMPTY_RPC_OPTIONS); - assertTrue(RPC.deleteZone(ZONE1.getName())); - assertNull(RPC.getZone(ZONE1.getName(), EMPTY_RPC_OPTIONS)); - // deleting non-existent zone - assertFalse(RPC.deleteZone(ZONE1.getName())); - assertNull(RPC.getZone(ZONE1.getName(), EMPTY_RPC_OPTIONS)); - RPC.create(ZONE1, EMPTY_RPC_OPTIONS); - RPC.create(ZONE2, EMPTY_RPC_OPTIONS); - assertNotNull(RPC.getZone(ZONE1.getName(), EMPTY_RPC_OPTIONS)); - assertNotNull(RPC.getZone(ZONE2.getName(), EMPTY_RPC_OPTIONS)); - // delete in reverse order - assertTrue(RPC.deleteZone(ZONE1.getName())); - assertNull(RPC.getZone(ZONE1.getName(), EMPTY_RPC_OPTIONS)); - assertNotNull(RPC.getZone(ZONE2.getName(), EMPTY_RPC_OPTIONS)); - assertTrue(RPC.deleteZone(ZONE2.getName())); - assertNull(RPC.getZone(ZONE1.getName(), EMPTY_RPC_OPTIONS)); - assertNull(RPC.getZone(ZONE2.getName(), EMPTY_RPC_OPTIONS)); - } - - @Test - public void testCreateAndApplyChange() { - LocalDnsHelper localDnsThreaded = LocalDnsHelper.create(5 * 1000L); // using threads here - localDnsThreaded.createZone(PROJECT_ID1, ZONE1, null); - assertNull(localDnsThreaded.findZone(PROJECT_ID1, ZONE_NAME1).findChange("1")); - LocalDnsHelper.Response response - = localDnsThreaded.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); // add - assertEquals(200, response.code()); - assertNotNull(localDnsThreaded.findZone(PROJECT_ID1, ZONE_NAME1).findChange("1")); - assertNull(localDnsThreaded.findZone(PROJECT_ID1, ZONE_NAME1).findChange("2")); - localDnsThreaded.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); // add - response = localDnsThreaded.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); // add - assertEquals(200, response.code()); - assertNotNull(localDnsThreaded.findZone(PROJECT_ID1, ZONE_NAME1).findChange("1")); - assertNotNull(localDnsThreaded.findZone(PROJECT_ID1, ZONE_NAME1).findChange("2")); - localDnsThreaded.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE2, null); // delete - assertNotNull(localDnsThreaded.findZone(PROJECT_ID1, ZONE_NAME1).findChange("1")); - assertNotNull(localDnsThreaded.findZone(PROJECT_ID1, ZONE_NAME1).findChange("2")); - assertNotNull(localDnsThreaded.findZone(PROJECT_ID1, ZONE_NAME1).findChange("3")); - localDnsThreaded.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE_KEEP, null); // id is "4" - // check execution - Change change = localDnsThreaded.findChange(PROJECT_ID1, ZONE_NAME1, "4"); - for (int i = 0; i < 10 && !change.getStatus().equals("done"); i++) { - // change has not been finished yet; wait at most 20 seconds - // it takes 5 seconds for the thread to kick in in the first place - try { - Thread.sleep(2 * 1000); - } catch (InterruptedException e) { - fail("Test was interrupted"); - } + ImmutableList defaultTypes = ImmutableList.of("SOA", "NS"); + Iterator iterator = listResult.results().iterator(); + assertTrue(defaultTypes.contains(iterator.next().getType())); + assertTrue(defaultTypes.contains(iterator.next().getType())); + assertFalse(iterator.hasNext()); + assertEquals(created, LOCAL_DNS_HELPER.findZone(REAL_PROJECT_ID, ZONE1.getName()).zone()); + ManagedZone zone = RPC.getZone(ZONE_NAME1, EMPTY_RPC_OPTIONS); + assertEquals(created, zone); + try { + RPC.create(null, EMPTY_RPC_OPTIONS); + fail("Zone cannot be null"); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + assertTrue(ex.getMessage().contains("entity.managedZone")); } - assertEquals("done", change.getStatus()); - List list = - localDnsThreaded.findZone(PROJECT_ID1, ZONE_NAME1).dnsRecords().get(ZONE_NAME1); - assertTrue(list.contains(new LocalDnsHelper.RrsetWrapper(RRSET_KEEP))); - localDnsThreaded.stop(); - } - - @Test - public void testCreateAndApplyChangeUsingRpc() { - // not using threads - RPC.create(ZONE1, EMPTY_RPC_OPTIONS); - assertNull(RPC.getChangeRequest(ZONE1.getName(), "1", EMPTY_RPC_OPTIONS)); - //add - Change createdChange = RPC.applyChangeRequest(ZONE1.getName(), CHANGE1, EMPTY_RPC_OPTIONS); - assertEquals(createdChange.getAdditions(), CHANGE1.getAdditions()); - assertEquals(createdChange.getDeletions(), CHANGE1.getDeletions()); - assertNotNull(createdChange.getStartTime()); - assertEquals("1", createdChange.getId()); - Change retrievedChange = RPC.getChangeRequest(ZONE1.getName(), "1", EMPTY_RPC_OPTIONS); - assertEquals(createdChange, retrievedChange); - assertNull(RPC.getChangeRequest(ZONE1.getName(), "2", EMPTY_RPC_OPTIONS)); + // create zone twice try { - Change anotherChange = RPC.applyChangeRequest(ZONE1.getName(), CHANGE1, EMPTY_RPC_OPTIONS); + RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + fail("Zone already exists."); } catch (DnsException ex) { + // expected assertEquals(409, ex.code()); + assertTrue(ex.getMessage().contains("already exists")); } - assertNotNull(RPC.getChangeRequest(ZONE1.getName(), "1", EMPTY_RPC_OPTIONS)); - assertNull(RPC.getChangeRequest(ZONE1.getName(), "2", EMPTY_RPC_OPTIONS)); - // delete - RPC.applyChangeRequest(ZONE1.getName(), CHANGE2, EMPTY_RPC_OPTIONS); - assertNotNull(RPC.getChangeRequest(ZONE1.getName(), "1", EMPTY_RPC_OPTIONS)); - assertNotNull(RPC.getChangeRequest(ZONE1.getName(), "2", EMPTY_RPC_OPTIONS)); - Change last = RPC.applyChangeRequest(ZONE1.getName(), CHANGE_KEEP, EMPTY_RPC_OPTIONS); - assertEquals("done", last.getStatus()); - // todo(mderka) replace with real call - List list = - LOCAL_DNS_HELPER.findZone(REAL_PROJECT_ID, ZONE_NAME1).dnsRecords().get(ZONE_NAME1); - assertTrue(list.contains(new LocalDnsHelper.RrsetWrapper(RRSET_KEEP))); - Iterable results = - RPC.listDnsRecords(ZONE1.getName(), EMPTY_RPC_OPTIONS).results(); - boolean ok = false; - for (ResourceRecordSet dnsRecord : results) { - if (dnsRecord.getName().equals(RRSET_KEEP.getName()) - && dnsRecord.getType().equals(RRSET_KEEP.getType())) { - ok = true; - } - } - assertTrue(ok); - } - - @Test - public void testFindChange() { - LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); - Change change = LOCAL_DNS_HELPER.findChange(PROJECT_ID1, ZONE1.getName(), "somerandomchange"); - assertNull(change); - LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE1.getName(), CHANGE1, null); - // changes are sequential so we should find ID 1 - assertNotNull(LOCAL_DNS_HELPER.findChange(PROJECT_ID1, ZONE1.getName(), "1")); - // add another - LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE2, null); - assertNotNull(LOCAL_DNS_HELPER.findChange(PROJECT_ID1, ZONE1.getName(), "1")); - assertNotNull(LOCAL_DNS_HELPER.findChange(PROJECT_ID1, ZONE1.getName(), "2")); - // try to find non-existent change - assertNull(LOCAL_DNS_HELPER.findChange(PROJECT_ID1, ZONE1.getName(), "3")); - // try to find a change in yet non-existent project - assertNull(LOCAL_DNS_HELPER.findChange(PROJECT_ID2, ZONE1.getName(), "3")); - } - - @Test - public void testRandomNameServers() { - assertEquals(4, LocalDnsHelper.randomNameservers().size()); - assertEquals(4, LocalDnsHelper.randomNameservers().size()); - assertEquals(4, LocalDnsHelper.randomNameservers().size()); - assertEquals(4, LocalDnsHelper.randomNameservers().size()); - } - - @Test - public void testGetProject() { - // only interested in no exceptions and non-null response here - assertNotNull(LOCAL_DNS_HELPER.getProject(PROJECT_ID1, null)); - assertNotNull(LOCAL_DNS_HELPER.getProject(PROJECT_ID2, null)); - Project project = RPC.getProject(EMPTY_RPC_OPTIONS); - assertNotNull(project.getQuota()); - assertEquals(REAL_PROJECT_ID, project.getId()); - // fields options - Map options = new HashMap<>(); - options.put(DnsRpc.Option.FIELDS, "number"); - project = RPC.getProject(options); - assertNull(project.getId()); - assertNotNull(project.getNumber()); - assertNull(project.getQuota()); - options.put(DnsRpc.Option.FIELDS, "id"); - project = RPC.getProject(options); - assertNotNull(project.getId()); - assertNull(project.getNumber()); - assertNull(project.getQuota()); - options.put(DnsRpc.Option.FIELDS, "quota"); - project = RPC.getProject(options); - assertNull(project.getId()); - assertNull(project.getNumber()); - assertNotNull(project.getQuota()); - } - - @Test - public void testGetZone() { - // non-existent - LocalDnsHelper.Response response = LOCAL_DNS_HELPER.getZone(PROJECT_ID1, ZONE_NAME1, null); - assertEquals(404, response.code()); - assertTrue(response.body().contains("does not exist")); - // existent - LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); - response = LOCAL_DNS_HELPER.getZone(PROJECT_ID1, ZONE1.getName(), null); - assertEquals(200, response.code()); - } - - @Test - public void testGetZoneUsingRpc() { - // non-existent - assertNull(RPC.getZone(ZONE_NAME1, EMPTY_RPC_OPTIONS)); - // existent - ManagedZone created = RPC.create(ZONE1, EMPTY_RPC_OPTIONS); - ManagedZone zone = RPC.getZone(ZONE_NAME1, EMPTY_RPC_OPTIONS); - assertEquals(created, zone); - assertEquals(ZONE1.getName(), zone.getName()); // field options + resetProjects(); Map options = new HashMap<>(); options.put(DnsRpc.Option.FIELDS, "id"); - zone = RPC.getZone(ZONE1.getName(), options); + zone = RPC.create(ZONE1, options); assertNull(zone.getCreationTime()); assertNull(zone.getName()); assertNull(zone.getDnsName()); @@ -396,8 +169,9 @@ public void testGetZoneUsingRpc() { assertNull(zone.getNameServers()); assertNull(zone.getNameServerSet()); assertNotNull(zone.getId()); + resetProjects(); options.put(DnsRpc.Option.FIELDS, "creationTime"); - zone = RPC.getZone(ZONE1.getName(), options); + zone = RPC.create(ZONE1, options); assertNotNull(zone.getCreationTime()); assertNull(zone.getName()); assertNull(zone.getDnsName()); @@ -406,7 +180,8 @@ public void testGetZoneUsingRpc() { assertNull(zone.getNameServerSet()); assertNull(zone.getId()); options.put(DnsRpc.Option.FIELDS, "dnsName"); - zone = RPC.getZone(ZONE1.getName(), options); + resetProjects(); + zone = RPC.create(ZONE1, options); assertNull(zone.getCreationTime()); assertNull(zone.getName()); assertNotNull(zone.getDnsName()); @@ -415,7 +190,8 @@ public void testGetZoneUsingRpc() { assertNull(zone.getNameServerSet()); assertNull(zone.getId()); options.put(DnsRpc.Option.FIELDS, "description"); - zone = RPC.getZone(ZONE1.getName(), options); + resetProjects(); + zone = RPC.create(ZONE1, options); assertNull(zone.getCreationTime()); assertNull(zone.getName()); assertNull(zone.getDnsName()); @@ -424,7 +200,8 @@ public void testGetZoneUsingRpc() { assertNull(zone.getNameServerSet()); assertNull(zone.getId()); options.put(DnsRpc.Option.FIELDS, "nameServers"); - zone = RPC.getZone(ZONE1.getName(), options); + resetProjects(); + zone = RPC.create(ZONE1, options); assertNull(zone.getCreationTime()); assertNull(zone.getName()); assertNull(zone.getDnsName()); @@ -433,7 +210,8 @@ public void testGetZoneUsingRpc() { assertNull(zone.getNameServerSet()); assertNull(zone.getId()); options.put(DnsRpc.Option.FIELDS, "nameServerSet"); - zone = RPC.getZone(ZONE1.getName(), options); + resetProjects(); + zone = RPC.create(ZONE1, options); assertNull(zone.getCreationTime()); assertNull(zone.getName()); assertNull(zone.getDnsName()); @@ -443,7 +221,8 @@ public void testGetZoneUsingRpc() { assertNull(zone.getId()); // several combined options.put(DnsRpc.Option.FIELDS, "nameServerSet,description,id,name"); - zone = RPC.getZone(ZONE1.getName(), options); + resetProjects(); + zone = RPC.create(ZONE1, options); assertNull(zone.getCreationTime()); assertNotNull(zone.getName()); assertNull(zone.getDnsName()); @@ -454,50 +233,18 @@ public void testGetZoneUsingRpc() { } @Test - public void testCreateZone() { - // only interested in no exceptions and non-null response here - LocalDnsHelper.Response response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); - assertEquals(200, response.code()); - assertEquals(1, LOCAL_DNS_HELPER.projects().get(PROJECT_ID1).zones().size()); - try { - LOCAL_DNS_HELPER.createZone(PROJECT_ID1, null, null); - fail("Zone cannot be null"); - } catch (NullPointerException ex) { - // expected - } - // create zone twice - response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); - assertEquals(409, response.code()); - assertTrue(response.body().contains("already exists")); - } - - @Test - public void testCreateZoneUsingRpc() { + public void testGetZone() { + // non-existent + assertNull(RPC.getZone(ZONE_NAME1, EMPTY_RPC_OPTIONS)); + // existent ManagedZone created = RPC.create(ZONE1, EMPTY_RPC_OPTIONS); - assertEquals(created, LOCAL_DNS_HELPER.findZone(REAL_PROJECT_ID, ZONE1.getName()).zone()); ManagedZone zone = RPC.getZone(ZONE_NAME1, EMPTY_RPC_OPTIONS); assertEquals(created, zone); - try { - RPC.create(null, EMPTY_RPC_OPTIONS); - fail("Zone cannot be null"); - } catch (DnsException ex) { - // expected - assertEquals(400, ex.code()); - assertTrue(ex.getMessage().contains("entity.managedZone")); - } - // create zone twice - try { - RPC.create(ZONE1, EMPTY_RPC_OPTIONS); - } catch (DnsException ex) { - // expected - assertEquals(409, ex.code()); - assertTrue(ex.getMessage().contains("already exists")); - } + assertEquals(ZONE1.getName(), zone.getName()); // field options - resetProjects(); Map options = new HashMap<>(); options.put(DnsRpc.Option.FIELDS, "id"); - zone = RPC.create(ZONE1, options); + zone = RPC.getZone(ZONE1.getName(), options); assertNull(zone.getCreationTime()); assertNull(zone.getName()); assertNull(zone.getDnsName()); @@ -505,9 +252,8 @@ public void testCreateZoneUsingRpc() { assertNull(zone.getNameServers()); assertNull(zone.getNameServerSet()); assertNotNull(zone.getId()); - resetProjects(); options.put(DnsRpc.Option.FIELDS, "creationTime"); - zone = RPC.create(ZONE1, options); + zone = RPC.getZone(ZONE1.getName(), options); assertNotNull(zone.getCreationTime()); assertNull(zone.getName()); assertNull(zone.getDnsName()); @@ -516,8 +262,7 @@ public void testCreateZoneUsingRpc() { assertNull(zone.getNameServerSet()); assertNull(zone.getId()); options.put(DnsRpc.Option.FIELDS, "dnsName"); - resetProjects(); - zone = RPC.create(ZONE1, options); + zone = RPC.getZone(ZONE1.getName(), options); assertNull(zone.getCreationTime()); assertNull(zone.getName()); assertNotNull(zone.getDnsName()); @@ -526,8 +271,7 @@ public void testCreateZoneUsingRpc() { assertNull(zone.getNameServerSet()); assertNull(zone.getId()); options.put(DnsRpc.Option.FIELDS, "description"); - resetProjects(); - zone = RPC.create(ZONE1, options); + zone = RPC.getZone(ZONE1.getName(), options); assertNull(zone.getCreationTime()); assertNull(zone.getName()); assertNull(zone.getDnsName()); @@ -536,8 +280,7 @@ public void testCreateZoneUsingRpc() { assertNull(zone.getNameServerSet()); assertNull(zone.getId()); options.put(DnsRpc.Option.FIELDS, "nameServers"); - resetProjects(); - zone = RPC.create(ZONE1, options); + zone = RPC.getZone(ZONE1.getName(), options); assertNull(zone.getCreationTime()); assertNull(zone.getName()); assertNull(zone.getDnsName()); @@ -546,8 +289,7 @@ public void testCreateZoneUsingRpc() { assertNull(zone.getNameServerSet()); assertNull(zone.getId()); options.put(DnsRpc.Option.FIELDS, "nameServerSet"); - resetProjects(); - zone = RPC.create(ZONE1, options); + zone = RPC.getZone(ZONE1.getName(), options); assertNull(zone.getCreationTime()); assertNull(zone.getName()); assertNull(zone.getDnsName()); @@ -557,8 +299,7 @@ public void testCreateZoneUsingRpc() { assertNull(zone.getId()); // several combined options.put(DnsRpc.Option.FIELDS, "nameServerSet,description,id,name"); - resetProjects(); - zone = RPC.create(ZONE1, options); + zone = RPC.getZone(ZONE1.getName(), options); assertNull(zone.getCreationTime()); assertNotNull(zone.getName()); assertNull(zone.getDnsName()); @@ -568,25 +309,144 @@ public void testCreateZoneUsingRpc() { assertNotNull(zone.getId()); } + @Test + public void testDeleteZone() { + RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + assertTrue(RPC.deleteZone(ZONE1.getName())); + assertNull(RPC.getZone(ZONE1.getName(), EMPTY_RPC_OPTIONS)); + // deleting non-existent zone + assertFalse(RPC.deleteZone(ZONE1.getName())); + assertNull(RPC.getZone(ZONE1.getName(), EMPTY_RPC_OPTIONS)); + RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + RPC.create(ZONE2, EMPTY_RPC_OPTIONS); + assertNotNull(RPC.getZone(ZONE1.getName(), EMPTY_RPC_OPTIONS)); + assertNotNull(RPC.getZone(ZONE2.getName(), EMPTY_RPC_OPTIONS)); + // delete in reverse order + assertTrue(RPC.deleteZone(ZONE1.getName())); + assertNull(RPC.getZone(ZONE1.getName(), EMPTY_RPC_OPTIONS)); + assertNotNull(RPC.getZone(ZONE2.getName(), EMPTY_RPC_OPTIONS)); + assertTrue(RPC.deleteZone(ZONE2.getName())); + assertNull(RPC.getZone(ZONE1.getName(), EMPTY_RPC_OPTIONS)); + assertNull(RPC.getZone(ZONE2.getName(), EMPTY_RPC_OPTIONS)); + RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + RPC.applyChangeRequest(ZONE1.getName(), CHANGE_KEEP, EMPTY_RPC_OPTIONS); + try { + RPC.deleteZone(ZONE1.getName()); + fail(); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + assertTrue(ex.getMessage().contains("not empty")); + } + } + + @Test + public void testCreateAndApplyChange() { + executeCreateAndApplyChangeTest(RPC); + } + + @Test + public void testCreateAndApplyChangeWithThreads() { + LocalDnsHelper localDnsThreaded = LocalDnsHelper.create(50L); + localDnsThreaded.start(); + DnsRpc rpc = new DefaultDnsRpc(localDnsThreaded.options()); + executeCreateAndApplyChangeTest(rpc); + localDnsThreaded.stop(); + } + + private static void waitForChangeToComplete(DnsRpc rpc, String zoneName, String changeId) { + while (true) { + Change change = rpc.getChangeRequest(zoneName, changeId, EMPTY_RPC_OPTIONS); + if ("done".equals(change.getStatus())) { + return; + } + try { + Thread.sleep(50L); + } catch (InterruptedException e) { + fail("Thread was interrupted while waiting for change processing."); + } + } + } + + private static void executeCreateAndApplyChangeTest(DnsRpc rpc) { + rpc.create(ZONE1, EMPTY_RPC_OPTIONS); + assertNull(rpc.getChangeRequest(ZONE1.getName(), "1", EMPTY_RPC_OPTIONS)); + // add + Change createdChange = rpc.applyChangeRequest(ZONE1.getName(), CHANGE1, EMPTY_RPC_OPTIONS); + assertEquals(CHANGE1.getAdditions(), createdChange.getAdditions()); + assertEquals(CHANGE1.getDeletions(), createdChange.getDeletions()); + assertNotNull(createdChange.getStartTime()); + assertEquals("1", createdChange.getId()); + waitForChangeToComplete(rpc, ZONE1.getName(), "1"); // necessary for the following to return 409 + try { + rpc.applyChangeRequest(ZONE1.getName(), CHANGE1, EMPTY_RPC_OPTIONS); + fail(); + } catch (DnsException ex) { + assertEquals(409, ex.code()); + assertTrue(ex.getMessage().contains("already exists")); + } + assertNotNull(rpc.getChangeRequest(ZONE1.getName(), "1", EMPTY_RPC_OPTIONS)); + assertNull(rpc.getChangeRequest(ZONE1.getName(), "2", EMPTY_RPC_OPTIONS)); + // delete + rpc.applyChangeRequest(ZONE1.getName(), CHANGE2, EMPTY_RPC_OPTIONS); + assertNotNull(rpc.getChangeRequest(ZONE1.getName(), "1", EMPTY_RPC_OPTIONS)); + assertNotNull(rpc.getChangeRequest(ZONE1.getName(), "2", EMPTY_RPC_OPTIONS)); + waitForChangeToComplete(rpc, ZONE1.getName(), "2"); + rpc.applyChangeRequest(ZONE1.getName(), CHANGE_KEEP, EMPTY_RPC_OPTIONS); + waitForChangeToComplete(rpc, ZONE1.getName(), "3"); + Iterable results = + rpc.listDnsRecords(ZONE1.getName(), EMPTY_RPC_OPTIONS).results(); + List defaults = ImmutableList.of("SOA", "NS"); + boolean rrsetKeep = false; + boolean rrset1 = false; + for (ResourceRecordSet dnsRecord : results) { + if (dnsRecord.getName().equals(RRSET_KEEP.getName()) + && dnsRecord.getType().equals(RRSET_KEEP.getType())) { + rrsetKeep = true; + } else if (dnsRecord.getName().equals(RRSET1.getName()) + && dnsRecord.getType().equals(RRSET1.getType())) { + rrset1 = true; + } else if (!defaults.contains(dnsRecord.getType())) { + fail(String.format("Record with type %s should not exist", dnsRecord.getType())); + } + } + assertTrue(rrset1); + assertTrue(rrsetKeep); + } + + @Test + public void testGetProject() { + // the projects are automatically created when getProject is called + assertNotNull(LOCAL_DNS_HELPER.getProject(PROJECT_ID1, null)); + assertNotNull(LOCAL_DNS_HELPER.getProject(PROJECT_ID2, null)); + Project project = RPC.getProject(EMPTY_RPC_OPTIONS); + assertNotNull(project.getQuota()); + assertEquals(REAL_PROJECT_ID, project.getId()); + // fields options + Map options = new HashMap<>(); + options.put(DnsRpc.Option.FIELDS, "number"); + project = RPC.getProject(options); + assertNull(project.getId()); + assertNotNull(project.getNumber()); + assertNull(project.getQuota()); + options.put(DnsRpc.Option.FIELDS, "id"); + project = RPC.getProject(options); + assertNotNull(project.getId()); + assertNull(project.getNumber()); + assertNull(project.getQuota()); + options.put(DnsRpc.Option.FIELDS, "quota"); + project = RPC.getProject(options); + assertNull(project.getId()); + assertNull(project.getNumber()); + assertNotNull(project.getQuota()); + } + @Test public void testCreateChange() { - // non-existent zone - LocalDnsHelper.Response response = - LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); - assertEquals(404, response.code()); - // existent zone - assertNotNull(LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null)); - assertNull(LOCAL_DNS_HELPER.findChange(PROJECT_ID1, ZONE_NAME1, "1")); - response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); - assertEquals(200, response.code()); - assertNotNull(LOCAL_DNS_HELPER.findChange(PROJECT_ID1, ZONE_NAME1, "1")); - } - - @Test - public void testCreateChangeUsingRpc() { // non-existent zone try { RPC.applyChangeRequest(ZONE_NAME1, CHANGE1, EMPTY_RPC_OPTIONS); + fail("Zone was not created yet."); } catch (DnsException ex) { assertEquals(404, ex.code()); } @@ -637,23 +497,6 @@ public void testCreateChangeUsingRpc() { @Test public void testGetChange() { - // existent - assertEquals(200, LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null).code()); - assertEquals(200, LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null).code()); - assertEquals(200, LOCAL_DNS_HELPER.getChange(PROJECT_ID1, ZONE_NAME1, "1", null).code()); - // non-existent - LocalDnsHelper.Response response = - LOCAL_DNS_HELPER.getChange(PROJECT_ID1, ZONE_NAME1, "2", null); - assertEquals(404, response.code()); - assertTrue(response.body().contains("parameters.changeId")); - // non-existent zone - response = LOCAL_DNS_HELPER.getChange(PROJECT_ID1, ZONE_NAME2, "1", null); - assertEquals(404, response.code()); - assertTrue(response.body().contains("parameters.managedZone")); - } - - @Test - public void testGetChangeUsingRpc() { // existent RPC.create(ZONE1, EMPTY_RPC_OPTIONS); Change created = RPC.applyChangeRequest(ZONE1.getName(), CHANGE1, EMPTY_RPC_OPTIONS); @@ -664,9 +507,11 @@ public void testGetChangeUsingRpc() { // non-existent zone try { RPC.getChangeRequest(ZONE_NAME2, "1", EMPTY_RPC_OPTIONS); + fail(); } catch (DnsException ex) { // expected assertEquals(404, ex.code()); + assertTrue(ex.getMessage().contains("managedZone")); } // field options RPC.applyChangeRequest(ZONE1.getName(), CHANGE_KEEP, EMPTY_RPC_OPTIONS); @@ -711,43 +556,6 @@ public void testGetChangeUsingRpc() { @Test public void testListZones() { - // only interested in no exceptions and non-null response here - optionsMap.put("dnsName", null); - optionsMap.put("fields", null); - optionsMap.put("pageToken", null); - optionsMap.put("maxResults", null); - LocalDnsHelper.Response response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); - assertEquals(200, response.code()); - // some zones exists - LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); - response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); - assertEquals(200, response.code()); - LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE2, null); - response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); - assertEquals(200, response.code()); - // error in options - optionsMap.put("maxResults", "aaa"); - response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); - assertEquals(400, response.code()); - optionsMap.put("maxResults", "0"); - response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); - assertEquals(400, response.code()); - optionsMap.put("maxResults", "-1"); - response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); - assertEquals(400, response.code()); - optionsMap.put("maxResults", "15"); - response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); - assertEquals(200, response.code()); - optionsMap.put("dnsName", "aaa"); - response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); - assertEquals(400, response.code()); - optionsMap.put("dnsName", "aaa."); - response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); - assertEquals(200, response.code()); - } - - @Test - public void testListZonesUsingRpc() { Iterable results = RPC.listZones(EMPTY_RPC_OPTIONS).results(); ImmutableList zones = ImmutableList.copyOf(results); assertEquals(0, zones.size()); @@ -767,32 +575,38 @@ public void testListZonesUsingRpc() { options.put(DnsRpc.Option.PAGE_SIZE, 0); try { RPC.listZones(options); + fail(); } catch (DnsException ex) { // expected assertEquals(400, ex.code()); + assertTrue(ex.getMessage().contains("parameters.maxResults")); } options = new HashMap<>(); options.put(DnsRpc.Option.PAGE_SIZE, -1); try { RPC.listZones(options); + fail(); } catch (DnsException ex) { // expected assertEquals(400, ex.code()); + assertTrue(ex.getMessage().contains("parameters.maxResults")); } // ok size options = new HashMap<>(); - options.put(DnsRpc.Option.PAGE_SIZE, 1); + options.put(DnsRpc.Option.PAGE_SIZE, 335); results = RPC.listZones(options).results(); zones = ImmutableList.copyOf(results); - assertEquals(1, zones.size()); + assertEquals(2, zones.size()); // dns name problems options = new HashMap<>(); options.put(DnsRpc.Option.DNS_NAME, "aaa"); try { RPC.listZones(options); + fail(); } catch (DnsException ex) { // expected assertEquals(400, ex.code()); + assertTrue(ex.getMessage().contains("parameters.dnsName")); } // ok name options = new HashMap<>(); @@ -848,9 +662,9 @@ public void testListZonesUsingRpc() { assertNull(zone.getNameServerSet()); assertNull(zone.getId()); options.put(DnsRpc.Option.FIELDS, "managedZones(nameServerSet)"); - DnsRpc.ListResult managedZoneListResult = RPC.listZones(options); - zone = managedZoneListResult.results().iterator().next(); - assertNull(managedZoneListResult.pageToken()); + DnsRpc.ListResult listResult = RPC.listZones(options); + zone = listResult.results().iterator().next(); + assertNull(listResult.pageToken()); assertNull(zone.getCreationTime()); assertNull(zone.getName()); assertNull(zone.getDnsName()); @@ -862,8 +676,8 @@ public void testListZonesUsingRpc() { options.put(DnsRpc.Option.FIELDS, "managedZones(nameServerSet,description,id,name),nextPageToken"); options.put(DnsRpc.Option.PAGE_SIZE, 1); - managedZoneListResult = RPC.listZones(options); - zone = managedZoneListResult.results().iterator().next(); + listResult = RPC.listZones(options); + zone = listResult.results().iterator().next(); assertNull(zone.getCreationTime()); assertNotNull(zone.getName()); assertNull(zone.getDnsName()); @@ -871,80 +685,19 @@ public void testListZonesUsingRpc() { assertNull(zone.getNameServers()); assertNotNull(zone.getNameServerSet()); assertNotNull(zone.getId()); - assertEquals(zone.getName(), managedZoneListResult.pageToken()); - // paging - options = new HashMap<>(); - options.put(DnsRpc.Option.PAGE_SIZE, 1); - managedZoneListResult = RPC.listZones(options); - ImmutableList page1 = ImmutableList.copyOf(managedZoneListResult.results()); - assertEquals(1, page1.size()); - options.put(DnsRpc.Option.PAGE_TOKEN, managedZoneListResult.pageToken()); - managedZoneListResult = RPC.listZones(options); - ImmutableList page2 = ImmutableList.copyOf(managedZoneListResult.results()); - assertEquals(1, page2.size()); - assertNotEquals(page1.get(0), page2.get(0)); + assertEquals(zone.getName(), listResult.pageToken()); } @Test public void testListDnsRecords() { - // only interested in no exceptions and non-null response here - optionsMap.put("name", null); - optionsMap.put("fields", null); - optionsMap.put("type", null); - optionsMap.put("pageToken", null); - optionsMap.put("maxResults", null); - // no zone exists - LocalDnsHelper.Response response = LOCAL_DNS_HELPER.listDnsRecords(PROJECT_ID1, ZONE_NAME1, - optionsMap); - assertEquals(404, response.code()); - // zone exists but has no records - LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); - LOCAL_DNS_HELPER.listDnsRecords(PROJECT_ID1, ZONE_NAME1, optionsMap); - // zone has records - LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); - response = LOCAL_DNS_HELPER.listDnsRecords(PROJECT_ID1, ZONE_NAME1, optionsMap); - assertEquals(200, response.code()); - // error in options - optionsMap.put("maxResults", "aaa"); - response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); - assertEquals(400, response.code()); - optionsMap.put("maxResults", "0"); - response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); - assertEquals(400, response.code()); - optionsMap.put("maxResults", "-1"); - response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); - assertEquals(400, response.code()); - optionsMap.put("maxResults", "15"); - response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); - assertEquals(200, response.code()); - optionsMap.put("name", "aaa"); - response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); - assertEquals(400, response.code()); - optionsMap.put("name", "aaa."); - response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); - assertEquals(200, response.code()); - optionsMap.put("name", null); - optionsMap.put("type", "A"); - response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); - assertEquals(400, response.code()); - optionsMap.put("name", "aaa."); - optionsMap.put("type", "a"); - response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); - assertEquals(400, response.code()); - optionsMap.put("name", "aaaa."); - optionsMap.put("type", "A"); - response = LOCAL_DNS_HELPER.listZones(PROJECT_ID1, optionsMap); - assertEquals(200, response.code()); - } - - @Test - public void testListDnsRecordsUsingRpc() { // no zone exists try { RPC.listDnsRecords(ZONE_NAME1, EMPTY_RPC_OPTIONS); + fail(); } catch (DnsException ex) { // expected assertEquals(404, ex.code()); + assertTrue(ex.getMessage().contains("managedZone")); } // zone exists but has no records RPC.create(ZONE1, EMPTY_RPC_OPTIONS); @@ -962,34 +715,35 @@ public void testListDnsRecordsUsingRpc() { options.put(DnsRpc.Option.PAGE_SIZE, 0); try { RPC.listDnsRecords(ZONE1.getName(), options); + fail(); } catch (DnsException ex) { // expected assertEquals(400, ex.code()); + assertTrue(ex.getMessage().contains("parameters.maxResults")); } options.put(DnsRpc.Option.PAGE_SIZE, -1); try { RPC.listDnsRecords(ZONE1.getName(), options); + fail(); } catch (DnsException ex) { // expected assertEquals(400, ex.code()); + assertTrue(ex.getMessage().contains("parameters.maxResults")); } - options.put(DnsRpc.Option.PAGE_SIZE, 1); - results = RPC.listDnsRecords(ZONE1.getName(), options).results(); - records = ImmutableList.copyOf(results); - assertEquals(1, records.size()); options.put(DnsRpc.Option.PAGE_SIZE, 15); results = RPC.listDnsRecords(ZONE1.getName(), options).results(); records = ImmutableList.copyOf(results); assertEquals(3, records.size()); - // dnsName filter options = new HashMap<>(); options.put(DnsRpc.Option.NAME, "aaa"); try { RPC.listDnsRecords(ZONE1.getName(), options); + fail(); } catch (DnsException ex) { // expected assertEquals(400, ex.code()); + assertTrue(ex.getMessage().contains("parameters.name")); } options.put(DnsRpc.Option.NAME, "aaa."); results = RPC.listDnsRecords(ZONE1.getName(), options).results(); @@ -999,17 +753,21 @@ public void testListDnsRecordsUsingRpc() { options.put(DnsRpc.Option.DNS_TYPE, "A"); try { RPC.listDnsRecords(ZONE1.getName(), options); + fail(); } catch (DnsException ex) { // expected assertEquals(400, ex.code()); + assertTrue(ex.getMessage().contains("parameters.name")); } options.put(DnsRpc.Option.NAME, "aaa."); options.put(DnsRpc.Option.DNS_TYPE, "a"); try { RPC.listDnsRecords(ZONE1.getName(), options); + fail(); } catch (DnsException ex) { // expected assertEquals(400, ex.code()); + assertTrue(ex.getMessage().contains("parameters.type")); } options.put(DnsRpc.Option.NAME, DNS_NAME); options.put(DnsRpc.Option.DNS_TYPE, "SOA"); @@ -1019,137 +777,74 @@ public void testListDnsRecordsUsingRpc() { // field options options = new HashMap<>(); options.put(DnsRpc.Option.FIELDS, "rrsets(name)"); - DnsRpc.ListResult resourceRecordSetListResult = + DnsRpc.ListResult listResult = RPC.listDnsRecords(ZONE1.getName(), options); - records = ImmutableList.copyOf(resourceRecordSetListResult.results()); + records = ImmutableList.copyOf(listResult.results()); ResourceRecordSet record = records.get(0); assertNotNull(record.getName()); assertNull(record.getRrdatas()); assertNull(record.getType()); assertNull(record.getTtl()); - assertNull(resourceRecordSetListResult.pageToken()); + assertNull(listResult.pageToken()); options.put(DnsRpc.Option.FIELDS, "rrsets(rrdatas)"); - resourceRecordSetListResult = RPC.listDnsRecords(ZONE1.getName(), options); - records = ImmutableList.copyOf(resourceRecordSetListResult.results()); + listResult = RPC.listDnsRecords(ZONE1.getName(), options); + records = ImmutableList.copyOf(listResult.results()); record = records.get(0); assertNull(record.getName()); assertNotNull(record.getRrdatas()); assertNull(record.getType()); assertNull(record.getTtl()); - assertNull(resourceRecordSetListResult.pageToken()); + assertNull(listResult.pageToken()); options.put(DnsRpc.Option.FIELDS, "rrsets(ttl)"); - resourceRecordSetListResult = RPC.listDnsRecords(ZONE1.getName(), options); - records = ImmutableList.copyOf(resourceRecordSetListResult.results()); + listResult = RPC.listDnsRecords(ZONE1.getName(), options); + records = ImmutableList.copyOf(listResult.results()); record = records.get(0); assertNull(record.getName()); assertNull(record.getRrdatas()); assertNull(record.getType()); assertNotNull(record.getTtl()); - assertNull(resourceRecordSetListResult.pageToken()); + assertNull(listResult.pageToken()); options.put(DnsRpc.Option.FIELDS, "rrsets(type)"); - resourceRecordSetListResult = RPC.listDnsRecords(ZONE1.getName(), options); - records = ImmutableList.copyOf(resourceRecordSetListResult.results()); + listResult = RPC.listDnsRecords(ZONE1.getName(), options); + records = ImmutableList.copyOf(listResult.results()); record = records.get(0); assertNull(record.getName()); assertNull(record.getRrdatas()); assertNotNull(record.getType()); assertNull(record.getTtl()); - assertNull(resourceRecordSetListResult.pageToken()); + assertNull(listResult.pageToken()); options.put(DnsRpc.Option.FIELDS, "nextPageToken"); - resourceRecordSetListResult = RPC.listDnsRecords(ZONE1.getName(), options); - records = ImmutableList.copyOf(resourceRecordSetListResult.results()); + listResult = RPC.listDnsRecords(ZONE1.getName(), options); + records = ImmutableList.copyOf(listResult.results()); record = records.get(0); assertNull(record.getName()); assertNull(record.getRrdatas()); assertNull(record.getType()); assertNull(record.getTtl()); - assertNull(resourceRecordSetListResult.pageToken()); + assertNull(listResult.pageToken()); options.put(DnsRpc.Option.FIELDS, "nextPageToken,rrsets(name,rrdatas)"); options.put(DnsRpc.Option.PAGE_SIZE, 1); - resourceRecordSetListResult = RPC.listDnsRecords(ZONE1.getName(), options); - records = ImmutableList.copyOf(resourceRecordSetListResult.results()); + listResult = RPC.listDnsRecords(ZONE1.getName(), options); + records = ImmutableList.copyOf(listResult.results()); assertEquals(1, records.size()); record = records.get(0); assertNotNull(record.getName()); assertNotNull(record.getRrdatas()); assertNull(record.getType()); assertNull(record.getTtl()); - assertNotNull(resourceRecordSetListResult.pageToken()); - // paging - options.put(DnsRpc.Option.PAGE_TOKEN, resourceRecordSetListResult.pageToken()); - resourceRecordSetListResult = RPC.listDnsRecords(ZONE1.getName(), options); - records = ImmutableList.copyOf(resourceRecordSetListResult.results()); - assertEquals(1, records.size()); - ResourceRecordSet nextRecord = records.get(0); - assertNotEquals(record, nextRecord); + assertNotNull(listResult.pageToken()); } @Test public void testListChanges() { - optionsMap.put("sortBy", null); - optionsMap.put("sortOrder", null); - optionsMap.put("fields", null); - optionsMap.put("pageToken", null); - optionsMap.put("maxResults", null); - // no such zone exists - LocalDnsHelper.Response response = - LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); - assertEquals(404, response.code()); - assertTrue(response.body().contains("managedZone")); - // zone exists but has no changes - LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); - assertNotNull(LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap)); - // zone has changes - LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); - assertNotNull(LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap)); - LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE1, null); - LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE2, null); - LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, CHANGE2, null); - assertNotNull(LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap)); - // error in options - optionsMap.put("maxResults", "aaa"); - response = LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); - assertEquals(400, response.code()); - optionsMap.put("maxResults", "0"); - response = LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); - assertEquals(400, response.code()); - optionsMap.put("maxResults", "-1"); - response = LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); - assertEquals(400, response.code()); - optionsMap.put("maxResults", "15"); - response = LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); - assertEquals(200, response.code()); - optionsMap.put("sortBy", "changeSequence"); - response = LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); - assertEquals(200, response.code()); - optionsMap.put("sortBy", "something else"); - response = LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); - assertEquals(400, response.code()); - assertTrue(response.body().contains("Allowed values: [changesequence]")); - optionsMap.put("sortBy", "ChAnGeSeQuEnCe"); // is not case sensitive - response = LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); - assertEquals(200, response.code()); - optionsMap.put("sortOrder", "ascending"); - response = LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); - assertEquals(200, response.code()); - optionsMap.put("sortBy", null); - optionsMap.put("sortOrder", "descending"); - response = LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); - assertEquals(200, response.code()); - optionsMap.put("sortOrder", "somethingelse"); - response = LOCAL_DNS_HELPER.listChanges(PROJECT_ID1, ZONE_NAME1, optionsMap); - assertEquals(400, response.code()); - assertTrue(response.body().contains("parameters.sortOrder")); - } - - @Test - public void testListChangesUsingRpc() { // no such zone exists try { RPC.listChangeRequests(ZONE_NAME1, EMPTY_RPC_OPTIONS); + fail(); } catch (DnsException ex) { // expected assertEquals(404, ex.code()); + assertTrue(ex.getMessage().contains("managedZone")); } // zone exists but has no changes RPC.create(ZONE1, EMPTY_RPC_OPTIONS); @@ -1168,24 +863,25 @@ public void testListChangesUsingRpc() { options.put(DnsRpc.Option.PAGE_SIZE, 0); try { RPC.listChangeRequests(ZONE1.getName(), options); + fail(); } catch (DnsException ex) { // expected assertEquals(400, ex.code()); + assertTrue(ex.getMessage().contains("parameters.maxResults")); } options.put(DnsRpc.Option.PAGE_SIZE, -1); try { RPC.listChangeRequests(ZONE1.getName(), options); + fail(); } catch (DnsException ex) { // expected assertEquals(400, ex.code()); + assertTrue(ex.getMessage().contains("parameters.maxResults")); } options.put(DnsRpc.Option.PAGE_SIZE, 15); - try { - RPC.listChangeRequests(ZONE1.getName(), options); - } catch (DnsException ex) { - // expected - assertEquals(400, ex.code()); - } + results = RPC.listChangeRequests(ZONE1.getName(), options).results(); + changes = ImmutableList.copyOf(results); + assertEquals(3, changes.size()); options = new HashMap<>(); options.put(DnsRpc.Option.SORTING_ORDER, "descending"); results = RPC.listChangeRequests(ZONE1.getName(), options).results(); @@ -1200,17 +896,18 @@ public void testListChangesUsingRpc() { options.put(DnsRpc.Option.SORTING_ORDER, "something else"); try { RPC.listChangeRequests(ZONE1.getName(), options); + fail(); } catch (DnsException ex) { // expected assertEquals(400, ex.code()); + assertTrue(ex.getMessage().contains("parameters.sortOrder")); } // field options RPC.applyChangeRequest(ZONE1.getName(), CHANGE_COMPLEX, EMPTY_RPC_OPTIONS); options = new HashMap<>(); options.put(DnsRpc.Option.SORTING_ORDER, "descending"); options.put(DnsRpc.Option.FIELDS, "changes(additions)"); - DnsRpc.ListResult changeListResult = - RPC.listChangeRequests(ZONE1.getName(), options); + DnsRpc.ListResult changeListResult = RPC.listChangeRequests(ZONE1.getName(), options); changes = ImmutableList.copyOf(changeListResult.results()); Change complex = changes.get(0); assertNotNull(complex.getAdditions()); @@ -1270,20 +967,68 @@ public void testListChangesUsingRpc() { assertNull(complex.getStartTime()); assertNull(complex.getStatus()); assertNotNull(changeListResult.pageToken()); - // paging - options.put(DnsRpc.Option.FIELDS, "nextPageToken,changes(id)"); + } + + @Test + public void testDnsRecordPaging() { + RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + List complete = ImmutableList.copyOf( + RPC.listDnsRecords(ZONE1.getName(), EMPTY_RPC_OPTIONS).results()); + Map options = new HashMap<>(); options.put(DnsRpc.Option.PAGE_SIZE, 1); - changeListResult = RPC.listChangeRequests(ZONE1.getName(), options); - changes = ImmutableList.copyOf(changeListResult.results()); + DnsRpc.ListResult listResult = RPC.listDnsRecords(ZONE1.getName(), options); + ImmutableList records = ImmutableList.copyOf(listResult.results()); + assertEquals(1, records.size()); + assertEquals(complete.get(0), records.get(0)); + options.put(DnsRpc.Option.PAGE_TOKEN, listResult.pageToken()); + listResult = RPC.listDnsRecords(ZONE1.getName(), options); + records = ImmutableList.copyOf(listResult.results()); + assertEquals(1, records.size()); + assertEquals(complete.get(1), records.get(0)); + } + + @Test + public void testZonePaging() { + RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + RPC.create(ZONE2, EMPTY_RPC_OPTIONS); + ImmutableList complete = ImmutableList.copyOf( + RPC.listZones(EMPTY_RPC_OPTIONS).results()); + Map options = new HashMap<>(); + options.put(DnsRpc.Option.PAGE_SIZE, 1); + DnsRpc.ListResult listResult = RPC.listZones(options); + ImmutableList page1 = ImmutableList.copyOf(listResult.results()); + assertEquals(1, page1.size()); + assertEquals(complete.get(0), page1.get(0)); + assertEquals(page1.get(0).getName(), listResult.pageToken()); + options.put(DnsRpc.Option.PAGE_TOKEN, listResult.pageToken()); + listResult = RPC.listZones(options); + ImmutableList page2 = ImmutableList.copyOf(listResult.results()); + assertEquals(1, page2.size()); + assertEquals(complete.get(1), page2.get(0)); + assertNull(listResult.pageToken()); + } + + @Test + public void testChangePaging() { + RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + RPC.applyChangeRequest(ZONE1.getName(), CHANGE1, EMPTY_RPC_OPTIONS); + RPC.applyChangeRequest(ZONE1.getName(), CHANGE2, EMPTY_RPC_OPTIONS); + RPC.applyChangeRequest(ZONE1.getName(), CHANGE_KEEP, EMPTY_RPC_OPTIONS); + ImmutableList complete = + ImmutableList.copyOf(RPC.listChangeRequests(ZONE1.getName(), EMPTY_RPC_OPTIONS).results()); + Map options = new HashMap<>(); + options.put(DnsRpc.Option.PAGE_SIZE, 1); + DnsRpc.ListResult changeListResult = RPC.listChangeRequests(ZONE1.getName(), options); + List changes = ImmutableList.copyOf(changeListResult.results()); assertEquals(1, changes.size()); - final Change first = changes.get(0); - assertNotNull(changeListResult.pageToken()); + assertEquals(complete.get(0), changes.get(0)); + assertEquals(complete.get(0).getId(), changeListResult.pageToken()); options.put(DnsRpc.Option.PAGE_TOKEN, changeListResult.pageToken()); changeListResult = RPC.listChangeRequests(ZONE1.getName(), options); changes = ImmutableList.copyOf(changeListResult.results()); assertEquals(1, changes.size()); - Change second = changes.get(0); - assertNotEquals(first, second); + assertEquals(complete.get(1), changes.get(0)); + assertEquals(complete.get(1).getId(), changeListResult.pageToken()); } @Test @@ -1303,95 +1048,71 @@ public void testToListResponse() { } @Test - public void testCheckZone() { + public void testCreateZoneValidation() { + ManagedZone minimalZone = copyZone(ZONE1); // no name ManagedZone copy = copyZone(minimalZone); copy.setName(null); - LocalDnsHelper.Response response = LocalDnsHelper.checkZone(copy); + LocalDnsHelper.Response response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy); assertEquals(400, response.code()); assertTrue(response.body().contains("entity.managedZone.name")); // no description copy = copyZone(minimalZone); copy.setDescription(null); - response = LocalDnsHelper.checkZone(copy); + response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy); assertEquals(400, response.code()); assertTrue(response.body().contains("entity.managedZone.description")); - // no description + // no dns name copy = copyZone(minimalZone); copy.setDnsName(null); - response = LocalDnsHelper.checkZone(copy); + response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy); assertEquals(400, response.code()); assertTrue(response.body().contains("entity.managedZone.dnsName")); - // zone name is a number + // zone name does not start with a letter copy = copyZone(minimalZone); - copy.setName("123456"); - response = LocalDnsHelper.checkZone(copy); + copy.setName("1aaaaaa"); + response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy); assertEquals(400, response.code()); assertTrue(response.body().contains("entity.managedZone.name")); assertTrue(response.body().contains("Invalid")); - // dns name does not end with period + // zone name is too long copy = copyZone(minimalZone); - copy.setDnsName("aaaaaa.com"); - response = LocalDnsHelper.checkZone(copy); + copy.setName("123456aaaa123456aaaa123456aaaa123456aaaa123456aaaa123456aaaa123456aaaa123456aa"); + response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy); assertEquals(400, response.code()); - assertTrue(response.body().contains("entity.managedZone.dnsName")); + assertTrue(response.body().contains("entity.managedZone.name")); assertTrue(response.body().contains("Invalid")); - // dns name is reserved - copy = copyZone(minimalZone); - copy.setDnsName("com."); - response = LocalDnsHelper.checkZone(copy); - assertEquals(400, response.code()); - assertTrue(response.body().contains("not available to be created.")); - // empty description should pass + // zone name contains invalid characters copy = copyZone(minimalZone); - copy.setDescription(""); - assertNull(LocalDnsHelper.checkZone(copy)); - } - - @Test - public void testCreateZoneValidatesZone() { - // no name - ManagedZone copy = copyZone(minimalZone); - copy.setName(null); - LocalDnsHelper.Response response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy, null); + copy.setName("x1234AA6aa"); + response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy); assertEquals(400, response.code()); assertTrue(response.body().contains("entity.managedZone.name")); - // no description - copy = copyZone(minimalZone); - copy.setDescription(null); - response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy, null); - assertEquals(400, response.code()); - assertTrue(response.body().contains("entity.managedZone.description")); - // no dns name - copy = copyZone(minimalZone); - copy.setDnsName(null); - response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy, null); - assertEquals(400, response.code()); - assertTrue(response.body().contains("entity.managedZone.dnsName")); - // zone name is a number + assertTrue(response.body().contains("Invalid")); + // zone name contains invalid characters copy = copyZone(minimalZone); - copy.setName("123456"); - response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy, null); + copy.setName("x a"); + response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy); assertEquals(400, response.code()); assertTrue(response.body().contains("entity.managedZone.name")); assertTrue(response.body().contains("Invalid")); // dns name does not end with period copy = copyZone(minimalZone); copy.setDnsName("aaaaaa.com"); - response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy, null); + response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy); assertEquals(400, response.code()); assertTrue(response.body().contains("entity.managedZone.dnsName")); assertTrue(response.body().contains("Invalid")); // dns name is reserved copy = copyZone(minimalZone); copy.setDnsName("com."); - response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy, null); + response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy); assertEquals(400, response.code()); assertTrue(response.body().contains("not available to be created.")); // empty description should pass copy = copyZone(minimalZone); copy.setDescription(""); - response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy, null); + response = LOCAL_DNS_HELPER.createZone(PROJECT_ID1, copy); assertEquals(200, response.code()); } @@ -1474,8 +1195,8 @@ public void testCheckRrset() { valid.setTtl(500); Change validChange = new Change(); validChange.setAdditions(ImmutableList.of(valid)); - LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); - LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1); + LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange); // delete with field mismatch LocalDnsHelper.ZoneContainer zone = LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE_NAME1); valid.setTtl(valid.getTtl() + 20); @@ -1501,11 +1222,10 @@ public void testCheckRrdata() { assertFalse(LocalDnsHelper.checkRrData("111.255.12", "A")); assertFalse(LocalDnsHelper.checkRrData("111.255.12.11.11", "A")); // AAAA - assertTrue(LocalDnsHelper.checkRrData(":::::::", "AAAA")); - assertTrue(LocalDnsHelper.checkRrData("1F:fa:09fd::343:aaaa:AAAA:", "AAAA")); - assertTrue(LocalDnsHelper.checkRrData("0000:FFFF:09fd::343:aaaa:AAAA:", "AAAA")); + assertTrue(LocalDnsHelper.checkRrData("1F:fa:09fd::343:aaaa:AAAA:0", "AAAA")); + assertTrue(LocalDnsHelper.checkRrData("0000:FFFF:09fd::343:aaaa:AAAA:0", "AAAA")); assertFalse(LocalDnsHelper.checkRrData("-2:::::::", "AAAA")); - assertTrue(LocalDnsHelper.checkRrData("0:::::::", "AAAA")); + assertTrue(LocalDnsHelper.checkRrData("0::0", "AAAA")); assertFalse(LocalDnsHelper.checkRrData("::1FFFF:::::", "AAAA")); assertFalse(LocalDnsHelper.checkRrData("::aqaa:::::", "AAAA")); assertFalse(LocalDnsHelper.checkRrData("::::::::", "AAAA")); // too long @@ -1587,62 +1307,59 @@ public void testCheckChange() { ResourceRecordSet nonExistent = new ResourceRecordSet(); nonExistent.setName(ZONE1.getDnsName()); nonExistent.setType("AAAA"); - nonExistent.setRrdatas(ImmutableList.of(":::::::")); + nonExistent.setRrdatas(ImmutableList.of("0:0:0:0:5::6")); Change delete = new Change(); delete.setDeletions(ImmutableList.of(nonExistent)); response = LocalDnsHelper.checkChange(delete, zoneContainer); assertEquals(404, response.code()); assertTrue(response.body().contains("deletions[0]")); - } @Test - public void testAdditionsMeetDeletions() { + public void testCheckAdditionsDeletions() { ResourceRecordSet validA = new ResourceRecordSet(); validA.setName(ZONE1.getDnsName()); validA.setType("A"); validA.setRrdatas(ImmutableList.of("0.255.1.5")); Change validChange = new Change(); validChange.setAdditions(ImmutableList.of(validA)); - LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); - LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1); + LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange); LocalDnsHelper.ZoneContainer container = LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE_NAME1); LocalDnsHelper.Response response = - LocalDnsHelper.additionsMeetDeletions(ImmutableList.of(validA), null, container); + LocalDnsHelper.checkAdditionsDeletions(ImmutableList.of(validA), null, container); assertEquals(409, response.code()); assertTrue(response.body().contains("already exists")); - } @Test - public void testCreateChangeValidatesChangeContent() { + public void testCreateChangeContentValidation() { ResourceRecordSet validA = new ResourceRecordSet(); validA.setName(ZONE1.getDnsName()); validA.setType("A"); validA.setRrdatas(ImmutableList.of("0.255.1.5")); Change validChange = new Change(); validChange.setAdditions(ImmutableList.of(validA)); - LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); - LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1); + LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange); LocalDnsHelper.Response response = - LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); + LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange); assertEquals(409, response.code()); assertTrue(response.body().contains("already exists")); // delete with field mismatch Change delete = new Change(); validA.setTtl(20); // mismatch delete.setDeletions(ImmutableList.of(validA)); - response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, delete, null); + response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, delete); assertEquals(412, response.code()); assertTrue(response.body().contains("entity.change.deletions[0]")); // delete and add SOA Change addition = new Change(); - ImmutableList rrsetWrappers - = LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE_NAME1).dnsRecords().get(ZONE_NAME1); + ImmutableCollection dnsRecords = + LOCAL_DNS_HELPER.findZone(PROJECT_ID1, ZONE_NAME1).dnsRecords().get().values(); LinkedList deletions = new LinkedList<>(); LinkedList additions = new LinkedList<>(); - for (LocalDnsHelper.RrsetWrapper wrapper : rrsetWrappers) { - ResourceRecordSet rrset = wrapper.rrset(); + for (ResourceRecordSet rrset : dnsRecords) { if (rrset.getType().equals("SOA")) { deletions.add(rrset); ResourceRecordSet copy = copyRrset(rrset); @@ -1653,12 +1370,12 @@ public void testCreateChangeValidatesChangeContent() { } delete.setDeletions(deletions); addition.setAdditions(additions); - response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, delete, null); + response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, delete); assertEquals(400, response.code()); assertTrue(response.body().contains( "zone must contain exactly one resource record set of type 'SOA' at the apex")); assertTrue(response.body().contains("deletions[0]")); - response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, addition, null); + response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, addition); assertEquals(400, response.code()); assertTrue(response.body().contains( "zone must contain exactly one resource record set of type 'SOA' at the apex")); @@ -1666,8 +1383,7 @@ public void testCreateChangeValidatesChangeContent() { // delete NS deletions = new LinkedList<>(); additions = new LinkedList<>(); - for (LocalDnsHelper.RrsetWrapper wrapper : rrsetWrappers) { - ResourceRecordSet rrset = wrapper.rrset(); + for (ResourceRecordSet rrset : dnsRecords) { if (rrset.getType().equals("NS")) { deletions.add(rrset); ResourceRecordSet copy = copyRrset(rrset); @@ -1678,96 +1394,38 @@ public void testCreateChangeValidatesChangeContent() { } delete.setDeletions(deletions); addition.setAdditions(additions); - response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, delete, null); + response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, delete); assertEquals(400, response.code()); assertTrue(response.body().contains( "zone must contain exactly one resource record set of type 'NS' at the apex")); - response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, addition, null); + response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, addition); assertEquals(400, response.code()); assertTrue(response.body().contains( "zone must contain exactly one resource record set of type 'NS' at the apex")); assertTrue(response.body().contains("additions[0]")); // change (delete + add) addition.setDeletions(deletions); - response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, addition, null); + response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, addition); assertEquals(200, response.code()); } @Test - public void testCreateChangeValidatesChange() { - LOCAL_DNS_HELPER.createZone(PROJECT_ID1, ZONE1, null); - ResourceRecordSet validA = new ResourceRecordSet(); - validA.setName(ZONE1.getDnsName()); - validA.setType("A"); - validA.setRrdatas(ImmutableList.of("0.255.1.5")); - ResourceRecordSet invalidA = new ResourceRecordSet(); - invalidA.setName(ZONE1.getDnsName()); - invalidA.setType("A"); - invalidA.setRrdatas(ImmutableList.of("0.-255.1.5")); - Change validChange = new Change(); - validChange.setAdditions(ImmutableList.of(validA)); - Change invalidChange = new Change(); - invalidChange.setAdditions(ImmutableList.of(invalidA)); - LocalDnsHelper.Response response = - LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); - assertEquals(200, response.code()); - response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, invalidChange, null); - assertEquals(400, response.code()); - // only empty additions/deletions - Change empty = new Change(); - empty.setAdditions(ImmutableList.of()); - empty.setDeletions(ImmutableList.of()); - response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, empty, null); - assertEquals(400, response.code()); - assertTrue(response.body().contains( - "The 'entity.change' parameter is required but was missing.")); - // non-matching name - validA.setName(ZONE1.getDnsName() + ".aaa."); - response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); - assertEquals(400, response.code()); - assertTrue(response.body().contains("additions[0].name")); - // wrong type - validA.setName(ZONE1.getDnsName()); // revert - validA.setType("ABCD"); - response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); - assertEquals(400, response.code()); - assertTrue(response.body().contains("additions[0].type")); - // wrong ttl - validA.setType("A"); // revert - validA.setTtl(-1); - response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); - assertEquals(400, response.code()); - assertTrue(response.body().contains("additions[0].ttl")); - validA.setTtl(null); // revert - // null name - validA.setName(null); - response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); - assertEquals(400, response.code()); - assertTrue(response.body().contains("additions[0].name")); - validA.setName(ZONE1.getDnsName()); - // null type - validA.setType(null); - response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); - assertEquals(400, response.code()); - assertTrue(response.body().contains("additions[0].type")); - validA.setType("A"); - // null rrdata - final List temp = validA.getRrdatas(); // preserve - validA.setRrdatas(null); - response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, validChange, null); - assertEquals(400, response.code()); - assertTrue(response.body().contains("additions[0].rrdata")); - validA.setRrdatas(temp); - // delete non-existent - ResourceRecordSet nonExistent = new ResourceRecordSet(); - nonExistent.setName(ZONE1.getDnsName()); - nonExistent.setType("AAAA"); - nonExistent.setRrdatas(ImmutableList.of(":::::::")); - Change delete = new Change(); - delete.setDeletions(ImmutableList.of(nonExistent)); - response = LOCAL_DNS_HELPER.createChange(PROJECT_ID1, ZONE_NAME1, delete, null); - assertEquals(404, response.code()); - assertTrue(response.body().contains("deletions[0]")); + public void testMatchesCriteria() { + assertTrue(LocalDnsHelper.matchesCriteria(RRSET1, RRSET1.getName(), RRSET1.getType())); + assertFalse(LocalDnsHelper.matchesCriteria(RRSET1, RRSET1.getName(), "anothertype")); + assertTrue(LocalDnsHelper.matchesCriteria(RRSET1, null, RRSET1.getType())); + assertTrue(LocalDnsHelper.matchesCriteria(RRSET1, RRSET1.getName(), null)); + assertFalse(LocalDnsHelper.matchesCriteria(RRSET1, "anothername", RRSET1.getType())); + } + + @Test + public void testGetUniqueId() { + assertNotNull(LocalDnsHelper.getUniqueId(new HashSet())); + } + + @Test + public void testRandomNameServers() { + assertEquals(4, LocalDnsHelper.randomNameservers().size()); } private static ManagedZone copyZone(ManagedZone original) { From 3cf07229834282f96f84cd783b4487a323967bfc Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Tue, 1 Mar 2016 14:41:17 -0800 Subject: [PATCH 153/375] Switched ZoneInfo.builder(). to ZoneInfo.of(). Fixes #698. --- .../java/com/google/gcloud/dns/ZoneInfo.java | 6 +-- .../com/google/gcloud/dns/DnsImplTest.java | 3 +- .../google/gcloud/dns/SerializationTest.java | 10 ++--- .../com/google/gcloud/dns/ZoneInfoTest.java | 42 ++++++++--------- .../java/com/google/gcloud/dns/ZoneTest.java | 9 ++-- .../com/google/gcloud/dns/it/ITDnsTest.java | 45 +++---------------- 6 files changed, 38 insertions(+), 77 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java index 7dffbcdd365c..38a88b67777e 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java @@ -185,10 +185,10 @@ public ZoneInfo build() { } /** - * Returns a builder for {@code ZoneInfo} with an assigned {@code name}. + * Returns a ZoneInfo object with assigned {@code name}, {@code dnsName} and {@code description}. */ - public static Builder builder(String name) { - return new BuilderImpl(name); + public static ZoneInfo of(String name, String dnsName, String description) { + return new BuilderImpl(name).dnsName(dnsName).description(description).build(); } /** diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java index e1974d6cccfd..9205de8d99dd 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java @@ -44,6 +44,7 @@ public class DnsImplTest { // Dns entities private static final String ZONE_NAME = "some zone name"; private static final String DNS_NAME = "example.com."; + private static final String DESCRIPTION = "desc"; private static final String CHANGE_ID = "some change id"; private static final DnsRecord DNS_RECORD1 = DnsRecord.builder("Something", DnsRecord.Type.AAAA) .build(); @@ -51,7 +52,7 @@ public class DnsImplTest { .build(); private static final Integer MAX_SIZE = 20; private static final String PAGE_TOKEN = "some token"; - private static final ZoneInfo ZONE_INFO = ZoneInfo.builder(ZONE_NAME).build(); + private static final ZoneInfo ZONE_INFO = ZoneInfo.of(ZONE_NAME, DNS_NAME, DESCRIPTION); private static final ProjectInfo PROJECT_INFO = ProjectInfo.builder().build(); private static final ChangeRequest CHANGE_REQUEST_PARTIAL = ChangeRequest.builder() .add(DNS_RECORD1) diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java index adf5744d854e..c2bf9cfca0bb 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java @@ -35,16 +35,15 @@ public class SerializationTest { - private static final ZoneInfo FULL_ZONE_INFO = Zone.builder("some zone name") + private static final ZoneInfo FULL_ZONE_INFO = Zone.of("some zone name", "www.example.com", + "some descriptions").toBuilder() .creationTimeMillis(132L) - .description("some descriptions") - .dnsName("www.example.com") .id("123333") .nameServers(ImmutableList.of("server 1", "server 2")) .nameServerSet("specificationstring") .build(); - private static final ZoneInfo PARTIAL_ZONE_INFO = Zone.builder("some zone name") - .build(); + private static final ZoneInfo PARTIAL_ZONE_INFO = Zone.of("some zone name", "www.example.com", + "some descriptions").toBuilder().build(); private static final ProjectInfo PARTIAL_PROJECT_INFO = ProjectInfo.builder().id("13").build(); private static final ProjectInfo FULL_PROJECT_INFO = ProjectInfo.builder() .id("342") @@ -87,7 +86,6 @@ public class SerializationTest { .startTimeMillis(132L) .build(); - @Test public void testModelAndRequests() throws Exception { Serializable[] objects = {FULL_ZONE_INFO, PARTIAL_ZONE_INFO, ZONE_LIST_OPTION, diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java index 227916b46f96..b743bd385274 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java @@ -41,25 +41,23 @@ public class ZoneInfoTest { private static final String NS2 = "name server 2"; private static final String NS3 = "name server 3"; private static final List NAME_SERVERS = ImmutableList.of(NS1, NS2, NS3); - private static final ZoneInfo INFO = ZoneInfo.builder(NAME) + private static final ZoneInfo INFO = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION).toBuilder() .creationTimeMillis(CREATION_TIME_MILLIS) .id(ID) - .dnsName(DNS_NAME) - .description(DESCRIPTION) .nameServerSet(NAME_SERVER_SET) .nameServers(NAME_SERVERS) .build(); @Test public void testDefaultBuilders() { - ZoneInfo zone = ZoneInfo.builder(NAME).build(); + ZoneInfo zone = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION); assertTrue(zone.nameServers().isEmpty()); assertEquals(NAME, zone.name()); assertNull(zone.id()); assertNull(zone.creationTimeMillis()); assertNull(zone.nameServerSet()); - assertNull(zone.description()); - assertNull(zone.dnsName()); + assertEquals(DESCRIPTION, zone.description()); + assertEquals(DNS_NAME, zone.dnsName()); } @Test @@ -109,42 +107,38 @@ public void testSameHashCodeOnEquals() { @Test public void testToBuilder() { assertEquals(INFO, INFO.toBuilder().build()); - ZoneInfo partial = ZoneInfo.builder(NAME).build(); + ZoneInfo partial = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION); assertEquals(partial, partial.toBuilder().build()); - partial = ZoneInfo.builder(NAME).id(ID).build(); + partial = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION).toBuilder().id(ID).build(); assertEquals(partial, partial.toBuilder().build()); - partial = ZoneInfo.builder(NAME).description(DESCRIPTION).build(); - assertEquals(partial, partial.toBuilder().build()); - partial = ZoneInfo.builder(NAME).dnsName(DNS_NAME).build(); - assertEquals(partial, partial.toBuilder().build()); - partial = ZoneInfo.builder(NAME).creationTimeMillis(CREATION_TIME_MILLIS).build(); + partial = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION).toBuilder() + .creationTimeMillis(CREATION_TIME_MILLIS).build(); assertEquals(partial, partial.toBuilder().build()); List nameServers = new LinkedList<>(); nameServers.add(NS1); - partial = ZoneInfo.builder(NAME).nameServers(nameServers).build(); + partial = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION).toBuilder().nameServers(nameServers).build(); assertEquals(partial, partial.toBuilder().build()); - partial = ZoneInfo.builder(NAME).nameServerSet(NAME_SERVER_SET).build(); + partial = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION).toBuilder().nameServerSet(NAME_SERVER_SET) + .build(); assertEquals(partial, partial.toBuilder().build()); } @Test public void testToAndFromPb() { assertEquals(INFO, ZoneInfo.fromPb(INFO.toPb())); - ZoneInfo partial = ZoneInfo.builder(NAME).build(); - assertEquals(partial, ZoneInfo.fromPb(partial.toPb())); - partial = ZoneInfo.builder(NAME).id(ID).build(); - assertEquals(partial, ZoneInfo.fromPb(partial.toPb())); - partial = ZoneInfo.builder(NAME).description(DESCRIPTION).build(); + ZoneInfo partial = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION); assertEquals(partial, ZoneInfo.fromPb(partial.toPb())); - partial = ZoneInfo.builder(NAME).dnsName(DNS_NAME).build(); + partial = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION).toBuilder().id(ID).build(); assertEquals(partial, ZoneInfo.fromPb(partial.toPb())); - partial = ZoneInfo.builder(NAME).creationTimeMillis(CREATION_TIME_MILLIS).build(); + partial = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION).toBuilder() + .creationTimeMillis(CREATION_TIME_MILLIS).build(); assertEquals(partial, ZoneInfo.fromPb(partial.toPb())); List nameServers = new LinkedList<>(); nameServers.add(NS1); - partial = ZoneInfo.builder(NAME).nameServers(nameServers).build(); + partial = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION).toBuilder().nameServers(nameServers).build(); assertEquals(partial, ZoneInfo.fromPb(partial.toPb())); - partial = ZoneInfo.builder(NAME).nameServerSet(NAME_SERVER_SET).build(); + partial = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION).toBuilder().nameServerSet(NAME_SERVER_SET) + .build(); assertEquals(partial, ZoneInfo.fromPb(partial.toPb())); } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java index 5164dfb6001c..759c34fc1167 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java @@ -43,13 +43,13 @@ public class ZoneTest { private static final String ZONE_NAME = "dns-zone-name"; private static final String ZONE_ID = "123"; - private static final ZoneInfo ZONE_INFO = Zone.builder(ZONE_NAME) + private static final ZoneInfo ZONE_INFO = Zone.of(ZONE_NAME, "example.com", "description") + .toBuilder() .id(ZONE_ID) - .dnsName("example.com") .creationTimeMillis(123478946464L) .build(); - private static final ZoneInfo NO_ID_INFO = ZoneInfo.builder(ZONE_NAME) - .dnsName("another-example.com") + private static final ZoneInfo NO_ID_INFO = + ZoneInfo.of(ZONE_NAME, "another-example.com", "description").toBuilder() .creationTimeMillis(893123464L) .build(); private static final Dns.ZoneOption ZONE_FIELD_OPTIONS = @@ -71,7 +71,6 @@ public class ZoneTest { private Zone zone; private Zone zoneNoId; - @Before public void setUp() throws Exception { dns = createStrictMock(Dns.class); diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java index fda579a4a94b..4ad17fa8b217 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java @@ -60,29 +60,14 @@ public class ITDnsTest { private static final String ZONE_DNS_NAME1 = ZONE_NAME1 + ".com."; private static final String ZONE_DNS_EMPTY_DESCRIPTION = ZONE_NAME_EMPTY_DESCRIPTION + ".com."; private static final String ZONE_DNS_NAME_NO_PERIOD = ZONE_NAME1 + ".com"; - private static final ZoneInfo ZONE1 = ZoneInfo.builder(ZONE_NAME1) - .description(ZONE_DESCRIPTION1) - .dnsName(ZONE_DNS_EMPTY_DESCRIPTION) - .build(); + private static final ZoneInfo ZONE1 = + ZoneInfo.of(ZONE_NAME1, ZONE_DNS_EMPTY_DESCRIPTION, ZONE_DESCRIPTION1); private static final ZoneInfo ZONE_EMPTY_DESCRIPTION = - ZoneInfo.builder(ZONE_NAME_EMPTY_DESCRIPTION) - .description(ZONE_DESCRIPTION1) - .dnsName(ZONE_DNS_NAME1) - .build(); - private static final ZoneInfo ZONE_NAME_ERROR = ZoneInfo.builder(ZONE_NAME_TOO_LONG) - .description(ZONE_DESCRIPTION1) - .dnsName(ZONE_DNS_NAME1) - .build(); - private static final ZoneInfo ZONE_MISSING_DESCRIPTION = ZoneInfo.builder(ZONE_NAME1) - .dnsName(ZONE_DNS_NAME1) - .build(); - private static final ZoneInfo ZONE_MISSING_DNS_NAME = ZoneInfo.builder(ZONE_NAME1) - .description(ZONE_DESCRIPTION1) - .build(); - private static final ZoneInfo ZONE_DNS_NO_PERIOD = ZoneInfo.builder(ZONE_NAME1) - .description(ZONE_DESCRIPTION1) - .dnsName(ZONE_DNS_NAME_NO_PERIOD) - .build(); + ZoneInfo.of(ZONE_NAME_EMPTY_DESCRIPTION, ZONE_DNS_NAME1, ZONE_DESCRIPTION1); + private static final ZoneInfo ZONE_NAME_ERROR = + ZoneInfo.of(ZONE_NAME_TOO_LONG, ZONE_DNS_NAME1, ZONE_DESCRIPTION1); + private static final ZoneInfo ZONE_DNS_NO_PERIOD = + ZoneInfo.of(ZONE_NAME1, ZONE_DNS_NAME_NO_PERIOD, ZONE_DESCRIPTION1); private static final DnsRecord A_RECORD_ZONE1 = DnsRecord.builder("www." + ZONE1.dnsName(), DnsRecord.Type.A) .records(ImmutableList.of("123.123.55.1")) @@ -211,20 +196,6 @@ public void testCreateValidZone() { @Test public void testCreateZoneWithErrors() { try { - try { - DNS.create(ZONE_MISSING_DNS_NAME); - fail("Zone is missing DNS name. The service returns an error."); - } catch (DnsException ex) { - // expected - // todo(mderka) test non-retryable when implemented within #593 - } - try { - DNS.create(ZONE_MISSING_DESCRIPTION); - fail("Zone is missing description name. The service returns an error."); - } catch (DnsException ex) { - // expected - // todo(mderka) test non-retryable when implemented within #593 - } try { DNS.create(ZONE_NAME_ERROR); fail("Zone name is missing a period. The service returns an error."); @@ -240,8 +211,6 @@ public void testCreateZoneWithErrors() { // todo(mderka) test non-retryable when implemented within #593 } } finally { - DNS.delete(ZONE_MISSING_DNS_NAME.name()); - DNS.delete(ZONE_MISSING_DESCRIPTION.name()); DNS.delete(ZONE_NAME_ERROR.name()); DNS.delete(ZONE_DNS_NO_PERIOD.name()); } From 90897f35fc7102456b0faecccad0a1171accc804 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Thu, 10 Mar 2016 08:01:04 -0800 Subject: [PATCH 154/375] Renamed a test method and a variable. --- .../com/google/gcloud/dns/ZoneInfoTest.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java index b743bd385274..923672bb85a7 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java @@ -49,15 +49,15 @@ public class ZoneInfoTest { .build(); @Test - public void testDefaultBuilders() { - ZoneInfo zone = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION); - assertTrue(zone.nameServers().isEmpty()); - assertEquals(NAME, zone.name()); - assertNull(zone.id()); - assertNull(zone.creationTimeMillis()); - assertNull(zone.nameServerSet()); - assertEquals(DESCRIPTION, zone.description()); - assertEquals(DNS_NAME, zone.dnsName()); + public void testOf() { + ZoneInfo partial = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION); + assertTrue(partial.nameServers().isEmpty()); + assertEquals(NAME, partial.name()); + assertNull(partial.id()); + assertNull(partial.creationTimeMillis()); + assertNull(partial.nameServerSet()); + assertEquals(DESCRIPTION, partial.description()); + assertEquals(DNS_NAME, partial.dnsName()); } @Test From 407c43604ea02902a94c4e26397ddd8e6ab4705a Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 10 Mar 2016 21:22:21 +0100 Subject: [PATCH 155/375] Create service-specific spi packages --- .../com/google/gcloud/bigquery/BigQuery.java | 2 +- .../google/gcloud/bigquery/BigQueryImpl.java | 2 +- .../gcloud/bigquery/BigQueryOptions.java | 6 +- .../com/google/gcloud/bigquery/Option.java | 2 +- .../{ => bigquery}/spi/BigQueryRpc.java | 2 +- .../spi/BigQueryRpcFactory.java | 3 +- .../spi/DefaultBigQueryRpc.java | 14 +- .../gcloud/bigquery/BigQueryImplTest.java | 6 +- .../google/gcloud/bigquery/OptionTest.java | 2 +- .../bigquery/TableDataWriteChannelTest.java | 4 +- .../gcloud/datastore/DatastoreImpl.java | 2 +- .../gcloud/datastore/DatastoreOptions.java | 6 +- .../{ => datastore}/spi/DatastoreRpc.java | 2 +- .../spi/DatastoreRpcFactory.java | 3 +- .../spi/DefaultDatastoreRpc.java | 2 +- .../datastore/DatastoreOptionsTest.java | 4 +- .../gcloud/datastore/DatastoreTest.java | 4 +- .../examples/bigquery/BigQueryExample.java | 2 +- .../examples/storage/StorageExample.java | 2 +- .../google/gcloud/resourcemanager/Option.java | 2 +- .../resourcemanager/ResourceManager.java | 2 +- .../resourcemanager/ResourceManagerImpl.java | 4 +- .../ResourceManagerOptions.java | 6 +- .../spi/DefaultResourceManagerRpc.java | 16 +-- .../spi/ResourceManagerRpc.java | 2 +- .../spi/ResourceManagerRpcFactory.java | 3 +- .../LocalResourceManagerHelperTest.java | 6 +- .../ResourceManagerImplTest.java | 4 +- .../java/com/google/gcloud/storage/Blob.java | 4 +- .../gcloud/storage/BlobReadChannel.java | 4 +- .../gcloud/storage/BlobWriteChannel.java | 2 +- .../com/google/gcloud/storage/Bucket.java | 2 +- .../com/google/gcloud/storage/CopyWriter.java | 6 +- .../com/google/gcloud/storage/Option.java | 2 +- .../com/google/gcloud/storage/Storage.java | 4 +- .../google/gcloud/storage/StorageImpl.java | 24 ++-- .../google/gcloud/storage/StorageOptions.java | 6 +- .../{ => storage}/spi/DefaultStorageRpc.java | 134 ++++++++---------- .../gcloud/{ => storage}/spi/StorageRpc.java | 2 +- .../{ => storage}/spi/StorageRpcFactory.java | 3 +- .../gcloud/storage/BlobReadChannelTest.java | 4 +- .../gcloud/storage/BlobWriteChannelTest.java | 4 +- .../google/gcloud/storage/CopyWriterTest.java | 8 +- .../com/google/gcloud/storage/OptionTest.java | 2 +- .../gcloud/storage/SerializationTest.java | 2 +- .../gcloud/storage/StorageImplTest.java | 6 +- 46 files changed, 159 insertions(+), 175 deletions(-) rename gcloud-java-bigquery/src/main/java/com/google/gcloud/{ => bigquery}/spi/BigQueryRpc.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/gcloud/{ => bigquery}/spi/BigQueryRpcFactory.java (90%) rename gcloud-java-bigquery/src/main/java/com/google/gcloud/{ => bigquery}/spi/DefaultBigQueryRpc.java (97%) rename gcloud-java-datastore/src/main/java/com/google/gcloud/{ => datastore}/spi/DatastoreRpc.java (98%) rename gcloud-java-datastore/src/main/java/com/google/gcloud/{ => datastore}/spi/DatastoreRpcFactory.java (90%) rename gcloud-java-datastore/src/main/java/com/google/gcloud/{ => datastore}/spi/DefaultDatastoreRpc.java (99%) rename gcloud-java-resourcemanager/src/main/java/com/google/gcloud/{ => resourcemanager}/spi/DefaultResourceManagerRpc.java (84%) rename gcloud-java-resourcemanager/src/main/java/com/google/gcloud/{ => resourcemanager}/spi/ResourceManagerRpc.java (98%) rename gcloud-java-resourcemanager/src/main/java/com/google/gcloud/{ => resourcemanager}/spi/ResourceManagerRpcFactory.java (90%) rename gcloud-java-storage/src/main/java/com/google/gcloud/{ => storage}/spi/DefaultStorageRpc.java (79%) rename gcloud-java-storage/src/main/java/com/google/gcloud/{ => storage}/spi/StorageRpc.java (99%) rename gcloud-java-storage/src/main/java/com/google/gcloud/{ => storage}/spi/StorageRpcFactory.java (91%) diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java index 986c595e350d..3acaacaf42e5 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java @@ -25,7 +25,7 @@ import com.google.common.collect.Sets; import com.google.gcloud.Page; import com.google.gcloud.Service; -import com.google.gcloud.spi.BigQueryRpc; +import com.google.gcloud.bigquery.spi.BigQueryRpc; import java.util.List; import java.util.Set; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryImpl.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryImpl.java index ce881c6ea079..27f4af5d5007 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryImpl.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryImpl.java @@ -35,7 +35,7 @@ import com.google.gcloud.PageImpl.NextPageFetcher; import com.google.gcloud.RetryHelper; import com.google.gcloud.bigquery.InsertAllRequest.RowToInsert; -import com.google.gcloud.spi.BigQueryRpc; +import com.google.gcloud.bigquery.spi.BigQueryRpc; import java.util.List; import java.util.Map; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryOptions.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryOptions.java index 71d43cfbe565..d48cf646f349 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryOptions.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryOptions.java @@ -18,9 +18,9 @@ import com.google.common.collect.ImmutableSet; import com.google.gcloud.ServiceOptions; -import com.google.gcloud.spi.BigQueryRpc; -import com.google.gcloud.spi.BigQueryRpcFactory; -import com.google.gcloud.spi.DefaultBigQueryRpc; +import com.google.gcloud.bigquery.spi.BigQueryRpc; +import com.google.gcloud.bigquery.spi.BigQueryRpcFactory; +import com.google.gcloud.bigquery.spi.DefaultBigQueryRpc; import java.util.Set; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Option.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Option.java index d88820fe5a29..3fdc27ecab99 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Option.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Option.java @@ -19,7 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.MoreObjects; -import com.google.gcloud.spi.BigQueryRpc; +import com.google.gcloud.bigquery.spi.BigQueryRpc; import java.io.Serializable; import java.util.Objects; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/spi/BigQueryRpc.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/spi/BigQueryRpc.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/spi/BigQueryRpc.java rename to gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/spi/BigQueryRpc.java index a1935e5ab136..d0b740e9e390 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/spi/BigQueryRpc.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/spi/BigQueryRpc.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.spi; +package com.google.gcloud.bigquery.spi; import com.google.api.services.bigquery.model.Dataset; import com.google.api.services.bigquery.model.GetQueryResultsResponse; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/spi/BigQueryRpcFactory.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/spi/BigQueryRpcFactory.java similarity index 90% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/spi/BigQueryRpcFactory.java rename to gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/spi/BigQueryRpcFactory.java index 2706868756a5..1323ec0624f4 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/spi/BigQueryRpcFactory.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/spi/BigQueryRpcFactory.java @@ -14,9 +14,10 @@ * limitations under the License. */ -package com.google.gcloud.spi; +package com.google.gcloud.bigquery.spi; import com.google.gcloud.bigquery.BigQueryOptions; +import com.google.gcloud.spi.ServiceRpcFactory; /** * An interface for BigQuery RPC factory. diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/spi/DefaultBigQueryRpc.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/spi/DefaultBigQueryRpc.java similarity index 97% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/spi/DefaultBigQueryRpc.java rename to gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/spi/DefaultBigQueryRpc.java index a5c44129955a..f73517086a02 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/spi/DefaultBigQueryRpc.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/spi/DefaultBigQueryRpc.java @@ -12,14 +12,14 @@ * the License. */ -package com.google.gcloud.spi; +package com.google.gcloud.bigquery.spi; -import static com.google.gcloud.spi.BigQueryRpc.Option.DELETE_CONTENTS; -import static com.google.gcloud.spi.BigQueryRpc.Option.FIELDS; -import static com.google.gcloud.spi.BigQueryRpc.Option.MAX_RESULTS; -import static com.google.gcloud.spi.BigQueryRpc.Option.PAGE_TOKEN; -import static com.google.gcloud.spi.BigQueryRpc.Option.START_INDEX; -import static com.google.gcloud.spi.BigQueryRpc.Option.TIMEOUT; +import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.DELETE_CONTENTS; +import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.FIELDS; +import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.MAX_RESULTS; +import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.PAGE_TOKEN; +import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.START_INDEX; +import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.TIMEOUT; import static java.net.HttpURLConnection.HTTP_CREATED; import static java.net.HttpURLConnection.HTTP_NOT_FOUND; import static java.net.HttpURLConnection.HTTP_OK; diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java index 385ee6dcc8bd..305745e72da9 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java @@ -40,9 +40,9 @@ import com.google.gcloud.RetryParams; import com.google.gcloud.WriteChannel; import com.google.gcloud.bigquery.InsertAllRequest.RowToInsert; -import com.google.gcloud.spi.BigQueryRpc; -import com.google.gcloud.spi.BigQueryRpc.Tuple; -import com.google.gcloud.spi.BigQueryRpcFactory; +import com.google.gcloud.bigquery.spi.BigQueryRpc; +import com.google.gcloud.bigquery.spi.BigQueryRpc.Tuple; +import com.google.gcloud.bigquery.spi.BigQueryRpcFactory; import org.easymock.Capture; import org.easymock.EasyMock; diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/OptionTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/OptionTest.java index 225fc284b203..2c89ececedb8 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/OptionTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/OptionTest.java @@ -18,7 +18,7 @@ import static org.junit.Assert.assertEquals; -import com.google.gcloud.spi.BigQueryRpc; +import com.google.gcloud.bigquery.spi.BigQueryRpc; import org.junit.Test; diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableDataWriteChannelTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableDataWriteChannelTest.java index 6b7edcd76db1..4c1be470ff57 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableDataWriteChannelTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableDataWriteChannelTest.java @@ -32,8 +32,8 @@ import com.google.gcloud.RestorableState; import com.google.gcloud.WriteChannel; -import com.google.gcloud.spi.BigQueryRpc; -import com.google.gcloud.spi.BigQueryRpcFactory; +import com.google.gcloud.bigquery.spi.BigQueryRpc; +import com.google.gcloud.bigquery.spi.BigQueryRpcFactory; import org.easymock.Capture; import org.easymock.CaptureType; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java index 92d18ed4787c..49a5728a4da9 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java @@ -26,7 +26,7 @@ import com.google.gcloud.RetryHelper; import com.google.gcloud.RetryHelper.RetryHelperException; import com.google.gcloud.RetryParams; -import com.google.gcloud.spi.DatastoreRpc; +import com.google.gcloud.datastore.spi.DatastoreRpc; import com.google.protobuf.ByteString; import java.util.Arrays; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java index 2ec0f2be8f2b..db1a5f800ce8 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java @@ -24,9 +24,9 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.gcloud.ServiceOptions; -import com.google.gcloud.spi.DatastoreRpc; -import com.google.gcloud.spi.DatastoreRpcFactory; -import com.google.gcloud.spi.DefaultDatastoreRpc; +import com.google.gcloud.datastore.spi.DatastoreRpc; +import com.google.gcloud.datastore.spi.DatastoreRpcFactory; +import com.google.gcloud.datastore.spi.DefaultDatastoreRpc; import java.lang.reflect.Method; import java.util.Iterator; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DatastoreRpc.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/spi/DatastoreRpc.java similarity index 98% rename from gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DatastoreRpc.java rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/spi/DatastoreRpc.java index 4d4540c70196..002078550d1f 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DatastoreRpc.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/spi/DatastoreRpc.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.spi; +package com.google.gcloud.datastore.spi; import com.google.api.services.datastore.DatastoreV1.AllocateIdsRequest; import com.google.api.services.datastore.DatastoreV1.AllocateIdsResponse; diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DatastoreRpcFactory.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/spi/DatastoreRpcFactory.java similarity index 90% rename from gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DatastoreRpcFactory.java rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/spi/DatastoreRpcFactory.java index 1815dda30f5d..0979b2203037 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DatastoreRpcFactory.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/spi/DatastoreRpcFactory.java @@ -14,9 +14,10 @@ * limitations under the License. */ -package com.google.gcloud.spi; +package com.google.gcloud.datastore.spi; import com.google.gcloud.datastore.DatastoreOptions; +import com.google.gcloud.spi.ServiceRpcFactory; /** * An interface for Datastore RPC factory. diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/spi/DefaultDatastoreRpc.java similarity index 99% rename from gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/spi/DefaultDatastoreRpc.java index f679cc0d5826..093322fa4117 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/spi/DefaultDatastoreRpc.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/spi/DefaultDatastoreRpc.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.spi; +package com.google.gcloud.datastore.spi; import com.google.api.services.datastore.DatastoreV1.AllocateIdsRequest; import com.google.api.services.datastore.DatastoreV1.AllocateIdsResponse; diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java index 284a9d322793..b0d6e8d7800b 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java @@ -23,8 +23,8 @@ import static org.junit.Assert.assertTrue; import com.google.gcloud.datastore.testing.LocalGcdHelper; -import com.google.gcloud.spi.DatastoreRpc; -import com.google.gcloud.spi.DatastoreRpcFactory; +import com.google.gcloud.datastore.spi.DatastoreRpc; +import com.google.gcloud.datastore.spi.DatastoreRpcFactory; import org.easymock.EasyMock; import org.junit.Before; diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index 5d106fc7d31d..1886c67e22a8 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -39,8 +39,8 @@ import com.google.gcloud.datastore.StructuredQuery.Projection; import com.google.gcloud.datastore.StructuredQuery.PropertyFilter; import com.google.gcloud.datastore.testing.LocalGcdHelper; -import com.google.gcloud.spi.DatastoreRpc; -import com.google.gcloud.spi.DatastoreRpcFactory; +import com.google.gcloud.datastore.spi.DatastoreRpc; +import com.google.gcloud.datastore.spi.DatastoreRpcFactory; import com.google.protobuf.ByteString; import org.easymock.EasyMock; diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/BigQueryExample.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/BigQueryExample.java index c8fbe7289f9c..fe27ee3cf63b 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/BigQueryExample.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/BigQueryExample.java @@ -43,7 +43,7 @@ import com.google.gcloud.bigquery.TableInfo; import com.google.gcloud.bigquery.ViewDefinition; import com.google.gcloud.bigquery.WriteChannelConfiguration; -import com.google.gcloud.spi.BigQueryRpc.Tuple; +import com.google.gcloud.bigquery.spi.BigQueryRpc.Tuple; import java.nio.channels.FileChannel; import java.nio.file.Paths; diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java index e73cfc427129..a10b5ef71817 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java @@ -20,7 +20,7 @@ import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials; import com.google.gcloud.ReadChannel; import com.google.gcloud.WriteChannel; -import com.google.gcloud.spi.StorageRpc.Tuple; +import com.google.gcloud.storage.spi.StorageRpc.Tuple; import com.google.gcloud.storage.Blob; import com.google.gcloud.storage.BlobId; import com.google.gcloud.storage.BlobInfo; diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Option.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Option.java index f48c057ba049..72d62d7fc224 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Option.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Option.java @@ -19,7 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.MoreObjects; -import com.google.gcloud.spi.ResourceManagerRpc; +import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc; import java.io.Serializable; import java.util.Objects; diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java index f9ddf6872414..a463937f875c 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java @@ -20,7 +20,7 @@ import com.google.common.collect.Sets; import com.google.gcloud.Page; import com.google.gcloud.Service; -import com.google.gcloud.spi.ResourceManagerRpc; +import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc; import java.util.Set; diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java index 4176b4e610ba..fb699dcb06f0 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java @@ -29,8 +29,8 @@ import com.google.gcloud.PageImpl; import com.google.gcloud.PageImpl.NextPageFetcher; import com.google.gcloud.RetryHelper.RetryHelperException; -import com.google.gcloud.spi.ResourceManagerRpc; -import com.google.gcloud.spi.ResourceManagerRpc.Tuple; +import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc; +import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc.Tuple; import java.util.Map; import java.util.concurrent.Callable; diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerOptions.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerOptions.java index 5c0c4baf1ecb..c744864147c2 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerOptions.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerOptions.java @@ -18,9 +18,9 @@ import com.google.common.collect.ImmutableSet; import com.google.gcloud.ServiceOptions; -import com.google.gcloud.spi.DefaultResourceManagerRpc; -import com.google.gcloud.spi.ResourceManagerRpc; -import com.google.gcloud.spi.ResourceManagerRpcFactory; +import com.google.gcloud.resourcemanager.spi.DefaultResourceManagerRpc; +import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc; +import com.google.gcloud.resourcemanager.spi.ResourceManagerRpcFactory; import java.util.Set; diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/DefaultResourceManagerRpc.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/DefaultResourceManagerRpc.java similarity index 84% rename from gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/DefaultResourceManagerRpc.java rename to gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/DefaultResourceManagerRpc.java index d30cd2df3627..19e40698a847 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/DefaultResourceManagerRpc.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/DefaultResourceManagerRpc.java @@ -1,9 +1,5 @@ -package com.google.gcloud.spi; +package com.google.gcloud.resourcemanager.spi; -import static com.google.gcloud.spi.ResourceManagerRpc.Option.FIELDS; -import static com.google.gcloud.spi.ResourceManagerRpc.Option.FILTER; -import static com.google.gcloud.spi.ResourceManagerRpc.Option.PAGE_SIZE; -import static com.google.gcloud.spi.ResourceManagerRpc.Option.PAGE_TOKEN; import static java.net.HttpURLConnection.HTTP_FORBIDDEN; import static java.net.HttpURLConnection.HTTP_NOT_FOUND; @@ -60,7 +56,7 @@ public Project get(String projectId, Map options) { try { return resourceManager.projects() .get(projectId) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { ResourceManagerException translated = translate(ex); @@ -78,10 +74,10 @@ public Tuple> list(Map options) { try { ListProjectsResponse response = resourceManager.projects() .list() - .setFields(FIELDS.getString(options)) - .setFilter(FILTER.getString(options)) - .setPageSize(PAGE_SIZE.getInt(options)) - .setPageToken(PAGE_TOKEN.getString(options)) + .setFields(Option.FIELDS.getString(options)) + .setFilter(Option.FILTER.getString(options)) + .setPageSize(Option.PAGE_SIZE.getInt(options)) + .setPageToken(Option.PAGE_TOKEN.getString(options)) .execute(); return Tuple.>of( response.getNextPageToken(), response.getProjects()); diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/ResourceManagerRpc.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/ResourceManagerRpc.java similarity index 98% rename from gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/ResourceManagerRpc.java rename to gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/ResourceManagerRpc.java index e1d72a6a373e..54531edd5ed5 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/ResourceManagerRpc.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/ResourceManagerRpc.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.spi; +package com.google.gcloud.resourcemanager.spi; import com.google.api.services.cloudresourcemanager.model.Project; import com.google.gcloud.resourcemanager.ResourceManagerException; diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/ResourceManagerRpcFactory.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/ResourceManagerRpcFactory.java similarity index 90% rename from gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/ResourceManagerRpcFactory.java rename to gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/ResourceManagerRpcFactory.java index c2c607c0c205..4dbd1a00d4c7 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/spi/ResourceManagerRpcFactory.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/ResourceManagerRpcFactory.java @@ -14,9 +14,10 @@ * limitations under the License. */ -package com.google.gcloud.spi; +package com.google.gcloud.resourcemanager.spi; import com.google.gcloud.resourcemanager.ResourceManagerOptions; +import com.google.gcloud.spi.ServiceRpcFactory; /** * An interface for Resource Manager RPC factory. diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java index a3418fff98ab..328db315e414 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java @@ -9,9 +9,9 @@ import com.google.common.collect.ImmutableMap; import com.google.gcloud.resourcemanager.testing.LocalResourceManagerHelper; -import com.google.gcloud.spi.DefaultResourceManagerRpc; -import com.google.gcloud.spi.ResourceManagerRpc; -import com.google.gcloud.spi.ResourceManagerRpc.Tuple; +import com.google.gcloud.resourcemanager.spi.DefaultResourceManagerRpc; +import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc; +import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc.Tuple; import org.junit.AfterClass; import org.junit.Before; diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java index 1bc233311a4d..92f5d2a18a0f 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java @@ -31,8 +31,8 @@ import com.google.gcloud.resourcemanager.ResourceManager.ProjectGetOption; import com.google.gcloud.resourcemanager.ResourceManager.ProjectListOption; import com.google.gcloud.resourcemanager.testing.LocalResourceManagerHelper; -import com.google.gcloud.spi.ResourceManagerRpc; -import com.google.gcloud.spi.ResourceManagerRpcFactory; +import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc; +import com.google.gcloud.resourcemanager.spi.ResourceManagerRpcFactory; import org.easymock.EasyMock; import org.junit.AfterClass; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java index 79ad3804faf0..2cd81af5793d 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java @@ -24,8 +24,8 @@ import com.google.common.base.Function; import com.google.gcloud.ReadChannel; import com.google.gcloud.WriteChannel; -import com.google.gcloud.spi.StorageRpc; -import com.google.gcloud.spi.StorageRpc.Tuple; +import com.google.gcloud.storage.spi.StorageRpc; +import com.google.gcloud.storage.spi.StorageRpc.Tuple; import com.google.gcloud.storage.Storage.BlobTargetOption; import com.google.gcloud.storage.Storage.BlobWriteOption; import com.google.gcloud.storage.Storage.CopyRequest; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobReadChannel.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobReadChannel.java index 52b8c39321da..f9c6f912563d 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobReadChannel.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobReadChannel.java @@ -23,8 +23,8 @@ import com.google.gcloud.ReadChannel; import com.google.gcloud.RestorableState; import com.google.gcloud.RetryHelper; -import com.google.gcloud.spi.StorageRpc; -import com.google.gcloud.spi.StorageRpc.Tuple; +import com.google.gcloud.storage.spi.StorageRpc; +import com.google.gcloud.storage.spi.StorageRpc.Tuple; import java.io.IOException; import java.io.Serializable; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobWriteChannel.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobWriteChannel.java index d1d12ec77638..30b0ec870f51 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobWriteChannel.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobWriteChannel.java @@ -23,7 +23,7 @@ import com.google.gcloud.RestorableState; import com.google.gcloud.RetryHelper; import com.google.gcloud.WriteChannel; -import com.google.gcloud.spi.StorageRpc; +import com.google.gcloud.storage.spi.StorageRpc; import java.util.Map; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java index d318626f4207..3cb8af4ef044 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java @@ -26,7 +26,7 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.google.gcloud.Page; -import com.google.gcloud.spi.StorageRpc; +import com.google.gcloud.storage.spi.StorageRpc; import com.google.gcloud.storage.Storage.BlobGetOption; import com.google.gcloud.storage.Storage.BucketTargetOption; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java index 7eb91d0910a2..62b39e005369 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java @@ -22,9 +22,9 @@ import com.google.gcloud.Restorable; import com.google.gcloud.RestorableState; import com.google.gcloud.RetryHelper; -import com.google.gcloud.spi.StorageRpc; -import com.google.gcloud.spi.StorageRpc.RewriteRequest; -import com.google.gcloud.spi.StorageRpc.RewriteResponse; +import com.google.gcloud.storage.spi.StorageRpc; +import com.google.gcloud.storage.spi.StorageRpc.RewriteRequest; +import com.google.gcloud.storage.spi.StorageRpc.RewriteResponse; import java.io.Serializable; import java.util.Map; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Option.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Option.java index 2ec8426bfa9f..65c55da7efc8 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Option.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Option.java @@ -19,7 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.MoreObjects; -import com.google.gcloud.spi.StorageRpc; +import com.google.gcloud.storage.spi.StorageRpc; import java.io.Serializable; import java.util.Objects; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index 0ee18f541284..6b2e9266f24b 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -29,8 +29,8 @@ import com.google.gcloud.ReadChannel; import com.google.gcloud.Service; import com.google.gcloud.WriteChannel; -import com.google.gcloud.spi.StorageRpc; -import com.google.gcloud.spi.StorageRpc.Tuple; +import com.google.gcloud.storage.spi.StorageRpc; +import com.google.gcloud.storage.spi.StorageRpc.Tuple; import java.io.InputStream; import java.io.Serializable; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java index 788072905871..d58c9e43aea9 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java @@ -19,15 +19,15 @@ import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.Preconditions.checkArgument; import static com.google.gcloud.RetryHelper.runWithRetries; -import static com.google.gcloud.spi.StorageRpc.Option.DELIMITER; -import static com.google.gcloud.spi.StorageRpc.Option.IF_GENERATION_MATCH; -import static com.google.gcloud.spi.StorageRpc.Option.IF_GENERATION_NOT_MATCH; -import static com.google.gcloud.spi.StorageRpc.Option.IF_METAGENERATION_MATCH; -import static com.google.gcloud.spi.StorageRpc.Option.IF_METAGENERATION_NOT_MATCH; -import static com.google.gcloud.spi.StorageRpc.Option.IF_SOURCE_GENERATION_MATCH; -import static com.google.gcloud.spi.StorageRpc.Option.IF_SOURCE_GENERATION_NOT_MATCH; -import static com.google.gcloud.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_MATCH; -import static com.google.gcloud.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_NOT_MATCH; +import static com.google.gcloud.storage.spi.StorageRpc.Option.DELIMITER; +import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_GENERATION_MATCH; +import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_GENERATION_NOT_MATCH; +import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_METAGENERATION_MATCH; +import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_METAGENERATION_NOT_MATCH; +import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_SOURCE_GENERATION_MATCH; +import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_SOURCE_GENERATION_NOT_MATCH; +import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_MATCH; +import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_NOT_MATCH; import static java.nio.charset.StandardCharsets.UTF_8; import com.google.api.services.storage.model.StorageObject; @@ -48,9 +48,9 @@ import com.google.gcloud.PageImpl.NextPageFetcher; import com.google.gcloud.ReadChannel; import com.google.gcloud.RetryHelper.RetryHelperException; -import com.google.gcloud.spi.StorageRpc; -import com.google.gcloud.spi.StorageRpc.RewriteResponse; -import com.google.gcloud.spi.StorageRpc.Tuple; +import com.google.gcloud.storage.spi.StorageRpc; +import com.google.gcloud.storage.spi.StorageRpc.RewriteResponse; +import com.google.gcloud.storage.spi.StorageRpc.Tuple; import java.io.ByteArrayInputStream; import java.io.InputStream; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageOptions.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageOptions.java index 86ce18eb71ec..e7e1c2778fa9 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageOptions.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageOptions.java @@ -18,9 +18,9 @@ import com.google.common.collect.ImmutableSet; import com.google.gcloud.ServiceOptions; -import com.google.gcloud.spi.DefaultStorageRpc; -import com.google.gcloud.spi.StorageRpc; -import com.google.gcloud.spi.StorageRpcFactory; +import com.google.gcloud.storage.spi.DefaultStorageRpc; +import com.google.gcloud.storage.spi.StorageRpc; +import com.google.gcloud.storage.spi.StorageRpcFactory; import java.util.Set; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/DefaultStorageRpc.java similarity index 79% rename from gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java rename to gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/DefaultStorageRpc.java index ec4447d406cb..71cd51da1e38 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/DefaultStorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/DefaultStorageRpc.java @@ -12,25 +12,9 @@ * the License. */ -package com.google.gcloud.spi; +package com.google.gcloud.storage.spi; import static com.google.common.base.MoreObjects.firstNonNull; -import static com.google.gcloud.spi.StorageRpc.Option.DELIMITER; -import static com.google.gcloud.spi.StorageRpc.Option.FIELDS; -import static com.google.gcloud.spi.StorageRpc.Option.IF_GENERATION_MATCH; -import static com.google.gcloud.spi.StorageRpc.Option.IF_GENERATION_NOT_MATCH; -import static com.google.gcloud.spi.StorageRpc.Option.IF_METAGENERATION_MATCH; -import static com.google.gcloud.spi.StorageRpc.Option.IF_METAGENERATION_NOT_MATCH; -import static com.google.gcloud.spi.StorageRpc.Option.IF_SOURCE_GENERATION_MATCH; -import static com.google.gcloud.spi.StorageRpc.Option.IF_SOURCE_GENERATION_NOT_MATCH; -import static com.google.gcloud.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_MATCH; -import static com.google.gcloud.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_NOT_MATCH; -import static com.google.gcloud.spi.StorageRpc.Option.MAX_RESULTS; -import static com.google.gcloud.spi.StorageRpc.Option.PAGE_TOKEN; -import static com.google.gcloud.spi.StorageRpc.Option.PREDEFINED_ACL; -import static com.google.gcloud.spi.StorageRpc.Option.PREDEFINED_DEFAULT_OBJECT_ACL; -import static com.google.gcloud.spi.StorageRpc.Option.PREFIX; -import static com.google.gcloud.spi.StorageRpc.Option.VERSIONS; import static java.net.HttpURLConnection.HTTP_NOT_FOUND; import static javax.servlet.http.HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE; @@ -108,8 +92,8 @@ public Bucket create(Bucket bucket, Map options) { return storage.buckets() .insert(this.options.projectId(), bucket) .setProjection(DEFAULT_PROJECTION) - .setPredefinedAcl(PREDEFINED_ACL.getString(options)) - .setPredefinedDefaultObjectAcl(PREDEFINED_DEFAULT_OBJECT_ACL.getString(options)) + .setPredefinedAcl(Option.PREDEFINED_ACL.getString(options)) + .setPredefinedDefaultObjectAcl(Option.PREDEFINED_DEFAULT_OBJECT_ACL.getString(options)) .execute(); } catch (IOException ex) { throw translate(ex); @@ -125,11 +109,11 @@ public StorageObject create(StorageObject storageObject, final InputStream conte new InputStreamContent(storageObject.getContentType(), content)); insert.getMediaHttpUploader().setDirectUploadEnabled(true); return insert.setProjection(DEFAULT_PROJECTION) - .setPredefinedAcl(PREDEFINED_ACL.getString(options)) - .setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options)) - .setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options)) - .setIfGenerationMatch(IF_GENERATION_MATCH.getLong(options)) - .setIfGenerationNotMatch(IF_GENERATION_NOT_MATCH.getLong(options)) + .setPredefinedAcl(Option.PREDEFINED_ACL.getString(options)) + .setIfMetagenerationMatch(Option.IF_METAGENERATION_MATCH.getLong(options)) + .setIfMetagenerationNotMatch(Option.IF_METAGENERATION_NOT_MATCH.getLong(options)) + .setIfGenerationMatch(Option.IF_GENERATION_MATCH.getLong(options)) + .setIfGenerationNotMatch(Option.IF_GENERATION_NOT_MATCH.getLong(options)) .execute(); } catch (IOException ex) { throw translate(ex); @@ -142,10 +126,10 @@ public Tuple> list(Map options) { Buckets buckets = storage.buckets() .list(this.options.projectId()) .setProjection(DEFAULT_PROJECTION) - .setPrefix(PREFIX.getString(options)) - .setMaxResults(MAX_RESULTS.getLong(options)) - .setPageToken(PAGE_TOKEN.getString(options)) - .setFields(FIELDS.getString(options)) + .setPrefix(Option.PREFIX.getString(options)) + .setMaxResults(Option.MAX_RESULTS.getLong(options)) + .setPageToken(Option.PAGE_TOKEN.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); return Tuple.>of(buckets.getNextPageToken(), buckets.getItems()); } catch (IOException ex) { @@ -159,12 +143,12 @@ public Tuple> list(final String bucket, Map storageObjects = Iterables.concat( firstNonNull(objects.getItems(), ImmutableList.of()), @@ -196,9 +180,9 @@ public Bucket get(Bucket bucket, Map options) { return storage.buckets() .get(bucket.getName()) .setProjection(DEFAULT_PROJECTION) - .setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options)) - .setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options)) - .setFields(FIELDS.getString(options)) + .setIfMetagenerationMatch(Option.IF_METAGENERATION_MATCH.getLong(options)) + .setIfMetagenerationNotMatch(Option.IF_METAGENERATION_NOT_MATCH.getLong(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { StorageException serviceException = translate(ex); @@ -228,11 +212,11 @@ private Storage.Objects.Get getRequest(StorageObject object, Map opti .get(object.getBucket(), object.getName()) .setGeneration(object.getGeneration()) .setProjection(DEFAULT_PROJECTION) - .setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options)) - .setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options)) - .setIfGenerationMatch(IF_GENERATION_MATCH.getLong(options)) - .setIfGenerationNotMatch(IF_GENERATION_NOT_MATCH.getLong(options)) - .setFields(FIELDS.getString(options)); + .setIfMetagenerationMatch(Option.IF_METAGENERATION_MATCH.getLong(options)) + .setIfMetagenerationNotMatch(Option.IF_METAGENERATION_NOT_MATCH.getLong(options)) + .setIfGenerationMatch(Option.IF_GENERATION_MATCH.getLong(options)) + .setIfGenerationNotMatch(Option.IF_GENERATION_NOT_MATCH.getLong(options)) + .setFields(Option.FIELDS.getString(options)); } @Override @@ -241,10 +225,10 @@ public Bucket patch(Bucket bucket, Map options) { return storage.buckets() .patch(bucket.getName(), bucket) .setProjection(DEFAULT_PROJECTION) - .setPredefinedAcl(PREDEFINED_ACL.getString(options)) - .setPredefinedDefaultObjectAcl(PREDEFINED_DEFAULT_OBJECT_ACL.getString(options)) - .setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options)) - .setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options)) + .setPredefinedAcl(Option.PREDEFINED_ACL.getString(options)) + .setPredefinedDefaultObjectAcl(Option.PREDEFINED_DEFAULT_OBJECT_ACL.getString(options)) + .setIfMetagenerationMatch(Option.IF_METAGENERATION_MATCH.getLong(options)) + .setIfMetagenerationNotMatch(Option.IF_METAGENERATION_NOT_MATCH.getLong(options)) .execute(); } catch (IOException ex) { throw translate(ex); @@ -265,11 +249,11 @@ private Storage.Objects.Patch patchRequest(StorageObject storageObject, Map options) { try { storage.buckets() .delete(bucket.getName()) - .setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options)) - .setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options)) + .setIfMetagenerationMatch(Option.IF_METAGENERATION_MATCH.getLong(options)) + .setIfMetagenerationNotMatch(Option.IF_METAGENERATION_NOT_MATCH.getLong(options)) .execute(); return true; } catch (IOException ex) { @@ -309,10 +293,10 @@ private Storage.Objects.Delete deleteRequest(StorageObject blob, Map return storage.objects() .delete(blob.getBucket(), blob.getName()) .setGeneration(blob.getGeneration()) - .setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options)) - .setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options)) - .setIfGenerationMatch(IF_GENERATION_MATCH.getLong(options)) - .setIfGenerationNotMatch(IF_GENERATION_NOT_MATCH.getLong(options)); + .setIfMetagenerationMatch(Option.IF_METAGENERATION_MATCH.getLong(options)) + .setIfMetagenerationNotMatch(Option.IF_METAGENERATION_NOT_MATCH.getLong(options)) + .setIfGenerationMatch(Option.IF_GENERATION_MATCH.getLong(options)) + .setIfGenerationNotMatch(Option.IF_GENERATION_NOT_MATCH.getLong(options)); } @Override @@ -339,8 +323,8 @@ public StorageObject compose(Iterable sources, StorageObject targ try { return storage.objects() .compose(target.getBucket(), target.getName(), request) - .setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(targetOptions)) - .setIfGenerationMatch(IF_GENERATION_MATCH.getLong(targetOptions)) + .setIfMetagenerationMatch(Option.IF_METAGENERATION_MATCH.getLong(targetOptions)) + .setIfGenerationMatch(Option.IF_GENERATION_MATCH.getLong(targetOptions)) .execute(); } catch (IOException ex) { throw translate(ex); @@ -353,10 +337,10 @@ public byte[] load(StorageObject from, Map options) { Storage.Objects.Get getRequest = storage.objects() .get(from.getBucket(), from.getName()) .setGeneration(from.getGeneration()) - .setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options)) - .setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options)) - .setIfGenerationMatch(IF_GENERATION_MATCH.getLong(options)) - .setIfGenerationNotMatch(IF_GENERATION_NOT_MATCH.getLong(options)); + .setIfMetagenerationMatch(Option.IF_METAGENERATION_MATCH.getLong(options)) + .setIfMetagenerationNotMatch(Option.IF_METAGENERATION_NOT_MATCH.getLong(options)) + .setIfGenerationMatch(Option.IF_GENERATION_MATCH.getLong(options)) + .setIfGenerationNotMatch(Option.IF_GENERATION_NOT_MATCH.getLong(options)); ByteArrayOutputStream out = new ByteArrayOutputStream(); getRequest.getMediaHttpDownloader().setDirectDownloadEnabled(true); getRequest.executeMediaAndDownloadTo(out); @@ -462,10 +446,10 @@ public Tuple read(StorageObject from, Map options, lo Get req = storage.objects() .get(from.getBucket(), from.getName()) .setGeneration(from.getGeneration()) - .setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options)) - .setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options)) - .setIfGenerationMatch(IF_GENERATION_MATCH.getLong(options)) - .setIfGenerationNotMatch(IF_GENERATION_NOT_MATCH.getLong(options)); + .setIfMetagenerationMatch(Option.IF_METAGENERATION_MATCH.getLong(options)) + .setIfMetagenerationNotMatch(Option.IF_METAGENERATION_NOT_MATCH.getLong(options)) + .setIfGenerationMatch(Option.IF_GENERATION_MATCH.getLong(options)) + .setIfGenerationNotMatch(Option.IF_GENERATION_NOT_MATCH.getLong(options)); StringBuilder range = new StringBuilder(); range.append("bytes=").append(position).append("-").append(position + bytes - 1); req.getRequestHeaders().setRange(range.toString()); @@ -589,15 +573,15 @@ private RewriteResponse rewrite(RewriteRequest req, String token) { .setRewriteToken(token) .setMaxBytesRewrittenPerCall(maxBytesRewrittenPerCall) .setProjection(DEFAULT_PROJECTION) - .setIfSourceMetagenerationMatch(IF_SOURCE_METAGENERATION_MATCH.getLong(req.sourceOptions)) + .setIfSourceMetagenerationMatch(Option.IF_SOURCE_METAGENERATION_MATCH.getLong(req.sourceOptions)) .setIfSourceMetagenerationNotMatch( - IF_SOURCE_METAGENERATION_NOT_MATCH.getLong(req.sourceOptions)) - .setIfSourceGenerationMatch(IF_SOURCE_GENERATION_MATCH.getLong(req.sourceOptions)) - .setIfSourceGenerationNotMatch(IF_SOURCE_GENERATION_NOT_MATCH.getLong(req.sourceOptions)) - .setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(req.targetOptions)) - .setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(req.targetOptions)) - .setIfGenerationMatch(IF_GENERATION_MATCH.getLong(req.targetOptions)) - .setIfGenerationNotMatch(IF_GENERATION_NOT_MATCH.getLong(req.targetOptions)) + Option.IF_SOURCE_METAGENERATION_NOT_MATCH.getLong(req.sourceOptions)) + .setIfSourceGenerationMatch(Option.IF_SOURCE_GENERATION_MATCH.getLong(req.sourceOptions)) + .setIfSourceGenerationNotMatch(Option.IF_SOURCE_GENERATION_NOT_MATCH.getLong(req.sourceOptions)) + .setIfMetagenerationMatch(Option.IF_METAGENERATION_MATCH.getLong(req.targetOptions)) + .setIfMetagenerationNotMatch(Option.IF_METAGENERATION_NOT_MATCH.getLong(req.targetOptions)) + .setIfGenerationMatch(Option.IF_GENERATION_MATCH.getLong(req.targetOptions)) + .setIfGenerationNotMatch(Option.IF_GENERATION_NOT_MATCH.getLong(req.targetOptions)) .execute(); return new RewriteResponse( req, diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/StorageRpc.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/StorageRpc.java similarity index 99% rename from gcloud-java-storage/src/main/java/com/google/gcloud/spi/StorageRpc.java rename to gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/StorageRpc.java index ab4a7a9d0acb..d239a475a6dd 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/StorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/StorageRpc.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.spi; +package com.google.gcloud.storage.spi; import static com.google.common.base.MoreObjects.firstNonNull; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/StorageRpcFactory.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/StorageRpcFactory.java similarity index 91% rename from gcloud-java-storage/src/main/java/com/google/gcloud/spi/StorageRpcFactory.java rename to gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/StorageRpcFactory.java index f4959d617d17..19b98e6273db 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/spi/StorageRpcFactory.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/StorageRpcFactory.java @@ -14,8 +14,9 @@ * limitations under the License. */ -package com.google.gcloud.spi; +package com.google.gcloud.storage.spi; +import com.google.gcloud.spi.ServiceRpcFactory; import com.google.gcloud.storage.StorageOptions; /** diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobReadChannelTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobReadChannelTest.java index 5dc947df51f8..1b0f36a864a2 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobReadChannelTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobReadChannelTest.java @@ -30,8 +30,8 @@ import com.google.gcloud.ReadChannel; import com.google.gcloud.RestorableState; import com.google.gcloud.RetryParams; -import com.google.gcloud.spi.StorageRpc; -import com.google.gcloud.spi.StorageRpcFactory; +import com.google.gcloud.storage.spi.StorageRpc; +import com.google.gcloud.storage.spi.StorageRpcFactory; import org.junit.After; import org.junit.Before; diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobWriteChannelTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobWriteChannelTest.java index e499f6b9de52..18ec64a9575f 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobWriteChannelTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobWriteChannelTest.java @@ -34,8 +34,8 @@ import com.google.gcloud.RestorableState; import com.google.gcloud.RetryParams; import com.google.gcloud.WriteChannel; -import com.google.gcloud.spi.StorageRpc; -import com.google.gcloud.spi.StorageRpcFactory; +import com.google.gcloud.storage.spi.StorageRpc; +import com.google.gcloud.storage.spi.StorageRpcFactory; import org.easymock.Capture; import org.easymock.CaptureType; diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyWriterTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyWriterTest.java index 1b1ffd987de6..ad4a04c34127 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyWriterTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyWriterTest.java @@ -27,10 +27,10 @@ import com.google.common.collect.ImmutableMap; import com.google.gcloud.RestorableState; import com.google.gcloud.RetryParams; -import com.google.gcloud.spi.StorageRpc; -import com.google.gcloud.spi.StorageRpc.RewriteRequest; -import com.google.gcloud.spi.StorageRpc.RewriteResponse; -import com.google.gcloud.spi.StorageRpcFactory; +import com.google.gcloud.storage.spi.StorageRpc; +import com.google.gcloud.storage.spi.StorageRpc.RewriteRequest; +import com.google.gcloud.storage.spi.StorageRpc.RewriteResponse; +import com.google.gcloud.storage.spi.StorageRpcFactory; import org.easymock.EasyMock; import org.junit.After; diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/OptionTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/OptionTest.java index 2703ddb401c5..5924174ab138 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/OptionTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/OptionTest.java @@ -18,7 +18,7 @@ import static org.junit.Assert.assertEquals; -import com.google.gcloud.spi.StorageRpc; +import com.google.gcloud.storage.spi.StorageRpc; import org.junit.Test; diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java index ac096375b120..7894f8fdee3c 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java @@ -26,7 +26,7 @@ import com.google.gcloud.RestorableState; import com.google.gcloud.RetryParams; import com.google.gcloud.WriteChannel; -import com.google.gcloud.spi.StorageRpc; +import com.google.gcloud.storage.spi.StorageRpc; import com.google.gcloud.storage.Acl.Project.ProjectRole; import org.junit.Test; diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java index 4050e7d6267b..428f770ae381 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java @@ -37,9 +37,9 @@ import com.google.gcloud.RetryParams; import com.google.gcloud.ServiceOptions; import com.google.gcloud.WriteChannel; -import com.google.gcloud.spi.StorageRpc; -import com.google.gcloud.spi.StorageRpc.Tuple; -import com.google.gcloud.spi.StorageRpcFactory; +import com.google.gcloud.storage.spi.StorageRpc; +import com.google.gcloud.storage.spi.StorageRpc.Tuple; +import com.google.gcloud.storage.spi.StorageRpcFactory; import com.google.gcloud.storage.Storage.CopyRequest; import org.easymock.Capture; From fd7d84d59c7dbff375268d07570dd46a45d4b2a0 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 10 Mar 2016 23:02:32 +0100 Subject: [PATCH 156/375] Reorder and add imports --- .../bigquery/spi/DefaultBigQueryRpc.java | 12 +- .../datastore/DatastoreOptionsTest.java | 2 +- .../gcloud/datastore/DatastoreTest.java | 2 +- .../examples/storage/StorageExample.java | 2 +- .../spi/DefaultResourceManagerRpc.java | 14 +- .../LocalResourceManagerHelperTest.java | 2 +- .../ResourceManagerImplTest.java | 2 +- .../java/com/google/gcloud/storage/Blob.java | 4 +- .../com/google/gcloud/storage/Bucket.java | 2 +- .../gcloud/storage/spi/DefaultStorageRpc.java | 132 ++++++++++-------- .../gcloud/storage/SerializationTest.java | 2 +- .../gcloud/storage/StorageImplTest.java | 2 +- 12 files changed, 101 insertions(+), 77 deletions(-) diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/spi/DefaultBigQueryRpc.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/spi/DefaultBigQueryRpc.java index f73517086a02..71712bda7806 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/spi/DefaultBigQueryRpc.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/spi/DefaultBigQueryRpc.java @@ -14,11 +14,14 @@ package com.google.gcloud.bigquery.spi; +import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.ALL_DATASETS; +import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.ALL_USERS; import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.DELETE_CONTENTS; import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.FIELDS; import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.MAX_RESULTS; import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.PAGE_TOKEN; import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.START_INDEX; +import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.STATE_FILTER; import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.TIMEOUT; import static java.net.HttpURLConnection.HTTP_CREATED; import static java.net.HttpURLConnection.HTTP_NOT_FOUND; @@ -110,9 +113,10 @@ public Tuple> listDatasets(Map options) { try { DatasetList datasetsList = bigquery.datasets() .list(this.options.projectId()) - .setAll(Option.ALL_DATASETS.getBoolean(options)) + .setAll(ALL_DATASETS.getBoolean(options)) .setMaxResults(MAX_RESULTS.getLong(options)) .setPageToken(PAGE_TOKEN.getString(options)) + .setPageToken(PAGE_TOKEN.getString(options)) .execute(); Iterable datasets = datasetsList.getDatasets(); return Tuple.of(datasetsList.getNextPageToken(), @@ -322,9 +326,9 @@ public Tuple> listJobs(Map options) { try { JobList jobsList = bigquery.jobs() .list(this.options.projectId()) - .setAllUsers(Option.ALL_USERS.getBoolean(options)) - .setFields(Option.FIELDS.getString(options)) - .setStateFilter(Option.STATE_FILTER.>get(options)) + .setAllUsers(ALL_USERS.getBoolean(options)) + .setFields(FIELDS.getString(options)) + .setStateFilter(STATE_FILTER.>get(options)) .setMaxResults(MAX_RESULTS.getLong(options)) .setPageToken(PAGE_TOKEN.getString(options)) .setProjection(DEFAULT_PROJECTION) diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java index b0d6e8d7800b..1d188c7f4e94 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java @@ -22,9 +22,9 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; -import com.google.gcloud.datastore.testing.LocalGcdHelper; import com.google.gcloud.datastore.spi.DatastoreRpc; import com.google.gcloud.datastore.spi.DatastoreRpcFactory; +import com.google.gcloud.datastore.testing.LocalGcdHelper; import org.easymock.EasyMock; import org.junit.Before; diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index 1886c67e22a8..e3829a2e71ce 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -38,9 +38,9 @@ import com.google.gcloud.datastore.StructuredQuery.OrderBy; import com.google.gcloud.datastore.StructuredQuery.Projection; import com.google.gcloud.datastore.StructuredQuery.PropertyFilter; -import com.google.gcloud.datastore.testing.LocalGcdHelper; import com.google.gcloud.datastore.spi.DatastoreRpc; import com.google.gcloud.datastore.spi.DatastoreRpcFactory; +import com.google.gcloud.datastore.testing.LocalGcdHelper; import com.google.protobuf.ByteString; import org.easymock.EasyMock; diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java index a10b5ef71817..a7260134202d 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java @@ -20,7 +20,6 @@ import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials; import com.google.gcloud.ReadChannel; import com.google.gcloud.WriteChannel; -import com.google.gcloud.storage.spi.StorageRpc.Tuple; import com.google.gcloud.storage.Blob; import com.google.gcloud.storage.BlobId; import com.google.gcloud.storage.BlobInfo; @@ -31,6 +30,7 @@ import com.google.gcloud.storage.Storage.CopyRequest; import com.google.gcloud.storage.Storage.SignUrlOption; import com.google.gcloud.storage.StorageOptions; +import com.google.gcloud.storage.spi.StorageRpc.Tuple; import java.io.FileOutputStream; import java.io.IOException; diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/DefaultResourceManagerRpc.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/DefaultResourceManagerRpc.java index 19e40698a847..2ef0d8c65ff2 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/DefaultResourceManagerRpc.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/DefaultResourceManagerRpc.java @@ -1,5 +1,9 @@ package com.google.gcloud.resourcemanager.spi; +import static com.google.gcloud.resourcemanager.spi.ResourceManagerRpc.Option.FIELDS; +import static com.google.gcloud.resourcemanager.spi.ResourceManagerRpc.Option.FILTER; +import static com.google.gcloud.resourcemanager.spi.ResourceManagerRpc.Option.PAGE_SIZE; +import static com.google.gcloud.resourcemanager.spi.ResourceManagerRpc.Option.PAGE_TOKEN; import static java.net.HttpURLConnection.HTTP_FORBIDDEN; import static java.net.HttpURLConnection.HTTP_NOT_FOUND; @@ -56,7 +60,7 @@ public Project get(String projectId, Map options) { try { return resourceManager.projects() .get(projectId) - .setFields(Option.FIELDS.getString(options)) + .setFields(FIELDS.getString(options)) .execute(); } catch (IOException ex) { ResourceManagerException translated = translate(ex); @@ -74,10 +78,10 @@ public Tuple> list(Map options) { try { ListProjectsResponse response = resourceManager.projects() .list() - .setFields(Option.FIELDS.getString(options)) - .setFilter(Option.FILTER.getString(options)) - .setPageSize(Option.PAGE_SIZE.getInt(options)) - .setPageToken(Option.PAGE_TOKEN.getString(options)) + .setFields(FIELDS.getString(options)) + .setFilter(FILTER.getString(options)) + .setPageSize(PAGE_SIZE.getInt(options)) + .setPageToken(PAGE_TOKEN.getString(options)) .execute(); return Tuple.>of( response.getNextPageToken(), response.getProjects()); diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java index 328db315e414..c9b2970a4efa 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java @@ -8,10 +8,10 @@ import static org.junit.Assert.fail; import com.google.common.collect.ImmutableMap; -import com.google.gcloud.resourcemanager.testing.LocalResourceManagerHelper; import com.google.gcloud.resourcemanager.spi.DefaultResourceManagerRpc; import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc; import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc.Tuple; +import com.google.gcloud.resourcemanager.testing.LocalResourceManagerHelper; import org.junit.AfterClass; import org.junit.Before; diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java index 92f5d2a18a0f..5b172d6a070e 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java @@ -30,9 +30,9 @@ import com.google.gcloud.resourcemanager.ResourceManager.ProjectField; import com.google.gcloud.resourcemanager.ResourceManager.ProjectGetOption; import com.google.gcloud.resourcemanager.ResourceManager.ProjectListOption; -import com.google.gcloud.resourcemanager.testing.LocalResourceManagerHelper; import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc; import com.google.gcloud.resourcemanager.spi.ResourceManagerRpcFactory; +import com.google.gcloud.resourcemanager.testing.LocalResourceManagerHelper; import org.easymock.EasyMock; import org.junit.AfterClass; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java index 2cd81af5793d..4c8e935f7071 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java @@ -24,12 +24,12 @@ import com.google.common.base.Function; import com.google.gcloud.ReadChannel; import com.google.gcloud.WriteChannel; -import com.google.gcloud.storage.spi.StorageRpc; -import com.google.gcloud.storage.spi.StorageRpc.Tuple; import com.google.gcloud.storage.Storage.BlobTargetOption; import com.google.gcloud.storage.Storage.BlobWriteOption; import com.google.gcloud.storage.Storage.CopyRequest; import com.google.gcloud.storage.Storage.SignUrlOption; +import com.google.gcloud.storage.spi.StorageRpc; +import com.google.gcloud.storage.spi.StorageRpc.Tuple; import java.io.IOException; import java.io.ObjectInputStream; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java index 3cb8af4ef044..5df305ff371c 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java @@ -26,9 +26,9 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.google.gcloud.Page; -import com.google.gcloud.storage.spi.StorageRpc; import com.google.gcloud.storage.Storage.BlobGetOption; import com.google.gcloud.storage.Storage.BucketTargetOption; +import com.google.gcloud.storage.spi.StorageRpc; import java.io.IOException; import java.io.InputStream; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/DefaultStorageRpc.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/DefaultStorageRpc.java index 71cd51da1e38..aa6085e161ed 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/DefaultStorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/DefaultStorageRpc.java @@ -15,6 +15,22 @@ package com.google.gcloud.storage.spi; import static com.google.common.base.MoreObjects.firstNonNull; +import static com.google.gcloud.storage.spi.StorageRpc.Option.DELIMITER; +import static com.google.gcloud.storage.spi.StorageRpc.Option.FIELDS; +import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_GENERATION_MATCH; +import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_GENERATION_NOT_MATCH; +import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_METAGENERATION_MATCH; +import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_METAGENERATION_NOT_MATCH; +import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_SOURCE_GENERATION_MATCH; +import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_SOURCE_GENERATION_NOT_MATCH; +import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_MATCH; +import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_NOT_MATCH; +import static com.google.gcloud.storage.spi.StorageRpc.Option.MAX_RESULTS; +import static com.google.gcloud.storage.spi.StorageRpc.Option.PAGE_TOKEN; +import static com.google.gcloud.storage.spi.StorageRpc.Option.PREDEFINED_ACL; +import static com.google.gcloud.storage.spi.StorageRpc.Option.PREDEFINED_DEFAULT_OBJECT_ACL; +import static com.google.gcloud.storage.spi.StorageRpc.Option.PREFIX; +import static com.google.gcloud.storage.spi.StorageRpc.Option.VERSIONS; import static java.net.HttpURLConnection.HTTP_NOT_FOUND; import static javax.servlet.http.HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE; @@ -92,8 +108,8 @@ public Bucket create(Bucket bucket, Map options) { return storage.buckets() .insert(this.options.projectId(), bucket) .setProjection(DEFAULT_PROJECTION) - .setPredefinedAcl(Option.PREDEFINED_ACL.getString(options)) - .setPredefinedDefaultObjectAcl(Option.PREDEFINED_DEFAULT_OBJECT_ACL.getString(options)) + .setPredefinedAcl(PREDEFINED_ACL.getString(options)) + .setPredefinedDefaultObjectAcl(PREDEFINED_DEFAULT_OBJECT_ACL.getString(options)) .execute(); } catch (IOException ex) { throw translate(ex); @@ -109,11 +125,11 @@ public StorageObject create(StorageObject storageObject, final InputStream conte new InputStreamContent(storageObject.getContentType(), content)); insert.getMediaHttpUploader().setDirectUploadEnabled(true); return insert.setProjection(DEFAULT_PROJECTION) - .setPredefinedAcl(Option.PREDEFINED_ACL.getString(options)) - .setIfMetagenerationMatch(Option.IF_METAGENERATION_MATCH.getLong(options)) - .setIfMetagenerationNotMatch(Option.IF_METAGENERATION_NOT_MATCH.getLong(options)) - .setIfGenerationMatch(Option.IF_GENERATION_MATCH.getLong(options)) - .setIfGenerationNotMatch(Option.IF_GENERATION_NOT_MATCH.getLong(options)) + .setPredefinedAcl(PREDEFINED_ACL.getString(options)) + .setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options)) + .setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options)) + .setIfGenerationMatch(IF_GENERATION_MATCH.getLong(options)) + .setIfGenerationNotMatch(IF_GENERATION_NOT_MATCH.getLong(options)) .execute(); } catch (IOException ex) { throw translate(ex); @@ -126,10 +142,10 @@ public Tuple> list(Map options) { Buckets buckets = storage.buckets() .list(this.options.projectId()) .setProjection(DEFAULT_PROJECTION) - .setPrefix(Option.PREFIX.getString(options)) - .setMaxResults(Option.MAX_RESULTS.getLong(options)) - .setPageToken(Option.PAGE_TOKEN.getString(options)) - .setFields(Option.FIELDS.getString(options)) + .setPrefix(PREFIX.getString(options)) + .setMaxResults(MAX_RESULTS.getLong(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + .setFields(FIELDS.getString(options)) .execute(); return Tuple.>of(buckets.getNextPageToken(), buckets.getItems()); } catch (IOException ex) { @@ -143,12 +159,12 @@ public Tuple> list(final String bucket, Map storageObjects = Iterables.concat( firstNonNull(objects.getItems(), ImmutableList.of()), @@ -180,9 +196,9 @@ public Bucket get(Bucket bucket, Map options) { return storage.buckets() .get(bucket.getName()) .setProjection(DEFAULT_PROJECTION) - .setIfMetagenerationMatch(Option.IF_METAGENERATION_MATCH.getLong(options)) - .setIfMetagenerationNotMatch(Option.IF_METAGENERATION_NOT_MATCH.getLong(options)) - .setFields(Option.FIELDS.getString(options)) + .setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options)) + .setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options)) + .setFields(FIELDS.getString(options)) .execute(); } catch (IOException ex) { StorageException serviceException = translate(ex); @@ -212,11 +228,11 @@ private Storage.Objects.Get getRequest(StorageObject object, Map opti .get(object.getBucket(), object.getName()) .setGeneration(object.getGeneration()) .setProjection(DEFAULT_PROJECTION) - .setIfMetagenerationMatch(Option.IF_METAGENERATION_MATCH.getLong(options)) - .setIfMetagenerationNotMatch(Option.IF_METAGENERATION_NOT_MATCH.getLong(options)) - .setIfGenerationMatch(Option.IF_GENERATION_MATCH.getLong(options)) - .setIfGenerationNotMatch(Option.IF_GENERATION_NOT_MATCH.getLong(options)) - .setFields(Option.FIELDS.getString(options)); + .setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options)) + .setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options)) + .setIfGenerationMatch(IF_GENERATION_MATCH.getLong(options)) + .setIfGenerationNotMatch(IF_GENERATION_NOT_MATCH.getLong(options)) + .setFields(FIELDS.getString(options)); } @Override @@ -225,10 +241,10 @@ public Bucket patch(Bucket bucket, Map options) { return storage.buckets() .patch(bucket.getName(), bucket) .setProjection(DEFAULT_PROJECTION) - .setPredefinedAcl(Option.PREDEFINED_ACL.getString(options)) - .setPredefinedDefaultObjectAcl(Option.PREDEFINED_DEFAULT_OBJECT_ACL.getString(options)) - .setIfMetagenerationMatch(Option.IF_METAGENERATION_MATCH.getLong(options)) - .setIfMetagenerationNotMatch(Option.IF_METAGENERATION_NOT_MATCH.getLong(options)) + .setPredefinedAcl(PREDEFINED_ACL.getString(options)) + .setPredefinedDefaultObjectAcl(PREDEFINED_DEFAULT_OBJECT_ACL.getString(options)) + .setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options)) + .setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options)) .execute(); } catch (IOException ex) { throw translate(ex); @@ -249,11 +265,11 @@ private Storage.Objects.Patch patchRequest(StorageObject storageObject, Map options) { try { storage.buckets() .delete(bucket.getName()) - .setIfMetagenerationMatch(Option.IF_METAGENERATION_MATCH.getLong(options)) - .setIfMetagenerationNotMatch(Option.IF_METAGENERATION_NOT_MATCH.getLong(options)) + .setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options)) + .setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options)) .execute(); return true; } catch (IOException ex) { @@ -293,10 +309,10 @@ private Storage.Objects.Delete deleteRequest(StorageObject blob, Map return storage.objects() .delete(blob.getBucket(), blob.getName()) .setGeneration(blob.getGeneration()) - .setIfMetagenerationMatch(Option.IF_METAGENERATION_MATCH.getLong(options)) - .setIfMetagenerationNotMatch(Option.IF_METAGENERATION_NOT_MATCH.getLong(options)) - .setIfGenerationMatch(Option.IF_GENERATION_MATCH.getLong(options)) - .setIfGenerationNotMatch(Option.IF_GENERATION_NOT_MATCH.getLong(options)); + .setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options)) + .setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options)) + .setIfGenerationMatch(IF_GENERATION_MATCH.getLong(options)) + .setIfGenerationNotMatch(IF_GENERATION_NOT_MATCH.getLong(options)); } @Override @@ -323,8 +339,8 @@ public StorageObject compose(Iterable sources, StorageObject targ try { return storage.objects() .compose(target.getBucket(), target.getName(), request) - .setIfMetagenerationMatch(Option.IF_METAGENERATION_MATCH.getLong(targetOptions)) - .setIfGenerationMatch(Option.IF_GENERATION_MATCH.getLong(targetOptions)) + .setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(targetOptions)) + .setIfGenerationMatch(IF_GENERATION_MATCH.getLong(targetOptions)) .execute(); } catch (IOException ex) { throw translate(ex); @@ -337,10 +353,10 @@ public byte[] load(StorageObject from, Map options) { Storage.Objects.Get getRequest = storage.objects() .get(from.getBucket(), from.getName()) .setGeneration(from.getGeneration()) - .setIfMetagenerationMatch(Option.IF_METAGENERATION_MATCH.getLong(options)) - .setIfMetagenerationNotMatch(Option.IF_METAGENERATION_NOT_MATCH.getLong(options)) - .setIfGenerationMatch(Option.IF_GENERATION_MATCH.getLong(options)) - .setIfGenerationNotMatch(Option.IF_GENERATION_NOT_MATCH.getLong(options)); + .setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options)) + .setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options)) + .setIfGenerationMatch(IF_GENERATION_MATCH.getLong(options)) + .setIfGenerationNotMatch(IF_GENERATION_NOT_MATCH.getLong(options)); ByteArrayOutputStream out = new ByteArrayOutputStream(); getRequest.getMediaHttpDownloader().setDirectDownloadEnabled(true); getRequest.executeMediaAndDownloadTo(out); @@ -446,10 +462,10 @@ public Tuple read(StorageObject from, Map options, lo Get req = storage.objects() .get(from.getBucket(), from.getName()) .setGeneration(from.getGeneration()) - .setIfMetagenerationMatch(Option.IF_METAGENERATION_MATCH.getLong(options)) - .setIfMetagenerationNotMatch(Option.IF_METAGENERATION_NOT_MATCH.getLong(options)) - .setIfGenerationMatch(Option.IF_GENERATION_MATCH.getLong(options)) - .setIfGenerationNotMatch(Option.IF_GENERATION_NOT_MATCH.getLong(options)); + .setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options)) + .setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options)) + .setIfGenerationMatch(IF_GENERATION_MATCH.getLong(options)) + .setIfGenerationNotMatch(IF_GENERATION_NOT_MATCH.getLong(options)); StringBuilder range = new StringBuilder(); range.append("bytes=").append(position).append("-").append(position + bytes - 1); req.getRequestHeaders().setRange(range.toString()); @@ -573,15 +589,15 @@ private RewriteResponse rewrite(RewriteRequest req, String token) { .setRewriteToken(token) .setMaxBytesRewrittenPerCall(maxBytesRewrittenPerCall) .setProjection(DEFAULT_PROJECTION) - .setIfSourceMetagenerationMatch(Option.IF_SOURCE_METAGENERATION_MATCH.getLong(req.sourceOptions)) + .setIfSourceMetagenerationMatch(IF_SOURCE_METAGENERATION_MATCH.getLong(req.sourceOptions)) .setIfSourceMetagenerationNotMatch( - Option.IF_SOURCE_METAGENERATION_NOT_MATCH.getLong(req.sourceOptions)) - .setIfSourceGenerationMatch(Option.IF_SOURCE_GENERATION_MATCH.getLong(req.sourceOptions)) - .setIfSourceGenerationNotMatch(Option.IF_SOURCE_GENERATION_NOT_MATCH.getLong(req.sourceOptions)) - .setIfMetagenerationMatch(Option.IF_METAGENERATION_MATCH.getLong(req.targetOptions)) - .setIfMetagenerationNotMatch(Option.IF_METAGENERATION_NOT_MATCH.getLong(req.targetOptions)) - .setIfGenerationMatch(Option.IF_GENERATION_MATCH.getLong(req.targetOptions)) - .setIfGenerationNotMatch(Option.IF_GENERATION_NOT_MATCH.getLong(req.targetOptions)) + IF_SOURCE_METAGENERATION_NOT_MATCH.getLong(req.sourceOptions)) + .setIfSourceGenerationMatch(IF_SOURCE_GENERATION_MATCH.getLong(req.sourceOptions)) + .setIfSourceGenerationNotMatch(IF_SOURCE_GENERATION_NOT_MATCH.getLong(req.sourceOptions)) + .setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(req.targetOptions)) + .setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(req.targetOptions)) + .setIfGenerationMatch(IF_GENERATION_MATCH.getLong(req.targetOptions)) + .setIfGenerationNotMatch(IF_GENERATION_NOT_MATCH.getLong(req.targetOptions)) .execute(); return new RewriteResponse( req, diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java index 7894f8fdee3c..ad13b14ae4e2 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java @@ -26,8 +26,8 @@ import com.google.gcloud.RestorableState; import com.google.gcloud.RetryParams; import com.google.gcloud.WriteChannel; -import com.google.gcloud.storage.spi.StorageRpc; import com.google.gcloud.storage.Acl.Project.ProjectRole; +import com.google.gcloud.storage.spi.StorageRpc; import org.junit.Test; diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java index 428f770ae381..9a306b2b03c6 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java @@ -37,10 +37,10 @@ import com.google.gcloud.RetryParams; import com.google.gcloud.ServiceOptions; import com.google.gcloud.WriteChannel; +import com.google.gcloud.storage.Storage.CopyRequest; import com.google.gcloud.storage.spi.StorageRpc; import com.google.gcloud.storage.spi.StorageRpc.Tuple; import com.google.gcloud.storage.spi.StorageRpcFactory; -import com.google.gcloud.storage.Storage.CopyRequest; import org.easymock.Capture; import org.easymock.EasyMock; From a595f6a0db96e2c9d146a594021ba4d7eda43aff Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 10 Mar 2016 16:36:26 +0100 Subject: [PATCH 157/375] Use groups to separate packages in javadoc's index --- .../java/com/google/gcloud/package-info.java | 20 +++++++++++++++++++ pom.xml | 14 +++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 gcloud-java-core/src/main/java/com/google/gcloud/package-info.java diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/package-info.java b/gcloud-java-core/src/main/java/com/google/gcloud/package-info.java new file mode 100644 index 000000000000..215264675dc2 --- /dev/null +++ b/gcloud-java-core/src/main/java/com/google/gcloud/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +/** + * Core classes for the {@code gcloud-java} library. + */ +package com.google.gcloud; \ No newline at end of file diff --git a/pom.xml b/pom.xml index b9d979c4d467..b6e8d3470edb 100644 --- a/pom.xml +++ b/pom.xml @@ -389,6 +389,20 @@ protected true ${project.build.directory}/javadoc + + + Main packages + com.google.gcloud* + + + SPI packages + com.google.gcloud.spi + + + Example packages + com.google.gcloud.examples* + + From 90d0917dde9acea5e85781b45b9d8bf210b90645 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 10 Mar 2016 18:50:34 +0100 Subject: [PATCH 158/375] Add group for testing packages --- .../src/main/java/com/google/gcloud/package-info.java | 2 +- pom.xml | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/package-info.java b/gcloud-java-core/src/main/java/com/google/gcloud/package-info.java index 215264675dc2..d527640c99f9 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/package-info.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/package-info.java @@ -17,4 +17,4 @@ /** * Core classes for the {@code gcloud-java} library. */ -package com.google.gcloud; \ No newline at end of file +package com.google.gcloud; diff --git a/pom.xml b/pom.xml index b6e8d3470edb..c0a0e9bfcffe 100644 --- a/pom.xml +++ b/pom.xml @@ -394,6 +394,10 @@ Main packages com.google.gcloud* + + Test helpers packages + com.google.gcloud.bigquery.testing:com.google.gcloud.datastore.testing:com.google.gcloud.resourcemanager.testing:com.google.gcloud.storage.testing + SPI packages com.google.gcloud.spi From 24a712ae2972b428987b8d1d6b74b7968e35dfc8 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 10 Mar 2016 20:14:00 +0100 Subject: [PATCH 159/375] Rename Main packages to API packages, reorder groups, add service's SPIs --- pom.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index c0a0e9bfcffe..b7766ac0e5c6 100644 --- a/pom.xml +++ b/pom.xml @@ -391,21 +391,21 @@ ${project.build.directory}/javadoc - Main packages + API packages com.google.gcloud* Test helpers packages com.google.gcloud.bigquery.testing:com.google.gcloud.datastore.testing:com.google.gcloud.resourcemanager.testing:com.google.gcloud.storage.testing - - SPI packages - com.google.gcloud.spi - Example packages com.google.gcloud.examples* + + SPI packages + com.google.gcloud.spi:com.google.gcloud.bigquery.spi:com.google.gcloud.datastore.spi:com.google.gcloud.resourcemanager.spi:com.google.gcloud.storage.spi + From ac1ba668cb933093235407d4eb04f4138e7fbf9c Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 11 Mar 2016 18:51:15 +0100 Subject: [PATCH 160/375] Add more detailed javadoc to Blob and Storage signUrl --- .../java/com/google/gcloud/storage/Blob.java | 30 ++++++++++++++++- .../com/google/gcloud/storage/Storage.java | 33 +++++++++++++++---- 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java index 4c8e935f7071..cb8b35a2ce88 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java @@ -22,6 +22,7 @@ import com.google.api.services.storage.model.StorageObject; import com.google.common.base.Function; +import com.google.gcloud.AuthCredentials; import com.google.gcloud.ReadChannel; import com.google.gcloud.WriteChannel; import com.google.gcloud.storage.Storage.BlobTargetOption; @@ -456,13 +457,40 @@ public WriteChannel writer(BlobWriteOption... options) { * Generates a signed URL for this blob. If you want to allow access to for a fixed amount of time * for this blob, you can use this method to generate a URL that is only valid within a certain * time period. This is particularly useful if you don't want publicly accessible blobs, but don't - * want to require users to explicitly log in. + * want to require users to explicitly log in. Signing a URL requires a service account + * and its associated key. If a {@link AuthCredentials.ServiceAccountAuthCredentials} was passed + * to {@link StorageOptions.Builder#authCredentials(AuthCredentials)} or the default credentials + * are being used and the environment variable {@code GOOGLE_APPLICATION_CREDENTIALS} is set, then + * {@code signUrl} will use that service account and associated key to sign the URL. If this + * is not the case, a service account with associated key can be passed to {@code signUrl} using + * the {@link SignUrlOption#serviceAccount(AuthCredentials.ServiceAccountAuthCredentials)} option. + * + *

    Example usage of creating a signed URL that is valid for 2 weeks: + *

     {@code
    +   * blob.signUrl(14, TimeUnit.DAYS);
    +   * }
    + * + *

    Example usage of creating a signed URL passing the {@code SignUrlOption.serviceAccount()} + * option: + *

     {@code
    +   * blob.signUrl(14, TimeUnit.DAYS, SignUrlOption.serviceAccount(
    +   *     AuthCredentials.createForJson(new FileInputStream("/path/to/key.json"))));
    +   * }
    * * @param duration time until the signed URL expires, expressed in {@code unit}. The finer * granularity supported is 1 second, finer granularities will be truncated * @param unit time unit of the {@code duration} parameter * @param options optional URL signing options * @return a signed URL for this bucket and the specified options + * @throws IllegalArgumentException if + * {@link SignUrlOption#serviceAccount(AuthCredentials.ServiceAccountAuthCredentials)} was not + * used and no service account was provided to {@link StorageOptions} + * @throws IllegalArgumentException if the key associated to the provided service account is + * invalid + * @throws IllegalArgumentException if {@link SignUrlOption#withMd5()} option is used and + * {@link #md5()} is {@code null} + * @throws IllegalArgumentException if {@link SignUrlOption#withContentType()} option is used and + * {@link #contentType()} is {@code null} * @see Signed-URLs */ public URL signUrl(long duration, TimeUnit unit, SignUrlOption... options) { diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index 6b2e9266f24b..f673a3ac5902 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -24,6 +24,7 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import com.google.gcloud.AuthCredentials; import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials; import com.google.gcloud.Page; import com.google.gcloud.ReadChannel; @@ -1476,23 +1477,43 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx WriteChannel writer(BlobInfo blobInfo, BlobWriteOption... options); /** - * Generates a signed URL for a blob. - * If you have a blob that you want to allow access to for a fixed - * amount of time, you can use this method to generate a URL that - * is only valid within a certain time period. - * This is particularly useful if you don't want publicly - * accessible blobs, but don't want to require users to explicitly log in. + * Generates a signed URL for a blob. If you have a blob that you want to allow access to for a + * fixed amount of time, you can use this method to generate a URL that is only valid within a + * certain time period. This is particularly useful if you don't want publicly accessible blobs, + * but don't want to require users to explicitly log in. Signing a URL requires a service account + * and its associated key. If a {@link ServiceAccountAuthCredentials} was passed to + * {@link StorageOptions.Builder#authCredentials(AuthCredentials)} or the default credentials are + * being used and the environment variable {@code GOOGLE_APPLICATION_CREDENTIALS} is set, then + * {@code signUrl} will use that service account and associated key to sign the URL. If this + * is not the case, a service account with associated key can be passed to {@code signUrl} using + * the {@code SignUrlOption.serviceAccount()} option. * *

    Example usage of creating a signed URL that is valid for 2 weeks: *

     {@code
        * service.signUrl(BlobInfo.builder("bucket", "name").build(), 14, TimeUnit.DAYS);
        * }
    * + *

    Example usage of creating a signed URL passing the {@code SignUrlOption.serviceAccount()} + * option: + *

     {@code
    +   * service.signUrl(BlobInfo.builder("bucket", "name").build(), 14, TimeUnit.DAYS,
    +   *     SignUrlOption.serviceAccount(
    +   *         AuthCredentials.createForJson(new FileInputStream("/path/to/key.json"))));
    +   * }
    + * * @param blobInfo the blob associated with the signed URL * @param duration time until the signed URL expires, expressed in {@code unit}. The finest * granularity supported is 1 second, finer granularities will be truncated * @param unit time unit of the {@code duration} parameter * @param options optional URL signing options + * @throws IllegalArgumentException if {@code SignUrlOption.serviceAccount()} was not used and no + * service account was provided to {@link StorageOptions} + * @throws IllegalArgumentException if the key associated to the provided service account is + * invalid + * @throws IllegalArgumentException if {@code SignUrlOption.withMd5()} option is used and + * {@code blobInfo.md5()} is {@code null} + * @throws IllegalArgumentException if {@code SignUrlOption.withContentType()} option is used and + * {@code blobInfo.contentType()} is {@code null} * @see Signed-URLs */ URL signUrl(BlobInfo blobInfo, long duration, TimeUnit unit, SignUrlOption... options); From 8a3b4f2194c6c3789e6dc4212beade7457382677 Mon Sep 17 00:00:00 2001 From: JP Martin Date: Fri, 11 Mar 2016 10:31:29 -0800 Subject: [PATCH 161/375] Remove final from Blob So we can mock it in test classes. Also make equals and hashCode final. --- .../src/main/java/com/google/gcloud/storage/Blob.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java index 4c8e935f7071..0c92a1f50594 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java @@ -49,7 +49,7 @@ * {@link BlobInfo}. *

    */ -public final class Blob extends BlobInfo { +public class Blob extends BlobInfo { private static final long serialVersionUID = -6806832496717441434L; @@ -482,13 +482,13 @@ public Builder toBuilder() { } @Override - public boolean equals(Object obj) { + public final boolean equals(Object obj) { return obj instanceof Blob && Objects.equals(toPb(), ((Blob) obj).toPb()) && Objects.equals(options, ((Blob) obj).options); } @Override - public int hashCode() { + public final int hashCode() { return Objects.hash(super.hashCode(), options); } From ddb1adee1e560b4001d335e3d7804f5723140854 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Sun, 13 Mar 2016 12:13:43 +0100 Subject: [PATCH 162/375] Rephrase signUrl javadoc for better clarity --- .../java/com/google/gcloud/storage/Blob.java | 25 +++++++++++-------- .../com/google/gcloud/storage/Storage.java | 12 ++++++--- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java index cb8b35a2ce88..c60a703eda91 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java @@ -454,16 +454,21 @@ public WriteChannel writer(BlobWriteOption... options) { } /** - * Generates a signed URL for this blob. If you want to allow access to for a fixed amount of time - * for this blob, you can use this method to generate a URL that is only valid within a certain - * time period. This is particularly useful if you don't want publicly accessible blobs, but don't - * want to require users to explicitly log in. Signing a URL requires a service account - * and its associated key. If a {@link AuthCredentials.ServiceAccountAuthCredentials} was passed - * to {@link StorageOptions.Builder#authCredentials(AuthCredentials)} or the default credentials - * are being used and the environment variable {@code GOOGLE_APPLICATION_CREDENTIALS} is set, then - * {@code signUrl} will use that service account and associated key to sign the URL. If this - * is not the case, a service account with associated key can be passed to {@code signUrl} using - * the {@link SignUrlOption#serviceAccount(AuthCredentials.ServiceAccountAuthCredentials)} option. + * Generates a signed URL for this blob. If you want to allow access for a fixed amount of time to + * this blob, you can use this method to generate a URL that is only valid within a certain time + * period. This is particularly useful if you don't want publicly accessible blobs, but don't want + * to require users to explicitly log in. Signing a URL requires a service account + * and its associated private key. If a {@link AuthCredentials.ServiceAccountAuthCredentials} was + * passed to {@link StorageOptions.Builder#authCredentials(AuthCredentials)} or the default + * credentials are being used and the environment variable {@code GOOGLE_APPLICATION_CREDENTIALS} + * is set, then {@code signUrl} will use that service account and associated key to sign the URL. + * If the credentials passed to {@link StorageOptions} do not expose a private key (this is the + * case for App Engine credentials, Compute Engine credentials and Google Cloud SDK credentials) + * then {@code signUrl} will throw an {@link IllegalArgumentException} unless a service account + * with associated key is passed using the {@code SignUrlOption.serviceAccount()} option. The + * service account and private key passed with {@code SignUrlOption.serviceAccount()} have + * priority over any credentials set with + * {@link StorageOptions.Builder#authCredentials(AuthCredentials)}. * *

    Example usage of creating a signed URL that is valid for 2 weeks: *

     {@code
    diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java
    index f673a3ac5902..91f7578d7f89 100644
    --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java
    +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java
    @@ -1481,12 +1481,16 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx
        * fixed amount of time, you can use this method to generate a URL that is only valid within a
        * certain time period. This is particularly useful if you don't want publicly accessible blobs,
        * but don't want to require users to explicitly log in. Signing a URL requires a service account
    -   * and its associated key. If a {@link ServiceAccountAuthCredentials} was passed to
    +   * and its associated private key. If a {@link ServiceAccountAuthCredentials} was passed to
        * {@link StorageOptions.Builder#authCredentials(AuthCredentials)} or the default credentials are
        * being used and the environment variable {@code GOOGLE_APPLICATION_CREDENTIALS} is set, then
    -   * {@code signUrl} will use that service account and associated key to sign the URL. If this
    -   * is not the case, a service account with associated key can be passed to {@code signUrl} using
    -   * the {@code SignUrlOption.serviceAccount()} option.
    +   * {@code signUrl} will use that service account and associated key to sign the URL. If the
    +   * credentials passed to {@link StorageOptions} do not expose a private key (this is the case for
    +   * App Engine credentials, Compute Engine credentials and Google Cloud SDK credentials) then
    +   * {@code signUrl} will throw an {@link IllegalArgumentException} unless a service account with
    +   * associated key is passed using the {@code SignUrlOption.serviceAccount()} option. The service
    +   * account and private key passed with {@code SignUrlOption.serviceAccount()} have priority over
    +   * any credentials set with {@link StorageOptions.Builder#authCredentials(AuthCredentials)}.
        *
        * 

    Example usage of creating a signed URL that is valid for 2 weeks: *

     {@code
    
    From d97c1887f4e24d1b9e03a3743d8481594041cede Mon Sep 17 00:00:00 2001
    From: Marco Ziccardi 
    Date: Mon, 14 Mar 2016 17:23:52 +0100
    Subject: [PATCH 163/375] Rename maxResults to pageSize
    
    ---
     gcloud-java-bigquery/README.md                |  2 +-
     .../com/google/gcloud/bigquery/BigQuery.java  | 38 +++++++++----------
     .../google/gcloud/bigquery/QueryRequest.java  | 28 +++++++-------
     .../gcloud/bigquery/BigQueryImplTest.java     | 34 ++++++++---------
     .../google/gcloud/bigquery/DatasetTest.java   |  4 +-
     .../gcloud/bigquery/QueryRequestTest.java     | 10 ++---
     .../gcloud/bigquery/SerializationTest.java    |  4 +-
     .../com/google/gcloud/bigquery/TableTest.java |  4 +-
     .../gcloud/bigquery/it/ITBigQueryTest.java    |  6 +--
     .../snippets/InsertDataAndQueryTable.java     |  2 +-
     .../com/google/gcloud/storage/Storage.java    | 12 +++---
     .../gcloud/storage/SerializationTest.java     |  2 +-
     .../gcloud/storage/StorageImplTest.java       | 28 +++++++-------
     13 files changed, 87 insertions(+), 87 deletions(-)
    
    diff --git a/gcloud-java-bigquery/README.md b/gcloud-java-bigquery/README.md
    index 3387cd8c4f41..81b5db71bcac 100644
    --- a/gcloud-java-bigquery/README.md
    +++ b/gcloud-java-bigquery/README.md
    @@ -185,7 +185,7 @@ Then add the following code to run the query and wait for the result:
     QueryRequest queryRequest =
         QueryRequest.builder("SELECT * FROM my_dataset_id.my_table_id")
             .maxWaitTime(60000L)
    -        .maxResults(1000L)
    +        .pageSize(1000L)
             .build();
     // Request query to be executed and wait for results
     QueryResponse queryResponse = bigquery.query(queryRequest);
    diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java
    index 3acaacaf42e5..e06c8d86ee5f 100644
    --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java
    +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java
    @@ -171,10 +171,10 @@ private DatasetListOption(BigQueryRpc.Option option, Object value) {
         }
     
         /**
    -     * Returns an option to specify the maximum number of datasets to be returned.
    +     * Returns an option to specify the maximum number of datasets returned per page.
          */
    -    public static DatasetListOption maxResults(long maxResults) {
    -      return new DatasetListOption(BigQueryRpc.Option.MAX_RESULTS, maxResults);
    +    public static DatasetListOption pageSize(long pageSize) {
    +      return new DatasetListOption(BigQueryRpc.Option.MAX_RESULTS, pageSize);
         }
     
         /**
    @@ -246,11 +246,11 @@ private TableListOption(BigQueryRpc.Option option, Object value) {
         }
     
         /**
    -     * Returns an option to specify the maximum number of tables to be returned.
    +     * Returns an option to specify the maximum number of tables returned per page.
          */
    -    public static TableListOption maxResults(long maxResults) {
    -      checkArgument(maxResults >= 0);
    -      return new TableListOption(BigQueryRpc.Option.MAX_RESULTS, maxResults);
    +    public static TableListOption pageSize(long pageSize) {
    +      checkArgument(pageSize >= 0);
    +      return new TableListOption(BigQueryRpc.Option.MAX_RESULTS, pageSize);
         }
     
         /**
    @@ -295,11 +295,11 @@ private TableDataListOption(BigQueryRpc.Option option, Object value) {
         }
     
         /**
    -     * Returns an option to specify the maximum number of rows to be returned.
    +     * Returns an option to specify the maximum number of rows returned per page.
          */
    -    public static TableDataListOption maxResults(long maxResults) {
    -      checkArgument(maxResults >= 0);
    -      return new TableDataListOption(BigQueryRpc.Option.MAX_RESULTS, maxResults);
    +    public static TableDataListOption pageSize(long pageSize) {
    +      checkArgument(pageSize >= 0);
    +      return new TableDataListOption(BigQueryRpc.Option.MAX_RESULTS, pageSize);
         }
     
         /**
    @@ -352,11 +352,11 @@ public String apply(JobStatus.State state) {
         }
     
         /**
    -     * Returns an option to specify the maximum number of jobs to be returned.
    +     * Returns an option to specify the maximum number of jobs returned per page.
          */
    -    public static JobListOption maxResults(long maxResults) {
    -      checkArgument(maxResults >= 0);
    -      return new JobListOption(BigQueryRpc.Option.MAX_RESULTS, maxResults);
    +    public static JobListOption pageSize(long pageSize) {
    +      checkArgument(pageSize >= 0);
    +      return new JobListOption(BigQueryRpc.Option.MAX_RESULTS, pageSize);
         }
     
         /**
    @@ -418,11 +418,11 @@ private QueryResultsOption(BigQueryRpc.Option option, Object value) {
         }
     
         /**
    -     * Returns an option to specify the maximum number of rows to be returned.
    +     * Returns an option to specify the maximum number of rows returned per page.
          */
    -    public static QueryResultsOption maxResults(long maxResults) {
    -      checkArgument(maxResults >= 0);
    -      return new QueryResultsOption(BigQueryRpc.Option.MAX_RESULTS, maxResults);
    +    public static QueryResultsOption pageSize(long pageSize) {
    +      checkArgument(pageSize >= 0);
    +      return new QueryResultsOption(BigQueryRpc.Option.MAX_RESULTS, pageSize);
         }
     
         /**
    diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryRequest.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryRequest.java
    index 5f99f3c5b4ee..b3522a2a6ba3 100644
    --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryRequest.java
    +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryRequest.java
    @@ -40,7 +40,7 @@
      * QueryRequest request = QueryRequest.builder("SELECT field FROM table")
      *     .defaultDataset(DatasetId.of("dataset"))
      *     .maxWaitTime(60000L)
    - *     .maxResults(1000L)
    + *     .pageSize(1000L)
      *     .build();
      * QueryResponse response = bigquery.query(request);
      * while (!response.jobCompleted()) {
    @@ -65,7 +65,7 @@ public class QueryRequest implements Serializable {
       private static final long serialVersionUID = -8727328332415880852L;
     
       private final String query;
    -  private final Long maxResults;
    +  private final Long pageSize;
       private final DatasetId defaultDataset;
       private final Long maxWaitTime;
       private final Boolean dryRun;
    @@ -74,7 +74,7 @@ public class QueryRequest implements Serializable {
       public static final class Builder {
     
         private String query;
    -    private Long maxResults;
    +    private Long pageSize;
         private DatasetId defaultDataset;
         private Long maxWaitTime;
         private Boolean dryRun;
    @@ -96,8 +96,8 @@ public Builder query(String query) {
          * query result set is large. In addition to this limit, responses are also limited to 10 MB.
          * By default, there is no maximum row count, and only the byte limit applies.
          */
    -    public Builder maxResults(Long maxResults) {
    -      this.maxResults = maxResults;
    +    public Builder pageSize(Long pageSize) {
    +      this.pageSize = pageSize;
           return this;
         }
     
    @@ -157,7 +157,7 @@ public QueryRequest build() {
     
       private QueryRequest(Builder builder) {
         query = builder.query;
    -    maxResults = builder.maxResults;
    +    pageSize = builder.pageSize;
         defaultDataset = builder.defaultDataset;
         maxWaitTime = builder.maxWaitTime;
         dryRun = builder.dryRun;
    @@ -174,8 +174,8 @@ public String query() {
       /**
        * Returns the maximum number of rows of data to return per page of results.
        */
    -  public Long maxResults() {
    -    return maxResults;
    +  public Long pageSize() {
    +    return pageSize;
       }
     
       /**
    @@ -224,7 +224,7 @@ public Boolean useQueryCache() {
       public Builder toBuilder() {
         return new Builder()
             .query(query)
    -        .maxResults(maxResults)
    +        .pageSize(pageSize)
             .defaultDataset(defaultDataset)
             .maxWaitTime(maxWaitTime)
             .dryRun(dryRun)
    @@ -235,7 +235,7 @@ public Builder toBuilder() {
       public String toString() {
         return MoreObjects.toStringHelper(this)
             .add("query", query)
    -        .add("maxResults", maxResults)
    +        .add("pageSize", pageSize)
             .add("defaultDataset", defaultDataset)
             .add("maxWaitTime", maxWaitTime)
             .add("dryRun", dryRun)
    @@ -245,7 +245,7 @@ public String toString() {
     
       @Override
       public int hashCode() {
    -    return Objects.hash(query, maxResults, defaultDataset, maxWaitTime, dryRun, useQueryCache);
    +    return Objects.hash(query, pageSize, defaultDataset, maxWaitTime, dryRun, useQueryCache);
       }
     
       @Override
    @@ -264,8 +264,8 @@ QueryRequest setProjectId(String projectId) {
       com.google.api.services.bigquery.model.QueryRequest toPb() {
         com.google.api.services.bigquery.model.QueryRequest queryRequestPb =
             new com.google.api.services.bigquery.model.QueryRequest().setQuery(query);
    -    if (maxResults != null) {
    -      queryRequestPb.setMaxResults(maxResults);
    +    if (pageSize != null) {
    +      queryRequestPb.setMaxResults(pageSize);
         }
         if (defaultDataset != null) {
           queryRequestPb.setDefaultDataset(defaultDataset.toPb());
    @@ -299,7 +299,7 @@ public static QueryRequest of(String query) {
       static QueryRequest fromPb(com.google.api.services.bigquery.model.QueryRequest queryRequestPb) {
         Builder builder = builder(queryRequestPb.getQuery());
         if (queryRequestPb.getMaxResults() != null) {
    -      builder.maxResults(queryRequestPb.getMaxResults());
    +      builder.pageSize(queryRequestPb.getMaxResults());
         }
         if (queryRequestPb.getDefaultDataset() != null) {
           builder.defaultDataset(DatasetId.fromPb(queryRequestPb.getDefaultDataset()));
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java
    index 305745e72da9..b398f238386a 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java
    @@ -148,12 +148,12 @@ public class BigQueryImplTest {
       private static final TableRow TABLE_ROW =
           new TableRow().setF(ImmutableList.of(BOOLEAN_FIELD, INTEGER_FIELD));
       private static final QueryRequest QUERY_REQUEST = QueryRequest.builder("SQL")
    -      .maxResults(42L)
    +      .pageSize(42L)
           .useQueryCache(false)
           .defaultDataset(DatasetId.of(DATASET))
           .build();
       private static final QueryRequest QUERY_REQUEST_WITH_PROJECT = QueryRequest.builder("SQL")
    -      .maxResults(42L)
    +      .pageSize(42L)
           .useQueryCache(false)
           .defaultDataset(DatasetId.of(PROJECT, DATASET))
           .build();
    @@ -170,8 +170,8 @@ public class BigQueryImplTest {
           BigQuery.DatasetListOption.all();
       private static final BigQuery.DatasetListOption DATASET_LIST_PAGE_TOKEN =
           BigQuery.DatasetListOption.startPageToken("cursor");
    -  private static final BigQuery.DatasetListOption DATASET_LIST_MAX_RESULTS =
    -      BigQuery.DatasetListOption.maxResults(42L);
    +  private static final BigQuery.DatasetListOption DATASET_LIST_PAGE_SIZE =
    +      BigQuery.DatasetListOption.pageSize(42L);
       private static final Map DATASET_LIST_OPTIONS = ImmutableMap.of(
           BigQueryRpc.Option.ALL_DATASETS, true,
           BigQueryRpc.Option.PAGE_TOKEN, "cursor",
    @@ -188,8 +188,8 @@ public class BigQueryImplTest {
           BigQuery.TableOption.fields(BigQuery.TableField.SCHEMA, BigQuery.TableField.ETAG);
     
       // Table list options
    -  private static final BigQuery.TableListOption TABLE_LIST_MAX_RESULTS =
    -      BigQuery.TableListOption.maxResults(42L);
    +  private static final BigQuery.TableListOption TABLE_LIST_PAGE_SIZE =
    +      BigQuery.TableListOption.pageSize(42L);
       private static final BigQuery.TableListOption TABLE_LIST_PAGE_TOKEN =
           BigQuery.TableListOption.startPageToken("cursor");
       private static final Map TABLE_LIST_OPTIONS = ImmutableMap.of(
    @@ -197,8 +197,8 @@ public class BigQueryImplTest {
           BigQueryRpc.Option.PAGE_TOKEN, "cursor");
     
       // TableData list options
    -  private static final BigQuery.TableDataListOption TABLE_DATA_LIST_MAX_RESULTS =
    -      BigQuery.TableDataListOption.maxResults(42L);
    +  private static final BigQuery.TableDataListOption TABLE_DATA_LIST_PAGE_SIZE =
    +      BigQuery.TableDataListOption.pageSize(42L);
       private static final BigQuery.TableDataListOption TABLE_DATA_LIST_PAGE_TOKEN =
           BigQuery.TableDataListOption.startPageToken("cursor");
       private static final BigQuery.TableDataListOption TABLE_DATA_LIST_START_INDEX =
    @@ -221,8 +221,8 @@ public class BigQueryImplTest {
           BigQuery.JobListOption.stateFilter(JobStatus.State.DONE, JobStatus.State.PENDING);
       private static final BigQuery.JobListOption JOB_LIST_PAGE_TOKEN =
           BigQuery.JobListOption.startPageToken("cursor");
    -  private static final BigQuery.JobListOption JOB_LIST_MAX_RESULTS =
    -      BigQuery.JobListOption.maxResults(42L);
    +  private static final BigQuery.JobListOption JOB_LIST_PAGE_SIZE =
    +      BigQuery.JobListOption.pageSize(42L);
       private static final Map JOB_LIST_OPTIONS = ImmutableMap.of(
           BigQueryRpc.Option.ALL_USERS, true,
           BigQueryRpc.Option.STATE_FILTER, ImmutableList.of("done", "pending"),
    @@ -236,8 +236,8 @@ public class BigQueryImplTest {
           BigQuery.QueryResultsOption.startIndex(1024L);
       private static final BigQuery.QueryResultsOption QUERY_RESULTS_OPTION_PAGE_TOKEN =
           BigQuery.QueryResultsOption.startPageToken("cursor");
    -  private static final BigQuery.QueryResultsOption QUERY_RESULTS_OPTION_MAX_RESULTS =
    -      BigQuery.QueryResultsOption.maxResults(0L);
    +  private static final BigQuery.QueryResultsOption QUERY_RESULTS_OPTION_PAGE_SIZE =
    +      BigQuery.QueryResultsOption.pageSize(0L);
       private static final Map QUERY_RESULTS_OPTIONS = ImmutableMap.of(
           BigQueryRpc.Option.TIMEOUT, 42L,
           BigQueryRpc.Option.START_INDEX, 1024L,
    @@ -388,7 +388,7 @@ public void testListDatasetsWithOptions() {
         EasyMock.expect(bigqueryRpcMock.listDatasets(DATASET_LIST_OPTIONS)).andReturn(result);
         EasyMock.replay(bigqueryRpcMock);
         Page page = bigquery.listDatasets(DATASET_LIST_ALL, DATASET_LIST_PAGE_TOKEN,
    -        DATASET_LIST_MAX_RESULTS);
    +        DATASET_LIST_PAGE_SIZE);
         assertEquals(cursor, page.nextPageCursor());
         assertArrayEquals(datasetList.toArray(), Iterables.toArray(page.values(), DatasetInfo.class));
       }
    @@ -560,7 +560,7 @@ public void testListTablesWithOptions() {
             Tuple.of(cursor, Iterables.transform(tableList, TableInfo.TO_PB_FUNCTION));
         EasyMock.expect(bigqueryRpcMock.listTables(DATASET, TABLE_LIST_OPTIONS)).andReturn(result);
         EasyMock.replay(bigqueryRpcMock);
    -    Page
    page = bigquery.listTables(DATASET, TABLE_LIST_MAX_RESULTS, TABLE_LIST_PAGE_TOKEN); + Page
    page = bigquery.listTables(DATASET, TABLE_LIST_PAGE_SIZE, TABLE_LIST_PAGE_TOKEN); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(tableList.toArray(), Iterables.toArray(page.values(), Table.class)); } @@ -733,7 +733,7 @@ public void testListTableDataWithOptions() { EasyMock.replay(bigqueryRpcMock); bigquery = options.service(); Page> page = bigquery.listTableData(DATASET, TABLE, - TABLE_DATA_LIST_MAX_RESULTS, TABLE_DATA_LIST_PAGE_TOKEN, TABLE_DATA_LIST_START_INDEX); + TABLE_DATA_LIST_PAGE_SIZE, TABLE_DATA_LIST_PAGE_TOKEN, TABLE_DATA_LIST_START_INDEX); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(tableData.toArray(), Iterables.toArray(page.values(), List.class)); } @@ -859,7 +859,7 @@ public com.google.api.services.bigquery.model.Job apply(Job job) { EasyMock.expect(bigqueryRpcMock.listJobs(JOB_LIST_OPTIONS)).andReturn(result); EasyMock.replay(bigqueryRpcMock); Page page = bigquery.listJobs(JOB_LIST_ALL_USERS, JOB_LIST_STATE_FILTER, - JOB_LIST_PAGE_TOKEN, JOB_LIST_MAX_RESULTS); + JOB_LIST_PAGE_TOKEN, JOB_LIST_PAGE_SIZE); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(jobList.toArray(), Iterables.toArray(page.values(), Job.class)); } @@ -1012,7 +1012,7 @@ public void testGetQueryResultsWithOptions() { EasyMock.replay(bigqueryRpcMock); bigquery = options.service(); QueryResponse response = bigquery.getQueryResults(queryJob, QUERY_RESULTS_OPTION_TIME, - QUERY_RESULTS_OPTION_INDEX, QUERY_RESULTS_OPTION_MAX_RESULTS, + QUERY_RESULTS_OPTION_INDEX, QUERY_RESULTS_OPTION_PAGE_SIZE, QUERY_RESULTS_OPTION_PAGE_TOKEN); assertEquals(queryJob, response.jobId()); assertEquals(true, response.jobCompleted()); diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetTest.java index 373291021b23..dd03b7899ebc 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetTest.java @@ -260,11 +260,11 @@ public void testListWithOptions() throws Exception { new Table(serviceMockReturnsOptions, new Table.BuilderImpl(TABLE_INFO3))); PageImpl
    expectedPage = new PageImpl<>(null, "c", tableResults); expect(bigquery.options()).andReturn(mockOptions); - expect(bigquery.listTables(DATASET_INFO.datasetId(), BigQuery.TableListOption.maxResults(10L))) + expect(bigquery.listTables(DATASET_INFO.datasetId(), BigQuery.TableListOption.pageSize(10L))) .andReturn(expectedPage); replay(bigquery); initializeDataset(); - Page
    tablePage = dataset.list(BigQuery.TableListOption.maxResults(10L)); + Page
    tablePage = dataset.list(BigQuery.TableListOption.pageSize(10L)); assertArrayEquals(tableResults.toArray(), Iterables.toArray(tablePage.values(), Table.class)); assertEquals(expectedPage.nextPageCursor(), tablePage.nextPageCursor()); } diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryRequestTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryRequestTest.java index 370b4d614cbf..7875dee9e315 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryRequestTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryRequestTest.java @@ -29,13 +29,13 @@ public class QueryRequestTest { private static final DatasetId DATASET_ID = DatasetId.of("dataset"); private static final Boolean USE_QUERY_CACHE = true; private static final Boolean DRY_RUN = false; - private static final Long MAX_RESULTS = 42L; + private static final Long PAGE_SIZE = 42L; private static final Long MAX_WAIT_TIME = 42000L; private static final QueryRequest QUERY_REQUEST = QueryRequest.builder(QUERY) .useQueryCache(USE_QUERY_CACHE) .defaultDataset(DATASET_ID) .dryRun(DRY_RUN) - .maxResults(MAX_RESULTS) + .pageSize(PAGE_SIZE) .maxWaitTime(MAX_WAIT_TIME) .build(); @@ -65,7 +65,7 @@ public void testBuilder() { assertEquals(USE_QUERY_CACHE, QUERY_REQUEST.useQueryCache()); assertEquals(DATASET_ID, QUERY_REQUEST.defaultDataset()); assertEquals(DRY_RUN, QUERY_REQUEST.dryRun()); - assertEquals(MAX_RESULTS, QUERY_REQUEST.maxResults()); + assertEquals(PAGE_SIZE, QUERY_REQUEST.pageSize()); assertEquals(MAX_WAIT_TIME, QUERY_REQUEST.maxWaitTime()); thrown.expect(NullPointerException.class); QueryRequest.builder(null); @@ -78,7 +78,7 @@ public void testOf() { assertNull(request.useQueryCache()); assertNull(request.defaultDataset()); assertNull(request.dryRun()); - assertNull(request.maxResults()); + assertNull(request.pageSize()); assertNull(request.maxWaitTime()); thrown.expect(NullPointerException.class); QueryRequest.of(null); @@ -102,7 +102,7 @@ private void compareQueryRequest(QueryRequest expected, QueryRequest value) { assertEquals(expected.useQueryCache(), value.useQueryCache()); assertEquals(expected.defaultDataset(), value.defaultDataset()); assertEquals(expected.dryRun(), value.dryRun()); - assertEquals(expected.maxResults(), value.maxResults()); + assertEquals(expected.pageSize(), value.pageSize()); assertEquals(expected.maxWaitTime(), value.maxWaitTime()); } } diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java index d877bff2138c..254c8954bf30 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java @@ -207,7 +207,7 @@ public class SerializationTest { .useQueryCache(true) .defaultDataset(DATASET_ID) .dryRun(false) - .maxResults(42L) + .pageSize(42L) .maxWaitTime(10L) .build(); private static final QueryResult QUERY_RESULT = QueryResult.builder() @@ -261,7 +261,7 @@ public void testModelAndRequests() throws Exception { INSERT_ALL_RESPONSE, FIELD_VALUE, QUERY_REQUEST, QUERY_RESPONSE, BigQuery.DatasetOption.fields(), BigQuery.DatasetDeleteOption.deleteContents(), BigQuery.DatasetListOption.all(), BigQuery.TableOption.fields(), - BigQuery.TableListOption.maxResults(42L), BigQuery.JobOption.fields(), + BigQuery.TableListOption.pageSize(42L), BigQuery.JobOption.fields(), BigQuery.JobListOption.allUsers(), DATASET, TABLE, JOB}; for (Serializable obj : objects) { Object copy = serializeAndDeserialize(obj); diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableTest.java index 4866ee9ab8ec..c7828ebeadf4 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableTest.java @@ -286,11 +286,11 @@ public void testListWithOptions() throws Exception { initializeExpectedTable(1); expect(bigquery.options()).andReturn(mockOptions); PageImpl> tableDataPage = new PageImpl<>(null, "c", ROWS); - expect(bigquery.listTableData(TABLE_ID1, BigQuery.TableDataListOption.maxResults(10L))) + expect(bigquery.listTableData(TABLE_ID1, BigQuery.TableDataListOption.pageSize(10L))) .andReturn(tableDataPage); replay(bigquery); initializeTable(); - Page> dataPage = table.list(BigQuery.TableDataListOption.maxResults(10L)); + Page> dataPage = table.list(BigQuery.TableDataListOption.pageSize(10L)); Iterator> tableDataIterator = tableDataPage.values().iterator(); Iterator> dataIterator = dataPage.values().iterator(); assertTrue(Iterators.elementsEqual(tableDataIterator, dataIterator)); diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java index 63a0551ece33..50780b4fc9a9 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java @@ -348,7 +348,7 @@ public void testCreateExternalTable() throws InterruptedException { + tableName) .defaultDataset(DatasetId.of(DATASET)) .maxWaitTime(60000L) - .maxResults(1000L) + .pageSize(1000L) .build(); QueryResponse response = bigquery.query(request); while (!response.jobCompleted()) { @@ -411,7 +411,7 @@ public void testCreateViewTable() throws InterruptedException { QueryRequest request = QueryRequest.builder("SELECT * FROM " + tableName) .defaultDataset(DatasetId.of(DATASET)) .maxWaitTime(60000L) - .maxResults(1000L) + .pageSize(1000L) .build(); QueryResponse response = bigquery.query(request); while (!response.jobCompleted()) { @@ -662,7 +662,7 @@ public void testQuery() throws InterruptedException { QueryRequest request = QueryRequest.builder(query) .defaultDataset(DatasetId.of(DATASET)) .maxWaitTime(60000L) - .maxResults(1000L) + .pageSize(1000L) .build(); QueryResponse response = bigquery.query(request); while (!response.jobCompleted()) { diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/snippets/InsertDataAndQueryTable.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/snippets/InsertDataAndQueryTable.java index f421bc832441..ba2d1291b229 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/snippets/InsertDataAndQueryTable.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/snippets/InsertDataAndQueryTable.java @@ -84,7 +84,7 @@ public static void main(String... args) throws InterruptedException { // Create a query request QueryRequest queryRequest = QueryRequest.builder("SELECT * FROM my_dataset_id.my_table_id") .maxWaitTime(60000L) - .maxResults(1000L) + .pageSize(1000L) .build(); // Request query to be executed and wait for results QueryResponse queryResponse = bigquery.query(queryRequest); diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index 6b2e9266f24b..c098c7ddc5d3 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -626,10 +626,10 @@ private BucketListOption(StorageRpc.Option option, Object value) { } /** - * Returns an option to specify the maximum number of buckets to be returned. + * Returns an option to specify the maximum number of buckets returned per page. */ - public static BucketListOption maxResults(long maxResults) { - return new BucketListOption(StorageRpc.Option.MAX_RESULTS, maxResults); + public static BucketListOption pageSize(long pageSize) { + return new BucketListOption(StorageRpc.Option.MAX_RESULTS, pageSize); } /** @@ -672,10 +672,10 @@ private BlobListOption(StorageRpc.Option option, Object value) { } /** - * Returns an option to specify the maximum number of blobs to be returned. + * Returns an option to specify the maximum number of blobs returned per page. */ - public static BlobListOption maxResults(long maxResults) { - return new BlobListOption(StorageRpc.Option.MAX_RESULTS, maxResults); + public static BlobListOption pageSize(long pageSize) { + return new BlobListOption(StorageRpc.Option.MAX_RESULTS, pageSize); } /** diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java index ad13b14ae4e2..efa56d9e39b2 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java @@ -64,7 +64,7 @@ public class SerializationTest { private static final PageImpl PAGE_RESULT = new PageImpl<>(null, "c", Collections.singletonList(BLOB)); private static final Storage.BlobListOption BLOB_LIST_OPTIONS = - Storage.BlobListOption.maxResults(100); + Storage.BlobListOption.pageSize(100); private static final Storage.BlobSourceOption BLOB_SOURCE_OPTIONS = Storage.BlobSourceOption.generationMatch(1); private static final Storage.BlobTargetOption BLOB_TARGET_OPTIONS = diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java index 9a306b2b03c6..38b4bb58e77f 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java @@ -181,8 +181,8 @@ public class StorageImplTest { StorageRpc.Option.IF_SOURCE_GENERATION_MATCH, BLOB_SOURCE_GENERATION.value()); // Bucket list options - private static final Storage.BucketListOption BUCKET_LIST_MAX_RESULT = - Storage.BucketListOption.maxResults(42L); + private static final Storage.BucketListOption BUCKET_LIST_PAGE_SIZE = + Storage.BucketListOption.pageSize(42L); private static final Storage.BucketListOption BUCKET_LIST_PREFIX = Storage.BucketListOption.prefix("prefix"); private static final Storage.BucketListOption BUCKET_LIST_FIELDS = @@ -190,12 +190,12 @@ public class StorageImplTest { private static final Storage.BucketListOption BUCKET_LIST_EMPTY_FIELDS = Storage.BucketListOption.fields(); private static final Map BUCKET_LIST_OPTIONS = ImmutableMap.of( - StorageRpc.Option.MAX_RESULTS, BUCKET_LIST_MAX_RESULT.value(), + StorageRpc.Option.MAX_RESULTS, BUCKET_LIST_PAGE_SIZE.value(), StorageRpc.Option.PREFIX, BUCKET_LIST_PREFIX.value()); // Blob list options - private static final Storage.BlobListOption BLOB_LIST_MAX_RESULT = - Storage.BlobListOption.maxResults(42L); + private static final Storage.BlobListOption BLOB_LIST_PAGE_SIZE = + Storage.BlobListOption.pageSize(42L); private static final Storage.BlobListOption BLOB_LIST_PREFIX = Storage.BlobListOption.prefix("prefix"); private static final Storage.BlobListOption BLOB_LIST_FIELDS = @@ -205,7 +205,7 @@ public class StorageImplTest { private static final Storage.BlobListOption BLOB_LIST_EMPTY_FIELDS = Storage.BlobListOption.fields(); private static final Map BLOB_LIST_OPTIONS = ImmutableMap.of( - StorageRpc.Option.MAX_RESULTS, BLOB_LIST_MAX_RESULT.value(), + StorageRpc.Option.MAX_RESULTS, BLOB_LIST_PAGE_SIZE.value(), StorageRpc.Option.PREFIX, BLOB_LIST_PREFIX.value(), StorageRpc.Option.VERSIONS, BLOB_LIST_VERSIONS.value()); @@ -567,7 +567,7 @@ public void testListBucketsWithOptions() { EasyMock.replay(storageRpcMock); initializeService(); ImmutableList bucketList = ImmutableList.of(expectedBucket1, expectedBucket2); - Page page = storage.list(BUCKET_LIST_MAX_RESULT, BUCKET_LIST_PREFIX); + Page page = storage.list(BUCKET_LIST_PAGE_SIZE, BUCKET_LIST_PREFIX); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(bucketList.toArray(), Iterables.toArray(page.values(), Bucket.class)); } @@ -654,7 +654,7 @@ public void testListBlobsWithOptions() { initializeService(); ImmutableList blobList = ImmutableList.of(expectedBlob1, expectedBlob2); Page page = - storage.list(BUCKET_NAME1, BLOB_LIST_MAX_RESULT, BLOB_LIST_PREFIX, BLOB_LIST_VERSIONS); + storage.list(BUCKET_NAME1, BLOB_LIST_PAGE_SIZE, BLOB_LIST_PREFIX, BLOB_LIST_VERSIONS); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(blobList.toArray(), Iterables.toArray(page.values(), Blob.class)); } @@ -673,9 +673,9 @@ public void testListBlobsWithSelectedFields() { initializeService(); ImmutableList blobList = ImmutableList.of(expectedBlob1, expectedBlob2); Page page = - storage.list(BUCKET_NAME1, BLOB_LIST_MAX_RESULT, BLOB_LIST_PREFIX, BLOB_LIST_FIELDS); - assertEquals(BLOB_LIST_MAX_RESULT.value(), - capturedOptions.getValue().get(BLOB_LIST_MAX_RESULT.rpcOption())); + storage.list(BUCKET_NAME1, BLOB_LIST_PAGE_SIZE, BLOB_LIST_PREFIX, BLOB_LIST_FIELDS); + assertEquals(BLOB_LIST_PAGE_SIZE.value(), + capturedOptions.getValue().get(BLOB_LIST_PAGE_SIZE.rpcOption())); assertEquals(BLOB_LIST_PREFIX.value(), capturedOptions.getValue().get(BLOB_LIST_PREFIX.rpcOption())); String selector = (String) capturedOptions.getValue().get(BLOB_LIST_FIELDS.rpcOption()); @@ -704,9 +704,9 @@ public void testListBlobsWithEmptyFields() { initializeService(); ImmutableList blobList = ImmutableList.of(expectedBlob1, expectedBlob2); Page page = - storage.list(BUCKET_NAME1, BLOB_LIST_MAX_RESULT, BLOB_LIST_PREFIX, BLOB_LIST_EMPTY_FIELDS); - assertEquals(BLOB_LIST_MAX_RESULT.value(), - capturedOptions.getValue().get(BLOB_LIST_MAX_RESULT.rpcOption())); + storage.list(BUCKET_NAME1, BLOB_LIST_PAGE_SIZE, BLOB_LIST_PREFIX, BLOB_LIST_EMPTY_FIELDS); + assertEquals(BLOB_LIST_PAGE_SIZE.value(), + capturedOptions.getValue().get(BLOB_LIST_PAGE_SIZE.rpcOption())); assertEquals(BLOB_LIST_PREFIX.value(), capturedOptions.getValue().get(BLOB_LIST_PREFIX.rpcOption())); String selector = (String) capturedOptions.getValue().get(BLOB_LIST_EMPTY_FIELDS.rpcOption()); From 767be657b14e8f6e86167389e9af8d65a7fff19d Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Mon, 14 Mar 2016 09:53:34 -0700 Subject: [PATCH 164/375] LocalDnsHelper adds the default change upon creating a zone. This now matches the behaviour of the service. Fixes #672. --- .../gcloud/dns/testing/LocalDnsHelper.java | 17 +++++++++++++---- .../gcloud/dns/testing/LocalDnsHelperTest.java | 8 ++++---- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/LocalDnsHelper.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/LocalDnsHelper.java index f9cd1a11281e..3b18ec5ce55b 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/LocalDnsHelper.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/LocalDnsHelper.java @@ -680,7 +680,15 @@ Response createZone(String projectId, ManagedZone zone, String... fields) { completeZone.setId(BigInteger.valueOf(Math.abs(ID_GENERATOR.nextLong() % Long.MAX_VALUE))); completeZone.setNameServers(randomNameservers()); ZoneContainer zoneContainer = new ZoneContainer(completeZone); - zoneContainer.dnsRecords().set(defaultRecords(completeZone)); + ImmutableSortedMap defaultsRecords = defaultRecords(completeZone); + zoneContainer.dnsRecords().set(defaultsRecords); + Change change = new Change(); + change.setAdditions(ImmutableList.copyOf(defaultsRecords.values())); + change.setStatus("done"); + change.setId("0"); + change.setStartTime(ISODateTimeFormat.dateTime().withZoneUTC() + .print(System.currentTimeMillis())); + zoneContainer.changes().add(change); ProjectContainer projectContainer = findProject(projectId); ZoneContainer oldValue = projectContainer.zones().putIfAbsent( completeZone.getName(), zoneContainer); @@ -718,8 +726,9 @@ Response createChange(String projectId, String zoneName, Change change, String.. completeChange.setDeletions(ImmutableList.copyOf(change.getDeletions())); } /* We need to set ID for the change. We are working in concurrent environment. We know that the - element fell on an index between 0 and maxId, so we will reset all IDs in this range (all of - them are valid for the respective objects). */ + element fell on an index between 1 and maxId (index 0 is the default change which creates SOA + and NS), so we will reset all IDs between 0 and maxId (all of them are valid for the respective + objects). */ ConcurrentLinkedQueue changeSequence = zoneContainer.changes(); changeSequence.add(completeChange); int maxId = changeSequence.size(); @@ -728,7 +737,7 @@ Response createChange(String projectId, String zoneName, Change change, String.. if (index == maxId) { break; } - c.setId(String.valueOf(++index)); + c.setId(String.valueOf(index++)); } completeChange.setStatus("pending"); completeChange.setStartTime(ISODateTimeFormat.dateTime().withZoneUTC() diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/testing/LocalDnsHelperTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/testing/LocalDnsHelperTest.java index 2d049e4ffeea..15fa437eb631 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/testing/LocalDnsHelperTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/testing/LocalDnsHelperTest.java @@ -850,14 +850,14 @@ public void testListChanges() { RPC.create(ZONE1, EMPTY_RPC_OPTIONS); Iterable results = RPC.listChangeRequests(ZONE1.getName(), EMPTY_RPC_OPTIONS).results(); ImmutableList changes = ImmutableList.copyOf(results); - assertEquals(0, changes.size()); + assertEquals(1, changes.size()); // zone has changes RPC.applyChangeRequest(ZONE1.getName(), CHANGE1, EMPTY_RPC_OPTIONS); RPC.applyChangeRequest(ZONE1.getName(), CHANGE2, EMPTY_RPC_OPTIONS); RPC.applyChangeRequest(ZONE1.getName(), CHANGE_KEEP, EMPTY_RPC_OPTIONS); results = RPC.listChangeRequests(ZONE1.getName(), EMPTY_RPC_OPTIONS).results(); changes = ImmutableList.copyOf(results); - assertEquals(3, changes.size()); + assertEquals(4, changes.size()); // error in options Map options = new HashMap<>(); options.put(DnsRpc.Option.PAGE_SIZE, 0); @@ -881,14 +881,14 @@ public void testListChanges() { options.put(DnsRpc.Option.PAGE_SIZE, 15); results = RPC.listChangeRequests(ZONE1.getName(), options).results(); changes = ImmutableList.copyOf(results); - assertEquals(3, changes.size()); + assertEquals(4, changes.size()); options = new HashMap<>(); options.put(DnsRpc.Option.SORTING_ORDER, "descending"); results = RPC.listChangeRequests(ZONE1.getName(), options).results(); ImmutableList descending = ImmutableList.copyOf(results); results = RPC.listChangeRequests(ZONE1.getName(), EMPTY_RPC_OPTIONS).results(); ImmutableList ascending = ImmutableList.copyOf(results); - int size = 3; + int size = 4; assertEquals(size, descending.size()); for (int i = 0; i < size; i++) { assertEquals(descending.get(i), ascending.get(size - i - 1)); From 86e23d55bc9cec8a2bd626d143882a998d1a165a Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 14 Mar 2016 17:59:18 +0100 Subject: [PATCH 165/375] Fix flaky RemoteGcsHelperTest.testForceDeleteTimeout --- .../java/com/google/gcloud/storage/RemoteGcsHelperTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteGcsHelperTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteGcsHelperTest.java index 154554a029fe..146922a9dae9 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteGcsHelperTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteGcsHelperTest.java @@ -132,7 +132,8 @@ public void testForceDelete() throws InterruptedException, ExecutionException { @Test public void testForceDeleteTimeout() throws InterruptedException, ExecutionException { Storage storageMock = EasyMock.createMock(Storage.class); - EasyMock.expect(storageMock.list(BUCKET_NAME)).andReturn(blobPage).anyTimes(); + EasyMock.expect(storageMock.list(BUCKET_NAME, BlobListOption.versions(true))) + .andReturn(blobPage).anyTimes(); for (BlobInfo info : blobList) { EasyMock.expect(storageMock.delete(info.blobId())).andReturn(true).anyTimes(); } From 96e380c182aa89f8c4f7dbdcb7df2d4c188c8343 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Mon, 14 Mar 2016 14:45:15 -0700 Subject: [PATCH 166/375] Moved spi package to dns.spi as per #742 --- .../com/google/gcloud/dns/AbstractOption.java | 2 +- .../main/java/com/google/gcloud/dns/Dns.java | 2 +- .../java/com/google/gcloud/dns/DnsImpl.java | 2 +- .../com/google/gcloud/dns/DnsOptions.java | 6 ++--- .../gcloud/{ => dns}/spi/DefaultDnsRpc.java | 22 +++++++++---------- .../google/gcloud/{ => dns}/spi/DnsRpc.java | 2 +- .../gcloud/{ => dns}/spi/DnsRpcFactory.java | 3 ++- .../google/gcloud/dns/AbstractOptionTest.java | 2 +- .../com/google/gcloud/dns/DnsImplTest.java | 4 ++-- .../java/com/google/gcloud/dns/DnsTest.java | 2 +- .../dns/testing/LocalDnsHelperTest.java | 4 ++-- 11 files changed, 26 insertions(+), 25 deletions(-) rename gcloud-java-dns/src/main/java/com/google/gcloud/{ => dns}/spi/DefaultDnsRpc.java (91%) rename gcloud-java-dns/src/main/java/com/google/gcloud/{ => dns}/spi/DnsRpc.java (99%) rename gcloud-java-dns/src/main/java/com/google/gcloud/{ => dns}/spi/DnsRpcFactory.java (91%) diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/AbstractOption.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/AbstractOption.java index a148468d14b5..e12f7412e687 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/AbstractOption.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/AbstractOption.java @@ -19,7 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.MoreObjects; -import com.google.gcloud.spi.DnsRpc; +import com.google.gcloud.dns.spi.DnsRpc; import java.io.Serializable; import java.util.Objects; diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index b2cb9fbad371..6ce6b4c19994 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -20,7 +20,7 @@ import com.google.common.collect.Sets; import com.google.gcloud.Page; import com.google.gcloud.Service; -import com.google.gcloud.spi.DnsRpc; +import com.google.gcloud.dns.spi.DnsRpc; import java.io.Serializable; import java.util.Set; diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java index 17521c13c625..a60cfd9151da 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java @@ -33,7 +33,7 @@ import com.google.gcloud.Page; import com.google.gcloud.PageImpl; import com.google.gcloud.RetryHelper; -import com.google.gcloud.spi.DnsRpc; +import com.google.gcloud.dns.spi.DnsRpc; import java.util.Map; import java.util.concurrent.Callable; diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java index d9317546cea0..db922b42a3cb 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java @@ -18,9 +18,9 @@ import com.google.common.collect.ImmutableSet; import com.google.gcloud.ServiceOptions; -import com.google.gcloud.spi.DefaultDnsRpc; -import com.google.gcloud.spi.DnsRpc; -import com.google.gcloud.spi.DnsRpcFactory; +import com.google.gcloud.dns.spi.DefaultDnsRpc; +import com.google.gcloud.dns.spi.DnsRpc; +import com.google.gcloud.dns.spi.DnsRpcFactory; import java.util.Set; diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DefaultDnsRpc.java similarity index 91% rename from gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java rename to gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DefaultDnsRpc.java index 1df0a8a2f831..f8b8adb87ada 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DefaultDnsRpc.java @@ -1,13 +1,13 @@ -package com.google.gcloud.spi; - -import static com.google.gcloud.spi.DnsRpc.ListResult.of; -import static com.google.gcloud.spi.DnsRpc.Option.DNS_NAME; -import static com.google.gcloud.spi.DnsRpc.Option.DNS_TYPE; -import static com.google.gcloud.spi.DnsRpc.Option.FIELDS; -import static com.google.gcloud.spi.DnsRpc.Option.NAME; -import static com.google.gcloud.spi.DnsRpc.Option.PAGE_SIZE; -import static com.google.gcloud.spi.DnsRpc.Option.PAGE_TOKEN; -import static com.google.gcloud.spi.DnsRpc.Option.SORTING_ORDER; +package com.google.gcloud.dns.spi; + +import static com.google.gcloud.dns.spi.DnsRpc.ListResult.of; +import static com.google.gcloud.dns.spi.DnsRpc.Option.DNS_NAME; +import static com.google.gcloud.dns.spi.DnsRpc.Option.DNS_TYPE; +import static com.google.gcloud.dns.spi.DnsRpc.Option.FIELDS; +import static com.google.gcloud.dns.spi.DnsRpc.Option.NAME; +import static com.google.gcloud.dns.spi.DnsRpc.Option.PAGE_SIZE; +import static com.google.gcloud.dns.spi.DnsRpc.Option.PAGE_TOKEN; +import static com.google.gcloud.dns.spi.DnsRpc.Option.SORTING_ORDER; import static java.net.HttpURLConnection.HTTP_NOT_FOUND; import com.google.api.client.http.HttpRequestInitializer; @@ -188,7 +188,7 @@ public ListResult listChangeRequests(String zoneName, Map opt request = request.setSortBy(SORT_BY).setSortOrder(SORTING_ORDER.getString(options)); } ChangesListResponse response = request.execute(); - return ListResult.of(response.getNextPageToken(), response.getChanges()); + return of(response.getNextPageToken(), response.getChanges()); } catch (IOException ex) { throw translate(ex); } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DnsRpc.java similarity index 99% rename from gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java rename to gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DnsRpc.java index addb69d24b40..bde93b99bfdd 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DnsRpc.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.spi; +package com.google.gcloud.dns.spi; import com.google.api.services.dns.model.Change; import com.google.api.services.dns.model.ManagedZone; diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpcFactory.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DnsRpcFactory.java similarity index 91% rename from gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpcFactory.java rename to gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DnsRpcFactory.java index 3d25f09bb1e5..ca1b1a0dd018 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DnsRpcFactory.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DnsRpcFactory.java @@ -14,9 +14,10 @@ * limitations under the License. */ -package com.google.gcloud.spi; +package com.google.gcloud.dns.spi; import com.google.gcloud.dns.DnsOptions; +import com.google.gcloud.spi.ServiceRpcFactory; /** * An interface for DnsRpc factory. Implementation will be loaded via {@link diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/AbstractOptionTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/AbstractOptionTest.java index 09e35527879b..d88ea85c5846 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/AbstractOptionTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/AbstractOptionTest.java @@ -20,7 +20,7 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.fail; -import com.google.gcloud.spi.DnsRpc; +import com.google.gcloud.dns.spi.DnsRpc; import org.junit.Test; diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java index 9205de8d99dd..a97c9c408036 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java @@ -28,8 +28,8 @@ import com.google.gcloud.Page; import com.google.gcloud.RetryParams; import com.google.gcloud.ServiceOptions; -import com.google.gcloud.spi.DnsRpc; -import com.google.gcloud.spi.DnsRpcFactory; +import com.google.gcloud.dns.spi.DnsRpc; +import com.google.gcloud.dns.spi.DnsRpcFactory; import org.easymock.Capture; import org.easymock.EasyMock; diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java index c9f4df4f5bdd..2e233e2df62a 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java @@ -19,7 +19,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import com.google.gcloud.spi.DnsRpc; +import com.google.gcloud.dns.spi.DnsRpc; import org.junit.Test; diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/testing/LocalDnsHelperTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/testing/LocalDnsHelperTest.java index 15fa437eb631..59002131cc9d 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/testing/LocalDnsHelperTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/testing/LocalDnsHelperTest.java @@ -32,8 +32,8 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.gcloud.dns.DnsException; -import com.google.gcloud.spi.DefaultDnsRpc; -import com.google.gcloud.spi.DnsRpc; +import com.google.gcloud.dns.spi.DefaultDnsRpc; +import com.google.gcloud.dns.spi.DnsRpc; import org.junit.AfterClass; import org.junit.Before; From 4e0248f951ddc61ae2a5cdb82d1f953f3bba17cb Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 15 Mar 2016 14:33:27 +0100 Subject: [PATCH 167/375] Add better javadoc for signUrl examples --- .../java/com/google/gcloud/storage/Blob.java | 30 +++++++++---------- .../com/google/gcloud/storage/Storage.java | 13 ++++---- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java index c60a703eda91..b4fc892d3df5 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java @@ -456,27 +456,27 @@ public WriteChannel writer(BlobWriteOption... options) { /** * Generates a signed URL for this blob. If you want to allow access for a fixed amount of time to * this blob, you can use this method to generate a URL that is only valid within a certain time - * period. This is particularly useful if you don't want publicly accessible blobs, but don't want - * to require users to explicitly log in. Signing a URL requires a service account - * and its associated private key. If a {@link AuthCredentials.ServiceAccountAuthCredentials} was - * passed to {@link StorageOptions.Builder#authCredentials(AuthCredentials)} or the default - * credentials are being used and the environment variable {@code GOOGLE_APPLICATION_CREDENTIALS} - * is set, then {@code signUrl} will use that service account and associated key to sign the URL. - * If the credentials passed to {@link StorageOptions} do not expose a private key (this is the - * case for App Engine credentials, Compute Engine credentials and Google Cloud SDK credentials) - * then {@code signUrl} will throw an {@link IllegalArgumentException} unless a service account - * with associated key is passed using the {@code SignUrlOption.serviceAccount()} option. The - * service account and private key passed with {@code SignUrlOption.serviceAccount()} have - * priority over any credentials set with - * {@link StorageOptions.Builder#authCredentials(AuthCredentials)}. + * period. This is particularly useful if you don't want publicly accessible blobs, but also don't + * want to require users to explicitly log in. Signing a URL requires a service account and its + * associated private key. If a {@link AuthCredentials.ServiceAccountAuthCredentials} was passed + * to {@link StorageOptions.Builder#authCredentials(AuthCredentials)} or the default credentials + * are being used and the environment variable {@code GOOGLE_APPLICATION_CREDENTIALS} is set, then + * {@code signUrl} will use that service account and associated key to sign the URL. If the + * credentials passed to {@link StorageOptions} do not expose a private key (this is the case for + * App Engine credentials, Compute Engine credentials and Google Cloud SDK credentials) then + * {@code signUrl} will throw an {@link IllegalArgumentException} unless a service account with + * associated key is passed using the {@code SignUrlOption.serviceAccount()} option. The service + * account and private key passed with {@code SignUrlOption.serviceAccount()} have priority over + * any credentials set with {@link StorageOptions.Builder#authCredentials(AuthCredentials)}. * - *

    Example usage of creating a signed URL that is valid for 2 weeks: + *

    Example usage of creating a signed URL that is valid for 2 weeks, using the default + * credentials for signing the URL: *

     {@code
        * blob.signUrl(14, TimeUnit.DAYS);
        * }
    * *

    Example usage of creating a signed URL passing the {@code SignUrlOption.serviceAccount()} - * option: + * option, that will be used for signing the URL: *

     {@code
        * blob.signUrl(14, TimeUnit.DAYS, SignUrlOption.serviceAccount(
        *     AuthCredentials.createForJson(new FileInputStream("/path/to/key.json"))));
    diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java
    index 91f7578d7f89..7a58878469f1 100644
    --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java
    +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java
    @@ -1480,10 +1480,10 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx
        * Generates a signed URL for a blob. If you have a blob that you want to allow access to for a
        * fixed amount of time, you can use this method to generate a URL that is only valid within a
        * certain time period. This is particularly useful if you don't want publicly accessible blobs,
    -   * but don't want to require users to explicitly log in. Signing a URL requires a service account
    -   * and its associated private key. If a {@link ServiceAccountAuthCredentials} was passed to
    -   * {@link StorageOptions.Builder#authCredentials(AuthCredentials)} or the default credentials are
    -   * being used and the environment variable {@code GOOGLE_APPLICATION_CREDENTIALS} is set, then
    +   * but also don't want to require users to explicitly log in. Signing a URL requires a service
    +   * account and its associated private key. If a {@link ServiceAccountAuthCredentials} was passed
    +   * to {@link StorageOptions.Builder#authCredentials(AuthCredentials)} or the default credentials
    +   * are being used and the environment variable {@code GOOGLE_APPLICATION_CREDENTIALS} is set, then
        * {@code signUrl} will use that service account and associated key to sign the URL. If the
        * credentials passed to {@link StorageOptions} do not expose a private key (this is the case for
        * App Engine credentials, Compute Engine credentials and Google Cloud SDK credentials) then
    @@ -1492,13 +1492,14 @@ private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentEx
        * account and private key passed with {@code SignUrlOption.serviceAccount()} have priority over
        * any credentials set with {@link StorageOptions.Builder#authCredentials(AuthCredentials)}.
        *
    -   * 

    Example usage of creating a signed URL that is valid for 2 weeks: + *

    Example usage of creating a signed URL that is valid for 2 weeks, using the default + * credentials for signing the URL: *

     {@code
        * service.signUrl(BlobInfo.builder("bucket", "name").build(), 14, TimeUnit.DAYS);
        * }
    * *

    Example usage of creating a signed URL passing the {@code SignUrlOption.serviceAccount()} - * option: + * option, that will be used for signing the URL: *

     {@code
        * service.signUrl(BlobInfo.builder("bucket", "name").build(), 14, TimeUnit.DAYS,
        *     SignUrlOption.serviceAccount(
    
    From 886a8bdf0885edcaf971bd6aca9de715727ae11c Mon Sep 17 00:00:00 2001
    From: Martin Derka 
    Date: Wed, 2 Mar 2016 10:13:20 -0800
    Subject: [PATCH 168/375]  Added a DNS example and documentation.
    
    ---
     gcloud-java-examples/README.md                |  19 +-
     .../google/gcloud/examples/DnsExample.java    | 516 ++++++++++++++++++
     gcloud-java/pom.xml                           |   5 +
     3 files changed, 539 insertions(+), 1 deletion(-)
     create mode 100644 gcloud-java-examples/src/main/java/com/google/gcloud/examples/DnsExample.java
    
    diff --git a/gcloud-java-examples/README.md b/gcloud-java-examples/README.md
    index 59fbca11e219..3807813b3df0 100644
    --- a/gcloud-java-examples/README.md
    +++ b/gcloud-java-examples/README.md
    @@ -63,7 +63,7 @@ To run examples from your command line:
         ```
     
       * Here's an example run of `DatastoreExample`.
    -  
    +
         Be sure to change the placeholder project ID "your-project-id" with your own project ID. Also note that you have to enable the Google Cloud Datastore API on the [Google Developers Console][developers-console] before running the following commands.
         ```
         mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.datastore.DatastoreExample" -Dexec.args="your-project-id my_name add my\ comment"
    @@ -71,6 +71,23 @@ To run examples from your command line:
         mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.datastore.DatastoreExample" -Dexec.args="your-project-id my_name delete"
         ```
     
    +  * Here's an example run of `DnsExample`.
    +
    +    Note that you have to enable the Google Cloud DNS API on the [Google Developers Console][developers-console] before running the following commands.
    +    Note that the example creates and deletes dns records of type A only. Operations with other record types are not implemented in the example.
    +    ```
    +    $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.DnsExample" -Dexec.args="create some-sample-zone elaborateexample.com. description"
    +    $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.DnsExample" -Dexec.args="get some-sample-zone"
    +    $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.DnsExample" -Dexec.args="list"
    +    $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.DnsExample" -Dexec.args="list some-sample-zone records"
    +    $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.DnsExample" -Dexec.args="add-record some-sample-zone www.elaborateexample.com. 12.13.14.15 69"
    +    $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.DnsExample" -Dexec.args="get some-sample-zone"
    +    $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.DnsExample" -Dexec.args="delete-record some-sample-zone www.elaborateexample.com. 12.13.14.15 69"
    +    $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.DnsExample" -Dexec.args="list some-sample-zone changes ascending"
    +    $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.DnsExample" -Dexec.args="delete some-sample-zone"
    +    $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.DnsExample" -Dexec.args="quota"
    +    ```
    +
       * Here's an example run of `ResourceManagerExample`.
     
         Be sure to change the placeholder project ID "your-project-id" with your own globally unique project ID.
    diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/DnsExample.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/DnsExample.java
    new file mode 100644
    index 000000000000..071ba59e0f7e
    --- /dev/null
    +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/DnsExample.java
    @@ -0,0 +1,516 @@
    +/*
    + * Copyright 2016 Google Inc. All Rights Reserved.
    + *
    + * 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.gcloud.examples;
    +
    +import com.google.common.base.Joiner;
    +import com.google.common.collect.ImmutableList;
    +import com.google.gcloud.dns.ChangeRequest;
    +import com.google.gcloud.dns.Dns;
    +import com.google.gcloud.dns.DnsOptions;
    +import com.google.gcloud.dns.DnsRecord;
    +import com.google.gcloud.dns.ProjectInfo;
    +import com.google.gcloud.dns.Zone;
    +import com.google.gcloud.dns.ZoneInfo;
    +
    +import java.util.Arrays;
    +import java.util.HashMap;
    +import java.util.Iterator;
    +import java.util.Map;
    +import java.util.concurrent.TimeUnit;
    +
    +/**
    + * An example of using Google Cloud DNS.
    + *
    + * 

    This example creates, deletes, gets, and lists zones, and creates and deletes DNS records of + * type A. + * + *

    Steps needed for running the example:

      + *
    1. login using gcloud SDK - {@code gcloud auth login}.
    2. + *
    3. compile using maven - {@code mvn compile}
    4. + *
    5. run using maven - {@code mvn exec:java + * -Dexec.mainClass="com.google.gcloud.examples.dns.DnsExample" + * -Dexec.args="[] + * create | + * get | + * delete | + * list [ [changes [descending | ascending] | records]] | + * add-record | + * delete-record [] | + * quota
    6. + *
    + * + *

    The first parameter is an optional {@code project_id} (logged-in project will be used if not + * supplied). Second parameter is a DNS operation (list, delete, create,...) and can be used to + * demonstrate the usage. The remaining arguments are specific to the operation. See each action's + * run method for the specific interaction. + */ +public class DnsExample { + + private static final Map ACTIONS = new HashMap<>(); + + private interface DnsAction { + void run(Dns dns, String... args); + + String params(); + + boolean check(String... args); + } + + private static class CreateZoneAction implements DnsAction { + + /** + * Creates a zone with the provided name, dns name and description (in this order). + */ + @Override + public void run(Dns dns, String... args) { + String zoneName = args[0]; + String dnsName = args[1]; + String description = args[2]; + ZoneInfo zoneInfo = ZoneInfo.builder(zoneName) + .dnsName(dnsName) + .description(description) + .build(); + Zone zone = dns.create(zoneInfo); + System.out.printf("Successfully created zone with name %s which was assigned ID %s.%n", + zone.name(), zone.id()); + } + + @Override + public String params() { + return " "; + } + + @Override + public boolean check(String... args) { + return args.length == 3; + } + } + + private static class ListZonesAction implements DnsAction { + + /** + * Lists all zones within the project. + */ + @Override + public void run(Dns dns, String... args) { + Iterator zoneIterator = dns.listZones().iterateAll(); + if (zoneIterator.hasNext()) { + System.out.println("The project contains the following zones:"); + System.out.println("Name\tID\tDNS Name\tCreated\tDesription"); + while (zoneIterator.hasNext()) { + Zone zone = zoneIterator.next(); + System.out.printf("%s\t%s\t%s\t%s\t%s%n", zone.name(), zone.id(), zone.dnsName(), + zone.creationTimeMillis(), zone.description()); + } + } else { + System.out.println("Project contains no zones."); + } + } + + @Override + public String params() { + return ""; + } + + @Override + public boolean check(String... args) { + return args.length == 0; + } + } + + private static class GetZoneAction implements DnsAction { + + /** + * Gets details about a zone with the given name. + */ + @Override + public void run(Dns dns, String... args) { + String zoneName = args[0]; + Zone zone = dns.getZone(zoneName); + if (zone == null) { + System.out.printf("No zone with name '%s' exists.%n", zoneName); + } else { + System.out.printf("Name: %s%n", zone.name()); + System.out.printf("ID: %s%n", zone.id()); + System.out.printf("Description: %s%n", zone.description()); + System.out.printf("Created: %s%n", zone.creationTimeMillis()); + System.out.printf("Name servers: %s%n", Joiner.on(",").join(zone.nameServers())); + } + } + + @Override + public String params() { + return ""; + } + + @Override + public boolean check(String... args) { + return args.length == 1; + } + } + + private static class DeleteZoneAction implements DnsAction { + + /** + * Deletes a zone with the given name. + */ + @Override + public void run(Dns dns, String... args) { + String zoneName = args[0]; + boolean deleted = dns.delete(zoneName); + if (deleted) { + System.out.printf("Zone %s was deleted.%n", zoneName); + } else { + System.out.printf("Zone %s was NOT deleted. It probably does not exist.%n", zoneName); + } + } + + @Override + public String params() { + return ""; + } + + @Override + public boolean check(String... args) { + return args.length == 1; + } + + } + + private static class DeleteDnsRecordAction implements DnsAction { + + /** + * Deletes a DNS record of type A from the given zone. The last parameter is ttl and it is not + * required. + */ + @Override + public void run(Dns dns, String... args) { + String zoneName = args[0]; + String recordName = args[1]; + String ip = args[2]; + DnsRecord record = DnsRecord.builder(recordName, DnsRecord.Type.A) + .records(ImmutableList.of(ip)) + .build(); + if (args.length > 3) { + Integer ttl = Integer.valueOf(args[3]); + record = record.toBuilder().ttl(ttl, TimeUnit.SECONDS).build(); + } + ChangeRequest changeRequest = ChangeRequest.builder() + .delete(record) + .build(); + changeRequest = dns.applyChangeRequest(zoneName, changeRequest); + System.out.printf("The request for deleting A record %s for zone %s was successfully " + + "submitted and assigned ID %s.%n", recordName, zoneName, changeRequest.id()); + while (changeRequest.status().equals(ChangeRequest.Status.PENDING)) { + try { + Thread.sleep(500); + } catch (InterruptedException e) { + System.err.println("Thread was interrupted while waiting."); + } + changeRequest = dns.getChangeRequest(zoneName, changeRequest.id()); + } + System.out.printf("The deletion has been completed.%n"); + } + + @Override + public String params() { + return " []"; + } + + @Override + public boolean check(String... args) { + if (args.length == 4) { + try { + Integer.valueOf(args[3]); + } catch (Exception ex) { + throw new IllegalArgumentException(ex); + } + return true; + } else { + return args.length == 3; + } + } + } + + private static class AddDnsRecordAction implements DnsAction { + + /** + * Adds a DNS record of type A. The last parameter is ttl and is not required. + */ + @Override + public void run(Dns dns, String... args) { + String zoneName = args[0]; + String recordName = args[1]; + String ip = args[2]; + DnsRecord record = DnsRecord.builder(recordName, DnsRecord.Type.A) + .records(ImmutableList.of(ip)) + .build(); + if (args.length > 3) { + Integer ttl = Integer.valueOf(args[3]); + record = record.toBuilder().ttl(ttl, TimeUnit.SECONDS).build(); + } + ChangeRequest changeRequest = ChangeRequest.builder() + .add(record) + .build(); + changeRequest = dns.applyChangeRequest(zoneName, changeRequest); + System.out.printf("The request for adding A record %s for zone %s was successfully " + + "submitted and assigned ID %s.%n", recordName, zoneName, changeRequest.id()); + while (changeRequest.status().equals(ChangeRequest.Status.PENDING)) { + try { + Thread.sleep(500); + } catch (InterruptedException e) { + System.err.println("Thread was interrupted while waiting."); + } + changeRequest = dns.getChangeRequest(zoneName, changeRequest.id()); + } + System.out.printf("The addition has been completed.%n"); + } + + @Override + public String params() { + return " []"; + } + + @Override + public boolean check(String... args) { + if (args.length == 4) { + try { + Integer.valueOf(args[3]); + } catch (Exception ex) { + throw new IllegalArgumentException(ex); + } + return true; + } else { + return args.length == 3; + } + } + } + + private static class ListDnsRecordsAction implements DnsAction { + + /** + * Lists all the DNS records in the given zone. + */ + @Override + public void run(Dns dns, String... args) { + String zoneName = args[0]; + Iterator iterator = dns.listDnsRecords(zoneName).iterateAll(); + if (iterator.hasNext()) { + System.out.printf("DNS records for zone %s:%n", zoneName); + System.out.printf("Record name\tTTL\tRecords%n"); + while (iterator.hasNext()) { + DnsRecord record = iterator.next(); + System.out.printf("%s\t%s\t%s%n", record.name(), record.ttl(), + Joiner.on(",").join(record.records())); + } + } else { + System.out.printf("Zone %s has no DNS records.%n", zoneName); + } + } + + @Override + public String params() { + return " records"; + } + + @Override + public boolean check(String... args) { + return args.length == 2; + } + } + + private static class ListChangesAction implements DnsAction { + + /** + * Lists all the changes for a given zone. Optionally, an order, "descending" or "ascending" can + * be specified using the last parameter. + */ + @Override + public void run(Dns dns, String... args) { + String zoneName = args[0]; + Iterator iterator; + if (args.length > 2) { + Dns.SortingOrder sortOrder = Dns.SortingOrder.valueOf(args[2].toUpperCase()); + iterator = dns.listChangeRequests(zoneName, + Dns.ChangeRequestListOption.sortOrder(sortOrder)).iterateAll(); + } else { + iterator = dns.listChangeRequests(zoneName).iterateAll(); + } + if (iterator.hasNext()) { + System.out.printf("Change requests for zone %s:%n", zoneName); + System.out.printf("ID\tStatus\tTimestamp%n"); + while (iterator.hasNext()) { + ChangeRequest change = iterator.next(); + System.out.printf("%s\t%s\t%s%n", change.id(), change.status(), change.startTimeMillis()); + System.out.printf("\tDeletions: %s%n", Joiner.on(",").join(change.deletions())); + System.out.printf("\tAdditions: %s%n", Joiner.on(",").join(change.additions())); + } + } else { + System.out.printf("Zone %s has no change requests.%n", zoneName); + } + } + + @Override + public String params() { + return " changes [descending | ascending]"; + } + + @Override + public boolean check(String... args) { + System.err.println(Arrays.asList(args)); + return args.length == 2 + || (args.length == 3 && ImmutableList.of("descending", "ascending").contains(args[2])); + } + } + + private static class ListAction implements DnsAction { + + /** + * Invokes a list action. If no parameter is provided, lists all zones. If zone name is the only + * parameter provided, lists both DNS records and changes. Otherwise, invokes listing changes or + * zones based on the parameter provided. + */ + @Override + public void run(Dns dns, String... args) { + if (args.length == 0) { + new ListZonesAction().run(dns); + } else { + if (args.length == 1 || "records".equals(args[1])) { + new ListDnsRecordsAction().run(dns, args); + } + if (args.length == 1 || "changes".equals(args[1])) { + new ListChangesAction().run(dns, args); + } + } + } + + @Override + public boolean check(String... args) { + if (args.length == 0 || args.length == 1) { + return true; + } + if ("records".equals(args[1])) { + return new ListDnsRecordsAction().check(args); + } + if ("changes".equals(args[1])) { + return new ListChangesAction().check(args); + } + return false; + } + + @Override + public String params() { + return "[ [changes [descending | ascending] | records]]"; + } + } + + private static class GetProjectAction implements DnsAction { + + @Override + public void run(Dns dns, String... args) { + ProjectInfo project = dns.getProject(); + System.out.printf("Project id: %s%nQuota:%n", dns.options().projectId()); + System.out.printf("\tZones: %d%n", project.quota().zones()); + System.out.printf("\tDNS records per zone: %d%n", project.quota().rrsetsPerZone()); + System.out.printf("\tRecord sets per DNS record: %d%n", + project.quota().resourceRecordsPerRrset()); + System.out.printf("\tAdditions per change: %d%n", project.quota().rrsetAdditionsPerChange()); + System.out.printf("\tDeletions per change: %d%n", project.quota().rrsetDeletionsPerChange()); + System.out.printf("\tTotal data size per change: %d%n", + project.quota().totalRrdataSizePerChange()); + } + + @Override + public String params() { + return ""; + } + + @Override + public boolean check(String... args) { + return args.length == 0; + } + } + + static { + ACTIONS.put("create", new CreateZoneAction()); + ACTIONS.put("delete", new DeleteZoneAction()); + ACTIONS.put("get", new GetZoneAction()); + ACTIONS.put("list", new ListAction()); + ACTIONS.put("add-record", new AddDnsRecordAction()); + ACTIONS.put("delete-record", new DeleteDnsRecordAction()); + ACTIONS.put("quota", new GetProjectAction()); + } + + private static void printUsage() { + StringBuilder actionAndParams = new StringBuilder(); + for (Map.Entry entry : ACTIONS.entrySet()) { + actionAndParams.append('\t').append(System.lineSeparator()).append(entry.getKey()); + String param = entry.getValue().params(); + if (param != null && !param.isEmpty()) { + actionAndParams.append(' ').append(param); + } + } + System.out.printf("Usage: %s [] operation *%s%n", + DnsExample.class.getSimpleName(), actionAndParams); + } + + public static void main(String... args) throws Exception { + if (args.length < 1) { + System.out.println("Missing required action"); + printUsage(); + return; + } + DnsOptions.Builder optionsBuilder = DnsOptions.builder(); + DnsAction action; + String actionName; + if (args.length >= 2 && !ACTIONS.containsKey(args[0])) { + actionName = args[1]; + optionsBuilder.projectId(args[0]); + action = ACTIONS.get(args[1]); + args = Arrays.copyOfRange(args, 2, args.length); + } else { + actionName = args[0]; + action = ACTIONS.get(args[0]); + args = Arrays.copyOfRange(args, 1, args.length); + } + if (action == null) { + System.out.println("Unrecognized action."); + printUsage(); + return; + } + Dns dns = optionsBuilder.build().service(); + boolean valid = false; + try { + valid = action.check(args); + } catch (NumberFormatException ex) { + System.out.println("Invalid input for action '" + actionName + "'."); + System.out.println("Ttl must be an integer."); + System.out.println("Expected: " + action.params()); + return; + } catch (Exception ex) { + System.out.println("Failed to parse request."); + ex.printStackTrace(); + return; + } + if (valid) { + action.run(dns, args); + } else { + System.out.println("Invalid input for action '" + actionName + "'"); + System.out.println("Expected: " + action.params()); + } + } +} diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml index adfa716fe27b..b7dfd3f12e8f 100644 --- a/gcloud-java/pom.xml +++ b/gcloud-java/pom.xml @@ -38,5 +38,10 @@ gcloud-java-storage ${project.version} + + ${project.groupId} + gcloud-java-dns + ${project.version} + From 8e82f351520d9e8768a2818545f99a6f41c7bf2b Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Wed, 9 Mar 2016 16:40:56 -0800 Subject: [PATCH 169/375] Fixed based on first round of comments: - moved to correct package - added printouts while waiting for changes - removed tab-based formatting - removed NumberFormatException hiding - some minor code refactoring - extended documentation - switched builder() to of() construct in DNS example --- gcloud-java-examples/README.md | 21 ++- .../gcloud/examples/{ => dns}/DnsExample.java | 132 ++++++++++-------- gcloud-java/pom.xml | 6 +- 3 files changed, 85 insertions(+), 74 deletions(-) rename gcloud-java-examples/src/main/java/com/google/gcloud/examples/{ => dns}/DnsExample.java (78%) diff --git a/gcloud-java-examples/README.md b/gcloud-java-examples/README.md index 3807813b3df0..73d613c94e27 100644 --- a/gcloud-java-examples/README.md +++ b/gcloud-java-examples/README.md @@ -74,18 +74,17 @@ To run examples from your command line: * Here's an example run of `DnsExample`. Note that you have to enable the Google Cloud DNS API on the [Google Developers Console][developers-console] before running the following commands. - Note that the example creates and deletes dns records of type A only. Operations with other record types are not implemented in the example. + You will need to replace the domain name `elaborateexample.com` with your own domain name with verified ownership. + Also, note that the example creates and deletes DNS records of type A only. Operations with other record types are not implemented in the example. ``` - $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.DnsExample" -Dexec.args="create some-sample-zone elaborateexample.com. description" - $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.DnsExample" -Dexec.args="get some-sample-zone" - $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.DnsExample" -Dexec.args="list" - $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.DnsExample" -Dexec.args="list some-sample-zone records" - $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.DnsExample" -Dexec.args="add-record some-sample-zone www.elaborateexample.com. 12.13.14.15 69" - $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.DnsExample" -Dexec.args="get some-sample-zone" - $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.DnsExample" -Dexec.args="delete-record some-sample-zone www.elaborateexample.com. 12.13.14.15 69" - $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.DnsExample" -Dexec.args="list some-sample-zone changes ascending" - $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.DnsExample" -Dexec.args="delete some-sample-zone" - $mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.DnsExample" -Dexec.args="quota" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.dns.DnsExample" -Dexec.args="create some-sample-zone elaborateexample.com. description" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.dns.DnsExample" -Dexec.args="list" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.dns.DnsExample" -Dexec.args="list some-sample-zone records" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.dns.DnsExample" -Dexec.args="add-record some-sample-zone www.elaborateexample.com. 12.13.14.15 69" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.dns.DnsExample" -Dexec.args="get some-sample-zone" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.dns.DnsExample" -Dexec.args="delete-record some-sample-zone www.elaborateexample.com. 12.13.14.15 69" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.dns.DnsExample" -Dexec.args="list some-sample-zone changes ascending" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.dns.DnsExample" -Dexec.args="delete some-sample-zone" ``` * Here's an example run of `ResourceManagerExample`. diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/DnsExample.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java similarity index 78% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/DnsExample.java rename to gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java index 071ba59e0f7e..2061f4931cab 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/DnsExample.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.examples; +package com.google.gcloud.examples.dns; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; @@ -26,7 +26,10 @@ import com.google.gcloud.dns.Zone; import com.google.gcloud.dns.ZoneInfo; +import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.util.Arrays; +import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -38,7 +41,8 @@ *

    This example creates, deletes, gets, and lists zones, and creates and deletes DNS records of * type A. * - *

    Steps needed for running the example:

      + *

      Steps needed for running the example: + *

        *
      1. login using gcloud SDK - {@code gcloud auth login}.
      2. *
      3. compile using maven - {@code mvn compile}
      4. *
      5. run using maven - {@code mvn exec:java @@ -50,13 +54,13 @@ * list [ [changes [descending | ascending] | records]] | * add-record | * delete-record [] | - * quota
      6. + * quota} *
      * *

      The first parameter is an optional {@code project_id} (logged-in project will be used if not - * supplied). Second parameter is a DNS operation (list, delete, create,...) and can be used to - * demonstrate the usage. The remaining arguments are specific to the operation. See each action's - * run method for the specific interaction. + * supplied). Second parameter is a DNS operation (list, delete, create,...). The remaining + * arguments are specific to the operation. See each action's run method for the specific + * interaction. */ public class DnsExample { @@ -80,10 +84,7 @@ public void run(Dns dns, String... args) { String zoneName = args[0]; String dnsName = args[1]; String description = args[2]; - ZoneInfo zoneInfo = ZoneInfo.builder(zoneName) - .dnsName(dnsName) - .description(description) - .build(); + ZoneInfo zoneInfo = ZoneInfo.of(zoneName, dnsName, description); Zone zone = dns.create(zoneInfo); System.out.printf("Successfully created zone with name %s which was assigned ID %s.%n", zone.name(), zone.id()); @@ -110,11 +111,14 @@ public void run(Dns dns, String... args) { Iterator zoneIterator = dns.listZones().iterateAll(); if (zoneIterator.hasNext()) { System.out.println("The project contains the following zones:"); - System.out.println("Name\tID\tDNS Name\tCreated\tDesription"); + DateFormat formatter = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss"); while (zoneIterator.hasNext()) { Zone zone = zoneIterator.next(); - System.out.printf("%s\t%s\t%s\t%s\t%s%n", zone.name(), zone.id(), zone.dnsName(), - zone.creationTimeMillis(), zone.description()); + System.out.printf("%nName: %s%n", zone.name()); + System.out.printf("ID: %s%n", zone.id()); + System.out.printf("Description: %s%n", zone.description()); + System.out.printf("Created: %s%n", formatter.format(new Date(zone.creationTimeMillis()))); + System.out.printf("Name servers: %s%n", Joiner.on(", ").join(zone.nameServers())); } } else { System.out.println("Project contains no zones."); @@ -147,8 +151,9 @@ public void run(Dns dns, String... args) { System.out.printf("Name: %s%n", zone.name()); System.out.printf("ID: %s%n", zone.id()); System.out.printf("Description: %s%n", zone.description()); - System.out.printf("Created: %s%n", zone.creationTimeMillis()); - System.out.printf("Name servers: %s%n", Joiner.on(",").join(zone.nameServers())); + DateFormat formatter = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss"); + System.out.printf("Created: %s%n", formatter.format(new Date(zone.creationTimeMillis()))); + System.out.printf("Name servers: %s%n", Joiner.on(", ").join(zone.nameServers())); } } @@ -175,7 +180,7 @@ public void run(Dns dns, String... args) { if (deleted) { System.out.printf("Zone %s was deleted.%n", zoneName); } else { - System.out.printf("Zone %s was NOT deleted. It probably does not exist.%n", zoneName); + System.out.printf("Zone %s was NOT deleted. It does not exist.%n", zoneName); } } @@ -195,27 +200,31 @@ private static class DeleteDnsRecordAction implements DnsAction { /** * Deletes a DNS record of type A from the given zone. The last parameter is ttl and it is not - * required. + * required. If ttl is not provided, a default value of 0 is used. The service requires a + * precise match (including ttl) for deleting a record. */ @Override public void run(Dns dns, String... args) { String zoneName = args[0]; String recordName = args[1]; String ip = args[2]; + int ttl = 0; + if (args.length > 3) { + ttl = Integer.valueOf(args[3]); + } DnsRecord record = DnsRecord.builder(recordName, DnsRecord.Type.A) .records(ImmutableList.of(ip)) + .ttl(ttl, TimeUnit.SECONDS) .build(); - if (args.length > 3) { - Integer ttl = Integer.valueOf(args[3]); - record = record.toBuilder().ttl(ttl, TimeUnit.SECONDS).build(); - } ChangeRequest changeRequest = ChangeRequest.builder() .delete(record) .build(); changeRequest = dns.applyChangeRequest(zoneName, changeRequest); System.out.printf("The request for deleting A record %s for zone %s was successfully " + "submitted and assigned ID %s.%n", recordName, zoneName, changeRequest.id()); + System.out.print("Waiting for deletion to happen..."); while (changeRequest.status().equals(ChangeRequest.Status.PENDING)) { + System.out.print("."); try { Thread.sleep(500); } catch (InterruptedException e) { @@ -223,7 +232,7 @@ record = record.toBuilder().ttl(ttl, TimeUnit.SECONDS).build(); } changeRequest = dns.getChangeRequest(zoneName, changeRequest.id()); } - System.out.printf("The deletion has been completed.%n"); + System.out.printf("%nThe deletion has been completed.%n"); } @Override @@ -234,11 +243,8 @@ public String params() { @Override public boolean check(String... args) { if (args.length == 4) { - try { - Integer.valueOf(args[3]); - } catch (Exception ex) { - throw new IllegalArgumentException(ex); - } + // to check that it can be parsed + Integer.valueOf(args[3]); return true; } else { return args.length == 3; @@ -249,27 +255,31 @@ public boolean check(String... args) { private static class AddDnsRecordAction implements DnsAction { /** - * Adds a DNS record of type A. The last parameter is ttl and is not required. + * Adds a DNS record of type A. The last parameter is ttl and is not required. If ttl is not + * provided, a default value of 0 will be used. */ @Override public void run(Dns dns, String... args) { String zoneName = args[0]; String recordName = args[1]; String ip = args[2]; + int ttl = 0; + if (args.length > 3) { + ttl = Integer.valueOf(args[3]); + } DnsRecord record = DnsRecord.builder(recordName, DnsRecord.Type.A) .records(ImmutableList.of(ip)) + .ttl(ttl, TimeUnit.SECONDS) .build(); - if (args.length > 3) { - Integer ttl = Integer.valueOf(args[3]); - record = record.toBuilder().ttl(ttl, TimeUnit.SECONDS).build(); - } ChangeRequest changeRequest = ChangeRequest.builder() .add(record) .build(); changeRequest = dns.applyChangeRequest(zoneName, changeRequest); System.out.printf("The request for adding A record %s for zone %s was successfully " + "submitted and assigned ID %s.%n", recordName, zoneName, changeRequest.id()); + System.out.print("Waiting for deletion to happen..."); while (changeRequest.status().equals(ChangeRequest.Status.PENDING)) { + System.out.print("."); try { Thread.sleep(500); } catch (InterruptedException e) { @@ -288,11 +298,8 @@ public String params() { @Override public boolean check(String... args) { if (args.length == 4) { - try { - Integer.valueOf(args[3]); - } catch (Exception ex) { - throw new IllegalArgumentException(ex); - } + // to check that it can be parsed + Integer.valueOf(args[3]); return true; } else { return args.length == 3; @@ -311,11 +318,10 @@ public void run(Dns dns, String... args) { Iterator iterator = dns.listDnsRecords(zoneName).iterateAll(); if (iterator.hasNext()) { System.out.printf("DNS records for zone %s:%n", zoneName); - System.out.printf("Record name\tTTL\tRecords%n"); while (iterator.hasNext()) { DnsRecord record = iterator.next(); - System.out.printf("%s\t%s\t%s%n", record.name(), record.ttl(), - Joiner.on(",").join(record.records())); + System.out.printf("%nRecord name: %s%nTTL: %s%nRecords: %s%n", record.name(), + record.ttl(), Joiner.on(", ").join(record.records())); } } else { System.out.printf("Zone %s has no DNS records.%n", zoneName); @@ -352,12 +358,14 @@ public void run(Dns dns, String... args) { } if (iterator.hasNext()) { System.out.printf("Change requests for zone %s:%n", zoneName); - System.out.printf("ID\tStatus\tTimestamp%n"); + DateFormat formatter = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss"); while (iterator.hasNext()) { ChangeRequest change = iterator.next(); - System.out.printf("%s\t%s\t%s%n", change.id(), change.status(), change.startTimeMillis()); - System.out.printf("\tDeletions: %s%n", Joiner.on(",").join(change.deletions())); - System.out.printf("\tAdditions: %s%n", Joiner.on(",").join(change.additions())); + System.out.printf("%nID: %s%n", change.id()); + System.out.printf("Status: %s%n", change.status()); + System.out.printf("Started: %s%n", formatter.format(change.startTimeMillis())); + System.out.printf("Deletions: %s%n", Joiner.on(", ").join(change.deletions())); + System.out.printf("Additions: %s%n", Joiner.on(", ").join(change.additions())); } } else { System.out.printf("Zone %s has no change requests.%n", zoneName); @@ -371,9 +379,9 @@ public String params() { @Override public boolean check(String... args) { - System.err.println(Arrays.asList(args)); return args.length == 2 - || (args.length == 3 && ImmutableList.of("descending", "ascending").contains(args[2])); + || (args.length == 3 + && ImmutableList.of("descending", "ascending").contains(args[2].toLowerCase())); } } @@ -400,7 +408,7 @@ public void run(Dns dns, String... args) { @Override public boolean check(String... args) { - if (args.length == 0 || args.length == 1) { + if (args.length == 0) { return true; } if ("records".equals(args[1])) { @@ -423,15 +431,16 @@ private static class GetProjectAction implements DnsAction { @Override public void run(Dns dns, String... args) { ProjectInfo project = dns.getProject(); + ProjectInfo.Quota quota = project.quota(); System.out.printf("Project id: %s%nQuota:%n", dns.options().projectId()); - System.out.printf("\tZones: %d%n", project.quota().zones()); - System.out.printf("\tDNS records per zone: %d%n", project.quota().rrsetsPerZone()); + System.out.printf("\tZones: %d%n", quota.zones()); + System.out.printf("\tDNS records per zone: %d%n", quota.rrsetsPerZone()); System.out.printf("\tRecord sets per DNS record: %d%n", - project.quota().resourceRecordsPerRrset()); - System.out.printf("\tAdditions per change: %d%n", project.quota().rrsetAdditionsPerChange()); - System.out.printf("\tDeletions per change: %d%n", project.quota().rrsetDeletionsPerChange()); + quota.resourceRecordsPerRrset()); + System.out.printf("\tAdditions per change: %d%n", quota.rrsetAdditionsPerChange()); + System.out.printf("\tDeletions per change: %d%n", quota.rrsetDeletionsPerChange()); System.out.printf("\tTotal data size per change: %d%n", - project.quota().totalRrdataSizePerChange()); + quota.totalRrdataSizePerChange()); } @Override @@ -458,7 +467,7 @@ public boolean check(String... args) { private static void printUsage() { StringBuilder actionAndParams = new StringBuilder(); for (Map.Entry entry : ACTIONS.entrySet()) { - actionAndParams.append('\t').append(System.lineSeparator()).append(entry.getKey()); + actionAndParams.append(System.lineSeparator()).append('\t').append(entry.getKey()); String param = entry.getValue().params(); if (param != null && !param.isEmpty()) { actionAndParams.append(' ').append(param); @@ -474,25 +483,23 @@ public static void main(String... args) throws Exception { printUsage(); return; } - DnsOptions.Builder optionsBuilder = DnsOptions.builder(); + String projectId = null; DnsAction action; String actionName; if (args.length >= 2 && !ACTIONS.containsKey(args[0])) { actionName = args[1]; - optionsBuilder.projectId(args[0]); - action = ACTIONS.get(args[1]); + projectId = args[0]; args = Arrays.copyOfRange(args, 2, args.length); } else { actionName = args[0]; - action = ACTIONS.get(args[0]); args = Arrays.copyOfRange(args, 1, args.length); } + action = ACTIONS.get(actionName); if (action == null) { - System.out.println("Unrecognized action."); + System.out.printf("Unrecognized action %s.%n", actionName); printUsage(); return; } - Dns dns = optionsBuilder.build().service(); boolean valid = false; try { valid = action.check(args); @@ -507,6 +514,11 @@ public static void main(String... args) throws Exception { return; } if (valid) { + DnsOptions.Builder optionsBuilder = DnsOptions.builder(); + if(projectId != null) { + optionsBuilder.projectId(projectId); + } + Dns dns = optionsBuilder.build().service(); action.run(dns, args); } else { System.out.println("Invalid input for action '" + actionName + "'"); diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml index b7dfd3f12e8f..03d2b6600ba3 100644 --- a/gcloud-java/pom.xml +++ b/gcloud-java/pom.xml @@ -30,17 +30,17 @@ ${project.groupId} - gcloud-java-resourcemanager + gcloud-java-dns ${project.version} ${project.groupId} - gcloud-java-storage + gcloud-java-resourcemanager ${project.version} ${project.groupId} - gcloud-java-dns + gcloud-java-storage ${project.version} From da877d86f55a46b93ee2cb5295e38707b65e93c2 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Thu, 10 Mar 2016 09:40:03 -0800 Subject: [PATCH 170/375] Added code snippets for DNS. Also extended example doc and added links. Refactored zone print. --- .../com/google/gcloud/dns/DnsOptions.java | 8 ++ gcloud-java-examples/README.md | 2 +- .../gcloud/examples/dns/DnsExample.java | 108 +++++++++--------- .../dns/snippets/CreateAndListDnsRecords.java | 73 ++++++++++++ .../dns/snippets/CreateAndListZones.java | 62 ++++++++++ .../examples/dns/snippets/DeleteZone.java | 88 ++++++++++++++ 6 files changed, 284 insertions(+), 57 deletions(-) create mode 100644 gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateAndListDnsRecords.java create mode 100644 gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateAndListZones.java create mode 100644 gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java index db922b42a3cb..541e7a6c6ea7 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java @@ -96,6 +96,14 @@ public static Builder builder() { return new Builder(); } + /** + * Creates a default instance of {@code DnsOptions} with the project ID and credentials inferred + * from the environment. + */ + public static DnsOptions defaultInstance() { + return builder().build(); + } + @Override public boolean equals(Object obj) { return obj instanceof DnsOptions && baseEquals((DnsOptions) obj); diff --git a/gcloud-java-examples/README.md b/gcloud-java-examples/README.md index 73d613c94e27..5e11fd2b0cb7 100644 --- a/gcloud-java-examples/README.md +++ b/gcloud-java-examples/README.md @@ -74,7 +74,7 @@ To run examples from your command line: * Here's an example run of `DnsExample`. Note that you have to enable the Google Cloud DNS API on the [Google Developers Console][developers-console] before running the following commands. - You will need to replace the domain name `elaborateexample.com` with your own domain name with verified ownership. + You will need to replace the domain name `elaborateexample.com` with your own domain name with [verified ownership] (https://www.google.com/webmasters/verification/home). Also, note that the example creates and deletes DNS records of type A only. Operations with other record types are not implemented in the example. ``` mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.dns.DnsExample" -Dexec.args="create some-sample-zone elaborateexample.com. description" diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java index 2061f4931cab..1b6ba8f179da 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java @@ -38,8 +38,8 @@ /** * An example of using Google Cloud DNS. * - *

      This example creates, deletes, gets, and lists zones, and creates and deletes DNS records of - * type A. + *

      This example creates, deletes, gets, and lists zones. It also creates and deletes DNS records + * of type A, and lists DNS records. * *

      Steps needed for running the example: *

        @@ -57,14 +57,16 @@ * quota} *
      * - *

      The first parameter is an optional {@code project_id} (logged-in project will be used if not - * supplied). Second parameter is a DNS operation (list, delete, create,...). The remaining - * arguments are specific to the operation. See each action's run method for the specific - * interaction. + *

      The first parameter is an optional {@code project_id}. The project specified in the Google + * Cloud SDK configuration (see {@code gcloud config list}) will be used if the project ID is not + * supplied. The second parameter is a DNS operation (list, delete, create, ...). The remaining + * arguments are specific to the operation. See each action's {@code run} method for the specific + * arguments. */ public class DnsExample { private static final Map ACTIONS = new HashMap<>(); + private static final DateFormat FORMATTER = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss"); private interface DnsAction { void run(Dns dns, String... args); @@ -77,7 +79,7 @@ private interface DnsAction { private static class CreateZoneAction implements DnsAction { /** - * Creates a zone with the provided name, dns name and description (in this order). + * Creates a zone with the provided name, DNS name and description (in this order). */ @Override public void run(Dns dns, String... args) { @@ -111,14 +113,8 @@ public void run(Dns dns, String... args) { Iterator zoneIterator = dns.listZones().iterateAll(); if (zoneIterator.hasNext()) { System.out.println("The project contains the following zones:"); - DateFormat formatter = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss"); while (zoneIterator.hasNext()) { - Zone zone = zoneIterator.next(); - System.out.printf("%nName: %s%n", zone.name()); - System.out.printf("ID: %s%n", zone.id()); - System.out.printf("Description: %s%n", zone.description()); - System.out.printf("Created: %s%n", formatter.format(new Date(zone.creationTimeMillis()))); - System.out.printf("Name servers: %s%n", Joiner.on(", ").join(zone.nameServers())); + printZone(zoneIterator.next()); } } else { System.out.println("Project contains no zones."); @@ -148,12 +144,7 @@ public void run(Dns dns, String... args) { if (zone == null) { System.out.printf("No zone with name '%s' exists.%n", zoneName); } else { - System.out.printf("Name: %s%n", zone.name()); - System.out.printf("ID: %s%n", zone.id()); - System.out.printf("Description: %s%n", zone.description()); - DateFormat formatter = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss"); - System.out.printf("Created: %s%n", formatter.format(new Date(zone.creationTimeMillis()))); - System.out.printf("Name servers: %s%n", Joiner.on(", ").join(zone.nameServers())); + printZone(zone); } } @@ -210,7 +201,7 @@ public void run(Dns dns, String... args) { String ip = args[2]; int ttl = 0; if (args.length > 3) { - ttl = Integer.valueOf(args[3]); + ttl = Integer.parseInt(args[3]); } DnsRecord record = DnsRecord.builder(recordName, DnsRecord.Type.A) .records(ImmutableList.of(ip)) @@ -220,18 +211,10 @@ public void run(Dns dns, String... args) { .delete(record) .build(); changeRequest = dns.applyChangeRequest(zoneName, changeRequest); - System.out.printf("The request for deleting A record %s for zone %s was successfully " + - "submitted and assigned ID %s.%n", recordName, zoneName, changeRequest.id()); + System.out.printf("The request for deleting A record %s for zone %s was successfully " + + "submitted and assigned ID %s.%n", recordName, zoneName, changeRequest.id()); System.out.print("Waiting for deletion to happen..."); - while (changeRequest.status().equals(ChangeRequest.Status.PENDING)) { - System.out.print("."); - try { - Thread.sleep(500); - } catch (InterruptedException e) { - System.err.println("Thread was interrupted while waiting."); - } - changeRequest = dns.getChangeRequest(zoneName, changeRequest.id()); - } + waitForChangeToFinish(dns, zoneName, changeRequest); System.out.printf("%nThe deletion has been completed.%n"); } @@ -244,7 +227,7 @@ public String params() { public boolean check(String... args) { if (args.length == 4) { // to check that it can be parsed - Integer.valueOf(args[3]); + Integer.parseInt(args[3]); return true; } else { return args.length == 3; @@ -265,28 +248,18 @@ public void run(Dns dns, String... args) { String ip = args[2]; int ttl = 0; if (args.length > 3) { - ttl = Integer.valueOf(args[3]); + ttl = Integer.parseInt(args[3]); } DnsRecord record = DnsRecord.builder(recordName, DnsRecord.Type.A) .records(ImmutableList.of(ip)) .ttl(ttl, TimeUnit.SECONDS) .build(); - ChangeRequest changeRequest = ChangeRequest.builder() - .add(record) - .build(); + ChangeRequest changeRequest = ChangeRequest.builder().add(record).build(); changeRequest = dns.applyChangeRequest(zoneName, changeRequest); - System.out.printf("The request for adding A record %s for zone %s was successfully " + - "submitted and assigned ID %s.%n", recordName, zoneName, changeRequest.id()); - System.out.print("Waiting for deletion to happen..."); - while (changeRequest.status().equals(ChangeRequest.Status.PENDING)) { - System.out.print("."); - try { - Thread.sleep(500); - } catch (InterruptedException e) { - System.err.println("Thread was interrupted while waiting."); - } - changeRequest = dns.getChangeRequest(zoneName, changeRequest.id()); - } + System.out.printf("The request for adding A record %s for zone %s was successfully " + + "submitted and assigned ID %s.%n", recordName, zoneName, changeRequest.id()); + System.out.print("Waiting for addition to happen..."); + waitForChangeToFinish(dns, zoneName, changeRequest); System.out.printf("The addition has been completed.%n"); } @@ -299,7 +272,7 @@ public String params() { public boolean check(String... args) { if (args.length == 4) { // to check that it can be parsed - Integer.valueOf(args[3]); + Integer.parseInt(args[3]); return true; } else { return args.length == 3; @@ -342,8 +315,8 @@ public boolean check(String... args) { private static class ListChangesAction implements DnsAction { /** - * Lists all the changes for a given zone. Optionally, an order, "descending" or "ascending" can - * be specified using the last parameter. + * Lists all the changes for a given zone. Optionally, an order ("descending" or "ascending") + * can be specified using the last parameter. */ @Override public void run(Dns dns, String... args) { @@ -358,12 +331,11 @@ public void run(Dns dns, String... args) { } if (iterator.hasNext()) { System.out.printf("Change requests for zone %s:%n", zoneName); - DateFormat formatter = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss"); while (iterator.hasNext()) { ChangeRequest change = iterator.next(); System.out.printf("%nID: %s%n", change.id()); System.out.printf("Status: %s%n", change.status()); - System.out.printf("Started: %s%n", formatter.format(change.startTimeMillis())); + System.out.printf("Started: %s%n", FORMATTER.format(change.startTimeMillis())); System.out.printf("Deletions: %s%n", Joiner.on(", ").join(change.deletions())); System.out.printf("Additions: %s%n", Joiner.on(", ").join(change.additions())); } @@ -408,7 +380,7 @@ public void run(Dns dns, String... args) { @Override public boolean check(String... args) { - if (args.length == 0) { + if (args.length == 0 || args.length == 1) { return true; } if ("records".equals(args[1])) { @@ -464,6 +436,29 @@ public boolean check(String... args) { ACTIONS.put("quota", new GetProjectAction()); } + private static void printZone(Zone zone) { + System.out.printf("%nName: %s%n", zone.name()); + System.out.printf("ID: %s%n", zone.id()); + System.out.printf("Description: %s%n", zone.description()); + System.out.printf("Created: %s%n", FORMATTER.format(new Date(zone.creationTimeMillis()))); + System.out.printf("Name servers: %s%n", Joiner.on(", ").join(zone.nameServers())); + } + + private static ChangeRequest waitForChangeToFinish(Dns dns, String zoneName, + ChangeRequest request) { + ChangeRequest current = request; + while (current.status().equals(ChangeRequest.Status.PENDING)) { + System.out.print("."); + try { + Thread.sleep(500); + } catch (InterruptedException e) { + System.err.println("Thread was interrupted while waiting."); + } + current = dns.getChangeRequest(zoneName, current.id()); + } + return current; + } + private static void printUsage() { StringBuilder actionAndParams = new StringBuilder(); for (Map.Entry entry : ACTIONS.entrySet()) { @@ -510,12 +505,13 @@ public static void main(String... args) throws Exception { return; } catch (Exception ex) { System.out.println("Failed to parse request."); + System.out.println("Expected: " + action.params()); ex.printStackTrace(); return; } if (valid) { DnsOptions.Builder optionsBuilder = DnsOptions.builder(); - if(projectId != null) { + if (projectId != null) { optionsBuilder.projectId(projectId); } Dns dns = optionsBuilder.build().service(); diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateAndListDnsRecords.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateAndListDnsRecords.java new file mode 100644 index 000000000000..1e47a12fed02 --- /dev/null +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateAndListDnsRecords.java @@ -0,0 +1,73 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +/* + * EDITING INSTRUCTIONS + * This file is referenced in README's and javadoc. Any change to this file should be reflected in + * the project's README's and package-info.java. + */ + +package com.google.gcloud.examples.dns.snippets; + +import com.google.gcloud.dns.ChangeRequest; +import com.google.gcloud.dns.Dns; +import com.google.gcloud.dns.DnsOptions; +import com.google.gcloud.dns.DnsRecord; +import com.google.gcloud.dns.Zone; + +import java.util.Iterator; +import java.util.concurrent.TimeUnit; + +/** + * A snippet for Google Cloud DNS showing how to create a DNS records. + */ +public class CreateAndListDnsRecords { + + public static void main(String... args) { + // Create a service object. + // The project ID and credentials will be inferred from the environment. + Dns dns = DnsOptions.defaultInstance().service(); + + // Change this to a zone name that exists within your project + String zoneName = "some-sample-zone"; + + // Get zone from the service + Zone zone = dns.getZone(zoneName); + + // Prepare a www.. type A record with ttl of 24 hours + String ip = "12.13.14.15"; + DnsRecord toCreate = DnsRecord.builder("www." + zone.dnsName(), DnsRecord.Type.A) + .ttl(24, TimeUnit.HOURS) + .addRecord(ip) + .build(); + + // Make a change + ChangeRequest.Builder changeBuilder = ChangeRequest.builder().add(toCreate); + + // Verify a www.. type A record does not exist yet. + // If it does exist, we will overwrite it with our prepared record. + Iterator recordIterator = zone.listDnsRecords().iterateAll(); + while (recordIterator.hasNext()) { + DnsRecord current = recordIterator.next(); + if (toCreate.name().equals(current.name()) && toCreate.type().equals(current.type())) { + changeBuilder.delete(current); + } + } + + // Build and apply the change request to our zone + zone.applyChangeRequest(changeBuilder.build()); + } +} diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateAndListZones.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateAndListZones.java new file mode 100644 index 000000000000..21fdba2b7449 --- /dev/null +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateAndListZones.java @@ -0,0 +1,62 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +/* + * EDITING INSTRUCTIONS + * This file is referenced in README's and javadoc. Any change to this file should be reflected in + * the project's README's and package-info.java. + */ + +package com.google.gcloud.examples.dns.snippets; + +import com.google.gcloud.dns.Dns; +import com.google.gcloud.dns.DnsOptions; +import com.google.gcloud.dns.Zone; +import com.google.gcloud.dns.ZoneInfo; + +import java.util.Iterator; + +/** + * A snippet for Google Cloud DNS showing how to create a zone and list all zones in the project. + * You will need to change the {@code domainName} to a domain name, the ownership of which you + * should verify with Google. + */ +public class CreateAndListZones { + + public static void main(String... args) { + // Create a service object + // The project ID and credentials will be inferred from the environment. + Dns dns = DnsOptions.defaultInstance().service(); + + // Create a zone metadata object + String zoneName = "my_unique_zone"; // Change this zone name which is unique within your project + String domainName = "someexampledomain.com."; // Change this to a domain which you own + String description = "This is a gcloud-java-dns sample zone."; + ZoneInfo zoneInfo = ZoneInfo.of(zoneName, domainName, description); + + // Create zone in Google Cloud DNS + Zone createdZone = dns.create(zoneInfo); + System.out.printf("Zone was created and assigned ID %s.%n", createdZone.id()); + + // Now list all the zones within this project + Iterator zoneIterator = dns.listZones().iterateAll(); + int counter = 1; + while (zoneIterator.hasNext()) { + System.out.printf("#%d.: %s%n%n", counter, zoneIterator.next().toString()); + counter++; + } + } +} diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java new file mode 100644 index 000000000000..667a0d89e6ab --- /dev/null +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java @@ -0,0 +1,88 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +/* + * EDITING INSTRUCTIONS + * This file is referenced in README's and javadoc. Any change to this file should be reflected in + * the project's README's and package-info.java. + */ + +package com.google.gcloud.examples.dns.snippets; + +import com.google.gcloud.dns.ChangeRequest; +import com.google.gcloud.dns.Dns; +import com.google.gcloud.dns.DnsOptions; +import com.google.gcloud.dns.DnsRecord; + +import java.util.Iterator; + +/** + * A snippet for Google Cloud DNS showing how to delete a zone. It also shows how to list and delete + * DNS records. + */ +public class DeleteZone { + + public static void main(String... args) { + // Create a service object. + // The project ID and credentials will be inferred from the environment. + Dns dns = DnsOptions.defaultInstance().service(); + + // Change this to a zone name that exists within your project and that you want to delete. + String zoneName = "some-sample-zone"; + + // Get iterator for the existing records which have to be deleted before deleting the zone + Iterator recordIterator = dns.listDnsRecords(zoneName).iterateAll(); + + // Make a change for deleting the records + ChangeRequest.Builder changeBuilder = ChangeRequest.builder(); + while (recordIterator.hasNext()) { + DnsRecord current = recordIterator.next(); + // SOA and NS records cannot be deleted + if (!DnsRecord.Type.SOA.equals(current.type()) && !DnsRecord.Type.NS.equals(current.type())) { + changeBuilder.delete(current); + } + } + + // Build and apply the change request to our zone if it contains records to delete + ChangeRequest changeRequest = changeBuilder.build(); + if (!changeRequest.deletions().isEmpty()) { + changeRequest = dns.applyChangeRequest(zoneName, changeRequest); + + // Wait for change to finish, but save data traffic by transferring only ID and status + Dns.ChangeRequestOption option = + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS); + while (ChangeRequest.Status.PENDING.equals(changeRequest.status())) { + System.out.println("Waiting for change to complete. Going to sleep for 500ms..."); + try { + Thread.sleep(500); + } catch (InterruptedException e) { + System.err.println("The thread was interrupted while waiting for change request to be " + + "processed."); + } + // Update the change, but fetch only change ID and status + changeRequest = dns.getChangeRequest(zoneName, changeRequest.id(), option); + } + } + + // Delete the zone + boolean result = dns.delete(zoneName); + if (result) { + System.out.println("Zone was deleted."); + } else { + System.out.println("Zone was not deleted because it does not exist."); + } + } +} From baee7d70fd9aa93d6f95b9ce8850ada77e2ccc7f Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Mon, 14 Mar 2016 15:37:03 -0700 Subject: [PATCH 171/375] Added integration test for invalid change request. Also added checks for the exceptions being non-retryable. Closes #673. --- .../com/google/gcloud/dns/it/ITDnsTest.java | 92 ++++++++++++++++--- 1 file changed, 79 insertions(+), 13 deletions(-) diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java index 4ad17fa8b217..e1a7c218c1b4 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java @@ -48,8 +48,6 @@ public class ITDnsTest { - // todo(mderka) Implement test for creating invalid change when DnsException is finished. #673 - private static final String PREFIX = "gcldjvit-"; private static final Dns DNS = DnsOptions.builder().build().service(); private static final String ZONE_NAME1 = (PREFIX + UUID.randomUUID()).substring(0, 32); @@ -201,14 +199,14 @@ public void testCreateZoneWithErrors() { fail("Zone name is missing a period. The service returns an error."); } catch (DnsException ex) { // expected - // todo(mderka) test non-retryable when implemented within #593 + assertFalse(ex.retryable()); } try { DNS.create(ZONE_DNS_NO_PERIOD); fail("Zone name is missing a period. The service returns an error."); } catch (DnsException ex) { // expected - // todo(mderka) test non-retryable when implemented within #593 + assertFalse(ex.retryable()); } } finally { DNS.delete(ZONE_NAME_ERROR.name()); @@ -393,7 +391,7 @@ public void testListZones() { } catch (DnsException ex) { // expected assertEquals(400, ex.code()); - // todo(mderka) test not-retryable + assertFalse(ex.retryable()); } try { DNS.listZones(Dns.ZoneListOption.pageSize(-1)); @@ -401,7 +399,7 @@ public void testListZones() { } catch (DnsException ex) { // expected assertEquals(400, ex.code()); - // todo(mderka) test not-retryable + assertFalse(ex.retryable()); } // ok size zones = filter(DNS.listZones(Dns.ZoneListOption.pageSize(1000)).iterateAll()); @@ -413,7 +411,7 @@ public void testListZones() { } catch (DnsException ex) { // expected assertEquals(400, ex.code()); - // todo(mderka) test not-retryable + assertFalse(ex.retryable()); } // ok name zones = filter(DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName())).iterateAll()); @@ -586,6 +584,74 @@ public void testCreateChange() { } } + @Test + public void testInvalidChangeRequest() { + Zone zone = DNS.create(ZONE1); + DnsRecord validA = DnsRecord.builder("subdomain." + zone.dnsName(), DnsRecord.Type.A) + .records(ImmutableList.of("0.255.1.5")) + .build(); + try { + ChangeRequest validChange = ChangeRequest.builder().add(validA).build(); + zone.applyChangeRequest(validChange); + try { + zone.applyChangeRequest(validChange); + fail("Created a record which already exists."); + } catch (DnsException ex) { + // expected + assertFalse(ex.retryable()); + assertEquals(409, ex.code()); + } + // delete with field mismatch + DnsRecord mismatch = validA.toBuilder().ttl(20, TimeUnit.SECONDS).build(); + ChangeRequest deletion = ChangeRequest.builder().delete(mismatch).build(); + try { + zone.applyChangeRequest(deletion); + fail("Deleted a record without a complete match."); + } catch (DnsException ex) { + // expected + assertEquals(412, ex.code()); + assertFalse(ex.retryable()); + } + // delete and add SOA + Iterator recordIterator = zone.listDnsRecords().iterateAll(); + LinkedList deletions = new LinkedList<>(); + LinkedList additions = new LinkedList<>(); + while (recordIterator.hasNext()) { + DnsRecord record = recordIterator.next(); + if (record.type() == DnsRecord.Type.SOA) { + deletions.add(record); + // the subdomain is necessary to get 400 instead of 412 + DnsRecord copy = record.toBuilder().name("x." + record.name()).build(); + additions.add(copy); + break; + } + } + deletion = deletion.toBuilder().deletions(deletions).build(); + ChangeRequest addition = ChangeRequest.builder().additions(additions).build(); + try { + zone.applyChangeRequest(deletion); + fail("Deleted SOA."); + } catch (DnsException ex) { + // expected + assertFalse(ex.retryable()); + assertEquals(400, ex.code()); + } + try { + zone.applyChangeRequest(addition); + fail("Added second SOA."); + } catch (DnsException ex) { + // expected + assertFalse(ex.retryable()); + assertEquals(400, ex.code()); + } + } finally { + ChangeRequest deletion = ChangeRequest.builder().delete(validA).build(); + ChangeRequest request = zone.applyChangeRequest(deletion); + waitForChangeToComplete(zone.name(), request.id()); + zone.delete(); + } + } + @Test public void testListChanges() { try { @@ -596,7 +662,7 @@ public void testListChanges() { } catch (DnsException ex) { // expected assertEquals(404, ex.code()); - // todo(mderka) test retry functionality + assertFalse(ex.retryable()); } // zone exists but has no changes DNS.create(ZONE1); @@ -621,7 +687,7 @@ public void testListChanges() { } catch (DnsException ex) { // expected assertEquals(400, ex.code()); - // todo(mderka) test retry functionality + assertFalse(ex.retryable()); } try { DNS.listChangeRequests(ZONE1.name(), Dns.ChangeRequestListOption.pageSize(-1)); @@ -629,7 +695,7 @@ public void testListChanges() { } catch (DnsException ex) { // expected assertEquals(400, ex.code()); - // todo(mderka) test retry functionality + assertFalse(ex.retryable()); } // sorting order ImmutableList ascending = ImmutableList.copyOf(DNS.listChangeRequests( @@ -863,7 +929,7 @@ public void testListDnsRecords() { } catch (DnsException ex) { // expected assertEquals(400, ex.code()); - // todo(mderka) test retry functionality when available + assertFalse(ex.retryable()); } try { DNS.listDnsRecords(ZONE1.name(), Dns.DnsRecordListOption.pageSize(0)); @@ -871,7 +937,7 @@ public void testListDnsRecords() { } catch (DnsException ex) { // expected assertEquals(400, ex.code()); - // todo(mderka) test retry functionality when available + assertFalse(ex.retryable()); } try { DNS.listDnsRecords(ZONE1.name(), Dns.DnsRecordListOption.pageSize(-1)); @@ -879,7 +945,7 @@ public void testListDnsRecords() { } catch (DnsException ex) { // expected assertEquals(400, ex.code()); - // todo(mderka) test retry functionality when available + assertFalse(ex.retryable()); } waitForChangeToComplete(ZONE1.name(), change.id()); } finally { From c2c662843263d53d702f88eb045bffa380697293 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 1 Mar 2016 10:02:57 -0800 Subject: [PATCH 172/375] Add get, replace, and test for IAM --- .../main/java/com/google/gcloud/Identity.java | 24 +-- .../java/com/google/gcloud/IdentityTest.java | 14 +- .../google/gcloud/resourcemanager/Policy.java | 102 +++++++++--- .../gcloud/resourcemanager/Project.java | 18 +- .../resourcemanager/ResourceManager.java | 157 ++++++++++++++++-- .../resourcemanager/ResourceManagerImpl.java | 84 ++++++++-- .../spi/DefaultResourceManagerRpc.java | 58 ++++++- .../spi/ResourceManagerRpc.java | 24 +++ .../testing/LocalResourceManagerHelper.java | 131 +++++++++++++-- .../LocalResourceManagerHelperTest.java | 82 ++++++++- .../gcloud/resourcemanager/PolicyTest.java | 30 +++- .../gcloud/resourcemanager/ProjectTest.java | 26 ++- .../ResourceManagerImplTest.java | 64 +++++++ .../resourcemanager/SerializationTest.java | 2 +- 14 files changed, 718 insertions(+), 98 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/Identity.java b/gcloud-java-core/src/main/java/com/google/gcloud/Identity.java index d1644198f759..687a76ffc42c 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/Identity.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/Identity.java @@ -44,7 +44,7 @@ public final class Identity implements Serializable { private static final long serialVersionUID = -8181841964597657446L; private final Type type; - private final String id; + private final String value; /** * The types of IAM identities. @@ -82,9 +82,9 @@ public enum Type { DOMAIN } - private Identity(Type type, String id) { + private Identity(Type type, String value) { this.type = type; - this.id = id; + this.value = value; } public Type type() { @@ -92,7 +92,7 @@ public Type type() { } /** - * Returns the string identifier for this identity. The id corresponds to: + * Returns the string identifier for this identity. The value corresponds to: *

        *
      • email address (for identities of type {@code USER}, {@code SERVICE_ACCOUNT}, and * {@code GROUP}) @@ -101,8 +101,8 @@ public Type type() { * {@code ALL_AUTHENTICATED_USERS}) *
      */ - public String id() { - return id; + public String value() { + return value; } /** @@ -163,7 +163,7 @@ public static Identity domain(String domain) { @Override public int hashCode() { - return Objects.hash(id, type); + return Objects.hash(value, type); } @Override @@ -172,7 +172,7 @@ public boolean equals(Object obj) { return false; } Identity other = (Identity) obj; - return Objects.equals(id, other.id()) && Objects.equals(type, other.type()); + return Objects.equals(value, other.value()) && Objects.equals(type, other.type()); } /** @@ -186,13 +186,13 @@ public String strValue() { case ALL_AUTHENTICATED_USERS: return "allAuthenticatedUsers"; case USER: - return "user:" + id; + return "user:" + value; case SERVICE_ACCOUNT: - return "serviceAccount:" + id; + return "serviceAccount:" + value; case GROUP: - return "group:" + id; + return "group:" + value; case DOMAIN: - return "domain:" + id; + return "domain:" + value; default: throw new IllegalStateException("Unexpected identity type: " + type); } diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/IdentityTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/IdentityTest.java index 828f1c839431..a42bc9db7abd 100644 --- a/gcloud-java-core/src/test/java/com/google/gcloud/IdentityTest.java +++ b/gcloud-java-core/src/test/java/com/google/gcloud/IdentityTest.java @@ -34,19 +34,19 @@ public class IdentityTest { @Test public void testAllUsers() { assertEquals(Identity.Type.ALL_USERS, ALL_USERS.type()); - assertNull(ALL_USERS.id()); + assertNull(ALL_USERS.value()); } @Test public void testAllAuthenticatedUsers() { assertEquals(Identity.Type.ALL_AUTHENTICATED_USERS, ALL_AUTH_USERS.type()); - assertNull(ALL_AUTH_USERS.id()); + assertNull(ALL_AUTH_USERS.value()); } @Test public void testUser() { assertEquals(Identity.Type.USER, USER.type()); - assertEquals("abc@gmail.com", USER.id()); + assertEquals("abc@gmail.com", USER.value()); } @Test(expected = NullPointerException.class) @@ -57,7 +57,7 @@ public void testUserNullEmail() { @Test public void testServiceAccount() { assertEquals(Identity.Type.SERVICE_ACCOUNT, SERVICE_ACCOUNT.type()); - assertEquals("service-account@gmail.com", SERVICE_ACCOUNT.id()); + assertEquals("service-account@gmail.com", SERVICE_ACCOUNT.value()); } @Test(expected = NullPointerException.class) @@ -68,7 +68,7 @@ public void testServiceAccountNullEmail() { @Test public void testGroup() { assertEquals(Identity.Type.GROUP, GROUP.type()); - assertEquals("group@gmail.com", GROUP.id()); + assertEquals("group@gmail.com", GROUP.value()); } @Test(expected = NullPointerException.class) @@ -79,7 +79,7 @@ public void testGroupNullEmail() { @Test public void testDomain() { assertEquals(Identity.Type.DOMAIN, DOMAIN.type()); - assertEquals("google.com", DOMAIN.id()); + assertEquals("google.com", DOMAIN.value()); } @Test(expected = NullPointerException.class) @@ -100,6 +100,6 @@ public void testIdentityToAndFromPb() { private void compareIdentities(Identity expected, Identity actual) { assertEquals(expected, actual); assertEquals(expected.type(), actual.type()); - assertEquals(expected.id(), actual.id()); + assertEquals(expected.value(), actual.value()); } } diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java index 0d7118dcbbd7..46330e19fa59 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java @@ -17,18 +17,19 @@ package com.google.gcloud.resourcemanager; import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.CaseFormat; import com.google.common.base.Function; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import com.google.gcloud.IamPolicy; import com.google.gcloud.Identity; +import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; /** @@ -48,40 +49,101 @@ public class Policy extends IamPolicy { /** * Represents legacy roles in an IAM Policy. */ - public enum Role { + public static class Role implements Serializable { /** - * Permissions for read-only actions that preserve state. + * The recognized roles in a Project's IAM policy. */ - VIEWER("roles/viewer"), + public enum Type { + + /** + * Permissions for read-only actions that preserve state. + */ + VIEWER, + + /** + * All viewer permissions and permissions for actions that modify state. + */ + EDITOR, + + /** + * All editor permissions and permissions for the following actions: + *
        + *
      • Manage access control for a resource. + *
      • Set up billing (for a project). + *
      + */ + OWNER + } + + private static final long serialVersionUID = 2421978909244287488L; + + private final String value; + private final Type type; + + private Role(String value, Type type) { + this.value = value; + this.type = type; + } + + String value() { + return value; + } /** - * All viewer permissions and permissions for actions that modify state. + * Returns the type of role (editor, owner, or viewer). Returns {@code null} if the role type + * is unrecognized. */ - EDITOR("roles/editor"), + public Type type() { + return type; + } /** - * All editor permissions and permissions for the following actions: - *
        - *
      • Manage access control for a resource. - *
      • Set up billing (for a project). - *
      + * Returns a {@code Role} of type {@link Type#VIEWER VIEWER}. */ - OWNER("roles/owner"); + public static Role viewer() { + return new Role("roles/viewer", Type.VIEWER); + } - private String strValue; + /** + * Returns a {@code Role} of type {@link Type#EDITOR EDITOR}. + */ + public static Role editor() { + return new Role("roles/editor", Type.EDITOR); + } - private Role(String strValue) { - this.strValue = strValue; + /** + * Returns a {@code Role} of type {@link Type#OWNER OWNER}. + */ + public static Role owner() { + return new Role("roles/owner", Type.OWNER); } - String strValue() { - return strValue; + static Role rawRole(String roleStr) { + return new Role(roleStr, null); } static Role fromStr(String roleStr) { - return Role.valueOf(CaseFormat.LOWER_CAMEL.to( - CaseFormat.UPPER_UNDERSCORE, roleStr.substring("roles/".length()))); + try { + Type type = Type.valueOf(roleStr.split("/")[1].toUpperCase()); + return new Role(roleStr, type); + } catch (Exception ex) { + return new Role(roleStr, null); + } + } + + @Override + public final int hashCode() { + return Objects.hash(value, type); + } + + @Override + public final boolean equals(Object obj) { + if (!(obj instanceof Role)) { + return false; + } + Role other = (Role) obj; + return Objects.equals(value, other.value()) && Objects.equals(type, other.type()); } } @@ -124,7 +186,7 @@ com.google.api.services.cloudresourcemanager.model.Policy toPb() { for (Map.Entry> binding : bindings().entrySet()) { com.google.api.services.cloudresourcemanager.model.Binding bindingPb = new com.google.api.services.cloudresourcemanager.model.Binding(); - bindingPb.setRole(binding.getKey().strValue()); + bindingPb.setRole(binding.getKey().value()); bindingPb.setMembers( Lists.transform( new ArrayList<>(binding.getValue()), diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java index 4d12a31274c0..46b142c5aa53 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java @@ -157,10 +157,10 @@ public Project reload() { * completes, the project is not retrievable by the {@link ResourceManager#get} and * {@link ResourceManager#list} methods. The caller must have modify permissions for this project. * - * @see Cloud - * Resource Manager delete * @throws ResourceManagerException upon failure + * @see Cloud + * Resource Manager delete */ public void delete() { resourceManager.delete(projectId()); @@ -174,10 +174,10 @@ public void delete() { * state of {@link ProjectInfo.State#DELETE_IN_PROGRESS}, the project cannot be restored. The * caller must have modify permissions for this project. * - * @see Cloud - * Resource Manager undelete * @throws ResourceManagerException upon failure (including when the project can't be restored) + * @see Cloud + * Resource Manager undelete */ public void undelete() { resourceManager.undelete(projectId()); @@ -188,11 +188,11 @@ public void undelete() { * *

      The caller must have modify permissions for this project. * - * @see Cloud - * Resource Manager update * @return the Project representing the new project metadata * @throws ResourceManagerException upon failure + * @see Cloud + * Resource Manager update */ public Project replace() { return resourceManager.replace(this); diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java index a463937f875c..f14d47f2a676 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java @@ -18,10 +18,12 @@ import com.google.common.base.Joiner; import com.google.common.collect.Sets; +import com.google.gcloud.IamPolicy; import com.google.gcloud.Page; import com.google.gcloud.Service; import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc; +import java.util.List; import java.util.Set; /** @@ -167,6 +169,38 @@ public static ProjectListOption fields(ProjectField... fields) { } } + /** + * The permissions associated with a Google Cloud project. These values can be used when calling + * {@link #testPermissions}. + * + * @see + * Project-level roles + */ + enum Permission { + DELETE("delete"), + GET("get"), + GET_POLICY("getIamPolicy"), + REPLACE("update"), + REPLACE_POLICY("setIamPolicy"), + UNDELETE("undelete"); + + private static final String PREFIX = "resourcemanager.projects."; + + private final String value; + + Permission(String suffix) { + this.value = PREFIX + suffix; + } + + /** + * Returns the string representation of the permission. + */ + public String value() { + return value; + } + } + /** * Creates a new project. * @@ -174,13 +208,13 @@ public static ProjectListOption fields(ProjectField... fields) { * grant permission to others to read or update the project. Several APIs are activated * automatically for the project, including Google Cloud Storage. * - * @see Cloud - * Resource Manager create * @return Project object representing the new project's metadata. The returned object will * include the following read-only fields supplied by the server: project number, lifecycle * state, and creation time. * @throws ResourceManagerException upon failure + * @see Cloud + * Resource Manager create */ Project create(ProjectInfo project); @@ -201,10 +235,10 @@ public static ProjectListOption fields(ProjectField... fields) { * completes, the project is not retrievable by the {@link ResourceManager#get} and * {@link ResourceManager#list} methods. The caller must have modify permissions for this project. * - * @see Cloud - * Resource Manager delete * @throws ResourceManagerException upon failure + * @see Cloud + * Resource Manager delete */ void delete(String projectId); @@ -214,10 +248,9 @@ public static ProjectListOption fields(ProjectField... fields) { *

      Returns {@code null} if the project is not found or if the user doesn't have read * permissions for the project. * - * @see Cloud - * Resource Manager get * @throws ResourceManagerException upon failure + * @see + * Cloud Resource Manager get */ Project get(String projectId, ProjectGetOption... options); @@ -228,11 +261,11 @@ public static ProjectListOption fields(ProjectField... fields) { * at the end of the list. Use {@link ProjectListOption} to filter this list, set page size, and * set page tokens. * - * @see Cloud - * Resource Manager list * @return {@code Page}, a page of projects * @throws ResourceManagerException upon failure + * @see Cloud + * Resource Manager list */ Page list(ProjectListOption... options); @@ -241,11 +274,11 @@ public static ProjectListOption fields(ProjectField... fields) { * *

      The caller must have modify permissions for this project. * - * @see Cloud - * Resource Manager update * @return the Project representing the new project metadata * @throws ResourceManagerException upon failure + * @see Cloud + * Resource Manager update */ Project replace(ProjectInfo newProject); @@ -257,10 +290,98 @@ public static ProjectListOption fields(ProjectField... fields) { * state of {@link ProjectInfo.State#DELETE_IN_PROGRESS}, the project cannot be restored. The * caller must have modify permissions for this project. * - * @see Cloud - * Resource Manager undelete * @throws ResourceManagerException upon failure + * @see Cloud + * Resource Manager undelete */ void undelete(String projectId); + + /** + * Returns the IAM access control policy for the specified project. Returns {@code null} if the + * resource does not exist or if you do not have adequate permission to view the project or get + * the policy. + * + * @throws ResourceManagerException upon failure + * @see + * Resource Manager getIamPolicy + */ + Policy getPolicy(String projectId); + + /** + * Sets the IAM access control policy for the specified project. Replaces any existing policy. The + * following constraints apply: + *

        + *
      • Projects currently support only user:{emailid} and serviceAccount:{emailid} + * members in a binding of a policy. + *
      • To be added as an owner, a user must be invited via Cloud Platform console and must accept + * the invitation. + *
      • Members cannot be added to more than one role in the same policy. + *
      • There must be at least one owner who has accepted the Terms of Service (ToS) agreement in + * the policy. An attempt to set a policy that removes the last ToS-accepted owner from the + * policy will fail. + *
      • Calling this method requires enabling the App Engine Admin API. + *
      + * Note: Removing service accounts from policies or changing their roles can render services + * completely inoperable. It is important to understand how the service account is being used + * before removing or updating its roles. + * + *

      It is recommended that you use the read-modify-write pattern. This pattern entails reading + * the project's current policy, updating it locally, and then sending the modified policy for + * writing. Cloud IAM solves the problem of conflicting processes simultaneously attempting to + * modify a policy by using the {@link IamPolicy#etag etag} property. This property is used to + * verify whether the policy has changed since the last request. When you make a request to Cloud + * IAM with an etag value, Cloud IAM compares the etag value in the request with the existing etag + * value associated with the policy. It writes the policy only if the etag values match. If the + * etags don't match, a {@code ResourceManagerException} is thrown, denoting that the server + * aborted update. If an etag is not provided, the policy is overwritten blindly. + * + *

      An example of using the read-write-modify pattern is as follows: + *

       {@code
      +   * Policy currentPolicy = resourceManager.getPolicy("my-project-id");
      +   * Policy modifiedPolicy =
      +   *     current.toBuilder().removeIdentity(Role.VIEWER, Identity.user("user@gmail.com"));
      +   * Policy newPolicy = resourceManager.replacePolicy("my-project-id", modified);
      +   * }
      +   * 
      + * + * @throws ResourceManagerException upon failure + * @see + * Resource Manager setIamPolicy + */ + Policy replacePolicy(String projectId, Policy newPolicy); + + /** + * Returns the permissions that a caller has on the specified project. You typically don't call + * this method if you're using Google Cloud Platform directly to manage permissions. This method + * is intended for integration with your proprietary software, such as a customized graphical user + * interface. For example, the Cloud Platform Console tests IAM permissions internally to + * determine which UI should be available to the logged-in user. + * + * @return A list of booleans representing whether the caller has the permissions specified (in + * the order of the given permissions) + * @throws ResourceManagerException upon failure + * @see + * Resource Manager testIamPermissions + */ + List testPermissions(String projectId, List permissions); + + /** + * Returns the permissions that a caller has on the specified project. You typically don't call + * this method if you're using Google Cloud Platform directly to manage permissions. This method + * is intended for integration with your proprietary software, such as a customized graphical user + * interface. For example, the Cloud Platform Console tests IAM permissions internally to + * determine which UI should be available to the logged-in user. + * + * @return A list of booleans representing whether the caller has the permissions specified (in + * the order of the given permissions) + * @throws ResourceManagerException upon failure + * @see + * Resource Manager testIamPermissions + */ + List testPermissions(String projectId, Permission first, Permission... others); } diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java index fb699dcb06f0..d9911b911f0b 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java @@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.gcloud.BaseService; import com.google.gcloud.Page; @@ -32,6 +33,7 @@ import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc; import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc.Tuple; +import java.util.List; import java.util.Map; import java.util.concurrent.Callable; @@ -55,8 +57,8 @@ public com.google.api.services.cloudresourcemanager.model.Project call() { return resourceManagerRpc.create(project.toPb()); } }, options().retryParams(), EXCEPTION_HANDLER)); - } catch (RetryHelperException e) { - throw ResourceManagerException.translateAndThrow(e); + } catch (RetryHelperException ex) { + throw ResourceManagerException.translateAndThrow(ex); } } @@ -70,8 +72,8 @@ public Void call() { return null; } }, options().retryParams(), EXCEPTION_HANDLER); - } catch (RetryHelperException e) { - throw ResourceManagerException.translateAndThrow(e); + } catch (RetryHelperException ex) { + throw ResourceManagerException.translateAndThrow(ex); } } @@ -87,8 +89,8 @@ public com.google.api.services.cloudresourcemanager.model.Project call() { } }, options().retryParams(), EXCEPTION_HANDLER); return answer == null ? null : Project.fromPb(this, answer); - } catch (RetryHelperException e) { - throw ResourceManagerException.translateAndThrow(e); + } catch (RetryHelperException ex) { + throw ResourceManagerException.translateAndThrow(ex); } } @@ -146,8 +148,8 @@ public Project apply( }); return new PageImpl<>( new ProjectPageFetcher(serviceOptions, cursor, optionsMap), cursor, projects); - } catch (RetryHelperException e) { - throw ResourceManagerException.translateAndThrow(e); + } catch (RetryHelperException ex) { + throw ResourceManagerException.translateAndThrow(ex); } } @@ -161,8 +163,8 @@ public com.google.api.services.cloudresourcemanager.model.Project call() { return resourceManagerRpc.replace(newProject.toPb()); } }, options().retryParams(), EXCEPTION_HANDLER)); - } catch (RetryHelperException e) { - throw ResourceManagerException.translateAndThrow(e); + } catch (RetryHelperException ex) { + throw ResourceManagerException.translateAndThrow(ex); } } @@ -176,11 +178,69 @@ public Void call() { return null; } }, options().retryParams(), EXCEPTION_HANDLER); - } catch (RetryHelperException e) { - throw ResourceManagerException.translateAndThrow(e); + } catch (RetryHelperException ex) { + throw ResourceManagerException.translateAndThrow(ex); } } + @Override + public Policy getPolicy(final String projectId) { + try { + com.google.api.services.cloudresourcemanager.model.Policy answer = + runWithRetries( + new Callable() { + @Override + public com.google.api.services.cloudresourcemanager.model.Policy call() { + return resourceManagerRpc.getPolicy(projectId); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Policy.fromPb(answer); + } catch (RetryHelperException ex) { + throw ResourceManagerException.translateAndThrow(ex); + } + } + + @Override + public Policy replacePolicy(final String projectId, final Policy newPolicy) { + try { + return Policy.fromPb(runWithRetries( + new Callable() { + @Override + public com.google.api.services.cloudresourcemanager.model.Policy call() { + return resourceManagerRpc.replacePolicy(projectId, newPolicy.toPb()); + } + }, options().retryParams(), EXCEPTION_HANDLER)); + } catch (RetryHelperException ex) { + throw ResourceManagerException.translateAndThrow(ex); + } + } + + @Override + public List testPermissions(final String projectId, final List permissions) { + try { + return runWithRetries( + new Callable>() { + @Override + public List call() { + return resourceManagerRpc.testPermissions(projectId, + Lists.transform(permissions, new Function() { + @Override + public String apply(Permission permission) { + return permission.value(); + } + })); + } + }, options().retryParams(), EXCEPTION_HANDLER); + } catch (RetryHelperException ex) { + throw ResourceManagerException.translateAndThrow(ex); + } + } + + @Override + public List testPermissions(String projectId, Permission first, Permission... others) { + return testPermissions(projectId, Lists.asList(first, others)); + } + private Map optionMap(Option... options) { Map temp = Maps.newEnumMap(ResourceManagerRpc.Option.class); for (Option option : options) { diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/DefaultResourceManagerRpc.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/DefaultResourceManagerRpc.java index 2ef0d8c65ff2..9f92ff545874 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/DefaultResourceManagerRpc.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/DefaultResourceManagerRpc.java @@ -1,5 +1,6 @@ package com.google.gcloud.resourcemanager.spi; +import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.gcloud.resourcemanager.spi.ResourceManagerRpc.Option.FIELDS; import static com.google.gcloud.resourcemanager.spi.ResourceManagerRpc.Option.FILTER; import static com.google.gcloud.resourcemanager.spi.ResourceManagerRpc.Option.PAGE_SIZE; @@ -11,13 +12,22 @@ import com.google.api.client.http.HttpTransport; import com.google.api.client.json.jackson.JacksonFactory; import com.google.api.services.cloudresourcemanager.Cloudresourcemanager; +import com.google.api.services.cloudresourcemanager.model.GetIamPolicyRequest; import com.google.api.services.cloudresourcemanager.model.ListProjectsResponse; +import com.google.api.services.cloudresourcemanager.model.Policy; import com.google.api.services.cloudresourcemanager.model.Project; +import com.google.api.services.cloudresourcemanager.model.SetIamPolicyRequest; +import com.google.api.services.cloudresourcemanager.model.TestIamPermissionsRequest; +import com.google.api.services.cloudresourcemanager.model.TestIamPermissionsResponse; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import com.google.gcloud.resourcemanager.ResourceManagerException; import com.google.gcloud.resourcemanager.ResourceManagerOptions; import java.io.IOException; +import java.util.List; import java.util.Map; +import java.util.Set; public class DefaultResourceManagerRpc implements ResourceManagerRpc { @@ -107,5 +117,51 @@ public Project replace(Project project) { throw translate(ex); } } -} + @Override + public Policy getPolicy(String projectId) throws ResourceManagerException { + try { + return resourceManager.projects() + .getIamPolicy(projectId, new GetIamPolicyRequest()) + .execute(); + } catch (IOException ex) { + ResourceManagerException translated = translate(ex); + if (translated.code() == HTTP_FORBIDDEN) { + // Service returns permission denied if policy doesn't exist. + return null; + } else { + throw translated; + } + } + } + + @Override + public Policy replacePolicy(String projectId, Policy newPolicy) throws ResourceManagerException { + try { + return resourceManager.projects() + .setIamPolicy(projectId, new SetIamPolicyRequest().setPolicy(newPolicy)).execute(); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public List testPermissions(String projectId, List permissions) + throws ResourceManagerException { + try { + TestIamPermissionsResponse response = resourceManager.projects() + .testIamPermissions( + projectId, new TestIamPermissionsRequest().setPermissions(permissions)) + .execute(); + Set permissionsOwned = + ImmutableSet.copyOf(firstNonNull(response.getPermissions(), ImmutableList.of())); + ImmutableList.Builder answer = ImmutableList.builder(); + for (String p : permissions) { + answer.add(permissionsOwned.contains(p)); + } + return answer.build(); + } catch (IOException ex) { + throw translate(ex); + } + } +} diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/ResourceManagerRpc.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/ResourceManagerRpc.java index 54531edd5ed5..d6ec068a92a3 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/ResourceManagerRpc.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/ResourceManagerRpc.java @@ -16,9 +16,11 @@ package com.google.gcloud.resourcemanager.spi; +import com.google.api.services.cloudresourcemanager.model.Policy; import com.google.api.services.cloudresourcemanager.model.Project; import com.google.gcloud.resourcemanager.ResourceManagerException; +import java.util.List; import java.util.Map; public interface ResourceManagerRpc { @@ -121,5 +123,27 @@ public Y y() { */ Project replace(Project project); + /** + * Returns the IAM policy associated with a project. + * + * @throws ResourceManagerException upon failure + */ + Policy getPolicy(String projectId); + + /** + * Replaces the IAM policy associated with the given project. + * + * @throws ResourceManagerException upon failure + */ + Policy replacePolicy(String projectId, Policy newPolicy); + + /** + * Tests whether the caller has the given permissions. Returns a list of booleans corresponding to + * whether or not the user has the permission in the same position of input list. + * + * @throws ResourceManagerException upon failure + */ + List testPermissions(String projectId, List permissions); + // TODO(ajaykannan): implement "Organization" functionality when available (issue #319) } diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java index cda2dd1e00ea..8ddca18b6261 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java @@ -5,7 +5,12 @@ import static java.net.HttpURLConnection.HTTP_OK; import com.google.api.client.json.JsonFactory; +import com.google.api.services.cloudresourcemanager.model.Binding; +import com.google.api.services.cloudresourcemanager.model.Policy; import com.google.api.services.cloudresourcemanager.model.Project; +import com.google.api.services.cloudresourcemanager.model.SetIamPolicyRequest; +import com.google.api.services.cloudresourcemanager.model.TestIamPermissionsRequest; +import com.google.api.services.cloudresourcemanager.model.TestIamPermissionsResponse; import com.google.common.base.Joiner; import com.google.common.base.Objects; import com.google.common.collect.ImmutableList; @@ -13,6 +18,7 @@ import com.google.common.collect.ImmutableSet; import com.google.common.io.ByteStreams; import com.google.gcloud.AuthCredentials; +import com.google.gcloud.resourcemanager.ResourceManager.Permission; import com.google.gcloud.resourcemanager.ResourceManagerOptions; import com.sun.net.httpserver.Headers; @@ -30,11 +36,14 @@ import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; +import java.util.UUID; import java.util.concurrent.ConcurrentSkipListMap; import java.util.logging.Level; import java.util.logging.Logger; @@ -46,7 +55,25 @@ * Utility to create a local Resource Manager mock for testing. * *

      The mock runs in a separate thread, listening for HTTP requests on the local machine at an - * ephemeral port. + * ephemeral port. While this mock attempts to simulate the Cloud Resource Manager, there are some + * divergences in behavior. The following is a non-exhaustive list of some of those behavioral + * differences: + * + *

        + *
      • This mock assumes you have adequate permissions for any action. Related to this, + * testIamPermissions always indicates that the caller has all permissions listed in the + * request. + *
      • IAM policies are set to an empty policy with version 0 (only legacy roles supported) upon + * project creation. The actual service will not have an empty list of bindings and may also + * set your version to 1. + *
      • There is no input validation for the policy provided when replacing a policy. + *
      • In this mock, projects never move from the DELETE_REQUESTED lifecycle state to + * DELETE_IN_PROGRESS without an explicit call to the utility method + * {@link #changeLifecycleState}. Similarly, a project is never completely removed without an + * explicit call to the utility method {@link #removeProject}. + *
      • The messages in the error responses given by this mock do not necessarily match the messages + * given by the actual service. + *
      */ @SuppressWarnings("restriction") public class LocalResourceManagerHelper { @@ -62,8 +89,12 @@ public class LocalResourceManagerHelper { private static final Pattern LIST_FIELDS_PATTERN = Pattern.compile("(.*?)projects\\((.*?)\\)(.*?)"); private static final String[] NO_FIELDS = {}; + private static final Set PERMISSIONS = new HashSet<>(); static { + for (Permission permission : Permission.values()) { + PERMISSIONS.add(permission.value()); + } try { BASE_CONTEXT = new URI(CONTEXT); } catch (URISyntaxException e) { @@ -78,6 +109,7 @@ public class LocalResourceManagerHelper { private final HttpServer server; private final ConcurrentSkipListMap projects = new ConcurrentSkipListMap<>(); + private final Map policies = new HashMap<>(); private final int port; private static class Response { @@ -99,6 +131,7 @@ String body() { } private enum Error { + ABORTED(409, "global", "aborted", "ABORTED"), ALREADY_EXISTS(409, "global", "alreadyExists", "ALREADY_EXISTS"), PERMISSION_DENIED(403, "global", "forbidden", "PERMISSION_DENIED"), FAILED_PRECONDITION(400, "global", "failedPrecondition", "FAILED_PRECONDITION"), @@ -150,13 +183,7 @@ public void handle(HttpExchange exchange) { try { switch (requestMethod) { case "POST": - if (path.endsWith(":undelete")) { - response = undelete(projectIdFromUri(path)); - } else { - String requestBody = - decodeContent(exchange.getRequestHeaders(), exchange.getRequestBody()); - response = create(jsonFactory.fromString(requestBody, Project.class)); - } + response = handlePost(exchange, path); break; case "DELETE": response = delete(projectIdFromUri(path)); @@ -187,6 +214,30 @@ public void handle(HttpExchange exchange) { } } + private Response handlePost(HttpExchange exchange, String path) throws IOException { + String requestBody = decodeContent(exchange.getRequestHeaders(), exchange.getRequestBody()); + if (!path.contains(":")) { + return create(jsonFactory.fromString(requestBody, Project.class)); + } else { + switch (path.split(":", 2)[1]) { + case "undelete": + return undelete(projectIdFromUri(path)); + case "getIamPolicy": + return getPolicy(projectIdFromUri(path)); + case "setIamPolicy": + return replacePolicy(projectIdFromUri(path), + jsonFactory.fromString(requestBody, SetIamPolicyRequest.class).getPolicy()); + case "testIamPermissions": + return testPermissions(projectIdFromUri(path), + jsonFactory.fromString(requestBody, TestIamPermissionsRequest.class) + .getPermissions()); + default: + return Error.BAD_REQUEST.response( + "The server could not understand the following request URI: POST " + path); + } + } + } + private static void writeResponse(HttpExchange exchange, Response response) { exchange.getResponseHeaders().set("Content-type", "application/json; charset=UTF-8"); OutputStream outputStream = exchange.getResponseBody(); @@ -259,7 +310,7 @@ private static Map parseListOptions(String query) throws IOExcep options.put("pageToken", argEntry[1]); break; case "pageSize": - int pageSize = Integer.valueOf(argEntry[1]); + int pageSize = Integer.parseInt(argEntry[1]); if (pageSize < 1) { throw new IOException("Page size must be greater than 0."); } @@ -317,7 +368,7 @@ private static boolean isValidIdOrLabel(String value, int minLength, int maxLeng return value.length() >= minLength && value.length() <= maxLength; } - Response create(Project project) { + synchronized Response create(Project project) { String customErrorMessage = checkForProjectErrors(project); if (customErrorMessage != null) { return Error.INVALID_ARGUMENT.response(customErrorMessage); @@ -329,6 +380,11 @@ Response create(Project project) { return Error.ALREADY_EXISTS.response( "A project with the same project ID (" + project.getProjectId() + ") already exists."); } + Policy emptyPolicy = new Policy() + .setBindings(Collections.emptyList()) + .setEtag(UUID.randomUUID().toString()) + .setVersion(0); + policies.put(project.getProjectId(), emptyPolicy); try { String createdProjectStr = jsonFactory.toString(project); return new Response(HTTP_OK, createdProjectStr); @@ -540,6 +596,58 @@ synchronized Response undelete(String projectId) { return response; } + synchronized Response getPolicy(String projectId) { + Policy policy = policies.get(projectId); + if (policy == null) { + return Error.PERMISSION_DENIED.response("Project " + projectId + " not found."); + } + try { + return new Response(HTTP_OK, jsonFactory.toString(policy)); + } catch (IOException e) { + return Error.INTERNAL_ERROR.response( + "Error when serializing the IAM policy for " + projectId); + } + } + + synchronized Response replacePolicy(String projectId, Policy policy) { + Policy originalPolicy = policies.get(projectId); + if (originalPolicy == null) { + return Error.PERMISSION_DENIED.response("Error when replacing the policy for " + projectId + + " because the project was not found."); + } + String etag = policy.getEtag(); + if (etag != null && !originalPolicy.getEtag().equals(etag)) { + return Error.ABORTED.response("Policy etag mismatch when replacing the policy for project " + + projectId + ", please retry the read."); + } + policy.setEtag(UUID.randomUUID().toString()); + policy.setVersion(originalPolicy.getVersion()); + policies.put(projectId, policy); + try { + return new Response(HTTP_OK, jsonFactory.toString(policy)); + } catch (IOException e) { + return Error.INTERNAL_ERROR.response( + "Error when serializing the policy for project " + projectId); + } + } + + synchronized Response testPermissions(String projectId, List permissions) { + if (!projects.containsKey(projectId)) { + return Error.PERMISSION_DENIED.response("Project " + projectId + " not found."); + } + for (String p : permissions) { + if (!PERMISSIONS.contains(p)) { + return Error.INVALID_ARGUMENT.response("Invalid permission: " + p); + } + } + try { + return new Response(HTTP_OK, + jsonFactory.toString(new TestIamPermissionsResponse().setPermissions(permissions))); + } catch (IOException e) { + return Error.INTERNAL_ERROR.response("Error when serializing permissions " + permissions); + } + } + private LocalResourceManagerHelper() { try { server = HttpServer.create(new InetSocketAddress(0), 0); @@ -611,6 +719,7 @@ public synchronized boolean changeLifecycleState(String projectId, String lifecy public synchronized boolean removeProject(String projectId) { // Because this method is synchronized, any code that relies on non-atomic read/write operations // should not fail if that code is also synchronized. - return projects.remove(checkNotNull(projectId)) != null; + policies.remove(checkNotNull(projectId)); + return projects.remove(projectId) != null; } } diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java index c9b2970a4efa..829094816664 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java @@ -2,11 +2,14 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.google.api.services.cloudresourcemanager.model.Binding; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.gcloud.resourcemanager.spi.DefaultResourceManagerRpc; import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc; @@ -18,8 +21,10 @@ import org.junit.BeforeClass; import org.junit.Test; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; public class LocalResourceManagerHelperTest { @@ -45,7 +50,12 @@ public class LocalResourceManagerHelperTest { .setLabels(ImmutableMap.of("k1", "v1", "k2", "v2")); private static final com.google.api.services.cloudresourcemanager.model.Project PROJECT_WITH_PARENT = - copyFrom(COMPLETE_PROJECT).setProjectId("project-with-parent-id").setParent(PARENT); + copyFrom(COMPLETE_PROJECT).setProjectId("project-with-parent-id").setParent(PARENT); + private static final List BINDINGS = ImmutableList.of( + new Binding().setRole("roles/owner").setMembers(ImmutableList.of("user:me@gmail.com")), + new Binding().setRole("roles/viewer").setMembers(ImmutableList.of("group:group@gmail.com"))); + private static final com.google.api.services.cloudresourcemanager.model.Policy POLICY = + new com.google.api.services.cloudresourcemanager.model.Policy().setBindings(BINDINGS); @BeforeClass public static void beforeClass() { @@ -92,6 +102,13 @@ public void testCreate() { assertNull(returnedProject.getParent()); assertNotNull(returnedProject.getProjectNumber()); assertNotNull(returnedProject.getCreateTime()); + com.google.api.services.cloudresourcemanager.model.Policy policy = + rpc.getPolicy(PARTIAL_PROJECT.getProjectId()); + assertEquals(Collections.emptyList(), policy.getBindings()); + assertNotNull(policy.getEtag()); + assertEquals(0, policy.getVersion().intValue()); + rpc.replacePolicy(PARTIAL_PROJECT.getProjectId(), POLICY); + assertEquals(POLICY.getBindings(), rpc.getPolicy(PARTIAL_PROJECT.getProjectId()).getBindings()); try { rpc.create(PARTIAL_PROJECT); fail("Should fail, project already exists."); @@ -99,6 +116,8 @@ public void testCreate() { assertEquals(409, e.code()); assertTrue(e.getMessage().startsWith("A project with the same project ID") && e.getMessage().endsWith("already exists.")); + assertEquals( + POLICY.getBindings(), rpc.getPolicy(PARTIAL_PROJECT.getProjectId()).getBindings()); } returnedProject = rpc.create(PROJECT_WITH_PARENT); compareReadWriteFields(PROJECT_WITH_PARENT, returnedProject); @@ -609,6 +628,65 @@ public void testUndeleteWhenDeleteInProgress() { } } + @Test + public void testGetPolicy() { + assertNull(rpc.getPolicy("nonexistent-project")); + rpc.create(PARTIAL_PROJECT); + com.google.api.services.cloudresourcemanager.model.Policy policy = + rpc.getPolicy(PARTIAL_PROJECT.getProjectId()); + assertEquals(Collections.emptyList(), policy.getBindings()); + assertNotNull(policy.getEtag()); + } + + @Test + public void testReplacePolicy() { + try { + rpc.replacePolicy("nonexistent-project", POLICY); + fail("Project doesn't exist."); + } catch (ResourceManagerException e) { + assertEquals(403, e.code()); + assertTrue(e.getMessage().contains("project was not found")); + } + rpc.create(PARTIAL_PROJECT); + com.google.api.services.cloudresourcemanager.model.Policy invalidPolicy = + new com.google.api.services.cloudresourcemanager.model.Policy().setEtag("wrong-etag"); + try { + rpc.replacePolicy(PARTIAL_PROJECT.getProjectId(), invalidPolicy); + fail("Invalid etag."); + } catch (ResourceManagerException e) { + assertEquals(409, e.code()); + assertTrue(e.getMessage().startsWith("Policy etag mismatch")); + } + String originalEtag = rpc.getPolicy(PARTIAL_PROJECT.getProjectId()).getEtag(); + com.google.api.services.cloudresourcemanager.model.Policy newPolicy = + rpc.replacePolicy(PARTIAL_PROJECT.getProjectId(), POLICY); + assertEquals(POLICY.getBindings(), newPolicy.getBindings()); + assertNotNull(newPolicy.getEtag()); + assertNotEquals(originalEtag, newPolicy.getEtag()); + } + + @Test + public void testTestPermissions() { + List permissions = ImmutableList.of("resourcemanager.projects.get"); + try { + rpc.testPermissions("nonexistent-project", permissions); + fail("Nonexistent project."); + } catch (ResourceManagerException e) { + assertEquals(403, e.code()); + assertEquals("Project nonexistent-project not found.", e.getMessage()); + } + rpc.create(PARTIAL_PROJECT); + try { + rpc.testPermissions(PARTIAL_PROJECT.getProjectId(), ImmutableList.of("get")); + fail("Invalid permission."); + } catch (ResourceManagerException e) { + assertEquals(400, e.code()); + assertEquals("Invalid permission: get", e.getMessage()); + } + assertEquals(ImmutableList.of(true), + rpc.testPermissions(PARTIAL_PROJECT.getProjectId(), permissions)); + } + @Test public void testChangeLifecycleStatus() { assertFalse(RESOURCE_MANAGER_HELPER.changeLifecycleState( @@ -632,8 +710,10 @@ public void testChangeLifecycleStatus() { public void testRemoveProject() { assertFalse(RESOURCE_MANAGER_HELPER.removeProject(COMPLETE_PROJECT.getProjectId())); rpc.create(COMPLETE_PROJECT); + assertNotNull(rpc.getPolicy(COMPLETE_PROJECT.getProjectId())); assertTrue(RESOURCE_MANAGER_HELPER.removeProject(COMPLETE_PROJECT.getProjectId())); assertNull(rpc.get(COMPLETE_PROJECT.getProjectId(), EMPTY_RPC_OPTIONS)); + assertNull(rpc.getPolicy(COMPLETE_PROJECT.getProjectId())); } private void compareReadWriteFields( diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/PolicyTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/PolicyTest.java index 05d1b85bdbed..e6d0105838b7 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/PolicyTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/PolicyTest.java @@ -17,9 +17,13 @@ package com.google.gcloud.resourcemanager; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; import com.google.common.collect.ImmutableSet; import com.google.gcloud.Identity; +import com.google.gcloud.resourcemanager.Policy.Role; +import com.google.gcloud.resourcemanager.Policy.Role.Type; import org.junit.Test; @@ -33,8 +37,10 @@ public class PolicyTest { private static final Identity GROUP = Identity.group("group@gmail.com"); private static final Identity DOMAIN = Identity.domain("google.com"); private static final Policy SIMPLE_POLICY = Policy.builder() - .addBinding(Policy.Role.VIEWER, ImmutableSet.of(USER, SERVICE_ACCOUNT, ALL_USERS)) - .addBinding(Policy.Role.EDITOR, ImmutableSet.of(ALL_AUTH_USERS, GROUP, DOMAIN)) + .addBinding(Role.owner(), ImmutableSet.of(USER)) + .addBinding(Role.viewer(), ImmutableSet.of(ALL_USERS)) + .addBinding(Role.editor(), ImmutableSet.of(ALL_AUTH_USERS, DOMAIN)) + .addBinding(Role.rawRole("some-role"), ImmutableSet.of(SERVICE_ACCOUNT, GROUP)) .build(); private static final Policy FULL_POLICY = new Policy.Builder(SIMPLE_POLICY.bindings(), "etag", 1).build(); @@ -50,4 +56,24 @@ public void testPolicyToAndFromPb() { assertEquals(FULL_POLICY, Policy.fromPb(FULL_POLICY.toPb())); assertEquals(SIMPLE_POLICY, Policy.fromPb(SIMPLE_POLICY.toPb())); } + + @Test + public void testRoleType() { + assertEquals(Type.OWNER, Role.owner().type()); + assertEquals(Type.EDITOR, Role.editor().type()); + assertEquals(Type.VIEWER, Role.viewer().type()); + assertNull(Role.rawRole("raw-role").type()); + } + + @Test + public void testEquals() { + Policy copy = Policy.builder() + .addBinding(Role.owner(), ImmutableSet.of(USER)) + .addBinding(Role.viewer(), ImmutableSet.of(ALL_USERS)) + .addBinding(Role.editor(), ImmutableSet.of(ALL_AUTH_USERS, DOMAIN)) + .addBinding(Role.rawRole("some-role"), ImmutableSet.of(SERVICE_ACCOUNT, GROUP)) + .build(); + assertEquals(SIMPLE_POLICY, copy); + assertNotEquals(SIMPLE_POLICY, FULL_POLICY); + } } diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectTest.java index 4e239acc45ef..882ec77197f3 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectTest.java @@ -26,6 +26,7 @@ import static org.junit.Assert.assertNull; import com.google.common.collect.ImmutableMap; +import com.google.gcloud.resourcemanager.ProjectInfo.ResourceId; import org.junit.After; import org.junit.Before; @@ -84,12 +85,12 @@ public void testToBuilder() { @Test public void testBuilder() { - initializeExpectedProject(4); - expect(resourceManager.options()).andReturn(mockOptions).times(4); + expect(resourceManager.options()).andReturn(mockOptions).times(7); replay(resourceManager); Project.Builder builder = - new Project.Builder(new Project(resourceManager, new ProjectInfo.BuilderImpl(PROJECT_ID))); - Project project = builder.name(NAME) + new Project.Builder(new Project(resourceManager, new ProjectInfo.BuilderImpl("wrong-id"))); + Project project = builder.projectId(PROJECT_ID) + .name(NAME) .labels(LABELS) .projectNumber(PROJECT_NUMBER) .createTimeMillis(CREATE_TIME_MILLIS) @@ -102,6 +103,23 @@ public void testBuilder() { assertEquals(CREATE_TIME_MILLIS, project.createTimeMillis()); assertEquals(STATE, project.state()); assertEquals(resourceManager.options(), project.resourceManager().options()); + assertNull(project.parent()); + ResourceId parent = new ResourceId("id", "type"); + project = project.toBuilder() + .clearLabels() + .addLabel("k3", "v3") + .addLabel("k4", "v4") + .removeLabel("k4") + .parent(parent) + .build(); + assertEquals(PROJECT_ID, project.projectId()); + assertEquals(NAME, project.name()); + assertEquals(ImmutableMap.of("k3", "v3"), project.labels()); + assertEquals(PROJECT_NUMBER, project.projectNumber()); + assertEquals(CREATE_TIME_MILLIS, project.createTimeMillis()); + assertEquals(STATE, project.state()); + assertEquals(resourceManager.options(), project.resourceManager().options()); + assertEquals(parent, project.parent()); } @Test diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java index 5b172d6a070e..a69880c5d064 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java @@ -18,15 +18,20 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.gcloud.Identity; import com.google.gcloud.Page; +import com.google.gcloud.resourcemanager.Policy.Role; import com.google.gcloud.resourcemanager.ProjectInfo.ResourceId; +import com.google.gcloud.resourcemanager.ResourceManager.Permission; import com.google.gcloud.resourcemanager.ResourceManager.ProjectField; import com.google.gcloud.resourcemanager.ResourceManager.ProjectGetOption; import com.google.gcloud.resourcemanager.ResourceManager.ProjectListOption; @@ -43,6 +48,7 @@ import org.junit.rules.ExpectedException; import java.util.Iterator; +import java.util.List; import java.util.Map; public class ResourceManagerImplTest { @@ -65,6 +71,10 @@ public class ResourceManagerImplTest { .parent(PARENT) .build(); private static final Map EMPTY_RPC_OPTIONS = ImmutableMap.of(); + private static final Policy POLICY = Policy.builder() + .addBinding(Role.owner(), Identity.user("me@gmail.com")) + .addBinding(Role.editor(), Identity.serviceAccount("serviceaccount@gmail.com")) + .build(); @Rule public ExpectedException thrown = ExpectedException.none(); @@ -320,6 +330,60 @@ public void testUndelete() { } } + @Test + public void testGetPolicy() { + assertNull(RESOURCE_MANAGER.getPolicy(COMPLETE_PROJECT.projectId())); + RESOURCE_MANAGER.create(COMPLETE_PROJECT); + RESOURCE_MANAGER.replacePolicy(COMPLETE_PROJECT.projectId(), POLICY); + Policy retrieved = RESOURCE_MANAGER.getPolicy(COMPLETE_PROJECT.projectId()); + assertEquals(POLICY.bindings(), retrieved.bindings()); + assertNotNull(retrieved.etag()); + assertEquals(0, retrieved.version().intValue()); + } + + @Test + public void testReplacePolicy() { + try { + RESOURCE_MANAGER.replacePolicy("nonexistent-project", POLICY); + fail("Project doesn't exist."); + } catch (ResourceManagerException e) { + assertEquals(403, e.code()); + assertTrue(e.getMessage().endsWith("project was not found.")); + } + RESOURCE_MANAGER.create(PARTIAL_PROJECT); + Policy oldPolicy = RESOURCE_MANAGER.getPolicy(PARTIAL_PROJECT.projectId()); + RESOURCE_MANAGER.replacePolicy(PARTIAL_PROJECT.projectId(), POLICY); + try { + RESOURCE_MANAGER.replacePolicy(PARTIAL_PROJECT.projectId(), oldPolicy); + fail("Policy with an invalid etag didn't cause error."); + } catch (ResourceManagerException e) { + assertEquals(409, e.code()); + assertTrue(e.getMessage().contains("Policy etag mismatch")); + } + String originalEtag = RESOURCE_MANAGER.getPolicy(PARTIAL_PROJECT.projectId()).etag(); + Policy newPolicy = RESOURCE_MANAGER.replacePolicy(PARTIAL_PROJECT.projectId(), POLICY); + assertEquals(POLICY.bindings(), newPolicy.bindings()); + assertNotNull(newPolicy.etag()); + assertNotEquals(originalEtag, newPolicy.etag()); + } + + @Test + public void testTestPermissions() { + List permissions = ImmutableList.of(Permission.GET); + try { + RESOURCE_MANAGER.testPermissions("nonexistent-project", permissions); + fail("Nonexistent project"); + } catch (ResourceManagerException e) { + assertEquals(403, e.code()); + assertEquals("Project nonexistent-project not found.", e.getMessage()); + } + RESOURCE_MANAGER.create(PARTIAL_PROJECT); + assertEquals(ImmutableList.of(true), + RESOURCE_MANAGER.testPermissions(PARTIAL_PROJECT.projectId(), permissions)); + assertEquals(ImmutableList.of(true, true), RESOURCE_MANAGER.testPermissions( + PARTIAL_PROJECT.projectId(), Permission.DELETE, Permission.GET)); + } + @Test public void testRetryableException() { ResourceManagerRpcFactory rpcFactoryMock = EasyMock.createMock(ResourceManagerRpcFactory.class); diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java index 35b72ae1713f..f71f5d7989d6 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java @@ -56,7 +56,7 @@ public class SerializationTest { private static final ResourceManager.ProjectListOption PROJECT_LIST_OPTION = ResourceManager.ProjectListOption.filter("name:*"); private static final Policy POLICY = Policy.builder() - .addBinding(Policy.Role.VIEWER, ImmutableSet.of(Identity.user("abc@gmail.com"))) + .addBinding(Policy.Role.viewer(), ImmutableSet.of(Identity.user("abc@gmail.com"))) .build(); @Test From 8ae8a1b160bbbd1e18bedf2a35d014449397ec3e Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 16 Mar 2016 09:35:09 +0100 Subject: [PATCH 173/375] Create base class for serialization tests --- gcloud-java-bigquery/pom.xml | 7 ++ .../gcloud/bigquery/SerializationTest.java | 47 ++-------- .../google/gcloud/BaseSerializationTest.java | 64 +++++++++++++ .../com/google/gcloud/SerializationTest.java | 33 +++++++ gcloud-java-datastore/pom.xml | 7 ++ .../gcloud/datastore/SerializationTest.java | 90 +++---------------- gcloud-java-resourcemanager/pom.xml | 7 ++ .../resourcemanager/SerializationTest.java | 50 ++--------- gcloud-java-storage/pom.xml | 7 ++ .../gcloud/storage/SerializationTest.java | 47 ++-------- pom.xml | 7 ++ 11 files changed, 163 insertions(+), 203 deletions(-) create mode 100644 gcloud-java-core/src/test/java/com/google/gcloud/BaseSerializationTest.java create mode 100644 gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java diff --git a/gcloud-java-bigquery/pom.xml b/gcloud-java-bigquery/pom.xml index 9a2137cb987d..5c79f150c722 100644 --- a/gcloud-java-bigquery/pom.xml +++ b/gcloud-java-bigquery/pom.xml @@ -39,6 +39,13 @@ + + ${project.groupId} + gcloud-java-core + ${project.version} + test-jar + test + junit junit diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java index 254c8954bf30..f64946e062d7 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java @@ -17,11 +17,11 @@ package com.google.gcloud.bigquery; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotSame; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.gcloud.AuthCredentials; +import com.google.gcloud.BaseSerializationTest; import com.google.gcloud.RestorableState; import com.google.gcloud.RetryParams; import com.google.gcloud.WriteChannel; @@ -29,17 +29,13 @@ import org.junit.Test; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; import java.io.Serializable; import java.nio.charset.StandardCharsets; import java.util.List; import java.util.Map; -public class SerializationTest { +public class SerializationTest extends BaseSerializationTest { private static final Acl DOMAIN_ACCESS = Acl.of(new Acl.Domain("domain"), Acl.Role.WRITER); @@ -231,27 +227,18 @@ public class SerializationTest { private static final Table TABLE = new Table(BIGQUERY, new TableInfo.BuilderImpl(TABLE_INFO)); private static final Job JOB = new Job(BIGQUERY, new JobInfo.BuilderImpl(JOB_INFO)); - @Test - public void testServiceOptions() throws Exception { + @Override + public Serializable[] serializableObjects() { BigQueryOptions options = BigQueryOptions.builder() .projectId("p1") .authCredentials(AuthCredentials.createForAppEngine()) .build(); - BigQueryOptions serializedCopy = serializeAndDeserialize(options); - assertEquals(options, serializedCopy); - - options = options.toBuilder() + BigQueryOptions otherOptions = options.toBuilder() .projectId("p2") .retryParams(RetryParams.defaultInstance()) .authCredentials(null) .build(); - serializedCopy = serializeAndDeserialize(options); - assertEquals(options, serializedCopy); - } - - @Test - public void testModelAndRequests() throws Exception { - Serializable[] objects = {DOMAIN_ACCESS, GROUP_ACCESS, USER_ACCESS, VIEW_ACCESS, DATASET_ID, + return new Serializable[]{DOMAIN_ACCESS, GROUP_ACCESS, USER_ACCESS, VIEW_ACCESS, DATASET_ID, DATASET_INFO, TABLE_ID, CSV_OPTIONS, STREAMING_BUFFER, TABLE_DEFINITION, EXTERNAL_TABLE_DEFINITION, VIEW_DEFINITION, TABLE_SCHEMA, TABLE_INFO, VIEW_INFO, EXTERNAL_TABLE_INFO, INLINE_FUNCTION, URI_FUNCTION, JOB_STATISTICS, EXTRACT_STATISTICS, @@ -262,14 +249,7 @@ public void testModelAndRequests() throws Exception { BigQuery.DatasetOption.fields(), BigQuery.DatasetDeleteOption.deleteContents(), BigQuery.DatasetListOption.all(), BigQuery.TableOption.fields(), BigQuery.TableListOption.pageSize(42L), BigQuery.JobOption.fields(), - BigQuery.JobListOption.allUsers(), DATASET, TABLE, JOB}; - for (Serializable obj : objects) { - Object copy = serializeAndDeserialize(obj); - assertEquals(obj, obj); - assertEquals(obj, copy); - assertNotSame(obj, copy); - assertEquals(copy, copy); - } + BigQuery.JobListOption.allUsers(), DATASET, TABLE, JOB, options, otherOptions}; } @Test @@ -288,17 +268,4 @@ public void testWriteChannelState() throws IOException, ClassNotFoundException { assertEquals(state.hashCode(), deserializedState.hashCode()); assertEquals(state.toString(), deserializedState.toString()); } - - @SuppressWarnings("unchecked") - private T serializeAndDeserialize(T obj) - throws IOException, ClassNotFoundException { - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - try (ObjectOutputStream output = new ObjectOutputStream(bytes)) { - output.writeObject(obj); - } - try (ObjectInputStream input = - new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray()))) { - return (T) input.readObject(); - } - } } diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/BaseSerializationTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/BaseSerializationTest.java new file mode 100644 index 000000000000..533dfcde6ad8 --- /dev/null +++ b/gcloud-java-core/src/test/java/com/google/gcloud/BaseSerializationTest.java @@ -0,0 +1,64 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotSame; + +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; + +/** + * Base class for serialization tests. To use this class in your tests override the + * {@code serializableObjects()} method to return all objects that must be serializable. + */ +public abstract class BaseSerializationTest { + + public abstract Serializable[] serializableObjects(); + + @Test + public void testSerializableObjects() throws Exception { + for (Serializable obj : serializableObjects()) { + Object copy = serializeAndDeserialize(obj); + assertEquals(obj, obj); + assertEquals(obj, copy); + assertEquals(obj.hashCode(), copy.hashCode()); + assertEquals(obj.toString(), copy.toString()); + assertNotSame(obj, copy); + assertEquals(copy, copy); + } + } + + @SuppressWarnings("unchecked") + public T serializeAndDeserialize(T obj) + throws IOException, ClassNotFoundException { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + try (ObjectOutputStream output = new ObjectOutputStream(bytes)) { + output.writeObject(obj); + } + try (ObjectInputStream input = + new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray()))) { + return (T) input.readObject(); + } + } +} diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java new file mode 100644 index 000000000000..aec9158e1ee0 --- /dev/null +++ b/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java @@ -0,0 +1,33 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud; + +import com.google.common.collect.ImmutableList; + +import java.io.Serializable; + +public class SerializationTest extends BaseSerializationTest { + + private static final PageImpl PAGE = + new PageImpl<>(null, "cursor", ImmutableList.of("string1", "string2")); + private static final RetryParams RETRY_PARAMS = RetryParams.defaultInstance(); + + @Override + public Serializable[] serializableObjects() { + return new Serializable[]{PAGE, RETRY_PARAMS}; + } +} diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index 977b6db22b14..f3b46e22b3c8 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -33,6 +33,13 @@ + + ${project.groupId} + gcloud-java-core + ${project.version} + test-jar + test + junit junit diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index 3976be2cc383..7a6f065d6ca6 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -17,28 +17,17 @@ package com.google.gcloud.datastore; import static java.nio.charset.StandardCharsets.UTF_8; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotSame; import com.google.api.services.datastore.DatastoreV1; -import com.google.common.collect.ImmutableMultimap; -import com.google.common.collect.Multimap; import com.google.gcloud.AuthCredentials; +import com.google.gcloud.BaseSerializationTest; import com.google.gcloud.RetryParams; import com.google.gcloud.datastore.StructuredQuery.CompositeFilter; import com.google.gcloud.datastore.StructuredQuery.OrderBy; import com.google.gcloud.datastore.StructuredQuery.Projection; import com.google.gcloud.datastore.StructuredQuery.PropertyFilter; -import org.junit.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - -public class SerializationTest { +public class SerializationTest extends BaseSerializationTest { private static final IncompleteKey INCOMPLETE_KEY1 = IncompleteKey.builder("ds", "k").ancestors(PathElement.of("p", 1)).build(); @@ -114,82 +103,23 @@ public class SerializationTest { .build(); private static final ProjectionEntity PROJECTION_ENTITY = ProjectionEntity.fromPb(ENTITY1.toPb()); - @SuppressWarnings("rawtypes") - private static final Multimap TYPE_TO_VALUES = - ImmutableMultimap.builder() - .put(ValueType.NULL, NULL_VALUE) - .put(ValueType.KEY, KEY_VALUE) - .put(ValueType.STRING, STRING_VALUE) - .putAll(ValueType.ENTITY, EMBEDDED_ENTITY_VALUE1, EMBEDDED_ENTITY_VALUE2, - EMBEDDED_ENTITY_VALUE3) - .put(ValueType.LIST, LIST_VALUE) - .put(ValueType.LONG, LONG_VALUE) - .put(ValueType.DOUBLE, DOUBLE_VALUE) - .put(ValueType.BOOLEAN, BOOLEAN_VALUE) - .put(ValueType.DATE_TIME, DATE_AND_TIME_VALUE) - .put(ValueType.BLOB, BLOB_VALUE) - .put(ValueType.RAW_VALUE, RAW_VALUE) - .build(); - - @Test - public void testServiceOptions() throws Exception { + @Override + public java.io.Serializable[] serializableObjects() { DatastoreOptions options = DatastoreOptions.builder() .authCredentials(AuthCredentials.createForAppEngine()) .normalizeDataset(false) .projectId("ds1") .build(); - DatastoreOptions serializedCopy = serializeAndDeserialize(options); - assertEquals(options, serializedCopy); - - options = options.toBuilder() + DatastoreOptions otherOptions = options.toBuilder() .namespace("ns1") .retryParams(RetryParams.defaultInstance()) .authCredentials(null) .force(true) .build(); - serializedCopy = serializeAndDeserialize(options); - assertEquals(options, serializedCopy); - } - - @Test - public void testValues() throws Exception { - for (ValueType valueType : ValueType.values()) { - for (Value value : TYPE_TO_VALUES.get(valueType)) { - Value copy = serializeAndDeserialize(value); - assertEquals(value, value); - assertEquals(value, copy); - assertNotSame(value, copy); - assertEquals(copy, copy); - assertEquals(value.get(), copy.get()); - } - } - } - - @Test - public void testTypes() throws Exception { - Serializable[] types = { KEY1, KEY2, INCOMPLETE_KEY1, INCOMPLETE_KEY2, ENTITY1, ENTITY2, - ENTITY3, EMBEDDED_ENTITY, PROJECTION_ENTITY, DATE_TIME1, BLOB1, CURSOR1, GQL1, GQL2, - QUERY1, QUERY2, QUERY3}; - for (Serializable obj : types) { - Object copy = serializeAndDeserialize(obj); - assertEquals(obj, obj); - assertEquals(obj, copy); - assertNotSame(obj, copy); - assertEquals(copy, copy); - } - } - - private T serializeAndDeserialize(T obj) - throws IOException, ClassNotFoundException { - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - try (ObjectOutputStream output = new ObjectOutputStream(bytes)) { - output.writeObject(obj); - } - try (ObjectInputStream input = - new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray()))) { - @SuppressWarnings("unchecked") - T result = (T) input.readObject(); - return result; - } + return new java.io.Serializable[]{KEY1, KEY2, INCOMPLETE_KEY1, INCOMPLETE_KEY2, ENTITY1, + ENTITY2, ENTITY3, EMBEDDED_ENTITY, PROJECTION_ENTITY, DATE_TIME1, BLOB1, CURSOR1, GQL1, + GQL2, QUERY1, QUERY2, QUERY3, NULL_VALUE, KEY_VALUE, STRING_VALUE, EMBEDDED_ENTITY_VALUE1, + EMBEDDED_ENTITY_VALUE2, EMBEDDED_ENTITY_VALUE3, LIST_VALUE, LONG_VALUE, DOUBLE_VALUE, + BOOLEAN_VALUE, DATE_AND_TIME_VALUE, BLOB_VALUE, RAW_VALUE, options, otherOptions}; } } diff --git a/gcloud-java-resourcemanager/pom.xml b/gcloud-java-resourcemanager/pom.xml index c10691d3b07d..c0c48af48f1e 100644 --- a/gcloud-java-resourcemanager/pom.xml +++ b/gcloud-java-resourcemanager/pom.xml @@ -33,6 +33,13 @@ + + ${project.groupId} + gcloud-java-core + ${project.version} + test-jar + test + junit junit diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java index f71f5d7989d6..2dcd3f9d3e7b 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java @@ -16,26 +16,17 @@ package com.google.gcloud.resourcemanager; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotSame; - import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.gcloud.Identity; +import com.google.gcloud.BaseSerializationTest; import com.google.gcloud.PageImpl; import com.google.gcloud.RetryParams; -import org.junit.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Collections; -public class SerializationTest { +public class SerializationTest extends BaseSerializationTest { private static final ResourceManager RESOURCE_MANAGER = ResourceManagerOptions.defaultInstance().service(); @@ -59,41 +50,14 @@ public class SerializationTest { .addBinding(Policy.Role.viewer(), ImmutableSet.of(Identity.user("abc@gmail.com"))) .build(); - @Test - public void testServiceOptions() throws Exception { + @Override + public Serializable[] serializableObjects() { ResourceManagerOptions options = ResourceManagerOptions.builder().build(); - ResourceManagerOptions serializedCopy = serializeAndDeserialize(options); - assertEquals(options, serializedCopy); - options = options.toBuilder() + ResourceManagerOptions otherOptions = options.toBuilder() .projectId("some-unnecessary-project-ID") .retryParams(RetryParams.defaultInstance()) .build(); - serializedCopy = serializeAndDeserialize(options); - assertEquals(options, serializedCopy); - } - - @Test - public void testModelAndRequests() throws Exception { - Serializable[] objects = {PARTIAL_PROJECT_INFO, FULL_PROJECT_INFO, PROJECT, PAGE_RESULT, - PROJECT_GET_OPTION, PROJECT_LIST_OPTION, POLICY}; - for (Serializable obj : objects) { - Object copy = serializeAndDeserialize(obj); - assertEquals(obj, obj); - assertEquals(obj, copy); - assertNotSame(obj, copy); - assertEquals(copy, copy); - } - } - - @SuppressWarnings("unchecked") - private T serializeAndDeserialize(T obj) throws IOException, ClassNotFoundException { - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - try (ObjectOutputStream output = new ObjectOutputStream(bytes)) { - output.writeObject(obj); - } - try (ObjectInputStream input = - new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray()))) { - return (T) input.readObject(); - } + return new Serializable[]{PARTIAL_PROJECT_INFO, FULL_PROJECT_INFO, PROJECT, PAGE_RESULT, + PROJECT_GET_OPTION, PROJECT_LIST_OPTION, POLICY, options, otherOptions}; } } diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml index d5f0f6d98660..16427d50de3a 100644 --- a/gcloud-java-storage/pom.xml +++ b/gcloud-java-storage/pom.xml @@ -37,6 +37,13 @@ + + ${project.groupId} + gcloud-java-core + ${project.version} + test-jar + test + junit junit diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java index efa56d9e39b2..ee3d7c946312 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java @@ -17,10 +17,10 @@ package com.google.gcloud.storage; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotSame; import com.google.common.collect.ImmutableMap; import com.google.gcloud.AuthCredentials; +import com.google.gcloud.BaseSerializationTest; import com.google.gcloud.PageImpl; import com.google.gcloud.ReadChannel; import com.google.gcloud.RestorableState; @@ -31,16 +31,12 @@ import org.junit.Test; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Collections; import java.util.Map; -public class SerializationTest { +public class SerializationTest extends BaseSerializationTest { private static final Storage STORAGE = StorageOptions.builder().projectId("p").build().service(); private static final Acl.Domain ACL_DOMAIN = new Acl.Domain("domain"); @@ -77,37 +73,21 @@ public class SerializationTest { Storage.BucketTargetOption.metagenerationNotMatch(); private static final Map EMPTY_RPC_OPTIONS = ImmutableMap.of(); - @Test - public void testServiceOptions() throws Exception { + @Override + public Serializable[] serializableObjects() { StorageOptions options = StorageOptions.builder() .projectId("p1") .authCredentials(AuthCredentials.createForAppEngine()) .build(); - StorageOptions serializedCopy = serializeAndDeserialize(options); - assertEquals(options, serializedCopy); - - options = options.toBuilder() + StorageOptions otherOptions = options.toBuilder() .projectId("p2") .retryParams(RetryParams.defaultInstance()) .authCredentials(null) .build(); - serializedCopy = serializeAndDeserialize(options); - assertEquals(options, serializedCopy); - } - - @Test - public void testModelAndRequests() throws Exception { - Serializable[] objects = {ACL_DOMAIN, ACL_GROUP, ACL_PROJECT_, ACL_USER, ACL_RAW, ACL, + return new Serializable[]{ACL_DOMAIN, ACL_GROUP, ACL_PROJECT_, ACL_USER, ACL_RAW, ACL, BLOB_INFO, BLOB, BUCKET_INFO, BUCKET, ORIGIN, CORS, BATCH_REQUEST, BATCH_RESPONSE, PAGE_RESULT, BLOB_LIST_OPTIONS, BLOB_SOURCE_OPTIONS, BLOB_TARGET_OPTIONS, - BUCKET_LIST_OPTIONS, BUCKET_SOURCE_OPTIONS, BUCKET_TARGET_OPTIONS}; - for (Serializable obj : objects) { - Object copy = serializeAndDeserialize(obj); - assertEquals(obj, obj); - assertEquals(obj, copy); - assertNotSame(obj, copy); - assertEquals(copy, copy); - } + BUCKET_LIST_OPTIONS, BUCKET_SOURCE_OPTIONS, BUCKET_TARGET_OPTIONS, options, otherOptions}; } @Test @@ -142,17 +122,4 @@ public void testWriteChannelState() throws IOException, ClassNotFoundException { assertEquals(state.hashCode(), deserializedState.hashCode()); assertEquals(state.toString(), deserializedState.toString()); } - - @SuppressWarnings("unchecked") - private T serializeAndDeserialize(T obj) - throws IOException, ClassNotFoundException { - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - try (ObjectOutputStream output = new ObjectOutputStream(bytes)) { - output.writeObject(obj); - } - try (ObjectInputStream input = - new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray()))) { - return (T) input.readObject(); - } - } } diff --git a/pom.xml b/pom.xml index b7766ac0e5c6..1abfb094ffb8 100644 --- a/pom.xml +++ b/pom.xml @@ -215,6 +215,13 @@ + + + + test-jar + + + maven-compiler-plugin From f7f4de852874b04e92cff4233dfa0f635c0792c2 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Tue, 1 Mar 2016 12:58:25 -0800 Subject: [PATCH 174/375] Added READMEs. This includes: - Package README - Adjusted global gcloud-java README - Package description - Reorganizing snippets to be consistent with readme --- README.md | 74 +++- gcloud-java-dns/README.md | 385 ++++++++++++++++++ .../com/google/gcloud/dns/package-info.java | 60 +++ .../com/google/gcloud/dns/it/ITDnsTest.java | 2 +- ...rds.java => CreateOrUpdateDnsRecords.java} | 9 +- ...reateAndListZones.java => CreateZone.java} | 23 +- .../examples/dns/snippets/DeleteZone.java | 2 +- .../snippets/ManipulateZonesAndRecords.java | 157 +++++++ 8 files changed, 688 insertions(+), 24 deletions(-) create mode 100644 gcloud-java-dns/README.md create mode 100644 gcloud-java-dns/src/main/java/com/google/gcloud/dns/package-info.java rename gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/{CreateAndListDnsRecords.java => CreateOrUpdateDnsRecords.java} (89%) rename gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/{CreateAndListZones.java => CreateZone.java} (70%) create mode 100644 gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecords.java diff --git a/README.md b/README.md index 32a0f539425e..a908cef0bf35 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ This client supports the following Google Cloud Platform services: - [Google Cloud BigQuery] (#google-cloud-bigquery-alpha) (Alpha) - [Google Cloud Datastore] (#google-cloud-datastore) +- [Google Cloud DNS] (#google-cloud-dns-alpha) (Alpha) - [Google Cloud Resource Manager] (#google-cloud-resource-manager-alpha) (Alpha) - [Google Cloud Storage] (#google-cloud-storage) @@ -48,8 +49,10 @@ Example Applications - Read more about using this application on the [`BigQueryExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/bigquery/BigQueryExample.html). - [`Bookshelf`](https://github.com/GoogleCloudPlatform/getting-started-java/tree/master/bookshelf) - An App Engine app that manages a virtual bookshelf. - This app uses `gcloud-java` to interface with Cloud Datastore and Cloud Storage. It also uses Cloud SQL, another Google Cloud Platform service. -- [`DatastoreExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/DatastoreExample.java) - A simple command line interface for the Cloud Datastore +- [`DatastoreExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/DatastoreExample.java) - A simple command line interface for Cloud Datastore - Read more about using this application on the [`DatastoreExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/datastore/DatastoreExample.html). +- [`DnsExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java) - A simple command line interface for Cloud DNS + - Read more about using this application on the [`DnsExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/dns/DnsExample.html). - [`ResourceManagerExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/ResourceManagerExample.java) - A simple command line interface providing some of Cloud Resource Manager's functionality - Read more about using this application on the [`ResourceManagerExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/resourcemanager/ResourceManagerExample.html). - [`SparkDemo`](https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/managed_vms/sparkjava) - An example of using gcloud-java-datastore from within the SparkJava and App Engine Managed VM frameworks. @@ -218,6 +221,71 @@ if (entity != null) { } ``` +Google Cloud DNS (Alpha) +---------------------- +- [API Documentation][dns-api] +- [Official Documentation][cloud-dns-docs] + +*Follow the [activation instructions][cloud-dns-activation] to use the Google Cloud DNS API with your project.* + +#### Preview + +Here are two code snippets showing simple usage examples from within Compute/App Engine. Note that you must [supply credentials](#authentication) and a project ID if running this snippet elsewhere. + +The first snippet shows how to create a zone resource. Complete source code can be found on +[CreateZone.java](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateZone.java). + +```java +import com.google.gcloud.dns.Dns; +import com.google.gcloud.dns.DnsOptions; +import com.google.gcloud.dns.Zone; +import com.google.gcloud.dns.ZoneInfo; + +Dns dns = DnsOptions.defaultInstance().service(); +String zoneName = "my-unique-zone"; +String domainName = "someexampledomain.com."; +String description = "This is a gcloud-java-dns sample zone."; +ZoneInfo zoneInfo = ZoneInfo.of(zoneName, domainName, description); +Zone zone = dns.create(zoneInfo); +``` + +The second snippet shows how to create records inside a zone. The complete code can be found on [CreateOrUpdateDnsRecords.java](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateDnsRecords.java). + +```java +import com.google.gcloud.dns.ChangeRequest; +import com.google.gcloud.dns.Dns; +import com.google.gcloud.dns.DnsOptions; +import com.google.gcloud.dns.DnsRecord; +import com.google.gcloud.dns.Zone; + +import java.util.Iterator; +import java.util.concurrent.TimeUnit; + +Dns dns = DnsOptions.defaultInstance().service(); +String zoneName = "my-unique-zone"; +Zone zone = dns.getZone(zoneName); +String ip = "12.13.14.15"; +DnsRecord toCreate = DnsRecord.builder("www.someexampledomain.com.", DnsRecord.Type.A) + .ttl(24, TimeUnit.HOURS) + .addRecord(ip) + .build(); +ChangeRequest.Builder changeBuilder = ChangeRequest.builder().add(toCreate); + +// Verify that the record does not exist yet. +// If it does exist, we will overwrite it with our prepared record. +Iterator recordIterator = zone.listDnsRecords().iterateAll(); +while (recordIterator.hasNext()) { + DnsRecord current = recordIterator.next(); + if (toCreate.name().equals(current.name()) && + toCreate.type().equals(current.type())) { + changeBuilder.delete(current); + } +} + +ChangeRequest changeRequest = changeBuilder.build(); +zone.applyChangeRequest(changeRequest); +``` + Google Cloud Resource Manager (Alpha) ---------------------- @@ -359,6 +427,10 @@ Apache 2.0 - See [LICENSE] for more information. [cloud-datastore-activation]: https://cloud.google.com/datastore/docs/activate [datastore-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/datastore/package-summary.html +[dns-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/dns/package-summary.html +[cloud-dns-docs]: https://cloud.google.com/dns/docs +[cloud-dns-activation]: https://console.cloud.google.com/start/api?id=dns + [cloud-pubsub]: https://cloud.google.com/pubsub/ [cloud-pubsub-docs]: https://cloud.google.com/pubsub/docs diff --git a/gcloud-java-dns/README.md b/gcloud-java-dns/README.md new file mode 100644 index 000000000000..4f65d8e3b814 --- /dev/null +++ b/gcloud-java-dns/README.md @@ -0,0 +1,385 @@ +Google Cloud Java Client for DNS +================================ + +Java idiomatic client for [Google Cloud DNS] (https://cloud.google.com/dns/). + +[![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java) +[![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) +[![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-dns.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-dns.svg) +[![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) +[![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969) + +- [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) +- [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/dns/package-summary.html) + +> Note: This client is a work-in-progress, and may occasionally +> make backwards-incompatible changes. + +Quickstart +---------- +If you are using Maven, add this to your pom.xml file +```xml + + com.google.gcloud + gcloud-java-dns + 0.1.5 + +``` +If you are using Gradle, add this to your dependencies +```Groovy +compile 'com.google.gcloud:gcloud-java-dns:0.1.5' +``` +If you are using SBT, add this to your dependencies +```Scala +libraryDependencies += "com.google.gcloud" % "gcloud-java-dns" % "0.1.5" +``` + +Example Application +------------------- + +[`DnsExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java) +is a simple command line interface that provides some of Google Cloud DNS's functionality. Read +more about using the application on the +[`DnsExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/dns/DnsExample.html). + +Authentication +-------------- + +See the [Authentication](https://github.com/GoogleCloudPlatform/gcloud-java#authentication) section +in the base directory's README. + +About Google Cloud DNS +-------------------------- + +[Google Cloud DNS][cloud-dns] is a scalable, reliable and managed authoritative Domain Name System +(DNS) service running on the same infrastructure as Google. It has low latency, high availability +and is a cost-effective way to make your applications and services available to your users. + +See the [Google Cloud DNS docs][dns-activate] for more details on how to activate +Cloud DNS for your project. + +See the [``gcloud-java-dns`` API documentation][dns-api] to learn how to interact +with the Cloud DNS using this client Library. + +Getting Started +--------------- +#### Prerequisites +For this tutorial, you will need a [Google Developers Console](https://console.developers.google.com/) +project with the DNS API enabled. You will need to [enable billing](https://support.google.com/cloud/answer/6158867?hl=en) +to use Google Cloud DNS. [Follow these instructions](https://cloud.google.com/docs/authentication#preparation) +to get your project set up. You will also need to set up the local development environment by +[installing the Google Cloud SDK](https://cloud.google.com/sdk/) and running the following commands +in command line: `gcloud auth login` and `gcloud config set project [YOUR PROJECT ID]`. + +#### Installation and setup +You'll need to obtain the `gcloud-java-dns` library. See the [Quickstart](#quickstart) section to +add `gcloud-java-dns` as a dependency in your code. + +#### Creating an authorized service object +To make authenticated requests to Google Cloud DNS, you must create a service object with +credentials. You can then make API calls by calling methods on the DNS service object. The simplest +way to authenticate is to use [Application Default Credentials](https://developers.google.com/identity/protocols/application-default-credentials). +These credentials are automatically inferred from your environment, so you only need the following +code to create your service object: + +```java +import com.google.gcloud.dns.Dns; +import com.google.gcloud.dns.DnsOptions; + +Dns dns = DnsOptions.defaultInstance().service(); +``` + +For other authentication options, see the [Authentication](https://github.com/GoogleCloudPlatform/gcloud-java#authentication) page. + +#### Managing Zones +DNS records in `gcloud-java-dns` are managed inside containers called "zones". `ZoneInfo` is a class +which encapsulates metadata that describe a zone in Google Cloud DNS. `Zone`, a subclass of `ZoneInfo`, adds service-related +functionality over `ZoneInfo`. + +*Important: Zone names must be unique to the project. If you choose a zone name that already +exists within your project, you'll get a helpful error message telling you to choose another name. In the code below, +replace "my-unique-zone" with a unique zone name. See more about naming rules [here](https://cloud.google.com/dns/api/v1/managedZones#name).* + +In this code snippet, we create a new zone to manage DNS records for domain `someexampledomain.com.` + +*Important: The service may require that you verify ownership of the domain for which you are creating a zone. +Hence, we recommend that you do so beforehand. You can verify ownership of +a domain name [here](https://www.google.com/webmasters/verification/home). Note that Cloud DNS +requires fully qualified domain names which must end with a period.* + +Add the following imports at the top of your file: + +```java +import com.google.gcloud.dns.Zone; +import com.google.gcloud.dns.ZoneInfo; +``` + +Then add the following code to create a zone. + +```java +// Create a zone metadata object +String zoneName = "my-unique-zone"; // Change this zone name which is unique within your project +String domainName = "someexampledomain.com."; // Change this to a domain which you own +String description = "This is a gcloud-java-dns sample zone."; +ZoneInfo zoneInfo = ZoneInfo.of(zoneName, domainName, description); + +// Create zone in Google Cloud DNS +Zone zone = dns.create(zoneInfo); +System.out.printf("Zone was created and assigned ID %s.%n", zone.id()); +``` + +You now have an empty zone hosted in Google Cloud DNS which is ready to be populated with DNS +records for domain name `someexampledomain.com.` Upon creating the zone, the cloud service +assigned a set of DNS servers to host records for this zone and +created the required SOA and NS records for the domain. The following snippet prints the list of servers +assigned to the zone created above. First, import + +```java +import java.util.List; +``` + +and then add + +```java +// Print assigned name servers +List nameServers = zone.nameServers(); +for(String nameServer : nameServers) { + System.out.println(nameServer); +} +``` + +You can now instruct your domain registrar to [update your domain name servers] (https://cloud.google.com/dns/update-name-servers). +As soon as this happens and the change propagates through cached values in DNS resolvers, +all the DNS queries will be directed to and answered by the Google Cloud DNS service. + +#### Creating DNS Records +Now that we have a zone, we can add some DNS records. The DNS records held within zones are +modified by "change requests". In this example, we create and apply a change request to +our zone that creates a DNS record of type A and points URL www.someexampledomain.com to +IP address 12.13.14.15. Start by adding + +```java +import com.google.gcloud.dns.ChangeRequest; +import com.google.gcloud.dns.DnsRecord; + +import java.util.concurrent.TimeUnit; +``` + +and proceed with: + +```java +// Prepare a www.someexampledomain.com. type A record with ttl of 24 hours +String ip = "12.13.14.15"; +DnsRecord toCreate = DnsRecord.builder("www.someexampledomain.com.", DnsRecord.Type.A) + .ttl(24, TimeUnit.HOURS) + .addRecord(ip) + .build(); + +// Make a change +ChangeRequest changeRequest = ChangeRequest.builder().add(toCreate).build(); + +// Build and apply the change request to our zone +changeRequest = zone.applyChangeRequest(changeRequest); +``` + +The `addRecord` method of `DnsRecord.Builder` accepts records in the form of +strings. The format of the strings depends on the type of the DNS record to be added. +More information on the supported DNS record types and record formats can be found [here](https://cloud.google.com/dns/what-is-cloud-dns#supported_record_types). + +If you already have a DNS record, Cloud DNS will return an error upon an attempt to create a duplicate of it. +You can modify the code above to create a DNS record or update it if it already exists by making the +following adjustment in your imports + +```java +import java.util.Iterator; +``` + +and in the code + +```java +// Make a change +ChangeRequest.Builder changeBuilder = ChangeRequest.builder().add(toCreate); + +// Verify the type A record does not exist yet. +// If it does exist, we will overwrite it with our prepared record. +Iterator recordIterator = zone.listDnsRecords().iterateAll(); +while (recordIterator.hasNext()) { + DnsRecord current = recordIterator.next(); + if (toCreate.name().equals(current.name()) && toCreate.type().equals(current.type())) { + changeBuilder.delete(current); + } +} + +// Build and apply the change request to our zone +ChangeRequest changeRequest = changeBuilder.build(); +zone.applyChangeRequest(changeRequest); +``` +You can find more information about changes in the [Cloud DNS documentation] (https://cloud.google.com/dns/what-is-cloud-dns#cloud_dns_api_concepts). + +When the change request is applied, it is registered with the Cloud DNS service for processing. We +can wait for its completion as follows: + +```java +while (ChangeRequest.Status.PENDING.equals(changeRequest.status())) { + try { + Thread.sleep(500L); + } catch (InterruptedException e) { + System.err.println("The thread was interrupted while waiting..."); + } + changeRequest = dns.getChangeRequest(zone.name(), changeRequest.id()); +} +System.out.println("The change request has been applied."); +``` + +Change requests are applied atomically to all the assigned DNS servers at once. Note that when this +happens, it may still take a while for the change to be registered by the DNS cache resolvers. +See more on this topic [here](https://cloud.google.com/dns/monitoring). + +#### Listing Zones and DNS Records +Suppose that you have added more zones and DNS records, and now you want to list them. +First, import the following (unless you have done so in the previous section): + +```java +import java.util.Iterator; +``` + +Then add the following code to list all your zones and DNS records. + +```java +// List all your zones +Iterator zoneIterator = dns.listZones().iterateAll(); +int counter = 1; +while (zoneIterator.hasNext()) { + System.out.printf("#%d.: %s%n%n", counter, zoneIterator.next()); + counter++; +} + +// List the DNS records in a particular zone +Iterator recordIterator = zone.listDnsRecords().iterateAll(); +System.out.println(String.format("DNS records inside %s:", zone.name())); +while (recordIterator.hasNext()) { + System.out.println(recordIterator.next()); +} +``` + +You can also list the history of change requests that were applied to a zone: + +```java +// List the change requests applied to a particular zone +Iterator changeIterator = zone.listChangeRequests().iterateAll(); +System.out.println(String.format("The history of changes in %s:", zone.name())); +while (changeIterator.hasNext()) { + System.out.println(changeIterator.next()); +} +``` + +#### Deleting Zones + +If you no longer want to host a zone in Cloud DNS, you can delete it. +First, you need to empty the zone by deleting all its records except for the default SOA and NS records. + +```java +// Make a change for deleting the records +ChangeRequest.Builder changeBuilder = ChangeRequest.builder(); +while (recordIterator.hasNext()) { + DnsRecord current = recordIterator.next(); + // SOA and NS records cannot be deleted + if (!DnsRecord.Type.SOA.equals(current.type()) && !DnsRecord.Type.NS.equals(current.type())) { + changeBuilder.delete(current); + } +} + +// Build and apply the change request to our zone if it contains records to delete +ChangeRequest changeRequest = changeBuilder.build(); +if (!changeRequest.deletions().isEmpty()) { + changeRequest = dns.applyChangeRequest(zoneName, changeRequest); + + // Wait for change to finish, but save data traffic by transferring only ID and status + Dns.ChangeRequestOption option = + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS); + while (ChangeRequest.Status.PENDING.equals(changeRequest.status())) { + System.out.println("Waiting for change to complete. Going to sleep for 500ms..."); + try { + Thread.sleep(500); + } catch (InterruptedException e) { + System.err.println("The thread was interrupted while waiting for change request to be " + + "processed."); + } + + // Update the change, but fetch only change ID and status + changeRequest = dns.getChangeRequest(zoneName, changeRequest.id(), option); + } +} + +// Delete the zone +boolean result = dns.delete(zoneName); +if (result) { + System.out.println("Zone was deleted."); +} else { + System.out.println("Zone was not deleted because it does not exist."); +} +``` + +#### Complete Source Code + +We composed some of the aforementioned snippets into complete executable code samples. In +[CreateZones.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateZone.java) +we create a zone. In [CreateOrUpdateDnsRecords.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateDnsRecords.java) +we create a type A record for a zone, or update an existing type A record to a new IP address. We +demonstrate how to delete a zone in [DeleteZone.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java). +Finally, in [ManipulateZonesAndRecords.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecords.java) +we assemble all the code snippets together and create zone, create or update a DNS record, list zones, list DNS records, list changes, and +delete a zone. The applications assume that they are running on Compute Engine or from your own desktop. To run any of these examples on App +Engine, simply move the code from the main method to your application's servlet class and change the +print statements to display on your webpage. + +Troubleshooting +--------------- + +To get help, follow the `gcloud-java` links in the `gcloud-*` [shared Troubleshooting document](https://github.com/GoogleCloudPlatform/gcloud-common/blob/master/troubleshooting/readme.md#troubleshooting). + +Java Versions +------------- + +Java 7 or above is required for using this client. + +Testing +------- + +This library has tools to help make tests for code using Cloud DNS. + +See [TESTING] to read more about testing. + +Versioning +---------- + +This library follows [Semantic Versioning] (http://semver.org/). + +It is currently in major version zero (``0.y.z``), which means that anything +may change at any time and the public API should not be considered +stable. + +Contributing +------------ + +Contributions to this library are always welcome and highly encouraged. + +See `gcloud-java`'s [CONTRIBUTING] documentation and the `gcloud-*` [shared documentation](https://github.com/GoogleCloudPlatform/gcloud-common/blob/master/contributing/readme.md#how-to-contribute-to-gcloud) for more information on how to get started. + +Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms. See [Code of Conduct][code-of-conduct] for more information. + +License +------- + +Apache 2.0 - See [LICENSE] for more information. + + +[CONTRIBUTING]:https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/CONTRIBUTING.md +[code-of-conduct]:https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/CODE_OF_CONDUCT.md#contributor-code-of-conduct +[LICENSE]: https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/LICENSE +[TESTING]: https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/TESTING.md#testing-code-that-uses-storage +[cloud-platform]: https://cloud.google.com/ + +[cloud-dns]: https://cloud.google.com/dns/ +[dns-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/dns/package-summary.html +[dns-activate]:https://cloud.google.com/dns/getting-started#prerequisites diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/package-info.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/package-info.java new file mode 100644 index 000000000000..8a137285c357 --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/package-info.java @@ -0,0 +1,60 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +/** + * A client to the Google Cloud DNS. + * + *

      Here are two simple usage examples from within Compute/App Engine. + * + * The first snippet shows how to create a zone resource. The complete source code can be found on + * + * CreateAndListZones.java. Note that you need to replace the {@code domainName} with a domain + * name that you own and the ownership of which you verified with Google. + * + *

       {@code
      + * Dns dns = DnsOptions.defaultInstance().service();
      + * String zoneName = "my-unique-zone";
      + * String domainName = "someexampledomain.com.";
      + * String description = "This is a gcloud-java-dns sample zone.";
      + * ZoneInfo zoneInfo = ZoneInfo.of(zoneName, domainName, description);
      + * Zone createdZone = dns.create(zoneInfo);
      + * } 
      + * + *

      The second example shows how to create records inside a zone. The complete code can be found + * on + * CreateAndListDnsRecords.java. + * + *

       {@code
      + * Dns dns = DnsOptions.defaultInstance().service();
      + * String zoneName = "my-unique-zone";
      + * Zone zone = dns.getZone(zoneName);
      + * String ip = "12.13.14.15";
      + * DnsRecord toCreate = DnsRecord.builder("www.someexampledomain.com.", DnsRecord.Type.A)
      + *   .ttl(24, TimeUnit.HOURS)
      + *   .addRecord(ip)
      + *   .build();
      + * ChangeRequest changeRequest = ChangeRequest.builder().add(toCreate).build();
      + * zone.applyChangeRequest(changeRequest);
      + * } 
      + * + *

      When using gcloud-java from outside of App/Compute Engine, you have to specify a + * project ID and provide + * credentials. + * + * @see Google Cloud DNS + */ +package com.google.gcloud.dns; diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java index e1a7c218c1b4..bfea46dfe039 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java @@ -49,7 +49,7 @@ public class ITDnsTest { private static final String PREFIX = "gcldjvit-"; - private static final Dns DNS = DnsOptions.builder().build().service(); + private static final Dns DNS = DnsOptions.defaultInstance().service(); private static final String ZONE_NAME1 = (PREFIX + UUID.randomUUID()).substring(0, 32); private static final String ZONE_NAME_EMPTY_DESCRIPTION = (PREFIX + UUID.randomUUID()).substring(0, 32); diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateAndListDnsRecords.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateDnsRecords.java similarity index 89% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateAndListDnsRecords.java rename to gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateDnsRecords.java index 1e47a12fed02..71327ba98a96 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateAndListDnsRecords.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateDnsRecords.java @@ -32,9 +32,9 @@ import java.util.concurrent.TimeUnit; /** - * A snippet for Google Cloud DNS showing how to create a DNS records. + * A snippet for Google Cloud DNS showing how to create and update a DNS record. */ -public class CreateAndListDnsRecords { +public class CreateOrUpdateDnsRecords { public static void main(String... args) { // Create a service object. @@ -42,7 +42,7 @@ public static void main(String... args) { Dns dns = DnsOptions.defaultInstance().service(); // Change this to a zone name that exists within your project - String zoneName = "some-sample-zone"; + String zoneName = "my-unique-zone"; // Get zone from the service Zone zone = dns.getZone(zoneName); @@ -68,6 +68,7 @@ public static void main(String... args) { } // Build and apply the change request to our zone - zone.applyChangeRequest(changeBuilder.build()); + ChangeRequest changeRequest = changeBuilder.build(); + zone.applyChangeRequest(changeRequest); } } diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateAndListZones.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateZone.java similarity index 70% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateAndListZones.java rename to gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateZone.java index 21fdba2b7449..2c2ba211bd86 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateAndListZones.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateZone.java @@ -27,14 +27,11 @@ import com.google.gcloud.dns.Zone; import com.google.gcloud.dns.ZoneInfo; -import java.util.Iterator; - /** - * A snippet for Google Cloud DNS showing how to create a zone and list all zones in the project. - * You will need to change the {@code domainName} to a domain name, the ownership of which you - * should verify with Google. + * A snippet for Google Cloud DNS showing how to create a zone. You will need to change the {@code + * domainName} to a domain name, the ownership of which you should verify with Google. */ -public class CreateAndListZones { +public class CreateZone { public static void main(String... args) { // Create a service object @@ -42,21 +39,13 @@ public static void main(String... args) { Dns dns = DnsOptions.defaultInstance().service(); // Create a zone metadata object - String zoneName = "my_unique_zone"; // Change this zone name which is unique within your project + String zoneName = "my-unique-zone"; // Change this zone name which is unique within your project String domainName = "someexampledomain.com."; // Change this to a domain which you own String description = "This is a gcloud-java-dns sample zone."; ZoneInfo zoneInfo = ZoneInfo.of(zoneName, domainName, description); // Create zone in Google Cloud DNS - Zone createdZone = dns.create(zoneInfo); - System.out.printf("Zone was created and assigned ID %s.%n", createdZone.id()); - - // Now list all the zones within this project - Iterator zoneIterator = dns.listZones().iterateAll(); - int counter = 1; - while (zoneIterator.hasNext()) { - System.out.printf("#%d.: %s%n%n", counter, zoneIterator.next().toString()); - counter++; - } + Zone zone = dns.create(zoneInfo); + System.out.printf("Zone was created and assigned ID %s.%n", zone.id()); } } diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java index 667a0d89e6ab..e841a4cd54ed 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java @@ -41,7 +41,7 @@ public static void main(String... args) { Dns dns = DnsOptions.defaultInstance().service(); // Change this to a zone name that exists within your project and that you want to delete. - String zoneName = "some-sample-zone"; + String zoneName = "my-unique-zone"; // Get iterator for the existing records which have to be deleted before deleting the zone Iterator recordIterator = dns.listDnsRecords(zoneName).iterateAll(); diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecords.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecords.java new file mode 100644 index 000000000000..4de262386d53 --- /dev/null +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecords.java @@ -0,0 +1,157 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +/* + * EDITING INSTRUCTIONS + * This file is referenced in README's and javadoc. Any change to this file should be reflected in + * the project's README's and package-info.java. + */ + +package com.google.gcloud.examples.dns.snippets; + +import com.google.gcloud.dns.ChangeRequest; +import com.google.gcloud.dns.Dns; +import com.google.gcloud.dns.DnsOptions; +import com.google.gcloud.dns.DnsRecord; +import com.google.gcloud.dns.Zone; +import com.google.gcloud.dns.ZoneInfo; + +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.TimeUnit; + +/** + * A complete snippet for Google Cloud DNS showing how to create and delete a zone. It also shows + * how to create, list and delete DNS records, and how to list changes. + */ +public class ManipulateZonesAndRecords { + + public static void main(String... args) { + Dns dns = DnsOptions.defaultInstance().service(); + + // Create a zone metadata object + String zoneName = "my-unique-zone"; // Change this zone name which is unique within your project + String domainName = "someexampledomain.com."; // Change this to a domain which you own + String description = "This is a gcloud-java-dns sample zone."; + ZoneInfo zoneInfo = ZoneInfo.of(zoneName, domainName, description); + + // Create zone in Google Cloud DNS + Zone zone = dns.create(zoneInfo); + System.out.printf("Zone was created and assigned ID %s.%n", zone.id()); + + // Print assigned name servers + List nameServers = zone.nameServers(); + for (String nameServer : nameServers) { + System.out.println(nameServer); + } + + // Prepare a www.someexampledomain.com. type A record with ttl of 24 hours + String ip = "12.13.14.15"; + DnsRecord toCreate = DnsRecord.builder("www.someexampledomain.com.", DnsRecord.Type.A) + .ttl(24, TimeUnit.HOURS) + .addRecord(ip) + .build(); + + // Make a change + ChangeRequest.Builder changeBuilder = ChangeRequest.builder().add(toCreate); + + // Verify the type A record does not exist yet. + // If it does exist, we will overwrite it with our prepared record. + Iterator recordIterator = zone.listDnsRecords().iterateAll(); + while (recordIterator.hasNext()) { + DnsRecord current = recordIterator.next(); + if (toCreate.name().equals(current.name()) && toCreate.type().equals(current.type())) { + changeBuilder.delete(current); + } + } + + // Build and apply the change request to our zone + ChangeRequest changeRequest = changeBuilder.build(); + zone.applyChangeRequest(changeRequest); + + while (ChangeRequest.Status.PENDING.equals(changeRequest.status())) { + try { + Thread.sleep(500L); + } catch (InterruptedException e) { + System.err.println("The thread was interrupted while waiting..."); + } + changeRequest = dns.getChangeRequest(zone.name(), changeRequest.id()); + } + System.out.println("The change request has been applied."); + + // List all your zones + Iterator zoneIterator = dns.listZones().iterateAll(); + int counter = 1; + while (zoneIterator.hasNext()) { + System.out.printf("#%d.: %s%n%n", counter, zoneIterator.next()); + counter++; + } + + // List the DNS records in a particular zone + recordIterator = zone.listDnsRecords().iterateAll(); + System.out.println(String.format("DNS records inside %s:", zone.name())); + while (recordIterator.hasNext()) { + System.out.println(recordIterator.next()); + } + + // List the change requests applied to a particular zone + Iterator changeIterator = zone.listChangeRequests().iterateAll(); + System.out.println(String.format("The history of changes in %s:", zone.name())); + while (changeIterator.hasNext()) { + System.out.println(changeIterator.next()); + } + + // Make a change for deleting the records + changeBuilder = ChangeRequest.builder(); + while (recordIterator.hasNext()) { + DnsRecord current = recordIterator.next(); + // SOA and NS records cannot be deleted + if (!DnsRecord.Type.SOA.equals(current.type()) && !DnsRecord.Type.NS.equals(current.type())) { + changeBuilder.delete(current); + } + } + + // Build and apply the change request to our zone if it contains records to delete + changeRequest = changeBuilder.build(); + if (!changeRequest.deletions().isEmpty()) { + changeRequest = dns.applyChangeRequest(zoneName, changeRequest); + + // Wait for change to finish, but save data traffic by transferring only ID and status + Dns.ChangeRequestOption option = + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS); + while (ChangeRequest.Status.PENDING.equals(changeRequest.status())) { + System.out.println("Waiting for change to complete. Going to sleep for 500ms..."); + try { + Thread.sleep(500); + } catch (InterruptedException e) { + System.err.println("The thread was interrupted while waiting for change request to be " + + "processed."); + } + + // Update the change, but fetch only change ID and status + changeRequest = dns.getChangeRequest(zoneName, changeRequest.id(), option); + } + } + + // Delete the zone + boolean result = dns.delete(zoneName); + if (result) { + System.out.println("Zone was deleted."); + } else { + System.out.println("Zone was not deleted because it does not exist."); + } + } +} From 967c5c5a20f39ce232e415b371e7b3a038e453fa Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 17 Mar 2016 09:54:13 +0100 Subject: [PATCH 175/375] Add tests for restorable classes. Fix serialization issues --- .../gcloud/bigquery/SerializationTest.java | 17 +------ .../com/google/gcloud/AuthCredentials.java | 10 ++++ .../com/google/gcloud/ExceptionHandler.java | 22 +++++++++ .../google/gcloud/BaseSerializationTest.java | 19 +++++++- .../com/google/gcloud/SerializationTest.java | 46 ++++++++++++++++++- .../gcloud/datastore/SerializationTest.java | 2 - .../resourcemanager/SerializationTest.java | 4 +- .../gcloud/storage/SerializationTest.java | 29 ++---------- 8 files changed, 101 insertions(+), 48 deletions(-) diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java index f64946e062d7..087d263b0fa4 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java @@ -16,15 +16,10 @@ package com.google.gcloud.bigquery; -import static org.junit.Assert.assertEquals; - import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.gcloud.AuthCredentials; import com.google.gcloud.BaseSerializationTest; -import com.google.gcloud.RestorableState; -import com.google.gcloud.RetryParams; -import com.google.gcloud.WriteChannel; import com.google.gcloud.bigquery.StandardTableDefinition.StreamingBuffer; import org.junit.Test; @@ -235,7 +230,6 @@ public Serializable[] serializableObjects() { .build(); BigQueryOptions otherOptions = options.toBuilder() .projectId("p2") - .retryParams(RetryParams.defaultInstance()) .authCredentials(null) .build(); return new Serializable[]{DOMAIN_ACCESS, GROUP_ACCESS, USER_ACCESS, VIEW_ACCESS, DATASET_ID, @@ -254,18 +248,11 @@ public Serializable[] serializableObjects() { @Test public void testWriteChannelState() throws IOException, ClassNotFoundException { - BigQueryOptions options = BigQueryOptions.builder() - .projectId("p2") - .retryParams(RetryParams.defaultInstance()) - .build(); + BigQueryOptions options = BigQueryOptions.builder().projectId("p2").build(); // avoid closing when you don't want partial writes upon failure @SuppressWarnings("resource") TableDataWriteChannel writer = new TableDataWriteChannel(options, LOAD_CONFIGURATION, "upload-id"); - RestorableState state = writer.capture(); - RestorableState deserializedState = serializeAndDeserialize(state); - assertEquals(state, deserializedState); - assertEquals(state.hashCode(), deserializedState.hashCode()); - assertEquals(state.toString(), deserializedState.toString()); + assertRestorable(writer); } } diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java index 6f9e09ca04bc..38265a26be2e 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java @@ -276,6 +276,16 @@ private static class NoAuthCredentialsState public AuthCredentials restore() { return INSTANCE; } + + @Override + public int hashCode() { + return getClass().getName().hashCode(); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof NoAuthCredentialsState; + } } @Override diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ExceptionHandler.java b/gcloud-java-core/src/main/java/com/google/gcloud/ExceptionHandler.java index 39d4c4e75a1a..0dbcbeb65378 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/ExceptionHandler.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/ExceptionHandler.java @@ -26,6 +26,7 @@ import java.io.Serializable; import java.lang.reflect.Method; +import java.util.Objects; import java.util.Set; import java.util.concurrent.Callable; @@ -259,6 +260,27 @@ boolean shouldRetry(Exception ex) { return retryResult == Interceptor.RetryResult.RETRY; } + @Override + public int hashCode() { + return Objects.hash(interceptors, retriableExceptions, nonRetriableExceptions, retryInfo); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ExceptionHandler)) { + return false; + } + ExceptionHandler other = (ExceptionHandler) obj; + return Objects.equals(interceptors, other.interceptors) + && Objects.equals(retriableExceptions, other.retriableExceptions) + && Objects.equals(nonRetriableExceptions, other.nonRetriableExceptions) + && Objects.equals(retryInfo, other.retryInfo); + + } + /** * Returns an instance which retry any checked exception and abort on any runtime exception. */ diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/BaseSerializationTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/BaseSerializationTest.java index 533dfcde6ad8..a8136bfbf0cc 100644 --- a/gcloud-java-core/src/test/java/com/google/gcloud/BaseSerializationTest.java +++ b/gcloud-java-core/src/test/java/com/google/gcloud/BaseSerializationTest.java @@ -34,6 +34,9 @@ */ public abstract class BaseSerializationTest { + /** + * Returns all objects for which correct serialization must be tested. + */ public abstract Serializable[] serializableObjects(); @Test @@ -50,8 +53,7 @@ public void testSerializableObjects() throws Exception { } @SuppressWarnings("unchecked") - public T serializeAndDeserialize(T obj) - throws IOException, ClassNotFoundException { + public T serializeAndDeserialize(T obj) throws IOException, ClassNotFoundException { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); try (ObjectOutputStream output = new ObjectOutputStream(bytes)) { output.writeObject(obj); @@ -61,4 +63,17 @@ public T serializeAndDeserialize(T obj) return (T) input.readObject(); } } + + /** + * Checks whether the state of a restorable object can correctly be captured, serialized and + * restored. + */ + public void assertRestorable(Restorable restorable) throws IOException, + ClassNotFoundException { + RestorableState state = restorable.capture(); + RestorableState deserializedState = serializeAndDeserialize(state); + assertEquals(state, deserializedState); + assertEquals(state.hashCode(), deserializedState.hashCode()); + assertEquals(state.toString(), deserializedState.toString()); + } } diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java index aec9158e1ee0..46f1f73563f7 100644 --- a/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java +++ b/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java @@ -18,16 +18,60 @@ import com.google.common.collect.ImmutableList; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.IOException; import java.io.Serializable; public class SerializationTest extends BaseSerializationTest { + private static final ExceptionHandler EXCEPTION_HANDLER = ExceptionHandler.defaultInstance(); + private static final Identity IDENTITY = Identity.allAuthenticatedUsers(); private static final PageImpl PAGE = new PageImpl<>(null, "cursor", ImmutableList.of("string1", "string2")); private static final RetryParams RETRY_PARAMS = RetryParams.defaultInstance(); + private static final String JSON_KEY = "{\n" + + " \"private_key_id\": \"somekeyid\",\n" + + " \"private_key\": \"-----BEGIN PRIVATE KEY-----\\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggS" + + "kAgEAAoIBAQC+K2hSuFpAdrJI\\nnCgcDz2M7t7bjdlsadsasad+fvRSW6TjNQZ3p5LLQY1kSZRqBqylRkzteMOyHg" + + "aR\\n0Pmxh3ILCND5men43j3h4eDbrhQBuxfEMalkG92sL+PNQSETY2tnvXryOvmBRwa/\\nQP/9dJfIkIDJ9Fw9N4" + + "Bhhhp6mCcRpdQjV38H7JsyJ7lih/oNjECgYAt\\nknddadwkwewcVxHFhcZJO+XWf6ofLUXpRwiTZakGMn8EE1uVa2" + + "LgczOjwWHGi99MFjxSer5m9\\n1tCa3/KEGKiS/YL71JvjwX3mb+cewlkcmweBKZHM2JPTk0ZednFSpVZMtycjkbLa" + + "\\ndYOS8V85AgMBewECggEBAKksaldajfDZDV6nGqbFjMiizAKJolr/M3OQw16K6o3/\\n0S31xIe3sSlgW0+UbYlF" + + "4U8KifhManD1apVSC3csafaspP4RZUHFhtBywLO9pR5c\\nr6S5aLp+gPWFyIp1pfXbWGvc5VY/v9x7ya1VEa6rXvL" + + "sKupSeWAW4tMj3eo/64ge\\nsdaceaLYw52KeBYiT6+vpsnYrEkAHO1fF/LavbLLOFJmFTMxmsNaG0tuiJHgjshB\\" + + "n82DpMCbXG9YcCgI/DbzuIjsdj2JC1cascSP//3PmefWysucBQe7Jryb6NQtASmnv\\nCdDw/0jmZTEjpe4S1lxfHp" + + "lAhHFtdgYTvyYtaLZiVVkCgYEA8eVpof2rceecw/I6\\n5ng1q3Hl2usdWV/4mZMvR0fOemacLLfocX6IYxT1zA1FF" + + "JlbXSRsJMf/Qq39mOR2\\nSpW+hr4jCoHeRVYLgsbggtrevGmILAlNoqCMpGZ6vDmJpq6ECV9olliDvpPgWOP+\\nm" + + "YPDreFBGxWvQrADNbRt2dmGsrsCgYEAyUHqB2wvJHFqdmeBsaacewzV8x9WgmeX\\ngUIi9REwXlGDW0Mz50dxpxcK" + + "CAYn65+7TCnY5O/jmL0VRxU1J2mSWyWTo1C+17L0\\n3fUqjxL1pkefwecxwecvC+gFFYdJ4CQ/MHHXU81Lwl1iWdF" + + "Cd2UoGddYaOF+KNeM\\nHC7cmqra+JsCgYEAlUNywzq8nUg7282E+uICfCB0LfwejuymR93CtsFgb7cRd6ak\\nECR" + + "8FGfCpH8ruWJINllbQfcHVCX47ndLZwqv3oVFKh6pAS/vVI4dpOepP8++7y1u\\ncoOvtreXCX6XqfrWDtKIvv0vjl" + + "HBhhhp6mCcRpdQjV38H7JsyJ7lih/oNjECgYAt\\nkndj5uNl5SiuVxHFhcZJO+XWf6ofLUregtevZakGMn8EE1uVa" + + "2AY7eafmoU/nZPT\\n00YB0TBATdCbn/nBSuKDESkhSg9s2GEKQZG5hBmL5uCMfo09z3SfxZIhJdlerreP\\nJ7gSi" + + "dI12N+EZxYd4xIJh/HFDgp7RRO87f+WJkofMQKBgGTnClK1VMaCRbJZPriw\\nEfeFCoOX75MxKwXs6xgrw4W//AYG" + + "GUjDt83lD6AZP6tws7gJ2IwY/qP7+lyhjEqN\\nHtfPZRGFkGZsdaksdlaksd323423d+15/UvrlRSFPNj1tWQmNKk" + + "XyRDW4IG1Oa2p\\nrALStNBx5Y9t0/LQnFI4w3aG\\n-----END PRIVATE KEY-----\\n\",\n" + + " \"client_email\": \"someclientid@developer.gserviceaccount.com\",\n" + + " \"client_id\": \"someclientid.apps.googleusercontent.com\",\n" + + " \"type\": \"service_account\"\n" + + "}"; @Override public Serializable[] serializableObjects() { - return new Serializable[]{PAGE, RETRY_PARAMS}; + return new Serializable[]{EXCEPTION_HANDLER, IDENTITY, PAGE, RETRY_PARAMS}; + } + + @Test + public void testAuthCredentialState() throws IOException, ClassNotFoundException { + AuthCredentials credentials = AuthCredentials.createApplicationDefaults(); + assertRestorable(credentials); + credentials = AuthCredentials.createForAppEngine(); + assertRestorable(credentials); + credentials = AuthCredentials.noAuth(); + assertRestorable(credentials); + credentials = AuthCredentials.createForJson(new ByteArrayInputStream(JSON_KEY.getBytes())); + assertRestorable(credentials); } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index 7a6f065d6ca6..5cbf63b9624d 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -21,7 +21,6 @@ import com.google.api.services.datastore.DatastoreV1; import com.google.gcloud.AuthCredentials; import com.google.gcloud.BaseSerializationTest; -import com.google.gcloud.RetryParams; import com.google.gcloud.datastore.StructuredQuery.CompositeFilter; import com.google.gcloud.datastore.StructuredQuery.OrderBy; import com.google.gcloud.datastore.StructuredQuery.Projection; @@ -112,7 +111,6 @@ public java.io.Serializable[] serializableObjects() { .build(); DatastoreOptions otherOptions = options.toBuilder() .namespace("ns1") - .retryParams(RetryParams.defaultInstance()) .authCredentials(null) .force(true) .build(); diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java index 2dcd3f9d3e7b..786865e0f872 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java @@ -18,10 +18,9 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; -import com.google.gcloud.Identity; import com.google.gcloud.BaseSerializationTest; +import com.google.gcloud.Identity; import com.google.gcloud.PageImpl; -import com.google.gcloud.RetryParams; import java.io.Serializable; import java.util.Collections; @@ -55,7 +54,6 @@ public Serializable[] serializableObjects() { ResourceManagerOptions options = ResourceManagerOptions.builder().build(); ResourceManagerOptions otherOptions = options.toBuilder() .projectId("some-unnecessary-project-ID") - .retryParams(RetryParams.defaultInstance()) .build(); return new Serializable[]{PARTIAL_PROJECT_INFO, FULL_PROJECT_INFO, PROJECT, PAGE_RESULT, PROJECT_GET_OPTION, PROJECT_LIST_OPTION, POLICY, options, otherOptions}; diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java index ee3d7c946312..392636ccd100 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java @@ -16,16 +16,11 @@ package com.google.gcloud.storage; -import static org.junit.Assert.assertEquals; - import com.google.common.collect.ImmutableMap; import com.google.gcloud.AuthCredentials; import com.google.gcloud.BaseSerializationTest; import com.google.gcloud.PageImpl; import com.google.gcloud.ReadChannel; -import com.google.gcloud.RestorableState; -import com.google.gcloud.RetryParams; -import com.google.gcloud.WriteChannel; import com.google.gcloud.storage.Acl.Project.ProjectRole; import com.google.gcloud.storage.spi.StorageRpc; @@ -81,7 +76,6 @@ public Serializable[] serializableObjects() { .build(); StorageOptions otherOptions = options.toBuilder() .projectId("p2") - .retryParams(RetryParams.defaultInstance()) .authCredentials(null) .build(); return new Serializable[]{ACL_DOMAIN, ACL_GROUP, ACL_PROJECT_, ACL_USER, ACL_RAW, ACL, @@ -92,34 +86,19 @@ public Serializable[] serializableObjects() { @Test public void testReadChannelState() throws IOException, ClassNotFoundException { - StorageOptions options = StorageOptions.builder() - .projectId("p2") - .retryParams(RetryParams.defaultInstance()) - .build(); + StorageOptions options = StorageOptions.builder().projectId("p2").build(); ReadChannel reader = new BlobReadChannel(options, BlobId.of("b", "n"), EMPTY_RPC_OPTIONS); - RestorableState state = reader.capture(); - RestorableState deserializedState = serializeAndDeserialize(state); - assertEquals(state, deserializedState); - assertEquals(state.hashCode(), deserializedState.hashCode()); - assertEquals(state.toString(), deserializedState.toString()); - reader.close(); + assertRestorable(reader); } @Test public void testWriteChannelState() throws IOException, ClassNotFoundException { - StorageOptions options = StorageOptions.builder() - .projectId("p2") - .retryParams(RetryParams.defaultInstance()) - .build(); + StorageOptions options = StorageOptions.builder().projectId("p2").build(); // avoid closing when you don't want partial writes to GCS upon failure @SuppressWarnings("resource") BlobWriteChannel writer = new BlobWriteChannel(options, BlobInfo.builder(BlobId.of("b", "n")).build(), "upload-id"); - RestorableState state = writer.capture(); - RestorableState deserializedState = serializeAndDeserialize(state); - assertEquals(state, deserializedState); - assertEquals(state.hashCode(), deserializedState.hashCode()); - assertEquals(state.toString(), deserializedState.toString()); + assertRestorable(writer); } } From 034432a4915439f8323cc898e38c47f5cd4f1788 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 17 Mar 2016 17:28:55 +0100 Subject: [PATCH 176/375] Remove serialization test for ApplicationDefaultAuthCredentials --- .../src/test/java/com/google/gcloud/SerializationTest.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java index 46f1f73563f7..a9526a42d7d7 100644 --- a/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java +++ b/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java @@ -65,9 +65,7 @@ public Serializable[] serializableObjects() { @Test public void testAuthCredentialState() throws IOException, ClassNotFoundException { - AuthCredentials credentials = AuthCredentials.createApplicationDefaults(); - assertRestorable(credentials); - credentials = AuthCredentials.createForAppEngine(); + AuthCredentials credentials = AuthCredentials.createForAppEngine(); assertRestorable(credentials); credentials = AuthCredentials.noAuth(); assertRestorable(credentials); From ce597930debaa6ab8ffc16af25547e1bfa7283a6 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 17 Mar 2016 18:59:46 +0100 Subject: [PATCH 177/375] Add restorableObjects method to BaseSerializationTest --- .../gcloud/bigquery/SerializationTest.java | 12 +++--- .../com/google/gcloud/ExceptionHandler.java | 1 - .../google/gcloud/BaseSerializationTest.java | 39 +++++++++++-------- .../com/google/gcloud/SerializationTest.java | 21 +++++----- .../gcloud/datastore/SerializationTest.java | 8 +++- .../resourcemanager/SerializationTest.java | 8 +++- .../gcloud/storage/SerializationTest.java | 18 +++------ 7 files changed, 57 insertions(+), 50 deletions(-) diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java index 087d263b0fa4..74644216c109 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java @@ -20,11 +20,9 @@ import com.google.common.collect.ImmutableMap; import com.google.gcloud.AuthCredentials; import com.google.gcloud.BaseSerializationTest; +import com.google.gcloud.Restorable; import com.google.gcloud.bigquery.StandardTableDefinition.StreamingBuffer; -import org.junit.Test; - -import java.io.IOException; import java.io.Serializable; import java.nio.charset.StandardCharsets; import java.util.List; @@ -223,7 +221,7 @@ public class SerializationTest extends BaseSerializationTest { private static final Job JOB = new Job(BIGQUERY, new JobInfo.BuilderImpl(JOB_INFO)); @Override - public Serializable[] serializableObjects() { + protected Serializable[] serializableObjects() { BigQueryOptions options = BigQueryOptions.builder() .projectId("p1") .authCredentials(AuthCredentials.createForAppEngine()) @@ -246,13 +244,13 @@ public Serializable[] serializableObjects() { BigQuery.JobListOption.allUsers(), DATASET, TABLE, JOB, options, otherOptions}; } - @Test - public void testWriteChannelState() throws IOException, ClassNotFoundException { + @Override + protected Restorable[] restorableObjects() { BigQueryOptions options = BigQueryOptions.builder().projectId("p2").build(); // avoid closing when you don't want partial writes upon failure @SuppressWarnings("resource") TableDataWriteChannel writer = new TableDataWriteChannel(options, LOAD_CONFIGURATION, "upload-id"); - assertRestorable(writer); + return new Restorable[]{writer}; } } diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ExceptionHandler.java b/gcloud-java-core/src/main/java/com/google/gcloud/ExceptionHandler.java index 0dbcbeb65378..0b3c923d1eb9 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/ExceptionHandler.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/ExceptionHandler.java @@ -278,7 +278,6 @@ public boolean equals(Object obj) { && Objects.equals(retriableExceptions, other.retriableExceptions) && Objects.equals(nonRetriableExceptions, other.nonRetriableExceptions) && Objects.equals(retryInfo, other.retryInfo); - } /** diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/BaseSerializationTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/BaseSerializationTest.java index a8136bfbf0cc..e9ab3d47984b 100644 --- a/gcloud-java-core/src/test/java/com/google/gcloud/BaseSerializationTest.java +++ b/gcloud-java-core/src/test/java/com/google/gcloud/BaseSerializationTest.java @@ -16,6 +16,7 @@ package com.google.gcloud; +import static com.google.common.base.MoreObjects.firstNonNull; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; @@ -30,18 +31,26 @@ /** * Base class for serialization tests. To use this class in your tests override the - * {@code serializableObjects()} method to return all objects that must be serializable. + * {@code serializableObjects()} method to return all objects that must be serializable. Also + * override {@code restorableObjects()} method to return all restorable objects whose state must be + * tested for proper serialization. Both methods can return {@code null} if no such object needs to + * be tested. */ public abstract class BaseSerializationTest { /** * Returns all objects for which correct serialization must be tested. */ - public abstract Serializable[] serializableObjects(); + protected abstract Serializable[] serializableObjects(); + + /** + * Returns all restorable objects whose state must be tested for proper serialization. + */ + protected abstract Restorable[] restorableObjects(); @Test public void testSerializableObjects() throws Exception { - for (Serializable obj : serializableObjects()) { + for (Serializable obj : firstNonNull(serializableObjects(), new Serializable[0])) { Object copy = serializeAndDeserialize(obj); assertEquals(obj, obj); assertEquals(obj, copy); @@ -52,6 +61,17 @@ public void testSerializableObjects() throws Exception { } } + @Test + public void testRestorableObjects() throws Exception { + for (Restorable restorable : firstNonNull(restorableObjects(), new Restorable[0])) { + RestorableState state = restorable.capture(); + RestorableState deserializedState = serializeAndDeserialize(state); + assertEquals(state, deserializedState); + assertEquals(state.hashCode(), deserializedState.hashCode()); + assertEquals(state.toString(), deserializedState.toString()); + } + } + @SuppressWarnings("unchecked") public T serializeAndDeserialize(T obj) throws IOException, ClassNotFoundException { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); @@ -63,17 +83,4 @@ public T serializeAndDeserialize(T obj) throws IOException, ClassNotFoundExc return (T) input.readObject(); } } - - /** - * Checks whether the state of a restorable object can correctly be captured, serialized and - * restored. - */ - public void assertRestorable(Restorable restorable) throws IOException, - ClassNotFoundException { - RestorableState state = restorable.capture(); - RestorableState deserializedState = serializeAndDeserialize(state); - assertEquals(state, deserializedState); - assertEquals(state.hashCode(), deserializedState.hashCode()); - assertEquals(state.toString(), deserializedState.toString()); - } } diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java index a9526a42d7d7..c4bcfcc13b1c 100644 --- a/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java +++ b/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java @@ -18,8 +18,6 @@ import com.google.common.collect.ImmutableList; -import org.junit.Test; - import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.Serializable; @@ -59,17 +57,18 @@ public class SerializationTest extends BaseSerializationTest { + "}"; @Override - public Serializable[] serializableObjects() { + protected Serializable[] serializableObjects() { return new Serializable[]{EXCEPTION_HANDLER, IDENTITY, PAGE, RETRY_PARAMS}; } - @Test - public void testAuthCredentialState() throws IOException, ClassNotFoundException { - AuthCredentials credentials = AuthCredentials.createForAppEngine(); - assertRestorable(credentials); - credentials = AuthCredentials.noAuth(); - assertRestorable(credentials); - credentials = AuthCredentials.createForJson(new ByteArrayInputStream(JSON_KEY.getBytes())); - assertRestorable(credentials); + @Override + protected Restorable[] restorableObjects() { + try { + return new Restorable[]{AuthCredentials.createForAppEngine(), AuthCredentials.noAuth(), + AuthCredentials.createForJson(new ByteArrayInputStream(JSON_KEY.getBytes()))}; + } catch (IOException ex) { + // never reached + throw new RuntimeException(ex); + } } } diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index 5cbf63b9624d..3ea74ef7c4d6 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -21,6 +21,7 @@ import com.google.api.services.datastore.DatastoreV1; import com.google.gcloud.AuthCredentials; import com.google.gcloud.BaseSerializationTest; +import com.google.gcloud.Restorable; import com.google.gcloud.datastore.StructuredQuery.CompositeFilter; import com.google.gcloud.datastore.StructuredQuery.OrderBy; import com.google.gcloud.datastore.StructuredQuery.Projection; @@ -103,7 +104,7 @@ public class SerializationTest extends BaseSerializationTest { private static final ProjectionEntity PROJECTION_ENTITY = ProjectionEntity.fromPb(ENTITY1.toPb()); @Override - public java.io.Serializable[] serializableObjects() { + protected java.io.Serializable[] serializableObjects() { DatastoreOptions options = DatastoreOptions.builder() .authCredentials(AuthCredentials.createForAppEngine()) .normalizeDataset(false) @@ -120,4 +121,9 @@ public java.io.Serializable[] serializableObjects() { EMBEDDED_ENTITY_VALUE2, EMBEDDED_ENTITY_VALUE3, LIST_VALUE, LONG_VALUE, DOUBLE_VALUE, BOOLEAN_VALUE, DATE_AND_TIME_VALUE, BLOB_VALUE, RAW_VALUE, options, otherOptions}; } + + @Override + protected Restorable[] restorableObjects() { + return null; + } } diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java index 786865e0f872..5bad065003e0 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java @@ -21,6 +21,7 @@ import com.google.gcloud.BaseSerializationTest; import com.google.gcloud.Identity; import com.google.gcloud.PageImpl; +import com.google.gcloud.Restorable; import java.io.Serializable; import java.util.Collections; @@ -50,7 +51,7 @@ public class SerializationTest extends BaseSerializationTest { .build(); @Override - public Serializable[] serializableObjects() { + protected Serializable[] serializableObjects() { ResourceManagerOptions options = ResourceManagerOptions.builder().build(); ResourceManagerOptions otherOptions = options.toBuilder() .projectId("some-unnecessary-project-ID") @@ -58,4 +59,9 @@ public Serializable[] serializableObjects() { return new Serializable[]{PARTIAL_PROJECT_INFO, FULL_PROJECT_INFO, PROJECT, PAGE_RESULT, PROJECT_GET_OPTION, PROJECT_LIST_OPTION, POLICY, options, otherOptions}; } + + @Override + protected Restorable[] restorableObjects() { + return null; + } } diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java index 392636ccd100..6aae7b1a0cb2 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java @@ -21,12 +21,10 @@ import com.google.gcloud.BaseSerializationTest; import com.google.gcloud.PageImpl; import com.google.gcloud.ReadChannel; +import com.google.gcloud.Restorable; import com.google.gcloud.storage.Acl.Project.ProjectRole; import com.google.gcloud.storage.spi.StorageRpc; -import org.junit.Test; - -import java.io.IOException; import java.io.Serializable; import java.util.Collections; import java.util.Map; @@ -69,7 +67,7 @@ public class SerializationTest extends BaseSerializationTest { private static final Map EMPTY_RPC_OPTIONS = ImmutableMap.of(); @Override - public Serializable[] serializableObjects() { + protected Serializable[] serializableObjects() { StorageOptions options = StorageOptions.builder() .projectId("p1") .authCredentials(AuthCredentials.createForAppEngine()) @@ -84,21 +82,15 @@ public Serializable[] serializableObjects() { BUCKET_LIST_OPTIONS, BUCKET_SOURCE_OPTIONS, BUCKET_TARGET_OPTIONS, options, otherOptions}; } - @Test - public void testReadChannelState() throws IOException, ClassNotFoundException { + @Override + protected Restorable[] restorableObjects() { StorageOptions options = StorageOptions.builder().projectId("p2").build(); ReadChannel reader = new BlobReadChannel(options, BlobId.of("b", "n"), EMPTY_RPC_OPTIONS); - assertRestorable(reader); - } - - @Test - public void testWriteChannelState() throws IOException, ClassNotFoundException { - StorageOptions options = StorageOptions.builder().projectId("p2").build(); // avoid closing when you don't want partial writes to GCS upon failure @SuppressWarnings("resource") BlobWriteChannel writer = new BlobWriteChannel(options, BlobInfo.builder(BlobId.of("b", "n")).build(), "upload-id"); - assertRestorable(writer); + return new Restorable[]{reader, writer}; } } From 0a113cd7431722d0c10d849a2760a41eb2ce4d87 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 18 Mar 2016 14:25:25 +0100 Subject: [PATCH 178/375] Remove default contentType from Storage's compose --- .../java/com/google/gcloud/storage/spi/DefaultStorageRpc.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/DefaultStorageRpc.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/DefaultStorageRpc.java index aa6085e161ed..3f465e0ab20e 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/DefaultStorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/DefaultStorageRpc.java @@ -319,9 +319,6 @@ private Storage.Objects.Delete deleteRequest(StorageObject blob, Map public StorageObject compose(Iterable sources, StorageObject target, Map targetOptions) { ComposeRequest request = new ComposeRequest(); - if (target.getContentType() == null) { - target.setContentType("application/octet-stream"); - } request.setDestination(target); List sourceObjects = new ArrayList<>(); for (StorageObject source : sources) { From 8840b33a9cfbb2ab780c846e12131716fda8e0ab Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 18 Mar 2016 14:56:46 +0100 Subject: [PATCH 179/375] Remove default contentType from Bucket's create --- .../com/google/gcloud/storage/Bucket.java | 50 +++++++++++++++---- .../com/google/gcloud/storage/Storage.java | 2 - .../com/google/gcloud/storage/BucketTest.java | 12 ++--- 3 files changed, 47 insertions(+), 17 deletions(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java index 5df305ff371c..e44bd60d785c 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java @@ -22,7 +22,6 @@ import static com.google.gcloud.storage.Bucket.BucketSourceOption.toSourceOptions; import com.google.common.base.Function; -import com.google.common.base.MoreObjects; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.google.gcloud.Page; @@ -633,15 +632,13 @@ public List get(String blobName1, String blobName2, String... blobNames) { * * @param blob a blob name * @param content the blob content - * @param contentType the blob content type. If {@code null} then - * {@value com.google.gcloud.storage.Storage#DEFAULT_CONTENT_TYPE} is used. + * @param contentType the blob content type * @param options options for blob creation * @return a complete blob information * @throws StorageException upon failure */ public Blob create(String blob, byte[] content, String contentType, BlobTargetOption... options) { - BlobInfo blobInfo = BlobInfo.builder(BlobId.of(name(), blob)) - .contentType(MoreObjects.firstNonNull(contentType, Storage.DEFAULT_CONTENT_TYPE)).build(); + BlobInfo blobInfo = BlobInfo.builder(BlobId.of(name(), blob)).contentType(contentType).build(); StorageRpc.Tuple target = BlobTargetOption.toTargetOptions(blobInfo, options); return storage.create(target.x(), content, target.y()); @@ -654,16 +651,51 @@ public Blob create(String blob, byte[] content, String contentType, BlobTargetOp * * @param blob a blob name * @param content the blob content as a stream - * @param contentType the blob content type. If {@code null} then - * {@value com.google.gcloud.storage.Storage#DEFAULT_CONTENT_TYPE} is used. + * @param contentType the blob content type * @param options options for blob creation * @return a complete blob information * @throws StorageException upon failure */ public Blob create(String blob, InputStream content, String contentType, BlobWriteOption... options) { - BlobInfo blobInfo = BlobInfo.builder(BlobId.of(name(), blob)) - .contentType(MoreObjects.firstNonNull(contentType, Storage.DEFAULT_CONTENT_TYPE)).build(); + BlobInfo blobInfo = BlobInfo.builder(BlobId.of(name(), blob)).contentType(contentType).build(); + StorageRpc.Tuple write = + BlobWriteOption.toWriteOptions(blobInfo, options); + return storage.create(write.x(), content, write.y()); + } + + /** + * Creates a new blob in this bucket. Direct upload is used to upload {@code content}. + * For large content, {@link Blob#writer(com.google.gcloud.storage.Storage.BlobWriteOption...)} + * is recommended as it uses resumable upload. MD5 and CRC32C hashes of {@code content} are + * computed and used for validating transferred data. + * + * @param blob a blob name + * @param content the blob content + * @param options options for blob creation + * @return a complete blob information + * @throws StorageException upon failure + */ + public Blob create(String blob, byte[] content, BlobTargetOption... options) { + BlobInfo blobInfo = BlobInfo.builder(BlobId.of(name(), blob)).build(); + StorageRpc.Tuple target = + BlobTargetOption.toTargetOptions(blobInfo, options); + return storage.create(target.x(), content, target.y()); + } + + /** + * Creates a new blob in this bucket. Direct upload is used to upload {@code content}. + * For large content, {@link Blob#writer(com.google.gcloud.storage.Storage.BlobWriteOption...)} + * is recommended as it uses resumable upload. + * + * @param blob a blob name + * @param content the blob content as a stream + * @param options options for blob creation + * @return a complete blob information + * @throws StorageException upon failure + */ + public Blob create(String blob, InputStream content, BlobWriteOption... options) { + BlobInfo blobInfo = BlobInfo.builder(BlobId.of(name(), blob)).build(); StorageRpc.Tuple write = BlobWriteOption.toWriteOptions(blobInfo, options); return storage.create(write.x(), content, write.y()); diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index c30111e50835..35fc6117cbc2 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -53,8 +53,6 @@ */ public interface Storage extends Service { - String DEFAULT_CONTENT_TYPE = "application/octet-stream"; - enum PredefinedAcl { AUTHENTICATED_READ("authenticatedRead"), ALL_AUTHENTICATED_USERS("allAuthenticatedUsers"), diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java index 236411e0c2d8..53056c39c0dc 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java @@ -293,16 +293,16 @@ public void testCreate() throws Exception { } @Test - public void testCreateNullContentType() throws Exception { + public void testCreateNoContentType() throws Exception { initializeExpectedBucket(5); - BlobInfo info = BlobInfo.builder("b", "n").contentType(Storage.DEFAULT_CONTENT_TYPE).build(); + BlobInfo info = BlobInfo.builder("b", "n").build(); Blob expectedBlob = new Blob(serviceMockReturnsOptions, new BlobInfo.BuilderImpl(info)); byte[] content = {0xD, 0xE, 0xA, 0xD}; expect(storage.options()).andReturn(mockOptions); expect(storage.create(info, content)).andReturn(expectedBlob); replay(storage); initializeBucket(); - Blob blob = bucket.create("n", content, null); + Blob blob = bucket.create("n", content); assertEquals(expectedBlob, blob); } @@ -388,9 +388,9 @@ public void testCreateFromStream() throws Exception { } @Test - public void testCreateFromStreamNullContentType() throws Exception { + public void testCreateFromStreamNoContentType() throws Exception { initializeExpectedBucket(5); - BlobInfo info = BlobInfo.builder("b", "n").contentType(Storage.DEFAULT_CONTENT_TYPE).build(); + BlobInfo info = BlobInfo.builder("b", "n").build(); Blob expectedBlob = new Blob(serviceMockReturnsOptions, new BlobInfo.BuilderImpl(info)); byte[] content = {0xD, 0xE, 0xA, 0xD}; InputStream streamContent = new ByteArrayInputStream(content); @@ -398,7 +398,7 @@ public void testCreateFromStreamNullContentType() throws Exception { expect(storage.create(info, streamContent)).andReturn(expectedBlob); replay(storage); initializeBucket(); - Blob blob = bucket.create("n", streamContent, null); + Blob blob = bucket.create("n", streamContent); assertEquals(expectedBlob, blob); } From 5c4e2886f8257470932341191b699e1d621c890e Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 18 Mar 2016 16:01:58 +0100 Subject: [PATCH 180/375] Make NoAuthCredentials constructor private --- .../src/main/java/com/google/gcloud/AuthCredentials.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java index 38265a26be2e..27cafc181505 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java @@ -288,6 +288,8 @@ public boolean equals(Object obj) { } } + private NoAuthCredentials() {} + @Override public GoogleCredentials credentials() { return null; From 19e0c6e9736bc13a26d6a8f811322ee97e477200 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 18 Mar 2016 16:03:46 +0100 Subject: [PATCH 181/375] Add IamPolicy to SerializationTest --- .../com/google/gcloud/SerializationTest.java | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java index c4bcfcc13b1c..194479ac365c 100644 --- a/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java +++ b/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java @@ -24,11 +24,34 @@ public class SerializationTest extends BaseSerializationTest { + private static class SomeIamPolicy extends IamPolicy { + + private static final long serialVersionUID = 271243551016958285L; + + private static class Builder extends IamPolicy.Builder { + + @Override + public SomeIamPolicy build() { + return new SomeIamPolicy(this); + } + } + + protected SomeIamPolicy(Builder builder) { + super(builder); + } + + @Override + public Builder toBuilder() { + return new Builder(); + } + } + private static final ExceptionHandler EXCEPTION_HANDLER = ExceptionHandler.defaultInstance(); private static final Identity IDENTITY = Identity.allAuthenticatedUsers(); private static final PageImpl PAGE = new PageImpl<>(null, "cursor", ImmutableList.of("string1", "string2")); private static final RetryParams RETRY_PARAMS = RetryParams.defaultInstance(); + private static final SomeIamPolicy SOME_IAM_POLICY = new SomeIamPolicy.Builder().build(); private static final String JSON_KEY = "{\n" + " \"private_key_id\": \"somekeyid\",\n" + " \"private_key\": \"-----BEGIN PRIVATE KEY-----\\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggS" @@ -58,7 +81,7 @@ public class SerializationTest extends BaseSerializationTest { @Override protected Serializable[] serializableObjects() { - return new Serializable[]{EXCEPTION_HANDLER, IDENTITY, PAGE, RETRY_PARAMS}; + return new Serializable[]{EXCEPTION_HANDLER, IDENTITY, PAGE, RETRY_PARAMS, SOME_IAM_POLICY}; } @Override From 83ddb08d0e6aae40707ab8b9d071fa62854e8769 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 18 Mar 2016 16:08:37 +0100 Subject: [PATCH 182/375] Add equals and hashCode to exceptions. Add exceptions to serialization tests --- .../gcloud/bigquery/BigQueryException.java | 18 ++++++++ .../gcloud/bigquery/SerializationTest.java | 4 +- .../google/gcloud/BaseServiceException.java | 45 ++++++++++++++----- .../com/google/gcloud/SerializationTest.java | 5 ++- .../gcloud/datastore/SerializationTest.java | 5 ++- .../resourcemanager/SerializationTest.java | 5 ++- .../gcloud/storage/SerializationTest.java | 4 +- 7 files changed, 71 insertions(+), 15 deletions(-) diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryException.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryException.java index a157afd25db2..e78734a2899e 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryException.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryException.java @@ -22,6 +22,7 @@ import com.google.gcloud.RetryHelper.RetryInterruptedException; import java.io.IOException; +import java.util.Objects; import java.util.Set; /** @@ -73,6 +74,23 @@ protected Set retryableErrors() { return RETRYABLE_ERRORS; } + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof BigQueryException)) { + return false; + } + BigQueryException other = (BigQueryException) obj; + return super.equals(other) && Objects.equals(error, other.error); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), error); + } + /** * Translate RetryHelperException to the BigQueryException that caused the error. This method will * always throw an exception. diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java index 74644216c109..111df074ffa2 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java @@ -219,6 +219,8 @@ public class SerializationTest extends BaseSerializationTest { new Dataset(BIGQUERY, new DatasetInfo.BuilderImpl(DATASET_INFO)); private static final Table TABLE = new Table(BIGQUERY, new TableInfo.BuilderImpl(TABLE_INFO)); private static final Job JOB = new Job(BIGQUERY, new JobInfo.BuilderImpl(JOB_INFO)); + private static final BigQueryException BIG_QUERY_EXCEPTION = + new BigQueryException(42, "message", BIGQUERY_ERROR); @Override protected Serializable[] serializableObjects() { @@ -237,7 +239,7 @@ protected Serializable[] serializableObjects() { LOAD_STATISTICS, QUERY_STATISTICS, BIGQUERY_ERROR, JOB_STATUS, JOB_ID, COPY_JOB_CONFIGURATION, EXTRACT_JOB_CONFIGURATION, LOAD_CONFIGURATION, LOAD_JOB_CONFIGURATION, QUERY_JOB_CONFIGURATION, JOB_INFO, INSERT_ALL_REQUEST, - INSERT_ALL_RESPONSE, FIELD_VALUE, QUERY_REQUEST, QUERY_RESPONSE, + INSERT_ALL_RESPONSE, FIELD_VALUE, QUERY_REQUEST, QUERY_RESPONSE, BIG_QUERY_EXCEPTION, BigQuery.DatasetOption.fields(), BigQuery.DatasetDeleteOption.deleteContents(), BigQuery.DatasetListOption.all(), BigQuery.TableOption.fields(), BigQuery.TableListOption.pageSize(42L), BigQuery.JobOption.fields(), diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/BaseServiceException.java b/gcloud-java-core/src/main/java/com/google/gcloud/BaseServiceException.java index 365243904436..4e0d03e0073a 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/BaseServiceException.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/BaseServiceException.java @@ -32,6 +32,16 @@ */ public class BaseServiceException extends RuntimeException { + private static final long serialVersionUID = 759921776378760835L; + public static final int UNKNOWN_CODE = 0; + + private final int code; + private final boolean retryable; + private final String reason; + private final boolean idempotent; + private final String location; + private final String debugInfo; + protected static final class Error implements Serializable { private static final long serialVersionUID = -4019600198652965721L; @@ -79,16 +89,6 @@ public int hashCode() { } } - private static final long serialVersionUID = 759921776378760835L; - public static final int UNKNOWN_CODE = 0; - - private final int code; - private final boolean retryable; - private final String reason; - private final boolean idempotent; - private final String location; - private final String debugInfo; - public BaseServiceException(IOException exception, boolean idempotent) { super(message(exception), exception); int code = UNKNOWN_CODE; @@ -198,6 +198,31 @@ protected String debugInfo() { return debugInfo; } + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof BaseServiceException)) { + return false; + } + BaseServiceException other = (BaseServiceException) obj; + return Objects.equals(getCause(), other.getCause()) + && Objects.equals(getMessage(), other.getMessage()) + && code == other.code + && retryable == other.retryable + && Objects.equals(reason, other.reason) + && idempotent == other.idempotent + && Objects.equals(location, other.location) + && Objects.equals(debugInfo, other.debugInfo); + } + + @Override + public int hashCode() { + return Objects.hash(getCause(), getMessage(), code, retryable, reason, idempotent, location, + debugInfo); + } + protected static String reason(GoogleJsonError error) { if (error.getErrors() != null && !error.getErrors().isEmpty()) { return error.getErrors().get(0).getReason(); diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java index 194479ac365c..3255a17333aa 100644 --- a/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java +++ b/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java @@ -46,6 +46,8 @@ public Builder toBuilder() { } } + private static final BaseServiceException BASE_SERVICE_EXCEPTION = + new BaseServiceException(42, "message", "reason", true); private static final ExceptionHandler EXCEPTION_HANDLER = ExceptionHandler.defaultInstance(); private static final Identity IDENTITY = Identity.allAuthenticatedUsers(); private static final PageImpl PAGE = @@ -81,7 +83,8 @@ public Builder toBuilder() { @Override protected Serializable[] serializableObjects() { - return new Serializable[]{EXCEPTION_HANDLER, IDENTITY, PAGE, RETRY_PARAMS, SOME_IAM_POLICY}; + return new Serializable[]{BASE_SERVICE_EXCEPTION, EXCEPTION_HANDLER, IDENTITY, PAGE, + RETRY_PARAMS, SOME_IAM_POLICY}; } @Override diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index 3ea74ef7c4d6..b9e78800ffab 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -102,6 +102,8 @@ public class SerializationTest extends BaseSerializationTest { .addValue(new NullValue()) .build(); private static final ProjectionEntity PROJECTION_ENTITY = ProjectionEntity.fromPb(ENTITY1.toPb()); + private static final DatastoreException DATASTORE_EXCEPTION = + new DatastoreException(42, "message", "reason"); @Override protected java.io.Serializable[] serializableObjects() { @@ -119,7 +121,8 @@ protected java.io.Serializable[] serializableObjects() { ENTITY2, ENTITY3, EMBEDDED_ENTITY, PROJECTION_ENTITY, DATE_TIME1, BLOB1, CURSOR1, GQL1, GQL2, QUERY1, QUERY2, QUERY3, NULL_VALUE, KEY_VALUE, STRING_VALUE, EMBEDDED_ENTITY_VALUE1, EMBEDDED_ENTITY_VALUE2, EMBEDDED_ENTITY_VALUE3, LIST_VALUE, LONG_VALUE, DOUBLE_VALUE, - BOOLEAN_VALUE, DATE_AND_TIME_VALUE, BLOB_VALUE, RAW_VALUE, options, otherOptions}; + BOOLEAN_VALUE, DATE_AND_TIME_VALUE, BLOB_VALUE, RAW_VALUE, DATASTORE_EXCEPTION, options, + otherOptions}; } @Override diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java index 5bad065003e0..c6e907da16a0 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java @@ -49,6 +49,8 @@ public class SerializationTest extends BaseSerializationTest { private static final Policy POLICY = Policy.builder() .addBinding(Policy.Role.viewer(), ImmutableSet.of(Identity.user("abc@gmail.com"))) .build(); + private static final ResourceManagerException RESOURCE_MANAGER_EXCEPTION = + new ResourceManagerException(42, "message"); @Override protected Serializable[] serializableObjects() { @@ -57,7 +59,8 @@ protected Serializable[] serializableObjects() { .projectId("some-unnecessary-project-ID") .build(); return new Serializable[]{PARTIAL_PROJECT_INFO, FULL_PROJECT_INFO, PROJECT, PAGE_RESULT, - PROJECT_GET_OPTION, PROJECT_LIST_OPTION, POLICY, options, otherOptions}; + PROJECT_GET_OPTION, PROJECT_LIST_OPTION, POLICY, RESOURCE_MANAGER_EXCEPTION, options, + otherOptions}; } @Override diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java index 6aae7b1a0cb2..613cb81c3549 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java @@ -52,6 +52,7 @@ public class SerializationTest extends BaseSerializationTest { Collections.>emptyList()); private static final PageImpl PAGE_RESULT = new PageImpl<>(null, "c", Collections.singletonList(BLOB)); + private static final StorageException STORAGE_EXCEPTION = new StorageException(42, "message"); private static final Storage.BlobListOption BLOB_LIST_OPTIONS = Storage.BlobListOption.pageSize(100); private static final Storage.BlobSourceOption BLOB_SOURCE_OPTIONS = @@ -79,7 +80,8 @@ protected Serializable[] serializableObjects() { return new Serializable[]{ACL_DOMAIN, ACL_GROUP, ACL_PROJECT_, ACL_USER, ACL_RAW, ACL, BLOB_INFO, BLOB, BUCKET_INFO, BUCKET, ORIGIN, CORS, BATCH_REQUEST, BATCH_RESPONSE, PAGE_RESULT, BLOB_LIST_OPTIONS, BLOB_SOURCE_OPTIONS, BLOB_TARGET_OPTIONS, - BUCKET_LIST_OPTIONS, BUCKET_SOURCE_OPTIONS, BUCKET_TARGET_OPTIONS, options, otherOptions}; + BUCKET_LIST_OPTIONS, BUCKET_SOURCE_OPTIONS, BUCKET_TARGET_OPTIONS, STORAGE_EXCEPTION, + options, otherOptions}; } @Override From 95a1f9070aa33cd0354591733588ac380f2cdf6d Mon Sep 17 00:00:00 2001 From: Garrett Jones Date: Fri, 18 Mar 2016 11:01:47 -0700 Subject: [PATCH 183/375] Bundling descriptor for Publish --- .../gcloud/pubsub/spi/v1/PublisherApi.java | 12 ++- .../pubsub/spi/v1/PublisherSettings.java | 98 ++++++++++++++++--- .../gcloud/pubsub/spi/v1/SubscriberApi.java | 1 - .../pubsub/spi/v1/SubscriberSettings.java | 24 ++--- gcloud-java-pubsub/pom.xml | 2 +- .../gcloud/pubsub/spi/v1/PublisherApi.java | 12 ++- .../pubsub/spi/v1/PublisherSettings.java | 98 ++++++++++++++++--- .../gcloud/pubsub/spi/v1/SubscriberApi.java | 1 - .../pubsub/spi/v1/SubscriberSettings.java | 24 ++--- .../pubsub/spi/v1/PublisherApiTest.java | 38 +++++++ 10 files changed, 253 insertions(+), 57 deletions(-) diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java index 6ace2998698b..1930702f9e84 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java @@ -33,8 +33,9 @@ package com.google.gcloud.pubsub.spi.v1; -import com.google.api.gax.grpc.ApiCallSettings; import com.google.api.gax.grpc.ApiCallable; +import com.google.api.gax.grpc.ApiCallable.BundlableApiCallableInfo; +import com.google.api.gax.grpc.BundlerFactory; import com.google.api.gax.protobuf.PathTemplate; import com.google.protobuf.Empty; import com.google.pubsub.v1.DeleteTopicRequest; @@ -207,7 +208,14 @@ protected PublisherApi(PublisherSettings settings) throws IOException { this.channel = settings.getChannel(); this.createTopicCallable = settings.createTopicMethod().build(settings); - this.publishCallable = settings.publishMethod().build(settings); + BundlableApiCallableInfo bundlablePublish = + settings.publishMethod().buildBundlable(settings); + this.publishCallable = bundlablePublish.getApiCallable(); + BundlerFactory publishBundlerFactory = + bundlablePublish.getBundlerFactory(); + if (publishBundlerFactory != null) { + this.closeables.add(publishBundlerFactory); + } this.getTopicCallable = settings.getTopicMethod().build(settings); this.listTopicsCallable = settings.listTopicsMethod().build(settings); this.listTopicsIterableCallable = settings.listTopicsMethod().buildPageStreaming(settings); diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java index 70b188735890..5f60fa374553 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java @@ -38,8 +38,11 @@ import com.google.api.gax.core.RetryParams; import com.google.api.gax.grpc.ApiCallSettings; import com.google.api.gax.grpc.ApiCallable.ApiCallableBuilder; +import com.google.api.gax.grpc.ApiCallable.BundlableApiCallableBuilder; import com.google.api.gax.grpc.ApiCallable.PageStreamingApiCallableBuilder; -import com.google.api.gax.grpc.PageDescriptor; +import com.google.api.gax.grpc.BundlingDescriptor; +import com.google.api.gax.grpc.PageStreamingDescriptor; +import com.google.api.gax.grpc.RequestIssuer; import com.google.api.gax.grpc.ServiceApiSettings; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -56,8 +59,12 @@ import com.google.pubsub.v1.PublishRequest; import com.google.pubsub.v1.PublishResponse; import com.google.pubsub.v1.PublisherGrpc; +import com.google.pubsub.v1.PubsubMessage; import com.google.pubsub.v1.Topic; import io.grpc.Status; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; // Manually-added imports: add custom (non-generated) imports after this point. @@ -134,7 +141,7 @@ public class PublisherSettings extends ServiceApiSettings { private static class MethodBuilders { private final ApiCallableBuilder createTopicMethod; - private final ApiCallableBuilder publishMethod; + private final BundlableApiCallableBuilder publishMethod; private final ApiCallableBuilder getTopicMethod; private final PageStreamingApiCallableBuilder listTopicsMethod; @@ -149,7 +156,8 @@ public MethodBuilders() { createTopicMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); createTopicMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - publishMethod = new ApiCallableBuilder<>(PublisherGrpc.METHOD_PUBLISH); + publishMethod = + new BundlableApiCallableBuilder<>(PublisherGrpc.METHOD_PUBLISH, PUBLISH_BUNDLING_DESC); publishMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); publishMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); @@ -223,7 +231,7 @@ protected PublisherSettings(MethodBuilders methods) { } /** - * Returns the ApiCallableBuilder for the API method createTopic. + * Returns the builder for the API method createTopic. * * * @@ -233,17 +241,17 @@ public ApiCallableBuilder createTopicMethod() { } /** - * Returns the ApiCallableBuilder for the API method publish. + * Returns the builder for the API method publish. * * * */ - public ApiCallableBuilder publishMethod() { + public BundlableApiCallableBuilder publishMethod() { return methods.publishMethod; } /** - * Returns the ApiCallableBuilder for the API method getTopic. + * Returns the builder for the API method getTopic. * * * @@ -253,7 +261,7 @@ public ApiCallableBuilder getTopicMethod() { } /** - * Returns the PageStreamingApiCallableBuilder for the API method listTopics. + * Returns the builder for the API method listTopics. * * * @@ -264,7 +272,7 @@ public ApiCallableBuilder getTopicMethod() { } /** - * Returns the PageStreamingApiCallableBuilder for the API method listTopicSubscriptions. + * Returns the builder for the API method listTopicSubscriptions. * * * @@ -276,7 +284,7 @@ public ApiCallableBuilder getTopicMethod() { } /** - * Returns the ApiCallableBuilder for the API method deleteTopic. + * Returns the builder for the API method deleteTopic. * * * @@ -285,9 +293,9 @@ public ApiCallableBuilder deleteTopicMethod() { return methods.deleteTopicMethod; } - private static PageDescriptor + private static PageStreamingDescriptor LIST_TOPICS_PAGE_STR_DESC = - new PageDescriptor() { + new PageStreamingDescriptor() { @Override public Object emptyToken() { return ""; @@ -309,10 +317,10 @@ public Iterable extractResources(ListTopicsResponse payload) { } }; - private static PageDescriptor< + private static PageStreamingDescriptor< ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> LIST_TOPIC_SUBSCRIPTIONS_PAGE_STR_DESC = - new PageDescriptor< + new PageStreamingDescriptor< ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String>() { @Override public Object emptyToken() { @@ -337,4 +345,66 @@ public Iterable extractResources(ListTopicSubscriptionsResponse payload) return payload.getSubscriptionsList(); } }; + + private static BundlingDescriptor PUBLISH_BUNDLING_DESC = + new BundlingDescriptor() { + @Override + public String getBundlePartitionKey(PublishRequest request) { + return request.getTopic(); + } + + @Override + public PublishRequest mergeRequests(Collection requests) { + PublishRequest firstRequest = requests.iterator().next(); + + List elements = new ArrayList<>(); + for (PublishRequest request : requests) { + elements.addAll(request.getMessagesList()); + } + + PublishRequest bundleRequest = + PublishRequest.newBuilder() + .setTopic(firstRequest.getTopic()) + .addAllMessages(elements) + .build(); + return bundleRequest; + } + + @Override + public void splitResponse( + PublishResponse bundleResponse, + Collection> bundle) { + int bundleMessageIndex = 0; + for (RequestIssuer responder : bundle) { + List subresponseElements = new ArrayList<>(); + int subresponseCount = responder.getRequest().getMessagesCount(); + for (int i = 0; i < subresponseCount; i++) { + subresponseElements.add(bundleResponse.getMessageIds(bundleMessageIndex)); + bundleMessageIndex += 1; + } + PublishResponse response = + PublishResponse.newBuilder().addAllMessageIds(subresponseElements).build(); + responder.setResponse(response); + } + } + + @Override + public void splitException( + Throwable throwable, + Collection> bundle) { + for (RequestIssuer responder : bundle) { + responder.setException(throwable); + } + } + + @Override + public long countElements(PublishRequest request) { + return request.getMessagesCount(); + } + + @Override + public long countBytes(PublishRequest request) { + return request.getSerializedSize(); + } + }; } diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java index 16e1435b8582..c794fddb1943 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java @@ -33,7 +33,6 @@ package com.google.gcloud.pubsub.spi.v1; -import com.google.api.gax.grpc.ApiCallSettings; import com.google.api.gax.grpc.ApiCallable; import com.google.api.gax.protobuf.PathTemplate; import com.google.protobuf.Empty; diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java index 2680d8429938..df9ea36e69b8 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java @@ -39,7 +39,7 @@ import com.google.api.gax.grpc.ApiCallSettings; import com.google.api.gax.grpc.ApiCallable.ApiCallableBuilder; import com.google.api.gax.grpc.ApiCallable.PageStreamingApiCallableBuilder; -import com.google.api.gax.grpc.PageDescriptor; +import com.google.api.gax.grpc.PageStreamingDescriptor; import com.google.api.gax.grpc.ServiceApiSettings; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -234,7 +234,7 @@ protected SubscriberSettings(MethodBuilders methods) { } /** - * Returns the ApiCallableBuilder for the API method createSubscription. + * Returns the builder for the API method createSubscription. * * * @@ -244,7 +244,7 @@ public ApiCallableBuilder createSubscriptionMethod() } /** - * Returns the ApiCallableBuilder for the API method getSubscription. + * Returns the builder for the API method getSubscription. * * * @@ -254,7 +254,7 @@ public ApiCallableBuilder getSubscriptionM } /** - * Returns the PageStreamingApiCallableBuilder for the API method listSubscriptions. + * Returns the builder for the API method listSubscriptions. * * * @@ -266,7 +266,7 @@ public ApiCallableBuilder getSubscriptionM } /** - * Returns the ApiCallableBuilder for the API method deleteSubscription. + * Returns the builder for the API method deleteSubscription. * * * @@ -276,7 +276,7 @@ public ApiCallableBuilder deleteSubscriptionMe } /** - * Returns the ApiCallableBuilder for the API method modifyAckDeadline. + * Returns the builder for the API method modifyAckDeadline. * * * @@ -286,7 +286,7 @@ public ApiCallableBuilder modifyAckDeadlineMeth } /** - * Returns the ApiCallableBuilder for the API method acknowledge. + * Returns the builder for the API method acknowledge. * * * @@ -296,7 +296,7 @@ public ApiCallableBuilder acknowledgeMethod() { } /** - * Returns the ApiCallableBuilder for the API method pull. + * Returns the builder for the API method pull. * * * @@ -306,7 +306,7 @@ public ApiCallableBuilder pullMethod() { } /** - * Returns the ApiCallableBuilder for the API method modifyPushConfig. + * Returns the builder for the API method modifyPushConfig. * * * @@ -315,9 +315,11 @@ public ApiCallableBuilder modifyPushConfigMethod return methods.modifyPushConfigMethod; } - private static PageDescriptor + private static PageStreamingDescriptor< + ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> LIST_SUBSCRIPTIONS_PAGE_STR_DESC = - new PageDescriptor() { + new PageStreamingDescriptor< + ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription>() { @Override public Object emptyToken() { return ""; diff --git a/gcloud-java-pubsub/pom.xml b/gcloud-java-pubsub/pom.xml index 2fccc5a6560c..987aa99667c9 100644 --- a/gcloud-java-pubsub/pom.xml +++ b/gcloud-java-pubsub/pom.xml @@ -19,7 +19,7 @@ com.google.api gax - 0.0.4 + 0.0.5-SNAPSHOT com.google.api.grpc diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java index 6ace2998698b..1930702f9e84 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java @@ -33,8 +33,9 @@ package com.google.gcloud.pubsub.spi.v1; -import com.google.api.gax.grpc.ApiCallSettings; import com.google.api.gax.grpc.ApiCallable; +import com.google.api.gax.grpc.ApiCallable.BundlableApiCallableInfo; +import com.google.api.gax.grpc.BundlerFactory; import com.google.api.gax.protobuf.PathTemplate; import com.google.protobuf.Empty; import com.google.pubsub.v1.DeleteTopicRequest; @@ -207,7 +208,14 @@ protected PublisherApi(PublisherSettings settings) throws IOException { this.channel = settings.getChannel(); this.createTopicCallable = settings.createTopicMethod().build(settings); - this.publishCallable = settings.publishMethod().build(settings); + BundlableApiCallableInfo bundlablePublish = + settings.publishMethod().buildBundlable(settings); + this.publishCallable = bundlablePublish.getApiCallable(); + BundlerFactory publishBundlerFactory = + bundlablePublish.getBundlerFactory(); + if (publishBundlerFactory != null) { + this.closeables.add(publishBundlerFactory); + } this.getTopicCallable = settings.getTopicMethod().build(settings); this.listTopicsCallable = settings.listTopicsMethod().build(settings); this.listTopicsIterableCallable = settings.listTopicsMethod().buildPageStreaming(settings); diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java index 70b188735890..5f60fa374553 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java @@ -38,8 +38,11 @@ import com.google.api.gax.core.RetryParams; import com.google.api.gax.grpc.ApiCallSettings; import com.google.api.gax.grpc.ApiCallable.ApiCallableBuilder; +import com.google.api.gax.grpc.ApiCallable.BundlableApiCallableBuilder; import com.google.api.gax.grpc.ApiCallable.PageStreamingApiCallableBuilder; -import com.google.api.gax.grpc.PageDescriptor; +import com.google.api.gax.grpc.BundlingDescriptor; +import com.google.api.gax.grpc.PageStreamingDescriptor; +import com.google.api.gax.grpc.RequestIssuer; import com.google.api.gax.grpc.ServiceApiSettings; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -56,8 +59,12 @@ import com.google.pubsub.v1.PublishRequest; import com.google.pubsub.v1.PublishResponse; import com.google.pubsub.v1.PublisherGrpc; +import com.google.pubsub.v1.PubsubMessage; import com.google.pubsub.v1.Topic; import io.grpc.Status; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; // Manually-added imports: add custom (non-generated) imports after this point. @@ -134,7 +141,7 @@ public class PublisherSettings extends ServiceApiSettings { private static class MethodBuilders { private final ApiCallableBuilder createTopicMethod; - private final ApiCallableBuilder publishMethod; + private final BundlableApiCallableBuilder publishMethod; private final ApiCallableBuilder getTopicMethod; private final PageStreamingApiCallableBuilder listTopicsMethod; @@ -149,7 +156,8 @@ public MethodBuilders() { createTopicMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); createTopicMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - publishMethod = new ApiCallableBuilder<>(PublisherGrpc.METHOD_PUBLISH); + publishMethod = + new BundlableApiCallableBuilder<>(PublisherGrpc.METHOD_PUBLISH, PUBLISH_BUNDLING_DESC); publishMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); publishMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); @@ -223,7 +231,7 @@ protected PublisherSettings(MethodBuilders methods) { } /** - * Returns the ApiCallableBuilder for the API method createTopic. + * Returns the builder for the API method createTopic. * * * @@ -233,17 +241,17 @@ public ApiCallableBuilder createTopicMethod() { } /** - * Returns the ApiCallableBuilder for the API method publish. + * Returns the builder for the API method publish. * * * */ - public ApiCallableBuilder publishMethod() { + public BundlableApiCallableBuilder publishMethod() { return methods.publishMethod; } /** - * Returns the ApiCallableBuilder for the API method getTopic. + * Returns the builder for the API method getTopic. * * * @@ -253,7 +261,7 @@ public ApiCallableBuilder getTopicMethod() { } /** - * Returns the PageStreamingApiCallableBuilder for the API method listTopics. + * Returns the builder for the API method listTopics. * * * @@ -264,7 +272,7 @@ public ApiCallableBuilder getTopicMethod() { } /** - * Returns the PageStreamingApiCallableBuilder for the API method listTopicSubscriptions. + * Returns the builder for the API method listTopicSubscriptions. * * * @@ -276,7 +284,7 @@ public ApiCallableBuilder getTopicMethod() { } /** - * Returns the ApiCallableBuilder for the API method deleteTopic. + * Returns the builder for the API method deleteTopic. * * * @@ -285,9 +293,9 @@ public ApiCallableBuilder deleteTopicMethod() { return methods.deleteTopicMethod; } - private static PageDescriptor + private static PageStreamingDescriptor LIST_TOPICS_PAGE_STR_DESC = - new PageDescriptor() { + new PageStreamingDescriptor() { @Override public Object emptyToken() { return ""; @@ -309,10 +317,10 @@ public Iterable extractResources(ListTopicsResponse payload) { } }; - private static PageDescriptor< + private static PageStreamingDescriptor< ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> LIST_TOPIC_SUBSCRIPTIONS_PAGE_STR_DESC = - new PageDescriptor< + new PageStreamingDescriptor< ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String>() { @Override public Object emptyToken() { @@ -337,4 +345,66 @@ public Iterable extractResources(ListTopicSubscriptionsResponse payload) return payload.getSubscriptionsList(); } }; + + private static BundlingDescriptor PUBLISH_BUNDLING_DESC = + new BundlingDescriptor() { + @Override + public String getBundlePartitionKey(PublishRequest request) { + return request.getTopic(); + } + + @Override + public PublishRequest mergeRequests(Collection requests) { + PublishRequest firstRequest = requests.iterator().next(); + + List elements = new ArrayList<>(); + for (PublishRequest request : requests) { + elements.addAll(request.getMessagesList()); + } + + PublishRequest bundleRequest = + PublishRequest.newBuilder() + .setTopic(firstRequest.getTopic()) + .addAllMessages(elements) + .build(); + return bundleRequest; + } + + @Override + public void splitResponse( + PublishResponse bundleResponse, + Collection> bundle) { + int bundleMessageIndex = 0; + for (RequestIssuer responder : bundle) { + List subresponseElements = new ArrayList<>(); + int subresponseCount = responder.getRequest().getMessagesCount(); + for (int i = 0; i < subresponseCount; i++) { + subresponseElements.add(bundleResponse.getMessageIds(bundleMessageIndex)); + bundleMessageIndex += 1; + } + PublishResponse response = + PublishResponse.newBuilder().addAllMessageIds(subresponseElements).build(); + responder.setResponse(response); + } + } + + @Override + public void splitException( + Throwable throwable, + Collection> bundle) { + for (RequestIssuer responder : bundle) { + responder.setException(throwable); + } + } + + @Override + public long countElements(PublishRequest request) { + return request.getMessagesCount(); + } + + @Override + public long countBytes(PublishRequest request) { + return request.getSerializedSize(); + } + }; } diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java index 16e1435b8582..c794fddb1943 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java @@ -33,7 +33,6 @@ package com.google.gcloud.pubsub.spi.v1; -import com.google.api.gax.grpc.ApiCallSettings; import com.google.api.gax.grpc.ApiCallable; import com.google.api.gax.protobuf.PathTemplate; import com.google.protobuf.Empty; diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java index 2680d8429938..df9ea36e69b8 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java @@ -39,7 +39,7 @@ import com.google.api.gax.grpc.ApiCallSettings; import com.google.api.gax.grpc.ApiCallable.ApiCallableBuilder; import com.google.api.gax.grpc.ApiCallable.PageStreamingApiCallableBuilder; -import com.google.api.gax.grpc.PageDescriptor; +import com.google.api.gax.grpc.PageStreamingDescriptor; import com.google.api.gax.grpc.ServiceApiSettings; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -234,7 +234,7 @@ protected SubscriberSettings(MethodBuilders methods) { } /** - * Returns the ApiCallableBuilder for the API method createSubscription. + * Returns the builder for the API method createSubscription. * * * @@ -244,7 +244,7 @@ public ApiCallableBuilder createSubscriptionMethod() } /** - * Returns the ApiCallableBuilder for the API method getSubscription. + * Returns the builder for the API method getSubscription. * * * @@ -254,7 +254,7 @@ public ApiCallableBuilder getSubscriptionM } /** - * Returns the PageStreamingApiCallableBuilder for the API method listSubscriptions. + * Returns the builder for the API method listSubscriptions. * * * @@ -266,7 +266,7 @@ public ApiCallableBuilder getSubscriptionM } /** - * Returns the ApiCallableBuilder for the API method deleteSubscription. + * Returns the builder for the API method deleteSubscription. * * * @@ -276,7 +276,7 @@ public ApiCallableBuilder deleteSubscriptionMe } /** - * Returns the ApiCallableBuilder for the API method modifyAckDeadline. + * Returns the builder for the API method modifyAckDeadline. * * * @@ -286,7 +286,7 @@ public ApiCallableBuilder modifyAckDeadlineMeth } /** - * Returns the ApiCallableBuilder for the API method acknowledge. + * Returns the builder for the API method acknowledge. * * * @@ -296,7 +296,7 @@ public ApiCallableBuilder acknowledgeMethod() { } /** - * Returns the ApiCallableBuilder for the API method pull. + * Returns the builder for the API method pull. * * * @@ -306,7 +306,7 @@ public ApiCallableBuilder pullMethod() { } /** - * Returns the ApiCallableBuilder for the API method modifyPushConfig. + * Returns the builder for the API method modifyPushConfig. * * * @@ -315,9 +315,11 @@ public ApiCallableBuilder modifyPushConfigMethod return methods.modifyPushConfigMethod; } - private static PageDescriptor + private static PageStreamingDescriptor< + ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> LIST_SUBSCRIPTIONS_PAGE_STR_DESC = - new PageDescriptor() { + new PageStreamingDescriptor< + ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription>() { @Override public Object emptyToken() { return ""; diff --git a/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/v1/PublisherApiTest.java b/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/v1/PublisherApiTest.java index aaf292ff917d..a092c2fdd7ee 100644 --- a/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/v1/PublisherApiTest.java +++ b/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/v1/PublisherApiTest.java @@ -16,6 +16,7 @@ import com.google.api.gax.core.BackoffParams; import com.google.api.gax.core.RetryParams; +import com.google.api.gax.grpc.BundlingSettings; import com.google.gcloud.pubsub.testing.LocalPubsubHelper; import com.google.protobuf.ByteString; import com.google.pubsub.v1.PubsubMessage; @@ -30,6 +31,7 @@ import java.util.Collections; import java.util.List; +import org.joda.time.Duration; import org.junit.After; import org.junit.AfterClass; import org.junit.Assert; @@ -40,6 +42,7 @@ public class PublisherApiTest { private static LocalPubsubHelper pubsubHelper; private PublisherApi publisherApi; + private PublisherApi bundledPublisherApi; private SubscriberApi subscriberApi; @BeforeClass @@ -79,6 +82,18 @@ public void setUp() throws Exception { publisherSettings.provideChannelWith(channel); publisherApi = PublisherApi.create(publisherSettings); + BundlingSettings bundlingSettings = + BundlingSettings.newBuilder() + .setElementCountThreshold(10) + .setDelayThreshold(Duration.standardSeconds(30)) + .build(); + + PublisherSettings bundledPublisherSettings = PublisherSettings.create(); + bundledPublisherSettings.setRetryParamsOnAllMethods(retryParams); + bundledPublisherSettings.provideChannelWith(channel); + bundledPublisherSettings.publishMethod().setBundlingSettings(bundlingSettings); + bundledPublisherApi = PublisherApi.create(bundledPublisherSettings); + SubscriberSettings subscriberSettings = SubscriberSettings.create(); subscriberSettings.setRetryParamsOnAllMethods(retryParams); subscriberSettings.provideChannelWith(channel); @@ -93,6 +108,9 @@ public void tearDown() throws Exception { if (subscriberApi != null) { subscriberApi.close(); } + if (bundledPublisherApi != null) { + bundledPublisherApi.close(); + } pubsubHelper.reset(); } @@ -122,6 +140,26 @@ public void testPublish() throws Exception { "pubsub-message", response.getReceivedMessages(0).getMessage().getData().toStringUtf8()); } + @Test + public void testBundledPublish() throws Exception { + String topicName = PublisherApi.ResourceNames.formatTopicPath("my-project", "publish-topic"); + bundledPublisherApi.createTopic(topicName); + + String subscriberName = SubscriberApi.ResourceNames.formatSubscriptionPath("my-project", "my-subscribe"); + PushConfig config = PushConfig.getDefaultInstance(); + subscriberApi.createSubscription(subscriberName, topicName, config, 5); + + PubsubMessage msg = + PubsubMessage.newBuilder().setData(ByteString.copyFromUtf8("pubsub-message")).build(); + // This is a synchronous publish and should trigger the default blockingCallCountThreshold of 1 + bundledPublisherApi.publish(topicName, Collections.singletonList(msg)); + + PullResponse response = subscriberApi.pull(subscriberName, true, 100); + Assert.assertEquals(1, response.getReceivedMessagesCount()); + Assert.assertEquals( + "pubsub-message", response.getReceivedMessages(0).getMessage().getData().toStringUtf8()); + } + @Test public void testGetTopic() throws Exception { String topicName = PublisherApi.ResourceNames.formatTopicPath("my-project", "fun-topic"); From 22636e276005b809e7bef8cc869a38cba786b162 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 18 Mar 2016 17:00:47 +0100 Subject: [PATCH 184/375] Remove checks for contentType in CopyRequest - update CopyRequest to hold both targetId and targetInfo - avoid sending storage object in StorageRpc.rewrite when only targetId is set - refactor CopyWriter and state - add integration tests --- .../com/google/gcloud/storage/CopyWriter.java | 57 +++++--- .../com/google/gcloud/storage/Storage.java | 80 ++++++------ .../google/gcloud/storage/StorageImpl.java | 15 ++- .../gcloud/storage/spi/DefaultStorageRpc.java | 4 +- .../google/gcloud/storage/spi/StorageRpc.java | 19 ++- .../com/google/gcloud/storage/BlobTest.java | 12 +- .../gcloud/storage/CopyRequestTest.java | 53 +++----- .../google/gcloud/storage/CopyWriterTest.java | 122 +++++++++++++++--- .../gcloud/storage/StorageImplTest.java | 14 +- .../gcloud/storage/it/ITStorageTest.java | 51 ++++++++ 10 files changed, 288 insertions(+), 139 deletions(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java index 62b39e005369..38d9c0d5e952 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java @@ -65,11 +65,11 @@ public class CopyWriter implements Restorable { * * @throws StorageException upon failure */ - public BlobInfo result() { + public Blob result() { while (!isDone()) { copyChunk(); } - return BlobInfo.fromPb(rewriteResponse.result); + return Blob.fromPb(serviceOptions.service(), rewriteResponse.result); } /** @@ -120,8 +120,12 @@ public RestorableState capture() { serviceOptions, BlobId.fromPb(rewriteResponse.rewriteRequest.source), rewriteResponse.rewriteRequest.sourceOptions, - BlobInfo.fromPb(rewriteResponse.rewriteRequest.target), + BlobId.of(rewriteResponse.rewriteRequest.targetBucket, + rewriteResponse.rewriteRequest.targetName), rewriteResponse.rewriteRequest.targetOptions) + .targetInfo(rewriteResponse.rewriteRequest.targetObject != null + ? BlobInfo.fromPb(rewriteResponse.rewriteRequest.targetObject) : null) + .result(rewriteResponse.result != null ? BlobInfo.fromPb(rewriteResponse.result) : null) .blobSize(blobSize()) .isDone(isDone()) .megabytesCopiedPerChunk(rewriteResponse.rewriteRequest.megabytesRewrittenPerCall) @@ -132,12 +136,13 @@ public RestorableState capture() { static class StateImpl implements RestorableState, Serializable { - private static final long serialVersionUID = 8279287678903181701L; + private static final long serialVersionUID = 1693964441435822700L; private final StorageOptions serviceOptions; private final BlobId source; private final Map sourceOptions; - private final BlobInfo target; + private final BlobId targetId; + private final BlobInfo targetInfo; private final Map targetOptions; private final BlobInfo result; private final long blobSize; @@ -150,7 +155,8 @@ static class StateImpl implements RestorableState, Serializable { this.serviceOptions = builder.serviceOptions; this.source = builder.source; this.sourceOptions = builder.sourceOptions; - this.target = builder.target; + this.targetId = builder.targetId; + this.targetInfo = builder.targetInfo; this.targetOptions = builder.targetOptions; this.result = builder.result; this.blobSize = builder.blobSize; @@ -165,8 +171,9 @@ static class Builder { private final StorageOptions serviceOptions; private final BlobId source; private final Map sourceOptions; - private final BlobInfo target; + private final BlobId targetId; private final Map targetOptions; + private BlobInfo targetInfo; private BlobInfo result; private long blobSize; private boolean isDone; @@ -176,14 +183,19 @@ static class Builder { private Builder(StorageOptions options, BlobId source, Map sourceOptions, - BlobInfo target, Map targetOptions) { + BlobId targetId, Map targetOptions) { this.serviceOptions = options; this.source = source; this.sourceOptions = sourceOptions; - this.target = target; + this.targetId = targetId; this.targetOptions = targetOptions; } + Builder targetInfo(BlobInfo targetInfo) { + this.targetInfo = targetInfo; + return this; + } + Builder result(BlobInfo result) { this.result = result; return this; @@ -220,15 +232,16 @@ RestorableState build() { } static Builder builder(StorageOptions options, BlobId source, - Map sourceOptions, BlobInfo target, + Map sourceOptions, BlobId targetId, Map targetOptions) { - return new Builder(options, source, sourceOptions, target, targetOptions); + return new Builder(options, source, sourceOptions, targetId, targetOptions); } @Override public CopyWriter restore() { - RewriteRequest rewriteRequest = new RewriteRequest( - source.toPb(), sourceOptions, target.toPb(), targetOptions, megabytesCopiedPerChunk); + RewriteRequest rewriteRequest = new RewriteRequest(source.toPb(), sourceOptions, + targetId.bucket(), targetId.name(), targetInfo != null ? targetInfo.toPb() : null, + targetOptions, megabytesCopiedPerChunk); RewriteResponse rewriteResponse = new RewriteResponse(rewriteRequest, result != null ? result.toPb() : null, blobSize, isDone, rewriteToken, totalBytesCopied); @@ -237,8 +250,9 @@ public CopyWriter restore() { @Override public int hashCode() { - return Objects.hash(serviceOptions, source, sourceOptions, target, targetOptions, result, - blobSize, isDone, megabytesCopiedPerChunk, rewriteToken, totalBytesCopied); + return Objects.hash(serviceOptions, source, sourceOptions, targetId, targetInfo, + targetOptions, result, blobSize, isDone, megabytesCopiedPerChunk, rewriteToken, + totalBytesCopied); } @Override @@ -253,7 +267,8 @@ public boolean equals(Object obj) { return Objects.equals(this.serviceOptions, other.serviceOptions) && Objects.equals(this.source, other.source) && Objects.equals(this.sourceOptions, other.sourceOptions) - && Objects.equals(this.target, other.target) + && Objects.equals(this.targetId, other.targetId) + && Objects.equals(this.targetInfo, other.targetInfo) && Objects.equals(this.targetOptions, other.targetOptions) && Objects.equals(this.result, other.result) && Objects.equals(this.rewriteToken, other.rewriteToken) @@ -267,10 +282,14 @@ public boolean equals(Object obj) { public String toString() { return MoreObjects.toStringHelper(this) .add("source", source) - .add("target", target) - .add("isDone", isDone) - .add("totalBytesRewritten", totalBytesCopied) + .add("targetId", targetId) + .add("targetInfo", targetInfo) + .add("result", result) .add("blobSize", blobSize) + .add("isDone", isDone) + .add("rewriteToken", rewriteToken) + .add("totalBytesCopied", totalBytesCopied) + .add("megabytesCopiedPerChunk", megabytesCopiedPerChunk) .toString(); } } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index 35fc6117cbc2..8204f0105e7e 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -962,7 +962,8 @@ class CopyRequest implements Serializable { private final BlobId source; private final List sourceOptions; - private final BlobInfo target; + private final BlobId targetId; + private final BlobInfo targetInfo; private final List targetOptions; private final Long megabytesCopiedPerChunk; @@ -971,7 +972,8 @@ public static class Builder { private final Set sourceOptions = new LinkedHashSet<>(); private final Set targetOptions = new LinkedHashSet<>(); private BlobId source; - private BlobInfo target; + private BlobId targetId; + private BlobInfo targetInfo; private Long megabytesCopiedPerChunk; /** @@ -1019,39 +1021,37 @@ public Builder sourceOptions(Iterable options) { * * @return the builder */ - public Builder target(BlobId target) { - this.target = BlobInfo.builder(target).build(); + public Builder target(BlobId targetId) { + this.targetId = targetId; return this; } /** * Sets the copy target and target options. {@code target} parameter is used to override - * source blob information (e.g. {@code contentType}, {@code contentLanguage}). {@code - * target.contentType} is a required field. + * source blob information (e.g. {@code contentType}, {@code contentLanguage}). Target blob + * information is set exactly to {@code target}, no information is inherited from the source + * blob. If not set, target blob information is inherited from the source blob. * * @return the builder - * @throws IllegalArgumentException if {@code target.contentType} is {@code null} */ - public Builder target(BlobInfo target, BlobTargetOption... options) - throws IllegalArgumentException { - checkContentType(target); - this.target = target; + public Builder target(BlobInfo targetInfo, BlobTargetOption... options) { + this.targetId = targetInfo.blobId(); + this.targetInfo = targetInfo; Collections.addAll(targetOptions, options); return this; } /** * Sets the copy target and target options. {@code target} parameter is used to override - * source blob information (e.g. {@code contentType}, {@code contentLanguage}). {@code - * target.contentType} is a required field. + * source blob information (e.g. {@code contentType}, {@code contentLanguage}). Target blob + * information is set exactly to {@code target}, no information is inherited from the source + * blob. If not set, target blob information is inherited from the source blob. * * @return the builder - * @throws IllegalArgumentException if {@code target.contentType} is {@code null} */ - public Builder target(BlobInfo target, Iterable options) - throws IllegalArgumentException { - checkContentType(target); - this.target = target; + public Builder target(BlobInfo targetInfo, Iterable options) { + this.targetId = targetInfo.blobId(); + this.targetInfo = targetInfo; Iterables.addAll(targetOptions, options); return this; } @@ -1072,8 +1072,6 @@ public Builder megabytesCopiedPerChunk(Long megabytesCopiedPerChunk) { * Creates a {@code CopyRequest} object. */ public CopyRequest build() { - checkNotNull(source); - checkNotNull(target); return new CopyRequest(this); } } @@ -1081,7 +1079,8 @@ public CopyRequest build() { private CopyRequest(Builder builder) { source = checkNotNull(builder.source); sourceOptions = ImmutableList.copyOf(builder.sourceOptions); - target = checkNotNull(builder.target); + targetId = checkNotNull(builder.targetId); + targetInfo = builder.targetInfo; targetOptions = ImmutableList.copyOf(builder.targetOptions); megabytesCopiedPerChunk = builder.megabytesCopiedPerChunk; } @@ -1101,10 +1100,20 @@ public List sourceOptions() { } /** - * Returns the {@link BlobInfo} for the target blob. + * Returns the {@link BlobId} for the target blob. */ - public BlobInfo target() { - return target; + public BlobId targetId() { + return targetId; + } + + /** + * Returns the {@link BlobInfo} for the target blob. If set, this value is used to replace + * source blob information (e.g. {@code contentType}, {@code contentLanguage}). Target blob + * information is set exactly to this value, no information is inherited from the source blob. + * If not set, target blob information is inherited from the source blob. + */ + public BlobInfo targetInfo() { + return targetInfo; } /** @@ -1125,34 +1134,27 @@ public Long megabytesCopiedPerChunk() { /** * Creates a copy request. {@code target} parameter is used to override source blob information - * (e.g. {@code contentType}, {@code contentLanguage}). {@code target.contentType} is a required - * field. + * (e.g. {@code contentType}, {@code contentLanguage}). * * @param sourceBucket name of the bucket containing the source blob * @param sourceBlob name of the source blob * @param target a {@code BlobInfo} object for the target blob * @return a copy request - * @throws IllegalArgumentException if {@code target.contentType} is {@code null} */ - public static CopyRequest of(String sourceBucket, String sourceBlob, BlobInfo target) - throws IllegalArgumentException { - checkContentType(target); + public static CopyRequest of(String sourceBucket, String sourceBlob, BlobInfo target) { return builder().source(sourceBucket, sourceBlob).target(target).build(); } /** - * Creates a copy request. {@code target} parameter is used to override source blob information - * (e.g. {@code contentType}, {@code contentLanguage}). {@code target.contentType} is a required - * field. + * Creates a copy request. {@code target} parameter is used to replace source blob information + * (e.g. {@code contentType}, {@code contentLanguage}). Target blob information is set exactly + * to {@code target}, no information is inherited from the source blob. * * @param sourceBlobId a {@code BlobId} object for the source blob * @param target a {@code BlobInfo} object for the target blob * @return a copy request - * @throws IllegalArgumentException if {@code target.contentType} is {@code null} */ - public static CopyRequest of(BlobId sourceBlobId, BlobInfo target) - throws IllegalArgumentException { - checkContentType(target); + public static CopyRequest of(BlobId sourceBlobId, BlobInfo target) { return builder().source(sourceBlobId).target(target).build(); } @@ -1214,10 +1216,6 @@ public static CopyRequest of(BlobId sourceBlobId, BlobId targetBlobId) { public static Builder builder() { return new Builder(); } - - private static void checkContentType(BlobInfo blobInfo) throws IllegalArgumentException { - checkArgument(blobInfo.contentType() != null, "Blob content type can not be null"); - } } /** diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java index d58c9e43aea9..30c0046b802c 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java @@ -413,15 +413,20 @@ public CopyWriter copy(final CopyRequest copyRequest) { final StorageObject source = copyRequest.source().toPb(); final Map sourceOptions = optionMap(copyRequest.source().generation(), null, copyRequest.sourceOptions(), true); - final StorageObject target = copyRequest.target().toPb(); - final Map targetOptions = optionMap(copyRequest.target().generation(), - copyRequest.target().metageneration(), copyRequest.targetOptions()); + final BlobId targetId = copyRequest.targetId(); + final StorageObject targetObject = + copyRequest.targetInfo() != null ? copyRequest.targetInfo().toPb() : null; + final Map targetOptions = optionMap( + copyRequest.targetInfo() != null ? copyRequest.targetInfo().generation() : null, + copyRequest.targetInfo() != null ? copyRequest.targetInfo().metageneration() : null, + copyRequest.targetOptions()); try { RewriteResponse rewriteResponse = runWithRetries(new Callable() { @Override public RewriteResponse call() { - return storageRpc.openRewrite(new StorageRpc.RewriteRequest(source, sourceOptions, target, - targetOptions, copyRequest.megabytesCopiedPerChunk())); + return storageRpc.openRewrite(new StorageRpc.RewriteRequest(source, sourceOptions, + targetId.bucket(), targetId.name(), targetObject, targetOptions, + copyRequest.megabytesCopiedPerChunk())); } }, options().retryParams(), EXCEPTION_HANDLER); return new CopyWriter(options(), rewriteResponse); diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/DefaultStorageRpc.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/DefaultStorageRpc.java index 3f465e0ab20e..7f13212556aa 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/DefaultStorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/DefaultStorageRpc.java @@ -580,8 +580,8 @@ private RewriteResponse rewrite(RewriteRequest req, String token) { Long maxBytesRewrittenPerCall = req.megabytesRewrittenPerCall != null ? req.megabytesRewrittenPerCall * MEGABYTE : null; com.google.api.services.storage.model.RewriteResponse rewriteResponse = storage.objects() - .rewrite(req.source.getBucket(), req.source.getName(), req.target.getBucket(), - req.target.getName(), req.target.getContentType() != null ? req.target : null) + .rewrite(req.source.getBucket(), req.source.getName(), req.targetBucket, + req.targetName, req.targetObject) .setSourceGeneration(req.source.getGeneration()) .setRewriteToken(token) .setMaxBytesRewrittenPerCall(maxBytesRewrittenPerCall) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/StorageRpc.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/StorageRpc.java index d239a475a6dd..7256368e189f 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/StorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/StorageRpc.java @@ -138,16 +138,20 @@ class RewriteRequest { public final StorageObject source; public final Map sourceOptions; - public final StorageObject target; + public final String targetBucket; + public final String targetName; + public final StorageObject targetObject; public final Map targetOptions; public final Long megabytesRewrittenPerCall; public RewriteRequest(StorageObject source, Map sourceOptions, - StorageObject target, Map targetOptions, - Long megabytesRewrittenPerCall) { + String targetBucket, String targetName, StorageObject targetObject, + Map targetOptions, Long megabytesRewrittenPerCall) { this.source = source; this.sourceOptions = sourceOptions; - this.target = target; + this.targetBucket = targetBucket; + this.targetName = targetName; + this.targetObject = targetObject; this.targetOptions = targetOptions; this.megabytesRewrittenPerCall = megabytesRewrittenPerCall; } @@ -163,14 +167,17 @@ public boolean equals(Object obj) { final RewriteRequest other = (RewriteRequest) obj; return Objects.equals(this.source, other.source) && Objects.equals(this.sourceOptions, other.sourceOptions) - && Objects.equals(this.target, other.target) + && Objects.equals(this.targetBucket, other.targetBucket) + && Objects.equals(this.targetName, other.targetName) + && Objects.equals(this.targetObject, other.targetObject) && Objects.equals(this.targetOptions, other.targetOptions) && Objects.equals(this.megabytesRewrittenPerCall, other.megabytesRewrittenPerCall); } @Override public int hashCode() { - return Objects.hash(source, sourceOptions, target, targetOptions, megabytesRewrittenPerCall); + return Objects.hash(source, sourceOptions, targetBucket, targetName, targetObject, + targetOptions, megabytesRewrittenPerCall); } } diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java index 5a6173c08199..2d4920816c38 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java @@ -222,7 +222,6 @@ public void testDelete() throws Exception { @Test public void testCopyToBucket() throws Exception { initializeExpectedBlob(2); - BlobInfo target = BlobInfo.builder(BlobId.of("bt", "n")).build(); CopyWriter copyWriter = createMock(CopyWriter.class); Capture capturedCopyRequest = Capture.newInstance(); expect(storage.options()).andReturn(mockOptions); @@ -232,7 +231,8 @@ public void testCopyToBucket() throws Exception { CopyWriter returnedCopyWriter = blob.copyTo("bt"); assertEquals(copyWriter, returnedCopyWriter); assertEquals(capturedCopyRequest.getValue().source(), blob.blobId()); - assertEquals(capturedCopyRequest.getValue().target(), target); + assertEquals(capturedCopyRequest.getValue().targetId(), BlobId.of("bt", "n")); + assertNull(capturedCopyRequest.getValue().targetInfo()); assertTrue(capturedCopyRequest.getValue().sourceOptions().isEmpty()); assertTrue(capturedCopyRequest.getValue().targetOptions().isEmpty()); } @@ -240,7 +240,6 @@ public void testCopyToBucket() throws Exception { @Test public void testCopyTo() throws Exception { initializeExpectedBlob(2); - BlobInfo target = BlobInfo.builder(BlobId.of("bt", "nt")).build(); CopyWriter copyWriter = createMock(CopyWriter.class); Capture capturedCopyRequest = Capture.newInstance(); expect(storage.options()).andReturn(mockOptions); @@ -250,7 +249,8 @@ public void testCopyTo() throws Exception { CopyWriter returnedCopyWriter = blob.copyTo("bt", "nt"); assertEquals(copyWriter, returnedCopyWriter); assertEquals(capturedCopyRequest.getValue().source(), blob.blobId()); - assertEquals(capturedCopyRequest.getValue().target(), target); + assertEquals(capturedCopyRequest.getValue().targetId(), BlobId.of("bt", "nt")); + assertNull(capturedCopyRequest.getValue().targetInfo()); assertTrue(capturedCopyRequest.getValue().sourceOptions().isEmpty()); assertTrue(capturedCopyRequest.getValue().targetOptions().isEmpty()); } @@ -260,7 +260,6 @@ public void testCopyToBlobId() throws Exception { initializeExpectedBlob(2); BlobId targetId = BlobId.of("bt", "nt"); CopyWriter copyWriter = createMock(CopyWriter.class); - BlobInfo target = BlobInfo.builder(targetId).build(); Capture capturedCopyRequest = Capture.newInstance(); expect(storage.options()).andReturn(mockOptions); expect(storage.copy(capture(capturedCopyRequest))).andReturn(copyWriter); @@ -269,7 +268,8 @@ public void testCopyToBlobId() throws Exception { CopyWriter returnedCopyWriter = blob.copyTo(targetId); assertEquals(copyWriter, returnedCopyWriter); assertEquals(capturedCopyRequest.getValue().source(), blob.blobId()); - assertEquals(capturedCopyRequest.getValue().target(), target); + assertEquals(capturedCopyRequest.getValue().targetId(), targetId); + assertNull(capturedCopyRequest.getValue().targetInfo()); assertTrue(capturedCopyRequest.getValue().sourceOptions().isEmpty()); assertTrue(capturedCopyRequest.getValue().targetOptions().isEmpty()); } diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyRequestTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyRequestTest.java index b7e8d14e53a1..5700ea804cd6 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyRequestTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyRequestTest.java @@ -18,6 +18,7 @@ import static com.google.gcloud.storage.Storage.PredefinedAcl.PUBLIC_READ; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import com.google.common.collect.ImmutableList; import com.google.gcloud.storage.Storage.BlobSourceOption; @@ -52,7 +53,8 @@ public void testCopyRequest() { assertEquals(SOURCE_BLOB_ID, copyRequest1.source()); assertEquals(1, copyRequest1.sourceOptions().size()); assertEquals(BlobSourceOption.generationMatch(1), copyRequest1.sourceOptions().get(0)); - assertEquals(TARGET_BLOB_INFO, copyRequest1.target()); + assertEquals(TARGET_BLOB_INFO.blobId(), copyRequest1.targetId()); + assertEquals(TARGET_BLOB_INFO, copyRequest1.targetInfo()); assertEquals(1, copyRequest1.targetOptions().size()); assertEquals(BlobTargetOption.predefinedAcl(PUBLIC_READ), copyRequest1.targetOptions().get(0)); @@ -61,14 +63,16 @@ public void testCopyRequest() { .target(TARGET_BLOB_ID) .build(); assertEquals(SOURCE_BLOB_ID, copyRequest2.source()); - assertEquals(BlobInfo.builder(TARGET_BLOB_ID).build(), copyRequest2.target()); + assertEquals(TARGET_BLOB_ID, copyRequest2.targetId()); + assertNull(copyRequest2.targetInfo()); Storage.CopyRequest copyRequest3 = Storage.CopyRequest.builder() .source(SOURCE_BLOB_ID) .target(TARGET_BLOB_INFO, ImmutableList.of(BlobTargetOption.predefinedAcl(PUBLIC_READ))) .build(); assertEquals(SOURCE_BLOB_ID, copyRequest3.source()); - assertEquals(TARGET_BLOB_INFO, copyRequest3.target()); + assertEquals(TARGET_BLOB_INFO.blobId(), copyRequest3.targetId()); + assertEquals(TARGET_BLOB_INFO, copyRequest3.targetInfo()); assertEquals(ImmutableList.of(BlobTargetOption.predefinedAcl(PUBLIC_READ)), copyRequest3.targetOptions()); } @@ -77,53 +81,34 @@ public void testCopyRequest() { public void testCopyRequestOf() { Storage.CopyRequest copyRequest1 = Storage.CopyRequest.of(SOURCE_BLOB_ID, TARGET_BLOB_INFO); assertEquals(SOURCE_BLOB_ID, copyRequest1.source()); - assertEquals(TARGET_BLOB_INFO, copyRequest1.target()); + assertEquals(TARGET_BLOB_INFO.blobId(), copyRequest1.targetId()); + assertEquals(TARGET_BLOB_INFO, copyRequest1.targetInfo()); Storage.CopyRequest copyRequest2 = Storage.CopyRequest.of(SOURCE_BLOB_ID, TARGET_BLOB_NAME); assertEquals(SOURCE_BLOB_ID, copyRequest2.source()); - assertEquals(BlobInfo.builder(SOURCE_BUCKET_NAME, TARGET_BLOB_NAME).build(), - copyRequest2.target()); + assertEquals(BlobId.of(SOURCE_BUCKET_NAME, TARGET_BLOB_NAME), copyRequest2.targetId()); + assertNull(copyRequest2.targetInfo()); Storage.CopyRequest copyRequest3 = Storage.CopyRequest.of(SOURCE_BUCKET_NAME, SOURCE_BLOB_NAME, TARGET_BLOB_INFO); assertEquals(SOURCE_BLOB_ID, copyRequest3.source()); - assertEquals(TARGET_BLOB_INFO, copyRequest3.target()); + assertEquals(TARGET_BLOB_INFO.blobId(), copyRequest3.targetId()); + assertEquals(TARGET_BLOB_INFO, copyRequest3.targetInfo()); Storage.CopyRequest copyRequest4 = Storage.CopyRequest.of(SOURCE_BUCKET_NAME, SOURCE_BLOB_NAME, TARGET_BLOB_NAME); assertEquals(SOURCE_BLOB_ID, copyRequest4.source()); - assertEquals(BlobInfo.builder(SOURCE_BUCKET_NAME, TARGET_BLOB_NAME).build(), - copyRequest4.target()); + assertEquals(BlobId.of(SOURCE_BUCKET_NAME, TARGET_BLOB_NAME), copyRequest4.targetId()); + assertNull(copyRequest4.targetInfo()); Storage.CopyRequest copyRequest5 = Storage.CopyRequest.of(SOURCE_BLOB_ID, TARGET_BLOB_ID); assertEquals(SOURCE_BLOB_ID, copyRequest5.source()); - assertEquals(BlobInfo.builder(TARGET_BLOB_ID).build(), copyRequest5.target()); + assertEquals(TARGET_BLOB_ID, copyRequest5.targetId()); + assertNull(copyRequest5.targetInfo()); Storage.CopyRequest copyRequest6 = Storage.CopyRequest.of(SOURCE_BUCKET_NAME, SOURCE_BLOB_NAME, TARGET_BLOB_ID); assertEquals(SOURCE_BLOB_ID, copyRequest6.source()); - assertEquals(BlobInfo.builder(TARGET_BLOB_ID).build(), copyRequest6.target()); - } - - @Test - public void testCopyRequestFail() { - thrown.expect(IllegalArgumentException.class); - Storage.CopyRequest.builder() - .source(SOURCE_BLOB_ID) - .target(BlobInfo.builder(TARGET_BLOB_ID).build()) - .build(); - } - - @Test - public void testCopyRequestOfBlobInfoFail() { - thrown.expect(IllegalArgumentException.class); - Storage.CopyRequest.of(SOURCE_BLOB_ID, BlobInfo.builder(TARGET_BLOB_ID).build()); - } - - @Test - public void testCopyRequestOfStringFail() { - thrown.expect(IllegalArgumentException.class); - Storage.CopyRequest.of( - SOURCE_BUCKET_NAME, SOURCE_BLOB_NAME, BlobInfo.builder(TARGET_BLOB_ID).build()); - } + assertEquals(TARGET_BLOB_ID, copyRequest6.targetId()); + assertNull(copyRequest6.targetInfo()); } } diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyWriterTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyWriterTest.java index ad4a04c34127..75b863075770 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyWriterTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyWriterTest.java @@ -48,20 +48,29 @@ public class CopyWriterTest { private static final BlobId BLOB_ID = BlobId.of(SOURCE_BUCKET_NAME, SOURCE_BLOB_NAME); private static final BlobInfo BLOB_INFO = BlobInfo.builder(DESTINATION_BUCKET_NAME, DESTINATION_BLOB_NAME).build(); - private static final BlobInfo RESULT = + private static final BlobInfo RESULT_INFO = BlobInfo.builder(DESTINATION_BUCKET_NAME, DESTINATION_BLOB_NAME).contentType("type").build(); private static final Map EMPTY_OPTIONS = ImmutableMap.of(); - private static final RewriteRequest REQUEST = new StorageRpc.RewriteRequest(BLOB_ID.toPb(), - EMPTY_OPTIONS, BLOB_INFO.toPb(), EMPTY_OPTIONS, null); - private static final RewriteResponse RESPONSE = new StorageRpc.RewriteResponse(REQUEST, - null, 42L, false, "token", 21L); - private static final RewriteResponse RESPONSE_DONE = new StorageRpc.RewriteResponse(REQUEST, - RESULT.toPb(), 42L, true, "token", 42L); + private static final RewriteRequest REQUEST_WITH_OBJECT = + new StorageRpc.RewriteRequest(BLOB_ID.toPb(), EMPTY_OPTIONS, DESTINATION_BUCKET_NAME, + DESTINATION_BLOB_NAME, BLOB_INFO.toPb(), EMPTY_OPTIONS, null); + private static final RewriteRequest REQUEST_WITHOUT_OBJECT = + new StorageRpc.RewriteRequest(BLOB_ID.toPb(), EMPTY_OPTIONS, DESTINATION_BUCKET_NAME, + DESTINATION_BLOB_NAME, null, EMPTY_OPTIONS, null); + private static final RewriteResponse RESPONSE_WITH_OBJECT = new RewriteResponse( + REQUEST_WITH_OBJECT, null, 42L, false, "token", 21L); + private static final RewriteResponse RESPONSE_WITHOUT_OBJECT = new RewriteResponse( + REQUEST_WITHOUT_OBJECT, null, 42L, false, "token", 21L); + private static final RewriteResponse RESPONSE_WITH_OBJECT_DONE = + new RewriteResponse(REQUEST_WITH_OBJECT, RESULT_INFO.toPb(), 42L, true, "token", 42L); + private static final RewriteResponse RESPONSE_WITHOUT_OBJECT_DONE = + new RewriteResponse(REQUEST_WITHOUT_OBJECT, RESULT_INFO.toPb(), 42L, true, "token", 42L); private StorageOptions options; private StorageRpcFactory rpcFactoryMock; private StorageRpc storageRpcMock; private CopyWriter copyWriter; + private Blob result; @Before public void setUp() { @@ -75,6 +84,7 @@ public void setUp() { .serviceRpcFactory(rpcFactoryMock) .retryParams(RetryParams.noRetries()) .build(); + result = new Blob(options.service(), new BlobInfo.BuilderImpl(RESULT_INFO)); } @After @@ -83,41 +93,111 @@ public void tearDown() throws Exception { } @Test - public void testRewrite() { - EasyMock.expect(storageRpcMock.continueRewrite(RESPONSE)).andReturn(RESPONSE_DONE); + public void testRewriteWithObject() { + EasyMock.expect(storageRpcMock.continueRewrite(RESPONSE_WITH_OBJECT)) + .andReturn(RESPONSE_WITH_OBJECT_DONE); EasyMock.replay(storageRpcMock); - copyWriter = new CopyWriter(options, RESPONSE); - assertEquals(RESULT, copyWriter.result()); + copyWriter = new CopyWriter(options, RESPONSE_WITH_OBJECT); + assertEquals(result, copyWriter.result()); assertTrue(copyWriter.isDone()); assertEquals(42L, copyWriter.totalBytesCopied()); assertEquals(42L, copyWriter.blobSize()); } @Test - public void testRewriteMultipleRequests() { - EasyMock.expect(storageRpcMock.continueRewrite(RESPONSE)).andReturn(RESPONSE); - EasyMock.expect(storageRpcMock.continueRewrite(RESPONSE)).andReturn(RESPONSE_DONE); + public void testRewriteWithoutObject() { + EasyMock.expect(storageRpcMock.continueRewrite(RESPONSE_WITHOUT_OBJECT)) + .andReturn(RESPONSE_WITHOUT_OBJECT_DONE); EasyMock.replay(storageRpcMock); - copyWriter = new CopyWriter(options, RESPONSE); - assertEquals(RESULT, copyWriter.result()); + copyWriter = new CopyWriter(options, RESPONSE_WITHOUT_OBJECT); + assertEquals(result, copyWriter.result()); assertTrue(copyWriter.isDone()); assertEquals(42L, copyWriter.totalBytesCopied()); assertEquals(42L, copyWriter.blobSize()); } @Test - public void testSaveAndRestore() { - EasyMock.expect(storageRpcMock.continueRewrite(RESPONSE)).andReturn(RESPONSE); - EasyMock.expect(storageRpcMock.continueRewrite(RESPONSE)).andReturn(RESPONSE_DONE); + public void testRewriteWithObjectMultipleRequests() { + EasyMock.expect(storageRpcMock.continueRewrite(RESPONSE_WITH_OBJECT)) + .andReturn(RESPONSE_WITH_OBJECT); + EasyMock.expect(storageRpcMock.continueRewrite(RESPONSE_WITH_OBJECT)) + .andReturn(RESPONSE_WITH_OBJECT_DONE); EasyMock.replay(storageRpcMock); - copyWriter = new CopyWriter(options, RESPONSE); + copyWriter = new CopyWriter(options, RESPONSE_WITH_OBJECT); + assertEquals(result, copyWriter.result()); + assertTrue(copyWriter.isDone()); + assertEquals(42L, copyWriter.totalBytesCopied()); + assertEquals(42L, copyWriter.blobSize()); + } + + @Test + public void testRewriteWithoutObjectMultipleRequests() { + EasyMock.expect(storageRpcMock.continueRewrite(RESPONSE_WITHOUT_OBJECT)) + .andReturn(RESPONSE_WITHOUT_OBJECT); + EasyMock.expect(storageRpcMock.continueRewrite(RESPONSE_WITHOUT_OBJECT)) + .andReturn(RESPONSE_WITHOUT_OBJECT_DONE); + EasyMock.replay(storageRpcMock); + copyWriter = new CopyWriter(options, RESPONSE_WITHOUT_OBJECT); + assertEquals(result, copyWriter.result()); + assertTrue(copyWriter.isDone()); + assertEquals(42L, copyWriter.totalBytesCopied()); + assertEquals(42L, copyWriter.blobSize()); + } + + @Test + public void testSaveAndRestoreWithObject() { + EasyMock.expect(storageRpcMock.continueRewrite(RESPONSE_WITH_OBJECT)) + .andReturn(RESPONSE_WITH_OBJECT); + EasyMock.expect(storageRpcMock.continueRewrite(RESPONSE_WITH_OBJECT)) + .andReturn(RESPONSE_WITH_OBJECT_DONE); + EasyMock.replay(storageRpcMock); + copyWriter = new CopyWriter(options, RESPONSE_WITH_OBJECT); + copyWriter.copyChunk(); + assertTrue(!copyWriter.isDone()); + assertEquals(21L, copyWriter.totalBytesCopied()); + assertEquals(42L, copyWriter.blobSize()); + RestorableState rewriterState = copyWriter.capture(); + CopyWriter restoredRewriter = rewriterState.restore(); + assertEquals(result, restoredRewriter.result()); + assertTrue(restoredRewriter.isDone()); + assertEquals(42L, restoredRewriter.totalBytesCopied()); + assertEquals(42L, restoredRewriter.blobSize()); + } + + @Test + public void testSaveAndRestoreWithoutObject() { + EasyMock.expect(storageRpcMock.continueRewrite(RESPONSE_WITHOUT_OBJECT)) + .andReturn(RESPONSE_WITHOUT_OBJECT); + EasyMock.expect(storageRpcMock.continueRewrite(RESPONSE_WITHOUT_OBJECT)) + .andReturn(RESPONSE_WITHOUT_OBJECT_DONE); + EasyMock.replay(storageRpcMock); + copyWriter = new CopyWriter(options, RESPONSE_WITHOUT_OBJECT); copyWriter.copyChunk(); assertTrue(!copyWriter.isDone()); assertEquals(21L, copyWriter.totalBytesCopied()); assertEquals(42L, copyWriter.blobSize()); RestorableState rewriterState = copyWriter.capture(); CopyWriter restoredRewriter = rewriterState.restore(); - assertEquals(RESULT, restoredRewriter.result()); + assertEquals(result, restoredRewriter.result()); + assertTrue(restoredRewriter.isDone()); + assertEquals(42L, restoredRewriter.totalBytesCopied()); + assertEquals(42L, restoredRewriter.blobSize()); + } + + @Test + public void testSaveAndRestoreWithResult() { + EasyMock.expect(storageRpcMock.continueRewrite(RESPONSE_WITH_OBJECT)) + .andReturn(RESPONSE_WITH_OBJECT_DONE); + EasyMock.replay(storageRpcMock); + copyWriter = new CopyWriter(options, RESPONSE_WITH_OBJECT); + copyWriter.copyChunk(); + assertEquals(result, copyWriter.result()); + assertTrue(copyWriter.isDone()); + assertEquals(42L, copyWriter.totalBytesCopied()); + assertEquals(42L, copyWriter.blobSize()); + RestorableState rewriterState = copyWriter.capture(); + CopyWriter restoredRewriter = rewriterState.restore(); + assertEquals(result, restoredRewriter.result()); assertTrue(restoredRewriter.isDone()); assertEquals(42L, restoredRewriter.totalBytesCopied()); assertEquals(42L, restoredRewriter.blobSize()); diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java index 38b4bb58e77f..db1166598237 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java @@ -866,7 +866,8 @@ public void testComposeWithOptions() { public void testCopy() { CopyRequest request = Storage.CopyRequest.of(BLOB_INFO1.blobId(), BLOB_INFO2.blobId()); StorageRpc.RewriteRequest rpcRequest = new StorageRpc.RewriteRequest(request.source().toPb(), - EMPTY_RPC_OPTIONS, request.target().toPb(), EMPTY_RPC_OPTIONS, null); + EMPTY_RPC_OPTIONS, BLOB_INFO2.blobId().bucket(), BLOB_INFO2.blobId().name(), null, + EMPTY_RPC_OPTIONS, null); StorageRpc.RewriteResponse rpcResponse = new StorageRpc.RewriteResponse(rpcRequest, null, 42L, false, "token", 21L); EasyMock.expect(storageRpcMock.openRewrite(rpcRequest)).andReturn(rpcResponse); @@ -886,7 +887,8 @@ public void testCopyWithOptions() { .target(BLOB_INFO1, BLOB_TARGET_GENERATION, BLOB_TARGET_METAGENERATION) .build(); StorageRpc.RewriteRequest rpcRequest = new StorageRpc.RewriteRequest(request.source().toPb(), - BLOB_SOURCE_OPTIONS_COPY, request.target().toPb(), BLOB_TARGET_OPTIONS_COMPOSE, null); + BLOB_SOURCE_OPTIONS_COPY, BLOB_INFO1.blobId().bucket(), BLOB_INFO1.blobId().name(), + request.targetInfo().toPb(), BLOB_TARGET_OPTIONS_COMPOSE, null); StorageRpc.RewriteResponse rpcResponse = new StorageRpc.RewriteResponse(rpcRequest, null, 42L, false, "token", 21L); EasyMock.expect(storageRpcMock.openRewrite(rpcRequest)).andReturn(rpcResponse); @@ -906,7 +908,8 @@ public void testCopyWithOptionsFromBlobId() { .target(BLOB_INFO1, BLOB_TARGET_GENERATION, BLOB_TARGET_METAGENERATION) .build(); StorageRpc.RewriteRequest rpcRequest = new StorageRpc.RewriteRequest(request.source().toPb(), - BLOB_SOURCE_OPTIONS_COPY, request.target().toPb(), BLOB_TARGET_OPTIONS_COMPOSE, null); + BLOB_SOURCE_OPTIONS_COPY, BLOB_INFO1.blobId().bucket(), BLOB_INFO1.blobId().name(), + request.targetInfo().toPb(), BLOB_TARGET_OPTIONS_COMPOSE, null); StorageRpc.RewriteResponse rpcResponse = new StorageRpc.RewriteResponse(rpcRequest, null, 42L, false, "token", 21L); EasyMock.expect(storageRpcMock.openRewrite(rpcRequest)).andReturn(rpcResponse); @@ -922,7 +925,8 @@ public void testCopyWithOptionsFromBlobId() { public void testCopyMultipleRequests() { CopyRequest request = Storage.CopyRequest.of(BLOB_INFO1.blobId(), BLOB_INFO2.blobId()); StorageRpc.RewriteRequest rpcRequest = new StorageRpc.RewriteRequest(request.source().toPb(), - EMPTY_RPC_OPTIONS, request.target().toPb(), EMPTY_RPC_OPTIONS, null); + EMPTY_RPC_OPTIONS, BLOB_INFO2.blobId().bucket(), BLOB_INFO2.blobId().name(), null, + EMPTY_RPC_OPTIONS, null); StorageRpc.RewriteResponse rpcResponse1 = new StorageRpc.RewriteResponse(rpcRequest, null, 42L, false, "token", 21L); StorageRpc.RewriteResponse rpcResponse2 = new StorageRpc.RewriteResponse(rpcRequest, @@ -935,7 +939,7 @@ public void testCopyMultipleRequests() { assertEquals(42L, writer.blobSize()); assertEquals(21L, writer.totalBytesCopied()); assertTrue(!writer.isDone()); - assertEquals(BLOB_INFO1, writer.result()); + assertEquals(expectedBlob1, writer.result()); assertTrue(writer.isDone()); assertEquals(42L, writer.totalBytesCopied()); assertEquals(42L, writer.blobSize()); diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java index 563a621c48fb..13d768442c34 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java @@ -599,6 +599,37 @@ public void testComposeBlob() { assertNotNull(remoteTargetBlob); assertEquals(targetBlob.name(), remoteTargetBlob.name()); assertEquals(targetBlob.bucket(), remoteTargetBlob.bucket()); + assertNull(remoteTargetBlob.contentType()); + byte[] readBytes = storage.readAllBytes(BUCKET, targetBlobName); + byte[] composedBytes = Arrays.copyOf(BLOB_BYTE_CONTENT, BLOB_BYTE_CONTENT.length * 2); + System.arraycopy(BLOB_BYTE_CONTENT, 0, composedBytes, BLOB_BYTE_CONTENT.length, + BLOB_BYTE_CONTENT.length); + assertArrayEquals(composedBytes, readBytes); + assertTrue(remoteSourceBlob1.delete()); + assertTrue(remoteSourceBlob2.delete()); + assertTrue(remoteTargetBlob.delete()); + } + + @Test + public void testComposeBlobWithContentType() { + String sourceBlobName1 = "test-compose-blob-with-content-type-source-1"; + String sourceBlobName2 = "test-compose-blob-with-content-type-source-2"; + BlobInfo sourceBlob1 = BlobInfo.builder(BUCKET, sourceBlobName1).build(); + BlobInfo sourceBlob2 = BlobInfo.builder(BUCKET, sourceBlobName2).build(); + Blob remoteSourceBlob1 = storage.create(sourceBlob1, BLOB_BYTE_CONTENT); + Blob remoteSourceBlob2 = storage.create(sourceBlob2, BLOB_BYTE_CONTENT); + assertNotNull(remoteSourceBlob1); + assertNotNull(remoteSourceBlob2); + String targetBlobName = "test-compose-blob-with-content-type-target"; + BlobInfo targetBlob = + BlobInfo.builder(BUCKET, targetBlobName).contentType(CONTENT_TYPE).build(); + Storage.ComposeRequest req = + Storage.ComposeRequest.of(ImmutableList.of(sourceBlobName1, sourceBlobName2), targetBlob); + Blob remoteTargetBlob = storage.compose(req); + assertNotNull(remoteTargetBlob); + assertEquals(targetBlob.name(), remoteTargetBlob.name()); + assertEquals(targetBlob.bucket(), remoteTargetBlob.bucket()); + assertEquals(CONTENT_TYPE, remoteTargetBlob.contentType()); byte[] readBytes = storage.readAllBytes(BUCKET, targetBlobName); byte[] composedBytes = Arrays.copyOf(BLOB_BYTE_CONTENT, BLOB_BYTE_CONTENT.length * 2); System.arraycopy(BLOB_BYTE_CONTENT, 0, composedBytes, BLOB_BYTE_CONTENT.length, @@ -682,6 +713,26 @@ public void testCopyBlobUpdateMetadata() { assertTrue(storage.delete(BUCKET, targetBlobName)); } + @Test + public void testCopyBlobNoContentType() { + String sourceBlobName = "test-copy-blob-no-content-type-source"; + BlobId source = BlobId.of(BUCKET, sourceBlobName); + Blob remoteSourceBlob = storage.create(BlobInfo.builder(source).build(), BLOB_BYTE_CONTENT); + assertNotNull(remoteSourceBlob); + String targetBlobName = "test-copy-blob-no-content-type-target"; + ImmutableMap metadata = ImmutableMap.of("k", "v"); + BlobInfo target = BlobInfo.builder(BUCKET, targetBlobName).metadata(metadata).build(); + Storage.CopyRequest req = Storage.CopyRequest.of(source, target); + CopyWriter copyWriter = storage.copy(req); + assertEquals(BUCKET, copyWriter.result().bucket()); + assertEquals(targetBlobName, copyWriter.result().name()); + assertNull(copyWriter.result().contentType()); + assertEquals(metadata, copyWriter.result().metadata()); + assertTrue(copyWriter.isDone()); + assertTrue(remoteSourceBlob.delete()); + assertTrue(storage.delete(BUCKET, targetBlobName)); + } + @Test public void testCopyBlobFail() { String sourceBlobName = "test-copy-blob-source-fail"; From 3e5db7a87013d677d179d6d484448fcae3cbdbc6 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Sun, 20 Mar 2016 21:05:16 +0100 Subject: [PATCH 185/375] Refactor CopyRequest: remove targetId, add boolean overrideInfo --- .../com/google/gcloud/storage/CopyWriter.java | 47 ++++++++--------- .../com/google/gcloud/storage/Storage.java | 50 ++++++++++--------- .../google/gcloud/storage/StorageImpl.java | 12 ++--- .../gcloud/storage/spi/DefaultStorageRpc.java | 4 +- .../google/gcloud/storage/spi/StorageRpc.java | 23 ++++----- .../com/google/gcloud/storage/BlobTest.java | 15 +++--- .../gcloud/storage/CopyRequestTest.java | 42 +++++++++------- .../google/gcloud/storage/CopyWriterTest.java | 8 +-- .../gcloud/storage/StorageImplTest.java | 12 ++--- 9 files changed, 102 insertions(+), 111 deletions(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java index 38d9c0d5e952..26c728942a28 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java @@ -120,11 +120,9 @@ public RestorableState capture() { serviceOptions, BlobId.fromPb(rewriteResponse.rewriteRequest.source), rewriteResponse.rewriteRequest.sourceOptions, - BlobId.of(rewriteResponse.rewriteRequest.targetBucket, - rewriteResponse.rewriteRequest.targetName), + rewriteResponse.rewriteRequest.overrideInfo, + BlobInfo.fromPb(rewriteResponse.rewriteRequest.target), rewriteResponse.rewriteRequest.targetOptions) - .targetInfo(rewriteResponse.rewriteRequest.targetObject != null - ? BlobInfo.fromPb(rewriteResponse.rewriteRequest.targetObject) : null) .result(rewriteResponse.result != null ? BlobInfo.fromPb(rewriteResponse.result) : null) .blobSize(blobSize()) .isDone(isDone()) @@ -141,8 +139,8 @@ static class StateImpl implements RestorableState, Serializable { private final StorageOptions serviceOptions; private final BlobId source; private final Map sourceOptions; - private final BlobId targetId; - private final BlobInfo targetInfo; + private final boolean overrideInfo; + private final BlobInfo target; private final Map targetOptions; private final BlobInfo result; private final long blobSize; @@ -155,8 +153,8 @@ static class StateImpl implements RestorableState, Serializable { this.serviceOptions = builder.serviceOptions; this.source = builder.source; this.sourceOptions = builder.sourceOptions; - this.targetId = builder.targetId; - this.targetInfo = builder.targetInfo; + this.overrideInfo = builder.overrideInfo; + this.target = builder.target; this.targetOptions = builder.targetOptions; this.result = builder.result; this.blobSize = builder.blobSize; @@ -171,9 +169,9 @@ static class Builder { private final StorageOptions serviceOptions; private final BlobId source; private final Map sourceOptions; - private final BlobId targetId; + private final boolean overrideInfo; + private BlobInfo target; private final Map targetOptions; - private BlobInfo targetInfo; private BlobInfo result; private long blobSize; private boolean isDone; @@ -182,20 +180,16 @@ static class Builder { private Long megabytesCopiedPerChunk; private Builder(StorageOptions options, BlobId source, - Map sourceOptions, - BlobId targetId, Map targetOptions) { + Map sourceOptions, boolean overrideInfo, BlobInfo target, + Map targetOptions) { this.serviceOptions = options; this.source = source; this.sourceOptions = sourceOptions; - this.targetId = targetId; + this.overrideInfo = overrideInfo; + this.target = target; this.targetOptions = targetOptions; } - Builder targetInfo(BlobInfo targetInfo) { - this.targetInfo = targetInfo; - return this; - } - Builder result(BlobInfo result) { this.result = result; return this; @@ -232,16 +226,15 @@ RestorableState build() { } static Builder builder(StorageOptions options, BlobId source, - Map sourceOptions, BlobId targetId, + Map sourceOptions, boolean overrideInfo, BlobInfo target, Map targetOptions) { - return new Builder(options, source, sourceOptions, targetId, targetOptions); + return new Builder(options, source, sourceOptions, overrideInfo, target, targetOptions); } @Override public CopyWriter restore() { RewriteRequest rewriteRequest = new RewriteRequest(source.toPb(), sourceOptions, - targetId.bucket(), targetId.name(), targetInfo != null ? targetInfo.toPb() : null, - targetOptions, megabytesCopiedPerChunk); + overrideInfo, target.toPb(), targetOptions, megabytesCopiedPerChunk); RewriteResponse rewriteResponse = new RewriteResponse(rewriteRequest, result != null ? result.toPb() : null, blobSize, isDone, rewriteToken, totalBytesCopied); @@ -250,7 +243,7 @@ public CopyWriter restore() { @Override public int hashCode() { - return Objects.hash(serviceOptions, source, sourceOptions, targetId, targetInfo, + return Objects.hash(serviceOptions, source, sourceOptions, overrideInfo, target, targetOptions, result, blobSize, isDone, megabytesCopiedPerChunk, rewriteToken, totalBytesCopied); } @@ -267,8 +260,8 @@ public boolean equals(Object obj) { return Objects.equals(this.serviceOptions, other.serviceOptions) && Objects.equals(this.source, other.source) && Objects.equals(this.sourceOptions, other.sourceOptions) - && Objects.equals(this.targetId, other.targetId) - && Objects.equals(this.targetInfo, other.targetInfo) + && Objects.equals(this.overrideInfo, other.overrideInfo) + && Objects.equals(this.target, other.target) && Objects.equals(this.targetOptions, other.targetOptions) && Objects.equals(this.result, other.result) && Objects.equals(this.rewriteToken, other.rewriteToken) @@ -282,8 +275,8 @@ public boolean equals(Object obj) { public String toString() { return MoreObjects.toStringHelper(this) .add("source", source) - .add("targetId", targetId) - .add("targetInfo", targetInfo) + .add("overrideInfo", overrideInfo) + .add("target", target) .add("result", result) .add("blobSize", blobSize) .add("isDone", isDone) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index 8204f0105e7e..b30d46431de0 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -962,8 +962,8 @@ class CopyRequest implements Serializable { private final BlobId source; private final List sourceOptions; - private final BlobId targetId; - private final BlobInfo targetInfo; + private final boolean overrideInfo; + private final BlobInfo target; private final List targetOptions; private final Long megabytesCopiedPerChunk; @@ -972,8 +972,8 @@ public static class Builder { private final Set sourceOptions = new LinkedHashSet<>(); private final Set targetOptions = new LinkedHashSet<>(); private BlobId source; - private BlobId targetId; - private BlobInfo targetInfo; + private boolean overrideInfo; + private BlobInfo target; private Long megabytesCopiedPerChunk; /** @@ -1022,7 +1022,8 @@ public Builder sourceOptions(Iterable options) { * @return the builder */ public Builder target(BlobId targetId) { - this.targetId = targetId; + this.overrideInfo = false; + this.target = BlobInfo.builder(targetId).build(); return this; } @@ -1030,13 +1031,13 @@ public Builder target(BlobId targetId) { * Sets the copy target and target options. {@code target} parameter is used to override * source blob information (e.g. {@code contentType}, {@code contentLanguage}). Target blob * information is set exactly to {@code target}, no information is inherited from the source - * blob. If not set, target blob information is inherited from the source blob. + * blob. * * @return the builder */ - public Builder target(BlobInfo targetInfo, BlobTargetOption... options) { - this.targetId = targetInfo.blobId(); - this.targetInfo = targetInfo; + public Builder target(BlobInfo target, BlobTargetOption... options) { + this.overrideInfo = true; + this.target = checkNotNull(target); Collections.addAll(targetOptions, options); return this; } @@ -1045,13 +1046,13 @@ public Builder target(BlobInfo targetInfo, BlobTargetOption... options) { * Sets the copy target and target options. {@code target} parameter is used to override * source blob information (e.g. {@code contentType}, {@code contentLanguage}). Target blob * information is set exactly to {@code target}, no information is inherited from the source - * blob. If not set, target blob information is inherited from the source blob. + * blob. * * @return the builder */ - public Builder target(BlobInfo targetInfo, Iterable options) { - this.targetId = targetInfo.blobId(); - this.targetInfo = targetInfo; + public Builder target(BlobInfo target, Iterable options) { + this.overrideInfo = true; + this.target = checkNotNull(target); Iterables.addAll(targetOptions, options); return this; } @@ -1079,8 +1080,8 @@ public CopyRequest build() { private CopyRequest(Builder builder) { source = checkNotNull(builder.source); sourceOptions = ImmutableList.copyOf(builder.sourceOptions); - targetId = checkNotNull(builder.targetId); - targetInfo = builder.targetInfo; + overrideInfo = builder.overrideInfo; + target = checkNotNull(builder.target); targetOptions = ImmutableList.copyOf(builder.targetOptions); megabytesCopiedPerChunk = builder.megabytesCopiedPerChunk; } @@ -1100,20 +1101,21 @@ public List sourceOptions() { } /** - * Returns the {@link BlobId} for the target blob. + * Returns the {@link BlobInfo} for the target blob. */ - public BlobId targetId() { - return targetId; + public BlobInfo target() { + return target; } /** - * Returns the {@link BlobInfo} for the target blob. If set, this value is used to replace - * source blob information (e.g. {@code contentType}, {@code contentLanguage}). Target blob - * information is set exactly to this value, no information is inherited from the source blob. - * If not set, target blob information is inherited from the source blob. + * Returns whether to override the target blob information with {@link #target()}. + * If {@code true}, the value of {@link #target()} is used to replace source blob information + * (e.g. {@code contentType}, {@code contentLanguage}). Target blob information is set exactly + * to this value, no information is inherited from the source blob. If {@code false}, target + * blob information is inherited from the source blob. */ - public BlobInfo targetInfo() { - return targetInfo; + public boolean overrideInfo() { + return overrideInfo; } /** diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java index 30c0046b802c..cf709ba5e293 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java @@ -413,19 +413,15 @@ public CopyWriter copy(final CopyRequest copyRequest) { final StorageObject source = copyRequest.source().toPb(); final Map sourceOptions = optionMap(copyRequest.source().generation(), null, copyRequest.sourceOptions(), true); - final BlobId targetId = copyRequest.targetId(); - final StorageObject targetObject = - copyRequest.targetInfo() != null ? copyRequest.targetInfo().toPb() : null; - final Map targetOptions = optionMap( - copyRequest.targetInfo() != null ? copyRequest.targetInfo().generation() : null, - copyRequest.targetInfo() != null ? copyRequest.targetInfo().metageneration() : null, - copyRequest.targetOptions()); + final StorageObject targetObject = copyRequest.target().toPb(); + final Map targetOptions = optionMap(copyRequest.target().generation(), + copyRequest.target().metageneration(), copyRequest.targetOptions()); try { RewriteResponse rewriteResponse = runWithRetries(new Callable() { @Override public RewriteResponse call() { return storageRpc.openRewrite(new StorageRpc.RewriteRequest(source, sourceOptions, - targetId.bucket(), targetId.name(), targetObject, targetOptions, + copyRequest.overrideInfo(), targetObject, targetOptions, copyRequest.megabytesCopiedPerChunk())); } }, options().retryParams(), EXCEPTION_HANDLER); diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/DefaultStorageRpc.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/DefaultStorageRpc.java index 7f13212556aa..8d06832534e2 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/DefaultStorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/DefaultStorageRpc.java @@ -580,8 +580,8 @@ private RewriteResponse rewrite(RewriteRequest req, String token) { Long maxBytesRewrittenPerCall = req.megabytesRewrittenPerCall != null ? req.megabytesRewrittenPerCall * MEGABYTE : null; com.google.api.services.storage.model.RewriteResponse rewriteResponse = storage.objects() - .rewrite(req.source.getBucket(), req.source.getName(), req.targetBucket, - req.targetName, req.targetObject) + .rewrite(req.source.getBucket(), req.source.getName(), req.target.getBucket(), + req.target.getName(), req.overrideInfo ? req.target : null) .setSourceGeneration(req.source.getGeneration()) .setRewriteToken(token) .setMaxBytesRewrittenPerCall(maxBytesRewrittenPerCall) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/StorageRpc.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/StorageRpc.java index 7256368e189f..74f8171de87f 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/StorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/StorageRpc.java @@ -138,20 +138,18 @@ class RewriteRequest { public final StorageObject source; public final Map sourceOptions; - public final String targetBucket; - public final String targetName; - public final StorageObject targetObject; + public final boolean overrideInfo; + public final StorageObject target; public final Map targetOptions; public final Long megabytesRewrittenPerCall; public RewriteRequest(StorageObject source, Map sourceOptions, - String targetBucket, String targetName, StorageObject targetObject, - Map targetOptions, Long megabytesRewrittenPerCall) { + boolean overrideInfo, StorageObject target, Map targetOptions, + Long megabytesRewrittenPerCall) { this.source = source; this.sourceOptions = sourceOptions; - this.targetBucket = targetBucket; - this.targetName = targetName; - this.targetObject = targetObject; + this.overrideInfo = overrideInfo; + this.target = target; this.targetOptions = targetOptions; this.megabytesRewrittenPerCall = megabytesRewrittenPerCall; } @@ -167,17 +165,16 @@ public boolean equals(Object obj) { final RewriteRequest other = (RewriteRequest) obj; return Objects.equals(this.source, other.source) && Objects.equals(this.sourceOptions, other.sourceOptions) - && Objects.equals(this.targetBucket, other.targetBucket) - && Objects.equals(this.targetName, other.targetName) - && Objects.equals(this.targetObject, other.targetObject) + && Objects.equals(this.overrideInfo, other.overrideInfo) + && Objects.equals(this.target, other.target) && Objects.equals(this.targetOptions, other.targetOptions) && Objects.equals(this.megabytesRewrittenPerCall, other.megabytesRewrittenPerCall); } @Override public int hashCode() { - return Objects.hash(source, sourceOptions, targetBucket, targetName, targetObject, - targetOptions, megabytesRewrittenPerCall); + return Objects.hash(source, sourceOptions, overrideInfo, target, targetOptions, + megabytesRewrittenPerCall); } } diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java index 2d4920816c38..d6c97ca9ca03 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java @@ -222,6 +222,7 @@ public void testDelete() throws Exception { @Test public void testCopyToBucket() throws Exception { initializeExpectedBlob(2); + BlobInfo target = BlobInfo.builder(BlobId.of("bt", "n")).build(); CopyWriter copyWriter = createMock(CopyWriter.class); Capture capturedCopyRequest = Capture.newInstance(); expect(storage.options()).andReturn(mockOptions); @@ -231,8 +232,8 @@ public void testCopyToBucket() throws Exception { CopyWriter returnedCopyWriter = blob.copyTo("bt"); assertEquals(copyWriter, returnedCopyWriter); assertEquals(capturedCopyRequest.getValue().source(), blob.blobId()); - assertEquals(capturedCopyRequest.getValue().targetId(), BlobId.of("bt", "n")); - assertNull(capturedCopyRequest.getValue().targetInfo()); + assertEquals(capturedCopyRequest.getValue().target(), target); + assertFalse(capturedCopyRequest.getValue().overrideInfo()); assertTrue(capturedCopyRequest.getValue().sourceOptions().isEmpty()); assertTrue(capturedCopyRequest.getValue().targetOptions().isEmpty()); } @@ -240,6 +241,7 @@ public void testCopyToBucket() throws Exception { @Test public void testCopyTo() throws Exception { initializeExpectedBlob(2); + BlobInfo target = BlobInfo.builder(BlobId.of("bt", "nt")).build(); CopyWriter copyWriter = createMock(CopyWriter.class); Capture capturedCopyRequest = Capture.newInstance(); expect(storage.options()).andReturn(mockOptions); @@ -249,8 +251,8 @@ public void testCopyTo() throws Exception { CopyWriter returnedCopyWriter = blob.copyTo("bt", "nt"); assertEquals(copyWriter, returnedCopyWriter); assertEquals(capturedCopyRequest.getValue().source(), blob.blobId()); - assertEquals(capturedCopyRequest.getValue().targetId(), BlobId.of("bt", "nt")); - assertNull(capturedCopyRequest.getValue().targetInfo()); + assertEquals(capturedCopyRequest.getValue().target(), target); + assertFalse(capturedCopyRequest.getValue().overrideInfo()); assertTrue(capturedCopyRequest.getValue().sourceOptions().isEmpty()); assertTrue(capturedCopyRequest.getValue().targetOptions().isEmpty()); } @@ -258,6 +260,7 @@ public void testCopyTo() throws Exception { @Test public void testCopyToBlobId() throws Exception { initializeExpectedBlob(2); + BlobInfo target = BlobInfo.builder(BlobId.of("bt", "nt")).build(); BlobId targetId = BlobId.of("bt", "nt"); CopyWriter copyWriter = createMock(CopyWriter.class); Capture capturedCopyRequest = Capture.newInstance(); @@ -268,8 +271,8 @@ public void testCopyToBlobId() throws Exception { CopyWriter returnedCopyWriter = blob.copyTo(targetId); assertEquals(copyWriter, returnedCopyWriter); assertEquals(capturedCopyRequest.getValue().source(), blob.blobId()); - assertEquals(capturedCopyRequest.getValue().targetId(), targetId); - assertNull(capturedCopyRequest.getValue().targetInfo()); + assertEquals(capturedCopyRequest.getValue().target(), target); + assertFalse(capturedCopyRequest.getValue().overrideInfo()); assertTrue(capturedCopyRequest.getValue().sourceOptions().isEmpty()); assertTrue(capturedCopyRequest.getValue().targetOptions().isEmpty()); } diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyRequestTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyRequestTest.java index 5700ea804cd6..9f8edfb84162 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyRequestTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyRequestTest.java @@ -18,7 +18,8 @@ import static com.google.gcloud.storage.Storage.PredefinedAcl.PUBLIC_READ; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import com.google.common.collect.ImmutableList; import com.google.gcloud.storage.Storage.BlobSourceOption; @@ -53,8 +54,8 @@ public void testCopyRequest() { assertEquals(SOURCE_BLOB_ID, copyRequest1.source()); assertEquals(1, copyRequest1.sourceOptions().size()); assertEquals(BlobSourceOption.generationMatch(1), copyRequest1.sourceOptions().get(0)); - assertEquals(TARGET_BLOB_INFO.blobId(), copyRequest1.targetId()); - assertEquals(TARGET_BLOB_INFO, copyRequest1.targetInfo()); + assertEquals(TARGET_BLOB_INFO, copyRequest1.target()); + assertTrue(copyRequest1.overrideInfo()); assertEquals(1, copyRequest1.targetOptions().size()); assertEquals(BlobTargetOption.predefinedAcl(PUBLIC_READ), copyRequest1.targetOptions().get(0)); @@ -63,16 +64,16 @@ public void testCopyRequest() { .target(TARGET_BLOB_ID) .build(); assertEquals(SOURCE_BLOB_ID, copyRequest2.source()); - assertEquals(TARGET_BLOB_ID, copyRequest2.targetId()); - assertNull(copyRequest2.targetInfo()); + assertEquals(BlobInfo.builder(TARGET_BLOB_ID).build(), copyRequest2.target()); + assertFalse(copyRequest2.overrideInfo()); Storage.CopyRequest copyRequest3 = Storage.CopyRequest.builder() .source(SOURCE_BLOB_ID) .target(TARGET_BLOB_INFO, ImmutableList.of(BlobTargetOption.predefinedAcl(PUBLIC_READ))) .build(); assertEquals(SOURCE_BLOB_ID, copyRequest3.source()); - assertEquals(TARGET_BLOB_INFO.blobId(), copyRequest3.targetId()); - assertEquals(TARGET_BLOB_INFO, copyRequest3.targetInfo()); + assertEquals(TARGET_BLOB_INFO, copyRequest3.target()); + assertTrue(copyRequest3.overrideInfo()); assertEquals(ImmutableList.of(BlobTargetOption.predefinedAcl(PUBLIC_READ)), copyRequest3.targetOptions()); } @@ -81,34 +82,37 @@ public void testCopyRequest() { public void testCopyRequestOf() { Storage.CopyRequest copyRequest1 = Storage.CopyRequest.of(SOURCE_BLOB_ID, TARGET_BLOB_INFO); assertEquals(SOURCE_BLOB_ID, copyRequest1.source()); - assertEquals(TARGET_BLOB_INFO.blobId(), copyRequest1.targetId()); - assertEquals(TARGET_BLOB_INFO, copyRequest1.targetInfo()); + assertEquals(TARGET_BLOB_INFO, copyRequest1.target()); + assertTrue(copyRequest1.overrideInfo()); Storage.CopyRequest copyRequest2 = Storage.CopyRequest.of(SOURCE_BLOB_ID, TARGET_BLOB_NAME); assertEquals(SOURCE_BLOB_ID, copyRequest2.source()); - assertEquals(BlobId.of(SOURCE_BUCKET_NAME, TARGET_BLOB_NAME), copyRequest2.targetId()); - assertNull(copyRequest2.targetInfo()); + assertEquals(BlobInfo.builder(BlobId.of(SOURCE_BUCKET_NAME, TARGET_BLOB_NAME)).build(), + copyRequest2.target()); + assertFalse(copyRequest2.overrideInfo()); Storage.CopyRequest copyRequest3 = Storage.CopyRequest.of(SOURCE_BUCKET_NAME, SOURCE_BLOB_NAME, TARGET_BLOB_INFO); assertEquals(SOURCE_BLOB_ID, copyRequest3.source()); - assertEquals(TARGET_BLOB_INFO.blobId(), copyRequest3.targetId()); - assertEquals(TARGET_BLOB_INFO, copyRequest3.targetInfo()); + assertEquals(TARGET_BLOB_INFO, copyRequest3.target()); + assertTrue(copyRequest3.overrideInfo()); Storage.CopyRequest copyRequest4 = Storage.CopyRequest.of(SOURCE_BUCKET_NAME, SOURCE_BLOB_NAME, TARGET_BLOB_NAME); assertEquals(SOURCE_BLOB_ID, copyRequest4.source()); - assertEquals(BlobId.of(SOURCE_BUCKET_NAME, TARGET_BLOB_NAME), copyRequest4.targetId()); - assertNull(copyRequest4.targetInfo()); + assertEquals(BlobInfo.builder(BlobId.of(SOURCE_BUCKET_NAME, TARGET_BLOB_NAME)).build(), + copyRequest4.target()); + assertFalse(copyRequest4.overrideInfo()); Storage.CopyRequest copyRequest5 = Storage.CopyRequest.of(SOURCE_BLOB_ID, TARGET_BLOB_ID); assertEquals(SOURCE_BLOB_ID, copyRequest5.source()); - assertEquals(TARGET_BLOB_ID, copyRequest5.targetId()); - assertNull(copyRequest5.targetInfo()); + assertEquals(BlobInfo.builder(TARGET_BLOB_ID).build(), copyRequest5.target()); + assertFalse(copyRequest5.overrideInfo()); Storage.CopyRequest copyRequest6 = Storage.CopyRequest.of(SOURCE_BUCKET_NAME, SOURCE_BLOB_NAME, TARGET_BLOB_ID); assertEquals(SOURCE_BLOB_ID, copyRequest6.source()); - assertEquals(TARGET_BLOB_ID, copyRequest6.targetId()); - assertNull(copyRequest6.targetInfo()); } + assertEquals(BlobInfo.builder(TARGET_BLOB_ID).build(), copyRequest6.target()); + assertFalse(copyRequest6.overrideInfo()); + } } diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyWriterTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyWriterTest.java index 75b863075770..8ccb81688b65 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyWriterTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyWriterTest.java @@ -52,11 +52,11 @@ public class CopyWriterTest { BlobInfo.builder(DESTINATION_BUCKET_NAME, DESTINATION_BLOB_NAME).contentType("type").build(); private static final Map EMPTY_OPTIONS = ImmutableMap.of(); private static final RewriteRequest REQUEST_WITH_OBJECT = - new StorageRpc.RewriteRequest(BLOB_ID.toPb(), EMPTY_OPTIONS, DESTINATION_BUCKET_NAME, - DESTINATION_BLOB_NAME, BLOB_INFO.toPb(), EMPTY_OPTIONS, null); + new StorageRpc.RewriteRequest(BLOB_ID.toPb(), EMPTY_OPTIONS, true, BLOB_INFO.toPb(), + EMPTY_OPTIONS, null); private static final RewriteRequest REQUEST_WITHOUT_OBJECT = - new StorageRpc.RewriteRequest(BLOB_ID.toPb(), EMPTY_OPTIONS, DESTINATION_BUCKET_NAME, - DESTINATION_BLOB_NAME, null, EMPTY_OPTIONS, null); + new StorageRpc.RewriteRequest(BLOB_ID.toPb(), EMPTY_OPTIONS, false, BLOB_INFO.toPb(), + EMPTY_OPTIONS, null); private static final RewriteResponse RESPONSE_WITH_OBJECT = new RewriteResponse( REQUEST_WITH_OBJECT, null, 42L, false, "token", 21L); private static final RewriteResponse RESPONSE_WITHOUT_OBJECT = new RewriteResponse( diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java index db1166598237..3cc99e3bf884 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java @@ -866,8 +866,7 @@ public void testComposeWithOptions() { public void testCopy() { CopyRequest request = Storage.CopyRequest.of(BLOB_INFO1.blobId(), BLOB_INFO2.blobId()); StorageRpc.RewriteRequest rpcRequest = new StorageRpc.RewriteRequest(request.source().toPb(), - EMPTY_RPC_OPTIONS, BLOB_INFO2.blobId().bucket(), BLOB_INFO2.blobId().name(), null, - EMPTY_RPC_OPTIONS, null); + EMPTY_RPC_OPTIONS, false, BLOB_INFO2.toPb(), EMPTY_RPC_OPTIONS, null); StorageRpc.RewriteResponse rpcResponse = new StorageRpc.RewriteResponse(rpcRequest, null, 42L, false, "token", 21L); EasyMock.expect(storageRpcMock.openRewrite(rpcRequest)).andReturn(rpcResponse); @@ -887,8 +886,7 @@ public void testCopyWithOptions() { .target(BLOB_INFO1, BLOB_TARGET_GENERATION, BLOB_TARGET_METAGENERATION) .build(); StorageRpc.RewriteRequest rpcRequest = new StorageRpc.RewriteRequest(request.source().toPb(), - BLOB_SOURCE_OPTIONS_COPY, BLOB_INFO1.blobId().bucket(), BLOB_INFO1.blobId().name(), - request.targetInfo().toPb(), BLOB_TARGET_OPTIONS_COMPOSE, null); + BLOB_SOURCE_OPTIONS_COPY, true, request.target().toPb(), BLOB_TARGET_OPTIONS_COMPOSE, null); StorageRpc.RewriteResponse rpcResponse = new StorageRpc.RewriteResponse(rpcRequest, null, 42L, false, "token", 21L); EasyMock.expect(storageRpcMock.openRewrite(rpcRequest)).andReturn(rpcResponse); @@ -908,8 +906,7 @@ public void testCopyWithOptionsFromBlobId() { .target(BLOB_INFO1, BLOB_TARGET_GENERATION, BLOB_TARGET_METAGENERATION) .build(); StorageRpc.RewriteRequest rpcRequest = new StorageRpc.RewriteRequest(request.source().toPb(), - BLOB_SOURCE_OPTIONS_COPY, BLOB_INFO1.blobId().bucket(), BLOB_INFO1.blobId().name(), - request.targetInfo().toPb(), BLOB_TARGET_OPTIONS_COMPOSE, null); + BLOB_SOURCE_OPTIONS_COPY, true, request.target().toPb(), BLOB_TARGET_OPTIONS_COMPOSE, null); StorageRpc.RewriteResponse rpcResponse = new StorageRpc.RewriteResponse(rpcRequest, null, 42L, false, "token", 21L); EasyMock.expect(storageRpcMock.openRewrite(rpcRequest)).andReturn(rpcResponse); @@ -925,8 +922,7 @@ public void testCopyWithOptionsFromBlobId() { public void testCopyMultipleRequests() { CopyRequest request = Storage.CopyRequest.of(BLOB_INFO1.blobId(), BLOB_INFO2.blobId()); StorageRpc.RewriteRequest rpcRequest = new StorageRpc.RewriteRequest(request.source().toPb(), - EMPTY_RPC_OPTIONS, BLOB_INFO2.blobId().bucket(), BLOB_INFO2.blobId().name(), null, - EMPTY_RPC_OPTIONS, null); + EMPTY_RPC_OPTIONS, false, BLOB_INFO2.toPb(), EMPTY_RPC_OPTIONS, null); StorageRpc.RewriteResponse rpcResponse1 = new StorageRpc.RewriteResponse(rpcRequest, null, 42L, false, "token", 21L); StorageRpc.RewriteResponse rpcResponse2 = new StorageRpc.RewriteResponse(rpcRequest, From 1855ae1a86370e90bc5fae34dff58bf39cb27671 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Sun, 20 Mar 2016 21:05:49 +0100 Subject: [PATCH 186/375] Add better javadoc to Storage.copy and CopyWriter --- .../com/google/gcloud/storage/CopyWriter.java | 8 +++++++- .../java/com/google/gcloud/storage/Storage.java | 17 +++++++++++------ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java index 26c728942a28..2f3850d5dd03 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java @@ -32,7 +32,13 @@ import java.util.concurrent.Callable; /** - * Google Storage blob copy writer. This class holds the result of a copy request. If source and + * Google Storage blob copy writer. A {@code CopyWriter} object allows to copy both blob's data and + * information. To override source blob's information call {@link Storage#copy(Storage.CopyRequest)} + * with a {@code CopyRequest} object where the copy target is set via + * {@link Storage.CopyRequest.Builder#target(BlobInfo, Storage.BlobTargetOption...)} or + * {@link Storage.CopyRequest.Builder#target(BlobInfo, Iterable)}. + * + *

      This class holds the result of a copy request. If source and * destination blobs share the same location and storage class the copy is completed in one RPC call * otherwise one or more {@link #copyChunk} calls are necessary to complete the copy. In addition, * {@link CopyWriter#result()} can be used to automatically complete the copy and return information diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index b30d46431de0..33c1d7e7e143 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -1385,12 +1385,17 @@ public static Builder builder() { Blob compose(ComposeRequest composeRequest); /** - * Sends a copy request. Returns a {@link CopyWriter} object for the provided - * {@code CopyRequest}. If source and destination objects share the same location and storage - * class the source blob is copied with one request and {@link CopyWriter#result()} immediately - * returns, regardless of the {@link CopyRequest#megabytesCopiedPerChunk} parameter. - * If source and destination have different location or storage class {@link CopyWriter#result()} - * might issue multiple RPC calls depending on blob's size. + * Sends a copy request. This method copies both blob's data and information. To override source + * blob's information set the copy target via + * {@link CopyRequest.Builder#target(BlobInfo, BlobTargetOption...)} or + * {@link CopyRequest.Builder#target(BlobInfo, Iterable)}. + * + *

      This method returns a {@link CopyWriter} object for the provided {@code CopyRequest}. If + * source and destination objects share the same location and storage class the source blob is + * copied with one request and {@link CopyWriter#result()} immediately returns, regardless of the + * {@link CopyRequest#megabytesCopiedPerChunk} parameter. If source and destination have different + * location or storage class {@link CopyWriter#result()} might issue multiple RPC calls depending + * on blob's size. * *

      Example usage of copy: *

       {@code BlobInfo blob = service.copy(copyRequest).result();}
      
      From 5dd0292085c00ac79aed381d4192bc33b09e2b97 Mon Sep 17 00:00:00 2001
      From: Marco Ziccardi 
      Date: Sun, 20 Mar 2016 22:39:16 +0100
      Subject: [PATCH 187/375] Rephrase RewriteChannel and Storage.copy javadoc. Add
       final to CopyWriter's StateImpl.target
      
      ---
       .../main/java/com/google/gcloud/storage/CopyWriter.java    | 6 +++---
       .../src/main/java/com/google/gcloud/storage/Storage.java   | 7 ++++---
       2 files changed, 7 insertions(+), 6 deletions(-)
      
      diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java
      index 2f3850d5dd03..743630b6c4c2 100644
      --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java
      +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java
      @@ -33,8 +33,8 @@
       
       /**
        * Google Storage blob copy writer. A {@code CopyWriter} object allows to copy both blob's data and
      - * information. To override source blob's information call {@link Storage#copy(Storage.CopyRequest)}
      - * with a {@code CopyRequest} object where the copy target is set via
      + * information. To override source blob's information supply a {@code BlobInfo} to the
      + * {@code CopyRequest} using either
        * {@link Storage.CopyRequest.Builder#target(BlobInfo, Storage.BlobTargetOption...)} or
        * {@link Storage.CopyRequest.Builder#target(BlobInfo, Iterable)}.
        *
      @@ -176,7 +176,7 @@ static class Builder {
             private final BlobId source;
             private final Map sourceOptions;
             private final boolean overrideInfo;
      -      private BlobInfo target;
      +      private final BlobInfo target;
             private final Map targetOptions;
             private BlobInfo result;
             private long blobSize;
      diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java
      index 33c1d7e7e143..b4fbe45244b0 100644
      --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java
      +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java
      @@ -1386,9 +1386,10 @@ public static Builder builder() {
       
         /**
          * Sends a copy request. This method copies both blob's data and information. To override source
      -   * blob's information set the copy target via
      -   * {@link CopyRequest.Builder#target(BlobInfo, BlobTargetOption...)} or
      -   * {@link CopyRequest.Builder#target(BlobInfo, Iterable)}.
      +   * blob's information supply a {@code BlobInfo} to the
      +   * {@code CopyRequest} using either
      +   * {@link Storage.CopyRequest.Builder#target(BlobInfo, Storage.BlobTargetOption...)} or
      +   * {@link Storage.CopyRequest.Builder#target(BlobInfo, Iterable)}.
          *
          * 

      This method returns a {@link CopyWriter} object for the provided {@code CopyRequest}. If * source and destination objects share the same location and storage class the source blob is From 3e9e1a0e8e034248c090e9c9b9918d3a783412be Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Wed, 16 Mar 2016 13:48:52 -0700 Subject: [PATCH 188/375] IAM docs and functional methods for policies --- .../snippets/ModifyPolicy.java | 64 +++++++++++++++++ gcloud-java-resourcemanager/README.md | 43 +++++++++++- .../google/gcloud/resourcemanager/Policy.java | 5 ++ .../gcloud/resourcemanager/Project.java | 68 +++++++++++++++++++ .../gcloud/resourcemanager/ProjectTest.java | 46 +++++++++++++ 5 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/ModifyPolicy.java diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/ModifyPolicy.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/ModifyPolicy.java new file mode 100644 index 000000000000..7401f0b88bbc --- /dev/null +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/ModifyPolicy.java @@ -0,0 +1,64 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +/* + * EDITING INSTRUCTIONS + * This file is referenced in READMEs and javadoc. Any change to this file should be reflected in + * the project's READMEs and package-info.java. + */ + +package com.google.gcloud.examples.resourcemanager.snippets; + +import com.google.gcloud.Identity; +import com.google.gcloud.resourcemanager.Policy; +import com.google.gcloud.resourcemanager.Policy.Role; +import com.google.gcloud.resourcemanager.Project; +import com.google.gcloud.resourcemanager.ResourceManager; +import com.google.gcloud.resourcemanager.ResourceManagerOptions; + +/** + * A snippet for Google Cloud Resource Manager showing how to modify a project's IAM policy. + */ +public class ModifyPolicy { + + public static void main(String... args) { + // Create Resource Manager service object + // By default, credentials are inferred from the runtime environment. + ResourceManager resourceManager = ResourceManagerOptions.defaultInstance().service(); + + // Get a project from the server + String projectId = "some-project-id"; // Use an existing project's ID + Project project = resourceManager.get(projectId); + + // Get the project's policy + Policy policy = project.getPolicy(); + + // Add a viewer + Policy.Builder modifiedPolicy = policy.toBuilder(); + Identity newViewer = Identity.user(""); + if (policy.bindings().containsKey(Role.viewer())) { + modifiedPolicy.addIdentity(Role.viewer(), newViewer); + } else { + modifiedPolicy.addBinding(Role.viewer(), newViewer); + } + + // Write policy + Policy updatedPolicy = project.replacePolicy(modifiedPolicy.build()); + + // Print policy + System.out.printf("Updated policy for %s: %n%s%n", projectId, updatedPolicy); + } +} diff --git a/gcloud-java-resourcemanager/README.md b/gcloud-java-resourcemanager/README.md index 94037e27a709..a2539df7adab 100644 --- a/gcloud-java-resourcemanager/README.md +++ b/gcloud-java-resourcemanager/README.md @@ -163,9 +163,46 @@ while (projectIterator.hasNext()) { } ``` +#### Managing IAM Policies +You can edit [Google Cloud IAM](https://cloud.google.com/iam/) (Identity and Access Management) +policies on the project-level using this library as well. We recommend using the read-modify-write +pattern to make policy changes. This entails reading the project's current policy, updating it +locally, and then sending the modified policy for writing, as shown in the snippet below. First, +add these imports: + +```java +import com.google.gcloud.Identity; +import com.google.gcloud.resourcemanager.Policy; +import com.google.gcloud.resourcemanager.Policy.Role; +``` + +Assuming you have completed the steps above to create the `ResourceManager` service object and load +a project from the server, you just need to add the following code: + +```java +// Get the project's policy +Policy policy = project.getPolicy(); + +// Add a viewer +Policy.Builder modifiedPolicy = policy.toBuilder(); +Identity newViewer = Identity.user(""); +if (policy.bindings().containsKey(Role.viewer())) { + modifiedPolicy.addIdentity(Role.viewer(), newViewer); +} else { + modifiedPolicy.addBinding(Role.viewer(), newViewer); +} + +// Write policy +Policy updatedPolicy = project.replacePolicy(modifiedPolicy.build()); +``` + +Note that the policy you pass in to `replacePolicy` overwrites the original policy. For example, if +the original policy has two bindings and you call `replacePolicy` with a new policy containing only +one binding, the two original bindings are lost. + #### Complete source code -We put together all the code shown above into two programs. Both programs assume that you are +We put together all the code shown above into three programs. The programs assume that you are running from your own desktop and used the Google Cloud SDK to authenticate yourself. The first program creates a project if it does not exist. Complete source code can be found at @@ -175,6 +212,10 @@ The second program updates a project if it exists and lists all projects the use view. Complete source code can be found at [UpdateAndListProjects.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/UpdateAndListProjects.java). +The third program modifies the IAM policy associated with a project using the read-modify-write +pattern. Complete source code can be found at +[ModifyPolicy.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/ModifyPolicy.java) + Java Versions ------------- diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java index 46330e19fa59..6399b52b3c04 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java @@ -178,6 +178,11 @@ public Builder toBuilder() { return new Builder(bindings(), etag(), version()); } + @Override + public String toString() { + return toPb().toString(); + } + com.google.api.services.cloudresourcemanager.model.Policy toPb() { com.google.api.services.cloudresourcemanager.model.Policy policyPb = new com.google.api.services.cloudresourcemanager.model.Policy(); diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java index 46b142c5aa53..dd252155645b 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java @@ -18,8 +18,11 @@ import static com.google.common.base.Preconditions.checkNotNull; +import com.google.gcloud.resourcemanager.ResourceManager.Permission; + import java.io.IOException; import java.io.ObjectInputStream; +import java.util.List; import java.util.Map; import java.util.Objects; @@ -198,6 +201,71 @@ public Project replace() { return resourceManager.replace(this); } + /** + * Returns the IAM access control policy for the specified project. Returns {@code null} if the + * resource does not exist or if you do not have adequate permission to view the project or get + * the policy. + * + * @throws ResourceManagerException upon failure + * @see + * Resource Manager getIamPolicy + */ + public Policy getPolicy() { + return resourceManager.getPolicy(projectId()); + } + + /** + * Sets the IAM access control policy for the specified project. Replaces any existing policy. + * It is recommended that you use the read-modify-write pattern. See code samples and important + * details of replacing policies in the documentation for {@link ResourceManager#replacePolicy}. + * + * @throws ResourceManagerException upon failure + * @see ResourceManager#replacePolicy + * @see + * Resource Manager setIamPolicy + */ + public Policy replacePolicy(Policy newPolicy) { + return resourceManager.replacePolicy(projectId(), newPolicy); + } + + /** + * Returns the permissions that a caller has on this project. You typically don't call this method + * if you're using Google Cloud Platform directly to manage permissions. This method is intended + * for integration with your proprietary software, such as a customized graphical user interface. + * For example, the Cloud Platform Console tests IAM permissions internally to determine which UI + * should be available to the logged-in user. + * + * @return A list of booleans representing whether the caller has the permissions specified (in + * the order of the given permissions) + * @throws ResourceManagerException upon failure + * @see + * Resource Manager testIamPermissions + */ + List testPermissions(List permissions) { + return resourceManager.testPermissions(projectId(), permissions); + } + + /** + * Returns the permissions that a caller has on this project. You typically don't call this method + * if you're using Google Cloud Platform directly to manage permissions. This method is intended + * for integration with your proprietary software, such as a customized graphical user interface. + * For example, the Cloud Platform Console tests IAM permissions internally to determine which UI + * should be available to the logged-in user. + * + * @return A list of booleans representing whether the caller has the permissions specified (in + * the order of the given permissions) + * @throws ResourceManagerException upon failure + * @see + * Resource Manager testIamPermissions + */ + List testPermissions(Permission first, Permission... others) { + return resourceManager.testPermissions(projectId(), first, others); + } + @Override public Builder toBuilder() { return new Builder(this); diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectTest.java index 882ec77197f3..816f541146d5 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectTest.java @@ -25,13 +25,19 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.gcloud.Identity; +import com.google.gcloud.resourcemanager.Policy.Role; import com.google.gcloud.resourcemanager.ProjectInfo.ResourceId; +import com.google.gcloud.resourcemanager.ResourceManager.Permission; import org.junit.After; import org.junit.Before; import org.junit.Test; +import java.util.List; import java.util.Map; public class ProjectTest { @@ -48,6 +54,13 @@ public class ProjectTest { .createTimeMillis(CREATE_TIME_MILLIS) .state(STATE) .build(); + private static final Identity USER = Identity.user("abc@gmail.com"); + private static final Identity SERVICE_ACCOUNT = + Identity.serviceAccount("service-account@gmail.com"); + private static final Policy POLICY = Policy.builder() + .addBinding(Role.owner(), ImmutableSet.of(USER)) + .addBinding(Role.editor(), ImmutableSet.of(SERVICE_ACCOUNT)) + .build(); private ResourceManager serviceMockReturnsOptions = createStrictMock(ResourceManager.class); private ResourceManagerOptions mockOptions = createMock(ResourceManagerOptions.class); @@ -205,6 +218,39 @@ public void testReplace() { compareProjectInfos(expectedReplacedProject, actualReplacedProject); } + @Test + public void testGetPolicy() { + expect(resourceManager.options()).andReturn(mockOptions).times(1); + expect(resourceManager.getPolicy(PROJECT_ID)).andReturn(POLICY); + replay(resourceManager); + initializeProject(); + assertEquals(POLICY, project.getPolicy()); + } + + @Test + public void testReplacePolicy() { + expect(resourceManager.options()).andReturn(mockOptions).times(1); + expect(resourceManager.replacePolicy(PROJECT_ID, POLICY)).andReturn(POLICY); + replay(resourceManager); + initializeProject(); + assertEquals(POLICY, project.replacePolicy(POLICY)); + } + + @Test + public void testTestPermissions() { + List response = ImmutableList.of(true, true); + expect(resourceManager.options()).andReturn(mockOptions).times(1); + expect(resourceManager.testPermissions(PROJECT_ID, Permission.GET, Permission.DELETE)) + .andReturn(response); + expect(resourceManager.testPermissions( + PROJECT_ID, ImmutableList.of(Permission.GET, Permission.DELETE))).andReturn(response); + replay(resourceManager); + initializeProject(); + assertEquals(response, project.testPermissions(Permission.GET, Permission.DELETE)); + assertEquals( + response, project.testPermissions(ImmutableList.of(Permission.GET, Permission.DELETE))); + } + private void compareProjects(Project expected, Project value) { assertEquals(expected, value); compareProjectInfos(expected, value); From c05e738b1f17048560b781f4445ca1ccff7f0759 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 21 Mar 2016 09:36:13 -0700 Subject: [PATCH 189/375] Add binding entries as necessary in IamPolicy.Builder --- .../java/com/google/gcloud/IamPolicy.java | 63 +++++-------------- .../java/com/google/gcloud/IamPolicyTest.java | 44 +++++++++---- .../snippets/ModifyPolicy.java | 6 +- .../gcloud/resourcemanager/Project.java | 18 +++--- .../gcloud/resourcemanager/PolicyTest.java | 16 ++--- .../gcloud/resourcemanager/ProjectTest.java | 4 +- .../ResourceManagerImplTest.java | 4 +- .../resourcemanager/SerializationTest.java | 6 +- 8 files changed, 73 insertions(+), 88 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java b/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java index 748eaba2ab4c..3d7c1422e6fa 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java @@ -83,39 +83,8 @@ public final B bindings(Map> bindings) { return self(); } - /** - * Adds a binding to the policy. - * - * @throws IllegalArgumentException if the policy already contains a binding with the same role - * or if the role or any identities are null - */ - public final B addBinding(R role, Set identities) { - verifyBinding(role, identities); - checkArgument(!bindings.containsKey(role), - "The policy already contains a binding with the role " + role.toString() + "."); - bindings.put(role, new HashSet(identities)); - return self(); - } - - /** - * Adds a binding to the policy. - * - * @throws IllegalArgumentException if the policy already contains a binding with the same role - * or if the role or any identities are null - */ - public final B addBinding(R role, Identity first, Identity... others) { - HashSet identities = new HashSet<>(); - identities.add(first); - identities.addAll(Arrays.asList(others)); - return addBinding(role, identities); - } - private void verifyBinding(R role, Collection identities) { checkArgument(role != null, "The role cannot be null."); - verifyIdentities(identities); - } - - private void verifyIdentities(Collection identities) { checkArgument(identities != null, "A role cannot be assigned to a null set of identities."); checkArgument(!identities.contains(null), "Null identities are not permitted."); } @@ -129,33 +98,33 @@ public final B removeBinding(R role) { } /** - * Adds one or more identities to an existing binding. - * - * @throws IllegalArgumentException if the policy doesn't contain a binding with the specified - * role or any identities are null + * Adds one or more identities to the policy under the role specified. Creates a new role + * binding if the binding corresponding to the given role did not previously exist. */ public final B addIdentity(R role, Identity first, Identity... others) { - checkArgument(bindings.containsKey(role), - "The policy doesn't contain the role " + role.toString() + "."); List toAdd = new LinkedList<>(); toAdd.add(first); toAdd.addAll(Arrays.asList(others)); - verifyIdentities(toAdd); - bindings.get(role).addAll(toAdd); + verifyBinding(role, toAdd); + Set identities = bindings.get(role); + if (identities == null) { + identities = new HashSet(); + bindings.put(role, identities); + } + identities.addAll(toAdd); return self(); } /** - * Removes one or more identities from an existing binding. - * - * @throws IllegalArgumentException if the policy doesn't contain a binding with the specified - * role + * Removes one or more identities from an existing binding. Does nothing if the binding + * associated with the provided role doesn't exist. */ public final B removeIdentity(R role, Identity first, Identity... others) { - checkArgument(bindings.containsKey(role), - "The policy doesn't contain the role " + role.toString() + "."); - bindings.get(role).remove(first); - bindings.get(role).removeAll(Arrays.asList(others)); + Set identities = bindings.get(role); + if (identities != null) { + identities.remove(first); + identities.removeAll(Arrays.asList(others)); + } return self(); } diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java index db0935c4766d..2f40c3b76001 100644 --- a/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java +++ b/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java @@ -28,6 +28,7 @@ import org.junit.Test; +import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -46,8 +47,8 @@ public class IamPolicyTest { "editor", ImmutableSet.of(ALL_AUTH_USERS, GROUP, DOMAIN)); private static final PolicyImpl SIMPLE_POLICY = PolicyImpl.builder() - .addBinding("viewer", ImmutableSet.of(USER, SERVICE_ACCOUNT, ALL_USERS)) - .addBinding("editor", ImmutableSet.of(ALL_AUTH_USERS, GROUP, DOMAIN)) + .addIdentity("viewer", USER, SERVICE_ACCOUNT, ALL_USERS) + .addIdentity("editor", ALL_AUTH_USERS, GROUP, DOMAIN) .build(); private static final PolicyImpl FULL_POLICY = new PolicyImpl.Builder(SIMPLE_POLICY.bindings(), "etag", 1).build(); @@ -105,22 +106,43 @@ public void testBuilder() { policy.bindings()); assertNull(policy.etag()); assertNull(policy.version()); - policy = PolicyImpl.builder().addBinding("owner", USER, SERVICE_ACCOUNT).build(); + policy = PolicyImpl.builder() + .removeIdentity("viewer", USER) + .addIdentity("owner", USER, SERVICE_ACCOUNT) + .build(); assertEquals( ImmutableMap.of("owner", ImmutableSet.of(USER, SERVICE_ACCOUNT)), policy.bindings()); assertNull(policy.etag()); assertNull(policy.version()); + } + + @Test + public void testIllegalPolicies() { + try { + PolicyImpl.builder().addIdentity(null, USER); + fail("Null role should cause exception."); + } catch (IllegalArgumentException ex) { + assertEquals("The role cannot be null.", ex.getMessage()); + } + try { + PolicyImpl.builder().addIdentity("viewer", null, USER); + fail("Null identity should cause exception."); + } catch (IllegalArgumentException ex) { + assertEquals("Null identities are not permitted.", ex.getMessage()); + } try { - SIMPLE_POLICY.toBuilder().addBinding("viewer", USER); - fail("Should have failed due to duplicate role."); - } catch (IllegalArgumentException e) { - assertEquals("The policy already contains a binding with the role viewer.", e.getMessage()); + PolicyImpl.builder().bindings(null); + fail("Null bindings map should cause exception."); + } catch (IllegalArgumentException ex) { + assertEquals("The provided map of bindings cannot be null.", ex.getMessage()); } try { - SIMPLE_POLICY.toBuilder().addBinding("editor", ImmutableSet.of(USER)); - fail("Should have failed due to duplicate role."); - } catch (IllegalArgumentException e) { - assertEquals("The policy already contains a binding with the role editor.", e.getMessage()); + Map> bindings = new HashMap<>(); + bindings.put("viewer", null); + PolicyImpl.builder().bindings(bindings); + fail("Null set of identities should cause exception."); + } catch (IllegalArgumentException ex) { + assertEquals("A role cannot be assigned to a null set of identities.", ex.getMessage()); } } diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/ModifyPolicy.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/ModifyPolicy.java index 7401f0b88bbc..478765a9ecf4 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/ModifyPolicy.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/ModifyPolicy.java @@ -49,11 +49,7 @@ public static void main(String... args) { // Add a viewer Policy.Builder modifiedPolicy = policy.toBuilder(); Identity newViewer = Identity.user(""); - if (policy.bindings().containsKey(Role.viewer())) { - modifiedPolicy.addIdentity(Role.viewer(), newViewer); - } else { - modifiedPolicy.addBinding(Role.viewer(), newViewer); - } + modifiedPolicy.addIdentity(Role.viewer(), newViewer); // Write policy Policy updatedPolicy = project.replacePolicy(modifiedPolicy.build()); diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java index dd252155645b..8c6a0eacd44f 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java @@ -202,10 +202,10 @@ public Project replace() { } /** - * Returns the IAM access control policy for the specified project. Returns {@code null} if the - * resource does not exist or if you do not have adequate permission to view the project or get - * the policy. + * Returns the IAM access control policy for this project. Returns {@code null} if the resource + * does not exist or if you do not have adequate permission to view the project or get the policy. * + * @return the IAM policy for the project * @throws ResourceManagerException upon failure * @see @@ -216,12 +216,12 @@ public Policy getPolicy() { } /** - * Sets the IAM access control policy for the specified project. Replaces any existing policy. - * It is recommended that you use the read-modify-write pattern. See code samples and important - * details of replacing policies in the documentation for {@link ResourceManager#replacePolicy}. + * Sets the IAM access control policy for this project. Replaces any existing policy. It is + * recommended that you use the read-modify-write pattern. See code samples and important details + * of replacing policies in the documentation for {@link ResourceManager#replacePolicy}. * + * @return the newly set IAM policy for this project * @throws ResourceManagerException upon failure - * @see ResourceManager#replacePolicy * @see * Resource Manager setIamPolicy @@ -237,7 +237,7 @@ public Policy replacePolicy(Policy newPolicy) { * For example, the Cloud Platform Console tests IAM permissions internally to determine which UI * should be available to the logged-in user. * - * @return A list of booleans representing whether the caller has the permissions specified (in + * @return a list of booleans representing whether the caller has the permissions specified (in * the order of the given permissions) * @throws ResourceManagerException upon failure * @see testPermissions(List permissions) { * For example, the Cloud Platform Console tests IAM permissions internally to determine which UI * should be available to the logged-in user. * - * @return A list of booleans representing whether the caller has the permissions specified (in + * @return a list of booleans representing whether the caller has the permissions specified (in * the order of the given permissions) * @throws ResourceManagerException upon failure * @see EMPTY_RPC_OPTIONS = ImmutableMap.of(); private static final Policy POLICY = Policy.builder() - .addBinding(Role.owner(), Identity.user("me@gmail.com")) - .addBinding(Role.editor(), Identity.serviceAccount("serviceaccount@gmail.com")) + .addIdentity(Role.owner(), Identity.user("me@gmail.com")) + .addIdentity(Role.editor(), Identity.serviceAccount("serviceaccount@gmail.com")) .build(); @Rule diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java index c6e907da16a0..1c0b9c68c86d 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java @@ -17,7 +17,6 @@ package com.google.gcloud.resourcemanager; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import com.google.gcloud.BaseSerializationTest; import com.google.gcloud.Identity; import com.google.gcloud.PageImpl; @@ -46,9 +45,8 @@ public class SerializationTest extends BaseSerializationTest { ResourceManager.ProjectGetOption.fields(ResourceManager.ProjectField.NAME); private static final ResourceManager.ProjectListOption PROJECT_LIST_OPTION = ResourceManager.ProjectListOption.filter("name:*"); - private static final Policy POLICY = Policy.builder() - .addBinding(Policy.Role.viewer(), ImmutableSet.of(Identity.user("abc@gmail.com"))) - .build(); + private static final Policy POLICY = + Policy.builder().addIdentity(Policy.Role.viewer(), Identity.user("abc@gmail.com")).build(); private static final ResourceManagerException RESOURCE_MANAGER_EXCEPTION = new ResourceManagerException(42, "message"); From 7bbe67fd3651f9294b6c3bcb3265a3872d2f1383 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 21 Mar 2016 16:29:10 -0700 Subject: [PATCH 190/375] Take care of minor changes --- .../java/com/google/gcloud/IamPolicy.java | 44 +++++++++++-------- .../java/com/google/gcloud/IamPolicyTest.java | 29 +++++++++--- 2 files changed, 49 insertions(+), 24 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java b/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java index 3d7c1422e6fa..9cce4b23c864 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java @@ -17,17 +17,16 @@ package com.google.gcloud; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import java.io.Serializable; import java.util.Arrays; -import java.util.Collection; import java.util.HashMap; import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; +import java.util.LinkedHashSet; import java.util.Map; import java.util.Objects; import java.util.Set; @@ -69,12 +68,16 @@ protected Builder() {} /** * Replaces the builder's map of bindings with the given map of bindings. * - * @throws IllegalArgumentException if the provided map is null or contain any null values + * @throws NullPointerException if the given map is null or contains any null keys or values + * @throws IllegalArgumentException if any identities in the given map are null */ public final B bindings(Map> bindings) { - checkArgument(bindings != null, "The provided map of bindings cannot be null."); + checkNotNull(bindings, "The provided map of bindings cannot be null."); for (Map.Entry> binding : bindings.entrySet()) { - verifyBinding(binding.getKey(), binding.getValue()); + checkNotNull(binding.getKey(), "The role cannot be null."); + Set identities = binding.getValue(); + checkNotNull(identities, "A role cannot be assigned to a null set of identities."); + checkArgument(!identities.contains(null), "Null identities are not permitted."); } this.bindings.clear(); for (Map.Entry> binding : bindings.entrySet()) { @@ -83,30 +86,30 @@ public final B bindings(Map> bindings) { return self(); } - private void verifyBinding(R role, Collection identities) { - checkArgument(role != null, "The role cannot be null."); - checkArgument(identities != null, "A role cannot be assigned to a null set of identities."); - checkArgument(!identities.contains(null), "Null identities are not permitted."); - } - /** - * Removes the binding associated with the specified role. + * Removes the role (and all identities associated with that role) from the policy. */ - public final B removeBinding(R role) { + public final B removeRole(R role) { bindings.remove(role); return self(); } /** - * Adds one or more identities to the policy under the role specified. Creates a new role - * binding if the binding corresponding to the given role did not previously exist. + * Adds one or more identities to the policy under the role specified. + * + * @throws NullPointerException if the role or any of the identities is null. */ public final B addIdentity(R role, Identity first, Identity... others) { - List toAdd = new LinkedList<>(); + String nullIdentityMessage = "Null identities are not permitted."; + checkNotNull(first, nullIdentityMessage); + checkNotNull(others, nullIdentityMessage); + for (Identity identity : others) { + checkNotNull(identity, nullIdentityMessage); + } + Set toAdd = new LinkedHashSet<>(); toAdd.add(first); toAdd.addAll(Arrays.asList(others)); - verifyBinding(role, toAdd); - Set identities = bindings.get(role); + Set identities = bindings.get(checkNotNull(role, "The role cannot be null.")); if (identities == null) { identities = new HashSet(); bindings.put(role, identities); @@ -125,6 +128,9 @@ public final B removeIdentity(R role, Identity first, Identity... others) { identities.remove(first); identities.removeAll(Arrays.asList(others)); } + if (identities != null && identities.isEmpty()) { + bindings.remove(role); + } return self(); } diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java index 2f40c3b76001..235c2c2b1c85 100644 --- a/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java +++ b/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java @@ -29,6 +29,7 @@ import org.junit.Test; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import java.util.Set; @@ -94,7 +95,7 @@ public void testBuilder() { assertEquals(editorBinding, policy.bindings()); assertEquals("etag", policy.etag()); assertEquals(1, policy.version().intValue()); - policy = SIMPLE_POLICY.toBuilder().removeBinding("editor").build(); + policy = SIMPLE_POLICY.toBuilder().removeRole("editor").build(); assertEquals(ImmutableMap.of("viewer", BINDINGS.get("viewer")), policy.bindings()); assertNull(policy.etag()); assertNull(policy.version()); @@ -109,6 +110,8 @@ public void testBuilder() { policy = PolicyImpl.builder() .removeIdentity("viewer", USER) .addIdentity("owner", USER, SERVICE_ACCOUNT) + .addIdentity("editor", GROUP) + .removeIdentity("editor", GROUP) .build(); assertEquals( ImmutableMap.of("owner", ImmutableSet.of(USER, SERVICE_ACCOUNT)), policy.bindings()); @@ -121,19 +124,25 @@ public void testIllegalPolicies() { try { PolicyImpl.builder().addIdentity(null, USER); fail("Null role should cause exception."); - } catch (IllegalArgumentException ex) { + } catch (NullPointerException ex) { assertEquals("The role cannot be null.", ex.getMessage()); } try { PolicyImpl.builder().addIdentity("viewer", null, USER); fail("Null identity should cause exception."); - } catch (IllegalArgumentException ex) { + } catch (NullPointerException ex) { + assertEquals("Null identities are not permitted.", ex.getMessage()); + } + try { + PolicyImpl.builder().addIdentity("viewer", USER, (Identity[]) null); + fail("Null identity should cause exception."); + } catch (NullPointerException ex) { assertEquals("Null identities are not permitted.", ex.getMessage()); } try { PolicyImpl.builder().bindings(null); fail("Null bindings map should cause exception."); - } catch (IllegalArgumentException ex) { + } catch (NullPointerException ex) { assertEquals("The provided map of bindings cannot be null.", ex.getMessage()); } try { @@ -141,9 +150,19 @@ public void testIllegalPolicies() { bindings.put("viewer", null); PolicyImpl.builder().bindings(bindings); fail("Null set of identities should cause exception."); - } catch (IllegalArgumentException ex) { + } catch (NullPointerException ex) { assertEquals("A role cannot be assigned to a null set of identities.", ex.getMessage()); } + try { + Map> bindings = new HashMap<>(); + Set identities = new HashSet<>(); + identities.add(null); + bindings.put("viewer", identities); + PolicyImpl.builder().bindings(bindings); + fail("Null identity should cause exception."); + } catch (IllegalArgumentException ex) { + assertEquals("Null identities are not permitted.", ex.getMessage()); + } } @Test From 3a97ae10587c21d34cf495447a3f9c3e9b9093da Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 21 Mar 2016 17:47:54 -0700 Subject: [PATCH 191/375] Make role and permission strings to allow for service-specific values --- .../snippets/ModifyPolicy.java | 4 +- .../google/gcloud/resourcemanager/Policy.java | 123 +++++------------- .../gcloud/resourcemanager/Project.java | 22 +++- .../resourcemanager/ResourceManager.java | 51 +++----- .../resourcemanager/ResourceManagerImpl.java | 15 +-- .../testing/LocalResourceManagerHelper.java | 14 +- .../LocalResourceManagerHelperTest.java | 7 - .../gcloud/resourcemanager/PolicyTest.java | 29 ++--- .../gcloud/resourcemanager/ProjectTest.java | 19 +-- .../ResourceManagerImplTest.java | 23 ++-- .../resourcemanager/SerializationTest.java | 6 +- 11 files changed, 108 insertions(+), 205 deletions(-) diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/ModifyPolicy.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/ModifyPolicy.java index 478765a9ecf4..f97adf5b0916 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/ModifyPolicy.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/ModifyPolicy.java @@ -24,7 +24,7 @@ import com.google.gcloud.Identity; import com.google.gcloud.resourcemanager.Policy; -import com.google.gcloud.resourcemanager.Policy.Role; +import com.google.gcloud.resourcemanager.Policy.ProjectRole; import com.google.gcloud.resourcemanager.Project; import com.google.gcloud.resourcemanager.ResourceManager; import com.google.gcloud.resourcemanager.ResourceManagerOptions; @@ -49,7 +49,7 @@ public static void main(String... args) { // Add a viewer Policy.Builder modifiedPolicy = policy.toBuilder(); Identity newViewer = Identity.user(""); - modifiedPolicy.addIdentity(Role.viewer(), newViewer); + modifiedPolicy.addIdentity(ProjectRole.VIEWER.value(), newViewer); // Write policy Policy updatedPolicy = project.replacePolicy(modifiedPolicy.build()); diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java index 6399b52b3c04..884f474bed59 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java @@ -23,13 +23,11 @@ import com.google.gcloud.IamPolicy; import com.google.gcloud.Identity; -import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Set; /** @@ -42,120 +40,63 @@ * * @see Policy */ -public class Policy extends IamPolicy { +public class Policy extends IamPolicy { private static final long serialVersionUID = -5573557282693961850L; /** - * Represents legacy roles in an IAM Policy. + * The project-level roles in an IAM policy. This enum is not an exhaustive list of all roles + * you can use in an IAM policy. You can also use service-specific roles (e.g. + * roles/pubsub.editor). See the Supported Cloud Platform Services page for links + * to service-specific roles. + * + * @see Supported Cloud + * Platform Services */ - public static class Role implements Serializable { + public enum ProjectRole { /** - * The recognized roles in a Project's IAM policy. + * Permissions for read-only actions that preserve state. */ - public enum Type { - - /** - * Permissions for read-only actions that preserve state. - */ - VIEWER, - - /** - * All viewer permissions and permissions for actions that modify state. - */ - EDITOR, - - /** - * All editor permissions and permissions for the following actions: - *

        - *
      • Manage access control for a resource. - *
      • Set up billing (for a project). - *
      - */ - OWNER - } - - private static final long serialVersionUID = 2421978909244287488L; - - private final String value; - private final Type type; - - private Role(String value, Type type) { - this.value = value; - this.type = type; - } - - String value() { - return value; - } + VIEWER("roles/viewer"), /** - * Returns the type of role (editor, owner, or viewer). Returns {@code null} if the role type - * is unrecognized. + * All viewer permissions and permissions for actions that modify state. */ - public Type type() { - return type; - } + EDITOR("roles/editor"), /** - * Returns a {@code Role} of type {@link Type#VIEWER VIEWER}. + * All editor permissions and permissions for the following actions: + *
        + *
      • Manage access control for a resource. + *
      • Set up billing (for a project). + *
      */ - public static Role viewer() { - return new Role("roles/viewer", Type.VIEWER); - } + OWNER("roles/owner"); - /** - * Returns a {@code Role} of type {@link Type#EDITOR EDITOR}. - */ - public static Role editor() { - return new Role("roles/editor", Type.EDITOR); + String value; + + private ProjectRole(String value) { + this.value = value; } /** - * Returns a {@code Role} of type {@link Type#OWNER OWNER}. + * Returns the string value associated with the role. */ - public static Role owner() { - return new Role("roles/owner", Type.OWNER); - } - - static Role rawRole(String roleStr) { - return new Role(roleStr, null); - } - - static Role fromStr(String roleStr) { - try { - Type type = Type.valueOf(roleStr.split("/")[1].toUpperCase()); - return new Role(roleStr, type); - } catch (Exception ex) { - return new Role(roleStr, null); - } - } - - @Override - public final int hashCode() { - return Objects.hash(value, type); - } - - @Override - public final boolean equals(Object obj) { - if (!(obj instanceof Role)) { - return false; - } - Role other = (Role) obj; - return Objects.equals(value, other.value()) && Objects.equals(type, other.type()); + public String value() { + return value; } } /** * Builder for an IAM Policy. */ - public static class Builder extends IamPolicy.Builder { + public static class Builder extends IamPolicy.Builder { private Builder() {} @VisibleForTesting - Builder(Map> bindings, String etag, Integer version) { + Builder(Map> bindings, String etag, Integer version) { bindings(bindings).etag(etag).version(version); } @@ -188,10 +129,10 @@ com.google.api.services.cloudresourcemanager.model.Policy toPb() { new com.google.api.services.cloudresourcemanager.model.Policy(); List bindingPbList = new LinkedList<>(); - for (Map.Entry> binding : bindings().entrySet()) { + for (Map.Entry> binding : bindings().entrySet()) { com.google.api.services.cloudresourcemanager.model.Binding bindingPb = new com.google.api.services.cloudresourcemanager.model.Binding(); - bindingPb.setRole(binding.getKey().value()); + bindingPb.setRole(binding.getKey()); bindingPb.setMembers( Lists.transform( new ArrayList<>(binding.getValue()), @@ -211,11 +152,11 @@ public String apply(Identity identity) { static Policy fromPb( com.google.api.services.cloudresourcemanager.model.Policy policyPb) { - Map> bindings = new HashMap<>(); + Map> bindings = new HashMap<>(); for (com.google.api.services.cloudresourcemanager.model.Binding bindingPb : policyPb.getBindings()) { bindings.put( - Role.fromStr(bindingPb.getRole()), + bindingPb.getRole(), ImmutableSet.copyOf( Lists.transform( bindingPb.getMembers(), diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java index 8c6a0eacd44f..de5e6c336af4 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java @@ -18,8 +18,6 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.gcloud.resourcemanager.ResourceManager.Permission; - import java.io.IOException; import java.io.ObjectInputStream; import java.util.List; @@ -235,7 +233,9 @@ public Policy replacePolicy(Policy newPolicy) { * if you're using Google Cloud Platform directly to manage permissions. This method is intended * for integration with your proprietary software, such as a customized graphical user interface. * For example, the Cloud Platform Console tests IAM permissions internally to determine which UI - * should be available to the logged-in user. + * should be available to the logged-in user. Each service that supports IAM lists the possible + * permissions; see the Supported Cloud Platform services page below for links to these + * lists. * * @return a list of booleans representing whether the caller has the permissions specified (in * the order of the given permissions) @@ -243,8 +243,11 @@ public Policy replacePolicy(Policy newPolicy) { * @see * Resource Manager testIamPermissions + * @see Supported Cloud Platform + * Services */ - List testPermissions(List permissions) { + List testPermissions(List permissions) { return resourceManager.testPermissions(projectId(), permissions); } @@ -253,7 +256,9 @@ List testPermissions(List permissions) { * if you're using Google Cloud Platform directly to manage permissions. This method is intended * for integration with your proprietary software, such as a customized graphical user interface. * For example, the Cloud Platform Console tests IAM permissions internally to determine which UI - * should be available to the logged-in user. + * should be available to the logged-in user. Each service that supports IAM lists the possible + * permissions; see the Supported Cloud Platform services page below for links to these + * lists. * * @return a list of booleans representing whether the caller has the permissions specified (in * the order of the given permissions) @@ -261,9 +266,12 @@ List testPermissions(List permissions) { * @see * Resource Manager testIamPermissions + * @see Supported Cloud Platform + * Services */ - List testPermissions(Permission first, Permission... others) { - return resourceManager.testPermissions(projectId(), first, others); + List testPermissions(String firstPermission, String... otherPermissions) { + return resourceManager.testPermissions(projectId(), firstPermission, otherPermissions); } @Override diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java index f14d47f2a676..708bd711b477 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java @@ -169,38 +169,6 @@ public static ProjectListOption fields(ProjectField... fields) { } } - /** - * The permissions associated with a Google Cloud project. These values can be used when calling - * {@link #testPermissions}. - * - * @see - * Project-level roles - */ - enum Permission { - DELETE("delete"), - GET("get"), - GET_POLICY("getIamPolicy"), - REPLACE("update"), - REPLACE_POLICY("setIamPolicy"), - UNDELETE("undelete"); - - private static final String PREFIX = "resourcemanager.projects."; - - private final String value; - - Permission(String suffix) { - this.value = PREFIX + suffix; - } - - /** - * Returns the string representation of the permission. - */ - public String value() { - return value; - } - } - /** * Creates a new project. * @@ -358,7 +326,9 @@ public String value() { * this method if you're using Google Cloud Platform directly to manage permissions. This method * is intended for integration with your proprietary software, such as a customized graphical user * interface. For example, the Cloud Platform Console tests IAM permissions internally to - * determine which UI should be available to the logged-in user. + * determine which UI should be available to the logged-in user. Each service that supports IAM + * lists the possible permissions; see the Supported Cloud Platform services page below for + * links to these lists. * * @return A list of booleans representing whether the caller has the permissions specified (in * the order of the given permissions) @@ -366,15 +336,20 @@ public String value() { * @see * Resource Manager testIamPermissions + * @see Supported Cloud Platform + * Services */ - List testPermissions(String projectId, List permissions); + List testPermissions(String projectId, List permissions); /** * Returns the permissions that a caller has on the specified project. You typically don't call * this method if you're using Google Cloud Platform directly to manage permissions. This method * is intended for integration with your proprietary software, such as a customized graphical user * interface. For example, the Cloud Platform Console tests IAM permissions internally to - * determine which UI should be available to the logged-in user. + * determine which UI should be available to the logged-in user. Each service that supports IAM + * lists the possible permissions; see the Supported Cloud Platform services page below for + * links to these lists. * * @return A list of booleans representing whether the caller has the permissions specified (in * the order of the given permissions) @@ -382,6 +357,10 @@ public String value() { * @see * Resource Manager testIamPermissions + * @see Supported Cloud Platform + * Services */ - List testPermissions(String projectId, Permission first, Permission... others); + List testPermissions( + String projectId, String firstPermission, String... otherPermissions); } diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java index d9911b911f0b..5526918bc1eb 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java @@ -216,19 +216,13 @@ public com.google.api.services.cloudresourcemanager.model.Policy call() { } @Override - public List testPermissions(final String projectId, final List permissions) { + public List testPermissions(final String projectId, final List permissions) { try { return runWithRetries( new Callable>() { @Override public List call() { - return resourceManagerRpc.testPermissions(projectId, - Lists.transform(permissions, new Function() { - @Override - public String apply(Permission permission) { - return permission.value(); - } - })); + return resourceManagerRpc.testPermissions(projectId, permissions); } }, options().retryParams(), EXCEPTION_HANDLER); } catch (RetryHelperException ex) { @@ -237,8 +231,9 @@ public String apply(Permission permission) { } @Override - public List testPermissions(String projectId, Permission first, Permission... others) { - return testPermissions(projectId, Lists.asList(first, others)); + public List testPermissions( + String projectId, String firstPermission, String... otherPermissions) { + return testPermissions(projectId, Lists.asList(firstPermission, otherPermissions)); } private Map optionMap(Option... options) { diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java index 8ddca18b6261..4d466e55a897 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java @@ -18,7 +18,6 @@ import com.google.common.collect.ImmutableSet; import com.google.common.io.ByteStreams; import com.google.gcloud.AuthCredentials; -import com.google.gcloud.resourcemanager.ResourceManager.Permission; import com.google.gcloud.resourcemanager.ResourceManagerOptions; import com.sun.net.httpserver.Headers; @@ -38,7 +37,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Random; @@ -66,7 +64,8 @@ *
    1. IAM policies are set to an empty policy with version 0 (only legacy roles supported) upon * project creation. The actual service will not have an empty list of bindings and may also * set your version to 1. - *
    2. There is no input validation for the policy provided when replacing a policy. + *
    3. There is no input validation for the policy provided when replacing a policy or calling + * testIamPermissions. *
    4. In this mock, projects never move from the DELETE_REQUESTED lifecycle state to * DELETE_IN_PROGRESS without an explicit call to the utility method * {@link #changeLifecycleState}. Similarly, a project is never completely removed without an @@ -89,12 +88,8 @@ public class LocalResourceManagerHelper { private static final Pattern LIST_FIELDS_PATTERN = Pattern.compile("(.*?)projects\\((.*?)\\)(.*?)"); private static final String[] NO_FIELDS = {}; - private static final Set PERMISSIONS = new HashSet<>(); static { - for (Permission permission : Permission.values()) { - PERMISSIONS.add(permission.value()); - } try { BASE_CONTEXT = new URI(CONTEXT); } catch (URISyntaxException e) { @@ -635,11 +630,6 @@ synchronized Response testPermissions(String projectId, List permissions if (!projects.containsKey(projectId)) { return Error.PERMISSION_DENIED.response("Project " + projectId + " not found."); } - for (String p : permissions) { - if (!PERMISSIONS.contains(p)) { - return Error.INVALID_ARGUMENT.response("Invalid permission: " + p); - } - } try { return new Response(HTTP_OK, jsonFactory.toString(new TestIamPermissionsResponse().setPermissions(permissions))); diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java index 829094816664..75df0ef9e3ae 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java @@ -676,13 +676,6 @@ public void testTestPermissions() { assertEquals("Project nonexistent-project not found.", e.getMessage()); } rpc.create(PARTIAL_PROJECT); - try { - rpc.testPermissions(PARTIAL_PROJECT.getProjectId(), ImmutableList.of("get")); - fail("Invalid permission."); - } catch (ResourceManagerException e) { - assertEquals(400, e.code()); - assertEquals("Invalid permission: get", e.getMessage()); - } assertEquals(ImmutableList.of(true), rpc.testPermissions(PARTIAL_PROJECT.getProjectId(), permissions)); } diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/PolicyTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/PolicyTest.java index 7315b9f92565..04826dd9540f 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/PolicyTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/PolicyTest.java @@ -18,12 +18,9 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNull; -import com.google.common.collect.ImmutableSet; import com.google.gcloud.Identity; -import com.google.gcloud.resourcemanager.Policy.Role; -import com.google.gcloud.resourcemanager.Policy.Role.Type; +import com.google.gcloud.resourcemanager.Policy.ProjectRole; import org.junit.Test; @@ -37,10 +34,10 @@ public class PolicyTest { private static final Identity GROUP = Identity.group("group@gmail.com"); private static final Identity DOMAIN = Identity.domain("google.com"); private static final Policy SIMPLE_POLICY = Policy.builder() - .addIdentity(Role.owner(), USER) - .addIdentity(Role.viewer(), ALL_USERS) - .addIdentity(Role.editor(), ALL_AUTH_USERS, DOMAIN) - .addIdentity(Role.rawRole("some-role"), SERVICE_ACCOUNT, GROUP) + .addIdentity(ProjectRole.OWNER.value(), USER) + .addIdentity(ProjectRole.VIEWER.value(), ALL_USERS) + .addIdentity(ProjectRole.EDITOR.value(), ALL_AUTH_USERS, DOMAIN) + .addIdentity("roles/some-role", SERVICE_ACCOUNT, GROUP) .build(); private static final Policy FULL_POLICY = new Policy.Builder(SIMPLE_POLICY.bindings(), "etag", 1).build(); @@ -57,21 +54,13 @@ public void testPolicyToAndFromPb() { assertEquals(SIMPLE_POLICY, Policy.fromPb(SIMPLE_POLICY.toPb())); } - @Test - public void testRoleType() { - assertEquals(Type.OWNER, Role.owner().type()); - assertEquals(Type.EDITOR, Role.editor().type()); - assertEquals(Type.VIEWER, Role.viewer().type()); - assertNull(Role.rawRole("raw-role").type()); - } - @Test public void testEquals() { Policy copy = Policy.builder() - .addIdentity(Role.owner(), USER) - .addIdentity(Role.viewer(), ALL_USERS) - .addIdentity(Role.editor(), ALL_AUTH_USERS, DOMAIN) - .addIdentity(Role.rawRole("some-role"), SERVICE_ACCOUNT, GROUP) + .addIdentity(ProjectRole.OWNER.value(), USER) + .addIdentity(ProjectRole.VIEWER.value(), ALL_USERS) + .addIdentity(ProjectRole.EDITOR.value(), ALL_AUTH_USERS, DOMAIN) + .addIdentity("roles/some-role", SERVICE_ACCOUNT, GROUP) .build(); assertEquals(SIMPLE_POLICY, copy); assertNotEquals(SIMPLE_POLICY, FULL_POLICY); diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectTest.java index 53b37111b705..acce6f84c680 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectTest.java @@ -27,11 +27,9 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import com.google.gcloud.Identity; -import com.google.gcloud.resourcemanager.Policy.Role; +import com.google.gcloud.resourcemanager.Policy.ProjectRole; import com.google.gcloud.resourcemanager.ProjectInfo.ResourceId; -import com.google.gcloud.resourcemanager.ResourceManager.Permission; import org.junit.After; import org.junit.Before; @@ -58,8 +56,8 @@ public class ProjectTest { private static final Identity SERVICE_ACCOUNT = Identity.serviceAccount("service-account@gmail.com"); private static final Policy POLICY = Policy.builder() - .addIdentity(Role.owner(), USER) - .addIdentity(Role.editor(), SERVICE_ACCOUNT) + .addIdentity(ProjectRole.OWNER.value(), USER) + .addIdentity(ProjectRole.EDITOR.value(), SERVICE_ACCOUNT) .build(); private ResourceManager serviceMockReturnsOptions = createStrictMock(ResourceManager.class); @@ -239,16 +237,19 @@ public void testReplacePolicy() { @Test public void testTestPermissions() { List response = ImmutableList.of(true, true); + String getPermission = "resourcemanager.projects.get"; + String deletePermission = "resourcemanager.projects.delete"; expect(resourceManager.options()).andReturn(mockOptions).times(1); - expect(resourceManager.testPermissions(PROJECT_ID, Permission.GET, Permission.DELETE)) + expect(resourceManager.testPermissions(PROJECT_ID, getPermission, deletePermission)) .andReturn(response); expect(resourceManager.testPermissions( - PROJECT_ID, ImmutableList.of(Permission.GET, Permission.DELETE))).andReturn(response); + PROJECT_ID, ImmutableList.of(getPermission, deletePermission))) + .andReturn(response); replay(resourceManager); initializeProject(); - assertEquals(response, project.testPermissions(Permission.GET, Permission.DELETE)); + assertEquals(response, project.testPermissions(getPermission, deletePermission)); assertEquals( - response, project.testPermissions(ImmutableList.of(Permission.GET, Permission.DELETE))); + response, project.testPermissions(ImmutableList.of(getPermission, deletePermission))); } private void compareProjects(Project expected, Project value) { diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java index 9cb9bfcba02f..2525039e9c0d 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java @@ -29,9 +29,8 @@ import com.google.common.collect.ImmutableMap; import com.google.gcloud.Identity; import com.google.gcloud.Page; -import com.google.gcloud.resourcemanager.Policy.Role; +import com.google.gcloud.resourcemanager.Policy.ProjectRole; import com.google.gcloud.resourcemanager.ProjectInfo.ResourceId; -import com.google.gcloud.resourcemanager.ResourceManager.Permission; import com.google.gcloud.resourcemanager.ResourceManager.ProjectField; import com.google.gcloud.resourcemanager.ResourceManager.ProjectGetOption; import com.google.gcloud.resourcemanager.ResourceManager.ProjectListOption; @@ -71,10 +70,12 @@ public class ResourceManagerImplTest { .parent(PARENT) .build(); private static final Map EMPTY_RPC_OPTIONS = ImmutableMap.of(); - private static final Policy POLICY = Policy.builder() - .addIdentity(Role.owner(), Identity.user("me@gmail.com")) - .addIdentity(Role.editor(), Identity.serviceAccount("serviceaccount@gmail.com")) - .build(); + private static final Policy POLICY = + Policy.builder() + .addIdentity(ProjectRole.OWNER.value(), Identity.user("me@gmail.com")) + .addIdentity( + ProjectRole.EDITOR.value(), Identity.serviceAccount("serviceaccount@gmail.com")) + .build(); @Rule public ExpectedException thrown = ExpectedException.none(); @@ -369,7 +370,7 @@ public void testReplacePolicy() { @Test public void testTestPermissions() { - List permissions = ImmutableList.of(Permission.GET); + List permissions = ImmutableList.of("resourcemanager.projects.get"); try { RESOURCE_MANAGER.testPermissions("nonexistent-project", permissions); fail("Nonexistent project"); @@ -380,8 +381,12 @@ public void testTestPermissions() { RESOURCE_MANAGER.create(PARTIAL_PROJECT); assertEquals(ImmutableList.of(true), RESOURCE_MANAGER.testPermissions(PARTIAL_PROJECT.projectId(), permissions)); - assertEquals(ImmutableList.of(true, true), RESOURCE_MANAGER.testPermissions( - PARTIAL_PROJECT.projectId(), Permission.DELETE, Permission.GET)); + assertEquals( + ImmutableList.of(true, true), + RESOURCE_MANAGER.testPermissions( + PARTIAL_PROJECT.projectId(), + "resourcemanager.projects.delete", + "resourcemanager.projects.get")); } @Test diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java index 1c0b9c68c86d..4bc1bcede195 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java @@ -21,6 +21,7 @@ import com.google.gcloud.Identity; import com.google.gcloud.PageImpl; import com.google.gcloud.Restorable; +import com.google.gcloud.resourcemanager.Policy.ProjectRole; import java.io.Serializable; import java.util.Collections; @@ -45,8 +46,9 @@ public class SerializationTest extends BaseSerializationTest { ResourceManager.ProjectGetOption.fields(ResourceManager.ProjectField.NAME); private static final ResourceManager.ProjectListOption PROJECT_LIST_OPTION = ResourceManager.ProjectListOption.filter("name:*"); - private static final Policy POLICY = - Policy.builder().addIdentity(Policy.Role.viewer(), Identity.user("abc@gmail.com")).build(); + private static final Policy POLICY = Policy.builder() + .addIdentity(ProjectRole.VIEWER.value(), Identity.user("abc@gmail.com")) + .build(); private static final ResourceManagerException RESOURCE_MANAGER_EXCEPTION = new ResourceManagerException(42, "message"); From 52bf6c1001716cd5f2145ff3be40631d542cd200 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 21 Mar 2016 19:51:37 -0700 Subject: [PATCH 192/375] remove varargs for testPermissions and other minor fixes --- .../google/gcloud/resourcemanager/Policy.java | 4 ++-- .../gcloud/resourcemanager/Project.java | 23 ------------------- .../resourcemanager/ResourceManager.java | 22 ------------------ .../resourcemanager/ResourceManagerImpl.java | 7 ------ .../gcloud/resourcemanager/ProjectTest.java | 3 --- .../ResourceManagerImplTest.java | 6 ----- 6 files changed, 2 insertions(+), 63 deletions(-) diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java index 884f474bed59..219d74262319 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java @@ -47,7 +47,7 @@ public class Policy extends IamPolicy { /** * The project-level roles in an IAM policy. This enum is not an exhaustive list of all roles * you can use in an IAM policy. You can also use service-specific roles (e.g. - * roles/pubsub.editor). See the Supported Cloud Platform Services page for links + * "roles/pubsub.editor"). See the Supported Cloud Platform Services page for links * to service-specific roles. * * @see Supported Cloud @@ -74,7 +74,7 @@ public enum ProjectRole { */ OWNER("roles/owner"); - String value; + private final String value; private ProjectRole(String value) { this.value = value; diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java index de5e6c336af4..bf9cf0e01a6d 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java @@ -251,29 +251,6 @@ List testPermissions(List permissions) { return resourceManager.testPermissions(projectId(), permissions); } - /** - * Returns the permissions that a caller has on this project. You typically don't call this method - * if you're using Google Cloud Platform directly to manage permissions. This method is intended - * for integration with your proprietary software, such as a customized graphical user interface. - * For example, the Cloud Platform Console tests IAM permissions internally to determine which UI - * should be available to the logged-in user. Each service that supports IAM lists the possible - * permissions; see the Supported Cloud Platform services page below for links to these - * lists. - * - * @return a list of booleans representing whether the caller has the permissions specified (in - * the order of the given permissions) - * @throws ResourceManagerException upon failure - * @see - * Resource Manager testIamPermissions - * @see Supported Cloud Platform - * Services - */ - List testPermissions(String firstPermission, String... otherPermissions) { - return resourceManager.testPermissions(projectId(), firstPermission, otherPermissions); - } - @Override public Builder toBuilder() { return new Builder(this); diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java index 708bd711b477..70eeb9c8eb50 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java @@ -341,26 +341,4 @@ public static ProjectListOption fields(ProjectField... fields) { * Services */ List testPermissions(String projectId, List permissions); - - /** - * Returns the permissions that a caller has on the specified project. You typically don't call - * this method if you're using Google Cloud Platform directly to manage permissions. This method - * is intended for integration with your proprietary software, such as a customized graphical user - * interface. For example, the Cloud Platform Console tests IAM permissions internally to - * determine which UI should be available to the logged-in user. Each service that supports IAM - * lists the possible permissions; see the Supported Cloud Platform services page below for - * links to these lists. - * - * @return A list of booleans representing whether the caller has the permissions specified (in - * the order of the given permissions) - * @throws ResourceManagerException upon failure - * @see - * Resource Manager testIamPermissions - * @see Supported Cloud Platform - * Services - */ - List testPermissions( - String projectId, String firstPermission, String... otherPermissions); } diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java index 5526918bc1eb..e4663cb74cb9 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java @@ -23,7 +23,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.gcloud.BaseService; import com.google.gcloud.Page; @@ -230,12 +229,6 @@ public List call() { } } - @Override - public List testPermissions( - String projectId, String firstPermission, String... otherPermissions) { - return testPermissions(projectId, Lists.asList(firstPermission, otherPermissions)); - } - private Map optionMap(Option... options) { Map temp = Maps.newEnumMap(ResourceManagerRpc.Option.class); for (Option option : options) { diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectTest.java index acce6f84c680..0f4c205dde17 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectTest.java @@ -240,14 +240,11 @@ public void testTestPermissions() { String getPermission = "resourcemanager.projects.get"; String deletePermission = "resourcemanager.projects.delete"; expect(resourceManager.options()).andReturn(mockOptions).times(1); - expect(resourceManager.testPermissions(PROJECT_ID, getPermission, deletePermission)) - .andReturn(response); expect(resourceManager.testPermissions( PROJECT_ID, ImmutableList.of(getPermission, deletePermission))) .andReturn(response); replay(resourceManager); initializeProject(); - assertEquals(response, project.testPermissions(getPermission, deletePermission)); assertEquals( response, project.testPermissions(ImmutableList.of(getPermission, deletePermission))); } diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java index 2525039e9c0d..7d52901aa372 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java @@ -381,12 +381,6 @@ public void testTestPermissions() { RESOURCE_MANAGER.create(PARTIAL_PROJECT); assertEquals(ImmutableList.of(true), RESOURCE_MANAGER.testPermissions(PARTIAL_PROJECT.projectId(), permissions)); - assertEquals( - ImmutableList.of(true, true), - RESOURCE_MANAGER.testPermissions( - PARTIAL_PROJECT.projectId(), - "resourcemanager.projects.delete", - "resourcemanager.projects.get")); } @Test From b7c6da4702a665b31e74ea6aef8b7dd7c89e0ce5 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 22 Mar 2016 17:13:45 +0100 Subject: [PATCH 193/375] Rename startPageToken to pageToken in Storage and BigQuery --- .../main/java/com/google/gcloud/bigquery/BigQuery.java | 10 +++++----- .../com/google/gcloud/bigquery/BigQueryImplTest.java | 10 +++++----- .../main/java/com/google/gcloud/storage/Storage.java | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java index e06c8d86ee5f..14e324a43370 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java @@ -180,7 +180,7 @@ public static DatasetListOption pageSize(long pageSize) { /** * Returns an option to specify the page token from which to start listing datasets. */ - public static DatasetListOption startPageToken(String pageToken) { + public static DatasetListOption pageToken(String pageToken) { return new DatasetListOption(BigQueryRpc.Option.PAGE_TOKEN, pageToken); } @@ -256,7 +256,7 @@ public static TableListOption pageSize(long pageSize) { /** * Returns an option to specify the page token from which to start listing tables. */ - public static TableListOption startPageToken(String pageToken) { + public static TableListOption pageToken(String pageToken) { return new TableListOption(BigQueryRpc.Option.PAGE_TOKEN, pageToken); } } @@ -305,7 +305,7 @@ public static TableDataListOption pageSize(long pageSize) { /** * Returns an option to specify the page token from which to start listing table data. */ - public static TableDataListOption startPageToken(String pageToken) { + public static TableDataListOption pageToken(String pageToken) { return new TableDataListOption(BigQueryRpc.Option.PAGE_TOKEN, pageToken); } @@ -362,7 +362,7 @@ public static JobListOption pageSize(long pageSize) { /** * Returns an option to specify the page token from which to start listing jobs. */ - public static JobListOption startPageToken(String pageToken) { + public static JobListOption pageToken(String pageToken) { return new JobListOption(BigQueryRpc.Option.PAGE_TOKEN, pageToken); } @@ -428,7 +428,7 @@ public static QueryResultsOption pageSize(long pageSize) { /** * Returns an option to specify the page token from which to start getting query results. */ - public static QueryResultsOption startPageToken(String pageToken) { + public static QueryResultsOption pageToken(String pageToken) { return new QueryResultsOption(BigQueryRpc.Option.PAGE_TOKEN, pageToken); } diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java index b398f238386a..a6f512800024 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java @@ -169,7 +169,7 @@ public class BigQueryImplTest { private static final BigQuery.DatasetListOption DATASET_LIST_ALL = BigQuery.DatasetListOption.all(); private static final BigQuery.DatasetListOption DATASET_LIST_PAGE_TOKEN = - BigQuery.DatasetListOption.startPageToken("cursor"); + BigQuery.DatasetListOption.pageToken("cursor"); private static final BigQuery.DatasetListOption DATASET_LIST_PAGE_SIZE = BigQuery.DatasetListOption.pageSize(42L); private static final Map DATASET_LIST_OPTIONS = ImmutableMap.of( @@ -191,7 +191,7 @@ public class BigQueryImplTest { private static final BigQuery.TableListOption TABLE_LIST_PAGE_SIZE = BigQuery.TableListOption.pageSize(42L); private static final BigQuery.TableListOption TABLE_LIST_PAGE_TOKEN = - BigQuery.TableListOption.startPageToken("cursor"); + BigQuery.TableListOption.pageToken("cursor"); private static final Map TABLE_LIST_OPTIONS = ImmutableMap.of( BigQueryRpc.Option.MAX_RESULTS, 42L, BigQueryRpc.Option.PAGE_TOKEN, "cursor"); @@ -200,7 +200,7 @@ public class BigQueryImplTest { private static final BigQuery.TableDataListOption TABLE_DATA_LIST_PAGE_SIZE = BigQuery.TableDataListOption.pageSize(42L); private static final BigQuery.TableDataListOption TABLE_DATA_LIST_PAGE_TOKEN = - BigQuery.TableDataListOption.startPageToken("cursor"); + BigQuery.TableDataListOption.pageToken("cursor"); private static final BigQuery.TableDataListOption TABLE_DATA_LIST_START_INDEX = BigQuery.TableDataListOption.startIndex(0L); private static final Map TABLE_DATA_LIST_OPTIONS = ImmutableMap.of( @@ -220,7 +220,7 @@ public class BigQueryImplTest { private static final BigQuery.JobListOption JOB_LIST_STATE_FILTER = BigQuery.JobListOption.stateFilter(JobStatus.State.DONE, JobStatus.State.PENDING); private static final BigQuery.JobListOption JOB_LIST_PAGE_TOKEN = - BigQuery.JobListOption.startPageToken("cursor"); + BigQuery.JobListOption.pageToken("cursor"); private static final BigQuery.JobListOption JOB_LIST_PAGE_SIZE = BigQuery.JobListOption.pageSize(42L); private static final Map JOB_LIST_OPTIONS = ImmutableMap.of( @@ -235,7 +235,7 @@ public class BigQueryImplTest { private static final BigQuery.QueryResultsOption QUERY_RESULTS_OPTION_INDEX = BigQuery.QueryResultsOption.startIndex(1024L); private static final BigQuery.QueryResultsOption QUERY_RESULTS_OPTION_PAGE_TOKEN = - BigQuery.QueryResultsOption.startPageToken("cursor"); + BigQuery.QueryResultsOption.pageToken("cursor"); private static final BigQuery.QueryResultsOption QUERY_RESULTS_OPTION_PAGE_SIZE = BigQuery.QueryResultsOption.pageSize(0L); private static final Map QUERY_RESULTS_OPTIONS = ImmutableMap.of( diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index b4fbe45244b0..78f421e94e52 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -634,7 +634,7 @@ public static BucketListOption pageSize(long pageSize) { /** * Returns an option to specify the page token from which to start listing buckets. */ - public static BucketListOption startPageToken(String pageToken) { + public static BucketListOption pageToken(String pageToken) { return new BucketListOption(StorageRpc.Option.PAGE_TOKEN, pageToken); } @@ -680,7 +680,7 @@ public static BlobListOption pageSize(long pageSize) { /** * Returns an option to specify the page token from which to start listing blobs. */ - public static BlobListOption startPageToken(String pageToken) { + public static BlobListOption pageToken(String pageToken) { return new BlobListOption(StorageRpc.Option.PAGE_TOKEN, pageToken); } From e369b3c32a4cfe71df798ed4dcc036f8cf3e3545 Mon Sep 17 00:00:00 2001 From: Garrett Jones Date: Tue, 22 Mar 2016 12:11:01 -0700 Subject: [PATCH 194/375] Regenerating (fixing style issues) --- .../gcloud/pubsub/spi/v1/PublisherApi.java | 48 +++++++++--------- .../pubsub/spi/v1/PublisherSettings.java | 9 ++-- .../gcloud/pubsub/spi/v1/SubscriberApi.java | 50 ++++++++++--------- .../pubsub/spi/v1/SubscriberSettings.java | 9 ++-- gcloud-java-pubsub/pom.xml | 2 +- .../gcloud/pubsub/spi/v1/PublisherApi.java | 48 +++++++++--------- .../pubsub/spi/v1/PublisherSettings.java | 9 ++-- .../gcloud/pubsub/spi/v1/SubscriberApi.java | 50 ++++++++++--------- .../pubsub/spi/v1/SubscriberSettings.java | 9 ++-- .../pubsub/spi/v1/PublisherApiTest.java | 6 ++- 10 files changed, 127 insertions(+), 113 deletions(-) diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java index 1930702f9e84..fa6da27a72bd 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java @@ -66,9 +66,25 @@ */ @javax.annotation.Generated("by GAPIC") public class PublisherApi implements AutoCloseable { + // ======== + // Members + // ======== + + private final ManagedChannel channel; + private final List closeables = new ArrayList<>(); + + private final ApiCallable createTopicCallable; + private final ApiCallable publishCallable; + private final ApiCallable getTopicCallable; + private final ApiCallable listTopicsCallable; + private final ApiCallable> listTopicsIterableCallable; + private final ApiCallable + listTopicSubscriptionsCallable; + private final ApiCallable> + listTopicSubscriptionsIterableCallable; + private final ApiCallable deleteTopicCallable; public static class ResourceNames { - private ResourceNames() {} // ======================= // ResourceNames Constants @@ -94,6 +110,8 @@ private ResourceNames() {} private static final PathTemplate TOPIC_PATH_TEMPLATE = PathTemplate.create("projects/{project}/topics/{topic}"); + private ResourceNames() {} + // ============================== // Resource Name Helper Functions // ============================== @@ -154,24 +172,6 @@ public static final String parseTopicFromTopicPath(String topicPath) { } } - // ======== - // Members - // ======== - - private final ManagedChannel channel; - private final List closeables = new ArrayList<>(); - - private final ApiCallable createTopicCallable; - private final ApiCallable publishCallable; - private final ApiCallable getTopicCallable; - private final ApiCallable listTopicsCallable; - private final ApiCallable> listTopicsIterableCallable; - private final ApiCallable - listTopicSubscriptionsCallable; - private final ApiCallable> - listTopicSubscriptionsIterableCallable; - private final ApiCallable deleteTopicCallable; - // =============== // Factory Methods // =============== @@ -187,8 +187,9 @@ public static PublisherApi create() throws IOException { } /** - * Constructs an instance of PublisherApi, using the given settings. The channels are created based - * on the settings passed in, or defaults for any settings that are not set. + * Constructs an instance of PublisherApi, using the given settings. + * The channels are created based on the settings passed in, or defaults for any + * settings that are not set. * * * @@ -198,8 +199,9 @@ public static PublisherApi create(PublisherSettings settings) throws IOException } /** - * Constructs an instance of PublisherApi, using the given settings. This is protected so that it - * easy to make a subclass, but otherwise, the static factory methods should be preferred. + * Constructs an instance of PublisherApi, using the given settings. + * This is protected so that it easy to make a subclass, but otherwise, the static + * factory methods should be preferred. * * * diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java index 5f60fa374553..11566404546f 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java @@ -139,6 +139,8 @@ public class PublisherSettings extends ServiceApiSettings { RETRY_PARAM_DEFINITIONS = definitions.build(); } + private final MethodBuilders methods; + private static class MethodBuilders { private final ApiCallableBuilder createTopicMethod; private final BundlableApiCallableBuilder publishMethod; @@ -195,8 +197,6 @@ public MethodBuilders() { } } - private final MethodBuilders methods; - // =============== // Factory Methods // =============== @@ -219,8 +219,9 @@ public static PublisherSettings create() { } /** - * Constructs an instance of PublisherSettings with default settings. This is protected so that it - * easy to make a subclass, but otherwise, the static factory methods should be preferred. + * Constructs an instance of PublisherSettings with default settings. This is protected + * so that it easy to make a subclass, but otherwise, the static factory methods should be + * preferred. * * * diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java index c794fddb1943..d53dca7f8885 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java @@ -65,9 +65,26 @@ */ @javax.annotation.Generated("by GAPIC") public class SubscriberApi implements AutoCloseable { + // ======== + // Members + // ======== + + private final ManagedChannel channel; + private final List closeables = new ArrayList<>(); + + private final ApiCallable createSubscriptionCallable; + private final ApiCallable getSubscriptionCallable; + private final ApiCallable + listSubscriptionsCallable; + private final ApiCallable> + listSubscriptionsIterableCallable; + private final ApiCallable deleteSubscriptionCallable; + private final ApiCallable modifyAckDeadlineCallable; + private final ApiCallable acknowledgeCallable; + private final ApiCallable pullCallable; + private final ApiCallable modifyPushConfigCallable; public static class ResourceNames { - private ResourceNames() {} // ======================= // ResourceNames Constants @@ -93,6 +110,8 @@ private ResourceNames() {} private static final PathTemplate SUBSCRIPTION_PATH_TEMPLATE = PathTemplate.create("projects/{project}/subscriptions/{subscription}"); + private ResourceNames() {} + // ============================== // Resource Name Helper Functions // ============================== @@ -154,25 +173,6 @@ public static final String parseSubscriptionFromSubscriptionPath(String subscrip } } - // ======== - // Members - // ======== - - private final ManagedChannel channel; - private final List closeables = new ArrayList<>(); - - private final ApiCallable createSubscriptionCallable; - private final ApiCallable getSubscriptionCallable; - private final ApiCallable - listSubscriptionsCallable; - private final ApiCallable> - listSubscriptionsIterableCallable; - private final ApiCallable deleteSubscriptionCallable; - private final ApiCallable modifyAckDeadlineCallable; - private final ApiCallable acknowledgeCallable; - private final ApiCallable pullCallable; - private final ApiCallable modifyPushConfigCallable; - // =============== // Factory Methods // =============== @@ -188,8 +188,9 @@ public static SubscriberApi create() throws IOException { } /** - * Constructs an instance of SubscriberApi, using the given settings. The channels are created based - * on the settings passed in, or defaults for any settings that are not set. + * Constructs an instance of SubscriberApi, using the given settings. + * The channels are created based on the settings passed in, or defaults for any + * settings that are not set. * * * @@ -199,8 +200,9 @@ public static SubscriberApi create(SubscriberSettings settings) throws IOExcepti } /** - * Constructs an instance of SubscriberApi, using the given settings. This is protected so that it - * easy to make a subclass, but otherwise, the static factory methods should be preferred. + * Constructs an instance of SubscriberApi, using the given settings. + * This is protected so that it easy to make a subclass, but otherwise, the static + * factory methods should be preferred. * * * diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java index df9ea36e69b8..d9da44aa81f7 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java @@ -133,6 +133,8 @@ public class SubscriberSettings extends ServiceApiSettings { RETRY_PARAM_DEFINITIONS = definitions.build(); } + private final MethodBuilders methods; + private static class MethodBuilders { private final ApiCallableBuilder createSubscriptionMethod; private final ApiCallableBuilder getSubscriptionMethod; @@ -198,8 +200,6 @@ public MethodBuilders() { } } - private final MethodBuilders methods; - // =============== // Factory Methods // =============== @@ -222,8 +222,9 @@ public static SubscriberSettings create() { } /** - * Constructs an instance of SubscriberSettings with default settings. This is protected so that it - * easy to make a subclass, but otherwise, the static factory methods should be preferred. + * Constructs an instance of SubscriberSettings with default settings. This is protected + * so that it easy to make a subclass, but otherwise, the static factory methods should be + * preferred. * * * diff --git a/gcloud-java-pubsub/pom.xml b/gcloud-java-pubsub/pom.xml index 987aa99667c9..2bd755f63a8c 100644 --- a/gcloud-java-pubsub/pom.xml +++ b/gcloud-java-pubsub/pom.xml @@ -19,7 +19,7 @@ com.google.api gax - 0.0.5-SNAPSHOT + 0.0.5 com.google.api.grpc diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java index 1930702f9e84..fa6da27a72bd 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java @@ -66,9 +66,25 @@ */ @javax.annotation.Generated("by GAPIC") public class PublisherApi implements AutoCloseable { + // ======== + // Members + // ======== + + private final ManagedChannel channel; + private final List closeables = new ArrayList<>(); + + private final ApiCallable createTopicCallable; + private final ApiCallable publishCallable; + private final ApiCallable getTopicCallable; + private final ApiCallable listTopicsCallable; + private final ApiCallable> listTopicsIterableCallable; + private final ApiCallable + listTopicSubscriptionsCallable; + private final ApiCallable> + listTopicSubscriptionsIterableCallable; + private final ApiCallable deleteTopicCallable; public static class ResourceNames { - private ResourceNames() {} // ======================= // ResourceNames Constants @@ -94,6 +110,8 @@ private ResourceNames() {} private static final PathTemplate TOPIC_PATH_TEMPLATE = PathTemplate.create("projects/{project}/topics/{topic}"); + private ResourceNames() {} + // ============================== // Resource Name Helper Functions // ============================== @@ -154,24 +172,6 @@ public static final String parseTopicFromTopicPath(String topicPath) { } } - // ======== - // Members - // ======== - - private final ManagedChannel channel; - private final List closeables = new ArrayList<>(); - - private final ApiCallable createTopicCallable; - private final ApiCallable publishCallable; - private final ApiCallable getTopicCallable; - private final ApiCallable listTopicsCallable; - private final ApiCallable> listTopicsIterableCallable; - private final ApiCallable - listTopicSubscriptionsCallable; - private final ApiCallable> - listTopicSubscriptionsIterableCallable; - private final ApiCallable deleteTopicCallable; - // =============== // Factory Methods // =============== @@ -187,8 +187,9 @@ public static PublisherApi create() throws IOException { } /** - * Constructs an instance of PublisherApi, using the given settings. The channels are created based - * on the settings passed in, or defaults for any settings that are not set. + * Constructs an instance of PublisherApi, using the given settings. + * The channels are created based on the settings passed in, or defaults for any + * settings that are not set. * * * @@ -198,8 +199,9 @@ public static PublisherApi create(PublisherSettings settings) throws IOException } /** - * Constructs an instance of PublisherApi, using the given settings. This is protected so that it - * easy to make a subclass, but otherwise, the static factory methods should be preferred. + * Constructs an instance of PublisherApi, using the given settings. + * This is protected so that it easy to make a subclass, but otherwise, the static + * factory methods should be preferred. * * * diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java index 5f60fa374553..11566404546f 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java @@ -139,6 +139,8 @@ public class PublisherSettings extends ServiceApiSettings { RETRY_PARAM_DEFINITIONS = definitions.build(); } + private final MethodBuilders methods; + private static class MethodBuilders { private final ApiCallableBuilder createTopicMethod; private final BundlableApiCallableBuilder publishMethod; @@ -195,8 +197,6 @@ public MethodBuilders() { } } - private final MethodBuilders methods; - // =============== // Factory Methods // =============== @@ -219,8 +219,9 @@ public static PublisherSettings create() { } /** - * Constructs an instance of PublisherSettings with default settings. This is protected so that it - * easy to make a subclass, but otherwise, the static factory methods should be preferred. + * Constructs an instance of PublisherSettings with default settings. This is protected + * so that it easy to make a subclass, but otherwise, the static factory methods should be + * preferred. * * * diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java index c794fddb1943..d53dca7f8885 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java @@ -65,9 +65,26 @@ */ @javax.annotation.Generated("by GAPIC") public class SubscriberApi implements AutoCloseable { + // ======== + // Members + // ======== + + private final ManagedChannel channel; + private final List closeables = new ArrayList<>(); + + private final ApiCallable createSubscriptionCallable; + private final ApiCallable getSubscriptionCallable; + private final ApiCallable + listSubscriptionsCallable; + private final ApiCallable> + listSubscriptionsIterableCallable; + private final ApiCallable deleteSubscriptionCallable; + private final ApiCallable modifyAckDeadlineCallable; + private final ApiCallable acknowledgeCallable; + private final ApiCallable pullCallable; + private final ApiCallable modifyPushConfigCallable; public static class ResourceNames { - private ResourceNames() {} // ======================= // ResourceNames Constants @@ -93,6 +110,8 @@ private ResourceNames() {} private static final PathTemplate SUBSCRIPTION_PATH_TEMPLATE = PathTemplate.create("projects/{project}/subscriptions/{subscription}"); + private ResourceNames() {} + // ============================== // Resource Name Helper Functions // ============================== @@ -154,25 +173,6 @@ public static final String parseSubscriptionFromSubscriptionPath(String subscrip } } - // ======== - // Members - // ======== - - private final ManagedChannel channel; - private final List closeables = new ArrayList<>(); - - private final ApiCallable createSubscriptionCallable; - private final ApiCallable getSubscriptionCallable; - private final ApiCallable - listSubscriptionsCallable; - private final ApiCallable> - listSubscriptionsIterableCallable; - private final ApiCallable deleteSubscriptionCallable; - private final ApiCallable modifyAckDeadlineCallable; - private final ApiCallable acknowledgeCallable; - private final ApiCallable pullCallable; - private final ApiCallable modifyPushConfigCallable; - // =============== // Factory Methods // =============== @@ -188,8 +188,9 @@ public static SubscriberApi create() throws IOException { } /** - * Constructs an instance of SubscriberApi, using the given settings. The channels are created based - * on the settings passed in, or defaults for any settings that are not set. + * Constructs an instance of SubscriberApi, using the given settings. + * The channels are created based on the settings passed in, or defaults for any + * settings that are not set. * * * @@ -199,8 +200,9 @@ public static SubscriberApi create(SubscriberSettings settings) throws IOExcepti } /** - * Constructs an instance of SubscriberApi, using the given settings. This is protected so that it - * easy to make a subclass, but otherwise, the static factory methods should be preferred. + * Constructs an instance of SubscriberApi, using the given settings. + * This is protected so that it easy to make a subclass, but otherwise, the static + * factory methods should be preferred. * * * diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java index df9ea36e69b8..d9da44aa81f7 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java @@ -133,6 +133,8 @@ public class SubscriberSettings extends ServiceApiSettings { RETRY_PARAM_DEFINITIONS = definitions.build(); } + private final MethodBuilders methods; + private static class MethodBuilders { private final ApiCallableBuilder createSubscriptionMethod; private final ApiCallableBuilder getSubscriptionMethod; @@ -198,8 +200,6 @@ public MethodBuilders() { } } - private final MethodBuilders methods; - // =============== // Factory Methods // =============== @@ -222,8 +222,9 @@ public static SubscriberSettings create() { } /** - * Constructs an instance of SubscriberSettings with default settings. This is protected so that it - * easy to make a subclass, but otherwise, the static factory methods should be preferred. + * Constructs an instance of SubscriberSettings with default settings. This is protected + * so that it easy to make a subclass, but otherwise, the static factory methods should be + * preferred. * * * diff --git a/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/v1/PublisherApiTest.java b/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/v1/PublisherApiTest.java index a092c2fdd7ee..c25ca51ee713 100644 --- a/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/v1/PublisherApiTest.java +++ b/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/v1/PublisherApiTest.java @@ -126,7 +126,8 @@ public void testPublish() throws Exception { String topicName = PublisherApi.ResourceNames.formatTopicPath("my-project", "publish-topic"); publisherApi.createTopic(topicName); - String subscriberName = SubscriberApi.ResourceNames.formatSubscriptionPath("my-project", "my-subscribe"); + String subscriberName = + SubscriberApi.ResourceNames.formatSubscriptionPath("my-project", "my-subscribe"); PushConfig config = PushConfig.getDefaultInstance(); subscriberApi.createSubscription(subscriberName, topicName, config, 5); @@ -145,7 +146,8 @@ public void testBundledPublish() throws Exception { String topicName = PublisherApi.ResourceNames.formatTopicPath("my-project", "publish-topic"); bundledPublisherApi.createTopic(topicName); - String subscriberName = SubscriberApi.ResourceNames.formatSubscriptionPath("my-project", "my-subscribe"); + String subscriberName = + SubscriberApi.ResourceNames.formatSubscriptionPath("my-project", "my-subscribe"); PushConfig config = PushConfig.getDefaultInstance(); subscriberApi.createSubscription(subscriberName, topicName, config, 5); From e946b76d00bd174c9d0fd767915b3c2808e10e0f Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Wed, 23 Mar 2016 13:16:21 -0700 Subject: [PATCH 195/375] Updated the version in pom. --- gcloud-java-dns/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcloud-java-dns/pom.xml b/gcloud-java-dns/pom.xml index 1a559473cc82..a690a1e509a7 100644 --- a/gcloud-java-dns/pom.xml +++ b/gcloud-java-dns/pom.xml @@ -13,7 +13,7 @@ com.google.gcloud gcloud-java-pom - 0.1.5-SNAPSHOT + 0.1.6-SNAPSHOT gcloud-java-dns From 5c3fc94f60391db0c32b6d8055101c0abb9bd0e9 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Wed, 23 Mar 2016 12:43:05 -0700 Subject: [PATCH 196/375] Refactored the serialization test to use the base test --- gcloud-java-dns/pom.xml | 7 +++ .../google/gcloud/dns/SerializationTest.java | 50 +++++++------------ 2 files changed, 25 insertions(+), 32 deletions(-) diff --git a/gcloud-java-dns/pom.xml b/gcloud-java-dns/pom.xml index a690a1e509a7..b55200b8fc7d 100644 --- a/gcloud-java-dns/pom.xml +++ b/gcloud-java-dns/pom.xml @@ -40,6 +40,13 @@ + + ${project.groupId} + gcloud-java-core + ${project.version} + test-jar + test + junit junit diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java index c2bf9cfca0bb..7a0c32036878 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java @@ -16,24 +16,17 @@ package com.google.gcloud.dns; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotSame; - import com.google.common.collect.ImmutableList; +import com.google.gcloud.AuthCredentials; +import com.google.gcloud.BaseSerializationTest; +import com.google.gcloud.Restorable; import com.google.gcloud.RetryParams; -import org.junit.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; import java.io.Serializable; import java.math.BigInteger; import java.util.concurrent.TimeUnit; -public class SerializationTest { +public class SerializationTest extends BaseSerializationTest { private static final ZoneInfo FULL_ZONE_INFO = Zone.of("some zone name", "www.example.com", "some descriptions").toBuilder() @@ -86,31 +79,24 @@ public class SerializationTest { .startTimeMillis(132L) .build(); - @Test - public void testModelAndRequests() throws Exception { - Serializable[] objects = {FULL_ZONE_INFO, PARTIAL_ZONE_INFO, ZONE_LIST_OPTION, + @Override + protected Serializable[] serializableObjects() { + DnsOptions options = DnsOptions.builder() + .authCredentials(AuthCredentials.createForAppEngine()) + .projectId("id1") + .build(); + DnsOptions otherOptions = options.toBuilder() + .authCredentials(null) + .build(); + return new Serializable[]{FULL_ZONE_INFO, PARTIAL_ZONE_INFO, ZONE_LIST_OPTION, DNS_REOCRD_LIST_OPTION, CHANGE_REQUEST_LIST_OPTION, ZONE_OPTION, CHANGE_REQUEST_OPTION, PROJECT_OPTION, PARTIAL_PROJECT_INFO, FULL_PROJECT_INFO, OPTIONS, FULL_ZONE, PARTIAL_ZONE, OPTIONS, CHANGE_REQUEST_PARTIAL, DNS_RECORD_PARTIAL, DNS_RECORD_COMPLETE, - CHANGE_REQUEST_COMPLETE}; - for (Serializable obj : objects) { - Object copy = serializeAndDeserialize(obj); - assertEquals(obj, obj); - assertEquals(obj, copy); - assertNotSame(obj, copy); - assertEquals(copy, copy); - } + CHANGE_REQUEST_COMPLETE, options, otherOptions}; } - @SuppressWarnings("unchecked") - private T serializeAndDeserialize(T obj) throws IOException, ClassNotFoundException { - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - try (ObjectOutputStream output = new ObjectOutputStream(bytes)) { - output.writeObject(obj); - } - try (ObjectInputStream input = - new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray()))) { - return (T) input.readObject(); - } + @Override + protected Restorable[] restorableObjects() { + return new Restorable[0]; } } From 1a5aade24d7cf0b7d0ee64eb80c3726174800446 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Tue, 22 Mar 2016 17:08:11 -0700 Subject: [PATCH 197/375] Renamed DnsRecord to RecordSet. Fixes #779. --- README.md | 12 +- gcloud-java-dns/README.md | 70 ++++---- .../com/google/gcloud/dns/ChangeRequest.java | 62 +++---- .../main/java/com/google/gcloud/dns/Dns.java | 67 +++---- .../java/com/google/gcloud/dns/DnsImpl.java | 26 +-- .../com/google/gcloud/dns/ProjectInfo.java | 23 +-- .../dns/{DnsRecord.java => RecordSet.java} | 56 +++--- .../main/java/com/google/gcloud/dns/Zone.java | 14 +- .../com/google/gcloud/dns/package-info.java | 2 +- .../google/gcloud/dns/spi/DefaultDnsRpc.java | 2 +- .../com/google/gcloud/dns/spi/DnsRpc.java | 4 +- .../gcloud/dns/testing/LocalDnsHelper.java | 44 ++--- .../gcloud/dns/testing/OptionParsers.java | 12 +- .../google/gcloud/dns/ChangeRequestTest.java | 22 +-- .../com/google/gcloud/dns/DnsImplTest.java | 36 ++-- .../java/com/google/gcloud/dns/DnsTest.java | 48 ++--- ...{DnsRecordTest.java => RecordSetTest.java} | 75 ++++---- .../google/gcloud/dns/SerializationTest.java | 20 +-- .../java/com/google/gcloud/dns/ZoneTest.java | 42 ++--- .../com/google/gcloud/dns/it/ITDnsTest.java | 170 +++++++++--------- .../dns/testing/LocalDnsHelperTest.java | 44 ++--- gcloud-java-examples/README.md | 2 +- .../gcloud/examples/dns/DnsExample.java | 36 ++-- ...rds.java => CreateOrUpdateRecordSets.java} | 16 +- .../examples/dns/snippets/DeleteZone.java | 10 +- ...java => ManipulateZonesAndRecordSets.java} | 32 ++-- 26 files changed, 477 insertions(+), 470 deletions(-) rename gcloud-java-dns/src/main/java/com/google/gcloud/dns/{DnsRecord.java => RecordSet.java} (83%) rename gcloud-java-dns/src/test/java/com/google/gcloud/dns/{DnsRecordTest.java => RecordSetTest.java} (63%) rename gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/{CreateOrUpdateDnsRecords.java => CreateOrUpdateRecordSets.java} (83%) rename gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/{ManipulateZonesAndRecords.java => ManipulateZonesAndRecordSets.java} (84%) diff --git a/README.md b/README.md index a753a96c8b21..52229f6d5d34 100644 --- a/README.md +++ b/README.md @@ -249,13 +249,13 @@ ZoneInfo zoneInfo = ZoneInfo.of(zoneName, domainName, description); Zone zone = dns.create(zoneInfo); ``` -The second snippet shows how to create records inside a zone. The complete code can be found on [CreateOrUpdateDnsRecords.java](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateDnsRecords.java). +The second snippet shows how to create records inside a zone. The complete code can be found on [CreateOrUpdateRecordSets.java](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateRecordSets.java). ```java import com.google.gcloud.dns.ChangeRequest; import com.google.gcloud.dns.Dns; import com.google.gcloud.dns.DnsOptions; -import com.google.gcloud.dns.DnsRecord; +import com.google.gcloud.dns.RecordSet; import com.google.gcloud.dns.Zone; import java.util.Iterator; @@ -265,7 +265,7 @@ Dns dns = DnsOptions.defaultInstance().service(); String zoneName = "my-unique-zone"; Zone zone = dns.getZone(zoneName); String ip = "12.13.14.15"; -DnsRecord toCreate = DnsRecord.builder("www.someexampledomain.com.", DnsRecord.Type.A) +RecordSet toCreate = RecordSet.builder("www.someexampledomain.com.", RecordSet.Type.A) .ttl(24, TimeUnit.HOURS) .addRecord(ip) .build(); @@ -273,9 +273,9 @@ ChangeRequest.Builder changeBuilder = ChangeRequest.builder().add(toCreate); // Verify that the record does not exist yet. // If it does exist, we will overwrite it with our prepared record. -Iterator recordIterator = zone.listDnsRecords().iterateAll(); -while (recordIterator.hasNext()) { - DnsRecord current = recordIterator.next(); +Iterator recordSetIterator = zone.listRecordSets().iterateAll(); +while (recordSetIterator.hasNext()) { + RecordSet current = recordSetIterator.next(); if (toCreate.name().equals(current.name()) && toCreate.type().equals(current.type())) { changeBuilder.delete(current); diff --git a/gcloud-java-dns/README.md b/gcloud-java-dns/README.md index 4f65d8e3b814..a2c3238d1f8f 100644 --- a/gcloud-java-dns/README.md +++ b/gcloud-java-dns/README.md @@ -92,7 +92,7 @@ Dns dns = DnsOptions.defaultInstance().service(); For other authentication options, see the [Authentication](https://github.com/GoogleCloudPlatform/gcloud-java#authentication) page. #### Managing Zones -DNS records in `gcloud-java-dns` are managed inside containers called "zones". `ZoneInfo` is a class +Record sets in `gcloud-java-dns` are managed inside containers called "zones". `ZoneInfo` is a class which encapsulates metadata that describe a zone in Google Cloud DNS. `Zone`, a subclass of `ZoneInfo`, adds service-related functionality over `ZoneInfo`. @@ -100,7 +100,7 @@ functionality over `ZoneInfo`. exists within your project, you'll get a helpful error message telling you to choose another name. In the code below, replace "my-unique-zone" with a unique zone name. See more about naming rules [here](https://cloud.google.com/dns/api/v1/managedZones#name).* -In this code snippet, we create a new zone to manage DNS records for domain `someexampledomain.com.` +In this code snippet, we create a new zone to manage record sets for domain `someexampledomain.com.` *Important: The service may require that you verify ownership of the domain for which you are creating a zone. Hence, we recommend that you do so beforehand. You can verify ownership of @@ -128,8 +128,8 @@ Zone zone = dns.create(zoneInfo); System.out.printf("Zone was created and assigned ID %s.%n", zone.id()); ``` -You now have an empty zone hosted in Google Cloud DNS which is ready to be populated with DNS -records for domain name `someexampledomain.com.` Upon creating the zone, the cloud service +You now have an empty zone hosted in Google Cloud DNS which is ready to be populated with +record sets for domain name `someexampledomain.com.` Upon creating the zone, the cloud service assigned a set of DNS servers to host records for this zone and created the required SOA and NS records for the domain. The following snippet prints the list of servers assigned to the zone created above. First, import @@ -152,15 +152,15 @@ You can now instruct your domain registrar to [update your domain name servers] As soon as this happens and the change propagates through cached values in DNS resolvers, all the DNS queries will be directed to and answered by the Google Cloud DNS service. -#### Creating DNS Records -Now that we have a zone, we can add some DNS records. The DNS records held within zones are +#### Creating Record Sets +Now that we have a zone, we can add some record sets. The record sets held within zones are modified by "change requests". In this example, we create and apply a change request to -our zone that creates a DNS record of type A and points URL www.someexampledomain.com to +our zone that creates a record set of type A and points URL www.someexampledomain.com to IP address 12.13.14.15. Start by adding ```java import com.google.gcloud.dns.ChangeRequest; -import com.google.gcloud.dns.DnsRecord; +import com.google.gcloud.dns.RecordSet; import java.util.concurrent.TimeUnit; ``` @@ -168,9 +168,9 @@ import java.util.concurrent.TimeUnit; and proceed with: ```java -// Prepare a www.someexampledomain.com. type A record with ttl of 24 hours +// Prepare a www.someexampledomain.com. type A record set with ttl of 24 hours String ip = "12.13.14.15"; -DnsRecord toCreate = DnsRecord.builder("www.someexampledomain.com.", DnsRecord.Type.A) +RecordSet toCreate = RecordSet.builder("www." + zone.dnsName(), RecordSet.Type.A) .ttl(24, TimeUnit.HOURS) .addRecord(ip) .build(); @@ -182,12 +182,12 @@ ChangeRequest changeRequest = ChangeRequest.builder().add(toCreate).build(); changeRequest = zone.applyChangeRequest(changeRequest); ``` -The `addRecord` method of `DnsRecord.Builder` accepts records in the form of -strings. The format of the strings depends on the type of the DNS record to be added. -More information on the supported DNS record types and record formats can be found [here](https://cloud.google.com/dns/what-is-cloud-dns#supported_record_types). +The `addRecord` method of `RecordSet.Builder` accepts records in the form of +strings. The format of the strings depends on the type of the record sets to be added. +More information on the supported record set types and record formats can be found [here](https://cloud.google.com/dns/what-is-cloud-dns#supported_record_types). -If you already have a DNS record, Cloud DNS will return an error upon an attempt to create a duplicate of it. -You can modify the code above to create a DNS record or update it if it already exists by making the +If you already have a record set, Cloud DNS will return an error upon an attempt to create a duplicate of it. +You can modify the code above to create a record set or update it if it already exists by making the following adjustment in your imports ```java @@ -202,9 +202,9 @@ ChangeRequest.Builder changeBuilder = ChangeRequest.builder().add(toCreate); // Verify the type A record does not exist yet. // If it does exist, we will overwrite it with our prepared record. -Iterator recordIterator = zone.listDnsRecords().iterateAll(); -while (recordIterator.hasNext()) { - DnsRecord current = recordIterator.next(); +Iterator recordSetIterator = zone.listRecordSets().iterateAll(); +while (recordSetIterator.hasNext()) { + RecordSet current = recordSetIterator.next(); if (toCreate.name().equals(current.name()) && toCreate.type().equals(current.type())) { changeBuilder.delete(current); } @@ -235,15 +235,15 @@ Change requests are applied atomically to all the assigned DNS servers at once. happens, it may still take a while for the change to be registered by the DNS cache resolvers. See more on this topic [here](https://cloud.google.com/dns/monitoring). -#### Listing Zones and DNS Records -Suppose that you have added more zones and DNS records, and now you want to list them. +#### Listing Zones and Record Sets +Suppose that you have added more zones and record sets, and now you want to list them. First, import the following (unless you have done so in the previous section): ```java import java.util.Iterator; ``` -Then add the following code to list all your zones and DNS records. +Then add the following code to list all your zones and record sets. ```java // List all your zones @@ -254,11 +254,11 @@ while (zoneIterator.hasNext()) { counter++; } -// List the DNS records in a particular zone -Iterator recordIterator = zone.listDnsRecords().iterateAll(); -System.out.println(String.format("DNS records inside %s:", zone.name())); -while (recordIterator.hasNext()) { - System.out.println(recordIterator.next()); +// List the record sets in a particular zone +recordSetIterator = zone.listRecordSets().iterateAll(); +System.out.println(String.format("Record sets inside %s:", zone.name())); +while (recordSetIterator.hasNext()) { + System.out.println(recordSetIterator.next()); } ``` @@ -276,15 +276,15 @@ while (changeIterator.hasNext()) { #### Deleting Zones If you no longer want to host a zone in Cloud DNS, you can delete it. -First, you need to empty the zone by deleting all its records except for the default SOA and NS records. +First, you need to empty the zone by deleting all its records except for the default SOA and NS record sets. ```java -// Make a change for deleting the records -ChangeRequest.Builder changeBuilder = ChangeRequest.builder(); +// Make a change for deleting the record sets +changeBuilder = ChangeRequest.builder(); while (recordIterator.hasNext()) { - DnsRecord current = recordIterator.next(); + RecordSet current = recordIterator.next(); // SOA and NS records cannot be deleted - if (!DnsRecord.Type.SOA.equals(current.type()) && !DnsRecord.Type.NS.equals(current.type())) { + if (!RecordSet.Type.SOA.equals(current.type()) && !RecordSet.Type.NS.equals(current.type())) { changeBuilder.delete(current); } } @@ -324,11 +324,11 @@ if (result) { We composed some of the aforementioned snippets into complete executable code samples. In [CreateZones.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateZone.java) -we create a zone. In [CreateOrUpdateDnsRecords.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateDnsRecords.java) -we create a type A record for a zone, or update an existing type A record to a new IP address. We +we create a zone. In [CreateOrUpdateRecordSets.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateRecordSets.java) +we create a type A record set for a zone, or update an existing type A record set to a new IP address. We demonstrate how to delete a zone in [DeleteZone.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java). -Finally, in [ManipulateZonesAndRecords.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecords.java) -we assemble all the code snippets together and create zone, create or update a DNS record, list zones, list DNS records, list changes, and +Finally, in [ManipulateZonesAndRecordSets.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java) +we assemble all the code snippets together and create zone, create or update a record set, list zones, list record sets, list changes, and delete a zone. The applications assume that they are running on Compute Engine or from your own desktop. To run any of these examples on App Engine, simply move the code from the main method to your application's servlet class and change the print statements to display on your webpage. diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java index 76d231b704c4..757d844cc3da 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java @@ -33,7 +33,7 @@ import java.util.Objects; /** - * A class representing an atomic update to a collection of {@link DnsRecord}s within a {@code + * A class representing an atomic update to a collection of {@link RecordSet}s within a {@code * Zone}. * * @see Google Cloud DNS documentation @@ -48,8 +48,8 @@ public ChangeRequest apply(com.google.api.services.dns.model.Change pb) { } }; private static final long serialVersionUID = -9027378042756366333L; - private final List additions; - private final List deletions; + private final List additions; + private final List deletions; private final String id; private final Long startTimeMillis; private final Status status; @@ -70,8 +70,8 @@ public enum Status { */ public static class Builder { - private List additions = new LinkedList<>(); - private List deletions = new LinkedList<>(); + private List additions = new LinkedList<>(); + private List deletions = new LinkedList<>(); private String id; private Long startTimeMillis; private Status status; @@ -88,43 +88,43 @@ private Builder() { } /** - * Sets a collection of {@link DnsRecord}s which are to be added to the zone upon executing this + * Sets a collection of {@link RecordSet}s which are to be added to the zone upon executing this * {@code ChangeRequest}. */ - public Builder additions(List additions) { + public Builder additions(List additions) { this.additions = Lists.newLinkedList(checkNotNull(additions)); return this; } /** - * Sets a collection of {@link DnsRecord}s which are to be deleted from the zone upon executing + * Sets a collection of {@link RecordSet}s which are to be deleted from the zone upon executing * this {@code ChangeRequest}. */ - public Builder deletions(List deletions) { + public Builder deletions(List deletions) { this.deletions = Lists.newLinkedList(checkNotNull(deletions)); return this; } /** - * Adds a {@link DnsRecord} to be added to the zone upon executing this {@code + * Adds a {@link RecordSet} to be added to the zone upon executing this {@code * ChangeRequest}. */ - public Builder add(DnsRecord record) { - this.additions.add(checkNotNull(record)); + public Builder add(RecordSet recordSet) { + this.additions.add(checkNotNull(recordSet)); return this; } /** - * Adds a {@link DnsRecord} to be deleted to the zone upon executing this + * Adds a {@link RecordSet} to be deleted to the zone upon executing this * {@code ChangeRequest}. */ - public Builder delete(DnsRecord record) { - this.deletions.add(checkNotNull(record)); + public Builder delete(RecordSet recordSet) { + this.deletions.add(checkNotNull(recordSet)); return this; } /** - * Clears the collection of {@link DnsRecord}s which are to be added to the zone upon executing + * Clears the collection of {@link RecordSet}s which are to be added to the zone upon executing * this {@code ChangeRequest}. */ public Builder clearAdditions() { @@ -133,7 +133,7 @@ public Builder clearAdditions() { } /** - * Clears the collection of {@link DnsRecord}s which are to be deleted from the zone upon + * Clears the collection of {@link RecordSet}s which are to be deleted from the zone upon * executing this {@code ChangeRequest}. */ public Builder clearDeletions() { @@ -142,20 +142,20 @@ public Builder clearDeletions() { } /** - * Removes a single {@link DnsRecord} from the collection of records to be + * Removes a single {@link RecordSet} from the collection of records to be * added to the zone upon executing this {@code ChangeRequest}. */ - public Builder removeAddition(DnsRecord record) { - this.additions.remove(record); + public Builder removeAddition(RecordSet recordSet) { + this.additions.remove(recordSet); return this; } /** - * Removes a single {@link DnsRecord} from the collection of records to be + * Removes a single {@link RecordSet} from the collection of records to be * deleted from the zone upon executing this {@code ChangeRequest}. */ - public Builder removeDeletion(DnsRecord record) { - this.deletions.remove(record); + public Builder removeDeletion(RecordSet recordSet) { + this.deletions.remove(recordSet); return this; } @@ -215,18 +215,18 @@ public Builder toBuilder() { } /** - * Returns the list of {@link DnsRecord}s to be added to the zone upon submitting this {@code + * Returns the list of {@link RecordSet}s to be added to the zone upon submitting this {@code * ChangeRequest}. */ - public List additions() { + public List additions() { return additions; } /** - * Returns the list of {@link DnsRecord}s to be deleted from the zone upon submitting this {@code + * Returns the list of {@link RecordSet}s to be deleted from the zone upon submitting this {@code * ChangeRequest}. */ - public List deletions() { + public List deletions() { return deletions; } @@ -267,9 +267,9 @@ com.google.api.services.dns.model.Change toPb() { pb.setStatus(status().name().toLowerCase()); } // set a list of additions - pb.setAdditions(Lists.transform(additions(), DnsRecord.TO_PB_FUNCTION)); + pb.setAdditions(Lists.transform(additions(), RecordSet.TO_PB_FUNCTION)); // set a list of deletions - pb.setDeletions(Lists.transform(deletions(), DnsRecord.TO_PB_FUNCTION)); + pb.setDeletions(Lists.transform(deletions(), RecordSet.TO_PB_FUNCTION)); return pb; } @@ -286,10 +286,10 @@ static ChangeRequest fromPb(com.google.api.services.dns.model.Change pb) { builder.status(ChangeRequest.Status.valueOf(pb.getStatus().toUpperCase())); } if (pb.getDeletions() != null) { - builder.deletions(Lists.transform(pb.getDeletions(), DnsRecord.FROM_PB_FUNCTION)); + builder.deletions(Lists.transform(pb.getDeletions(), RecordSet.FROM_PB_FUNCTION)); } if (pb.getAdditions() != null) { - builder.additions(Lists.transform(pb.getAdditions(), DnsRecord.FROM_PB_FUNCTION)); + builder.additions(Lists.transform(pb.getAdditions(), RecordSet.FROM_PB_FUNCTION)); } return builder.build(); } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index 6ce6b4c19994..f8614a8d6169 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -101,13 +101,13 @@ static String selector(ZoneField... fields) { } /** - * The fields of a DNS record. + * The fields of a record set. * *

      These values can be used to specify the fields to include in a partial response when calling - * {@link Dns#listDnsRecords(String, DnsRecordListOption...)}. The name and type are always + * {@link Dns#listRecordSets(String, RecordSetListOption...)}. The name and type are always * returned even if not selected. */ - enum DnsRecordField { + enum RecordSetField { DNS_RECORDS("rrdatas"), NAME("name"), TTL("ttl"), @@ -115,7 +115,7 @@ enum DnsRecordField { private final String selector; - DnsRecordField(String selector) { + RecordSetField(String selector) { this.selector = selector; } @@ -123,11 +123,11 @@ String selector() { return selector; } - static String selector(DnsRecordField... fields) { + static String selector(RecordSetField... fields) { Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); fieldStrings.add(NAME.selector()); fieldStrings.add(TYPE.selector()); - for (DnsRecordField field : fields) { + for (RecordSetField field : fields) { fieldStrings.add(field.selector()); } return Joiner.on(',').join(fieldStrings); @@ -180,28 +180,29 @@ public String selector() { } /** - * Class that for specifying DNS record options. + * Class for specifying record set listing options. */ - class DnsRecordListOption extends AbstractOption implements Serializable { + class RecordSetListOption extends AbstractOption implements Serializable { private static final long serialVersionUID = 1009627025381096098L; - DnsRecordListOption(DnsRpc.Option option, Object value) { + RecordSetListOption(DnsRpc.Option option, Object value) { super(option, value); } /** - * Returns an option to specify the DNS record's fields to be returned by the RPC call. + * Returns an option to specify the record set's fields to be returned by the RPC call. * *

      If this option is not provided all record fields are returned. {@code - * DnsRecordField.fields} can be used to specify only the fields of interest. The name of the - * DNS record always returned, even if not specified. {@link DnsRecordField} provides a list of - * fields that can be used. + * RecordSetField.fields} can be used to specify only the fields of interest. The name of the + * record set in always returned, even if not specified. {@link RecordSetField} provides a list + * of fields that can be used. */ - public static DnsRecordListOption fields(DnsRecordField... fields) { + public static RecordSetListOption fields(RecordSetField... fields) { StringBuilder builder = new StringBuilder(); - builder.append("nextPageToken,rrsets(").append(DnsRecordField.selector(fields)).append(')'); - return new DnsRecordListOption(DnsRpc.Option.FIELDS, builder.toString()); + builder.append("nextPageToken,rrsets(").append(RecordSetField.selector(fields)) + .append(')'); + return new RecordSetListOption(DnsRpc.Option.FIELDS, builder.toString()); } /** @@ -210,33 +211,33 @@ public static DnsRecordListOption fields(DnsRecordField... fields) { *

      The page token (returned from a previous call to list) indicates from where listing should * continue. */ - public static DnsRecordListOption pageToken(String pageToken) { - return new DnsRecordListOption(DnsRpc.Option.PAGE_TOKEN, pageToken); + public static RecordSetListOption pageToken(String pageToken) { + return new RecordSetListOption(DnsRpc.Option.PAGE_TOKEN, pageToken); } /** - * The maximum number of DNS records to return per RPC. + * The maximum number of record sets to return per RPC. * - *

      The server can return fewer records than requested. When there are more results than the - * page size, the server will return a page token that can be used to fetch other results. + *

      The server can return fewer record sets than requested. When there are more results than + * the page size, the server will return a page token that can be used to fetch other results. */ - public static DnsRecordListOption pageSize(int pageSize) { - return new DnsRecordListOption(DnsRpc.Option.PAGE_SIZE, pageSize); + public static RecordSetListOption pageSize(int pageSize) { + return new RecordSetListOption(DnsRpc.Option.PAGE_SIZE, pageSize); } /** - * Restricts the list to only DNS records with this fully qualified domain name. + * Restricts the list to only record sets with this fully qualified domain name. */ - public static DnsRecordListOption dnsName(String dnsName) { - return new DnsRecordListOption(DnsRpc.Option.NAME, dnsName); + public static RecordSetListOption dnsName(String dnsName) { + return new RecordSetListOption(DnsRpc.Option.NAME, dnsName); } /** - * Restricts the list to return only records of this type. If present, {@link - * Dns.DnsRecordListOption#dnsName(String)} must also be present. + * Restricts the list to return only record sets of this type. If present, {@link + * RecordSetListOption#dnsName(String)} must also be present. */ - public static DnsRecordListOption type(DnsRecord.Type type) { - return new DnsRecordListOption(DnsRpc.Option.DNS_TYPE, type.name()); + public static RecordSetListOption type(RecordSet.Type type) { + return new RecordSetListOption(DnsRpc.Option.DNS_TYPE, type.name()); } } @@ -478,16 +479,16 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) { boolean delete(String zoneName); // delete does not admit any options /** - * Lists the DNS records in the zone identified by name. + * Lists the record sets in the zone identified by name. * *

      The fields to be returned, page size and page tokens can be specified using {@link - * DnsRecordListOption}s. + * RecordSetListOption}s. * * @throws DnsException upon failure or if the zone cannot be found * @see Cloud DNS * ResourceRecordSets: list */ - Page listDnsRecords(String zoneName, DnsRecordListOption... options); + Page listRecordSets(String zoneName, RecordSetListOption... options); /** * Retrieves the information about the current project. The returned fields can be optionally diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java index a60cfd9151da..2fbf4e8b5a79 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java @@ -85,7 +85,7 @@ public Page nextPage() { } } - private static class DnsRecordPageFetcher implements PageImpl.NextPageFetcher { + private static class DnsRecordPageFetcher implements PageImpl.NextPageFetcher { private static final long serialVersionUID = -6039369212511530846L; private final Map requestOptions; @@ -101,8 +101,8 @@ private static class DnsRecordPageFetcher implements PageImpl.NextPageFetcher nextPage() { - return listDnsRecords(zoneName, serviceOptions, requestOptions); + public Page nextPage() { + return listRecordSets(zoneName, serviceOptions, requestOptions); } } @@ -178,29 +178,29 @@ public DnsRpc.ListResult call() { } @Override - public Page listDnsRecords(String zoneName, DnsRecordListOption... options) { - return listDnsRecords(zoneName, options(), optionMap(options)); + public Page listRecordSets(String zoneName, RecordSetListOption... options) { + return listRecordSets(zoneName, options(), optionMap(options)); } - private static Page listDnsRecords(final String zoneName, + private static Page listRecordSets(final String zoneName, final DnsOptions serviceOptions, final Map optionsMap) { try { - // get a list of resource record sets + // get a list of record sets final DnsRpc rpc = serviceOptions.rpc(); DnsRpc.ListResult result = runWithRetries( new Callable>() { @Override public DnsRpc.ListResult call() { - return rpc.listDnsRecords(zoneName, optionsMap); + return rpc.listRecordSets(zoneName, optionsMap); } }, serviceOptions.retryParams(), EXCEPTION_HANDLER); String cursor = result.pageToken(); - // transform that list into dns records - Iterable records = result.results() == null - ? ImmutableList.of() - : Iterables.transform(result.results(), DnsRecord.FROM_PB_FUNCTION); + // transform that list into record sets + Iterable recordSets = result.results() == null + ? ImmutableList.of() + : Iterables.transform(result.results(), RecordSet.FROM_PB_FUNCTION); return new PageImpl<>(new DnsRecordPageFetcher(zoneName, serviceOptions, cursor, optionsMap), - cursor, records); + cursor, recordSets); } catch (RetryHelperException e) { throw DnsException.translateAndThrow(e); } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java index f7b12b94bae8..319f06ad2444 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java @@ -26,8 +26,8 @@ /** * The class provides the Google Cloud DNS information associated with this project. A project is a - * top level container for resources including {@code Zone}s. Projects can be created only in - * the APIs console. + * top level container for resources including {@code Zone}s. Projects can be created only in the + * APIs console. * * @see Google Cloud DNS documentation */ @@ -62,11 +62,11 @@ public static class Quota implements Serializable { * builder. */ Quota(int zones, - int resourceRecordsPerRrset, - int rrsetAdditionsPerChange, - int rrsetDeletionsPerChange, - int rrsetsPerZone, - int totalRrdataSizePerChange) { + int resourceRecordsPerRrset, + int rrsetAdditionsPerChange, + int rrsetDeletionsPerChange, + int rrsetsPerZone, + int totalRrdataSizePerChange) { this.zones = zones; this.resourceRecordsPerRrset = resourceRecordsPerRrset; this.rrsetAdditionsPerChange = rrsetAdditionsPerChange; @@ -83,21 +83,22 @@ public int zones() { } /** - * Returns the maximum allowed number of records per {@link DnsRecord}. + * Returns the maximum allowed number of records per {@link RecordSet}. */ public int resourceRecordsPerRrset() { return resourceRecordsPerRrset; } /** - * Returns the maximum allowed number of {@link DnsRecord}s to add per {@link ChangeRequest}. + * Returns the maximum allowed number of {@link RecordSet}s to add per {@link + * ChangeRequest}. */ public int rrsetAdditionsPerChange() { return rrsetAdditionsPerChange; } /** - * Returns the maximum allowed number of {@link DnsRecord}s to delete per {@link + * Returns the maximum allowed number of {@link RecordSet}s to delete per {@link * ChangeRequest}. */ public int rrsetDeletionsPerChange() { @@ -105,7 +106,7 @@ public int rrsetDeletionsPerChange() { } /** - * Returns the maximum allowed number of {@link DnsRecord}s per {@link ZoneInfo} in the + * Returns the maximum allowed number of {@link RecordSet}s per {@link ZoneInfo} in the * project. */ public int rrsetsPerZone() { diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/RecordSet.java similarity index 83% rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java rename to gcloud-java-dns/src/main/java/com/google/gcloud/dns/RecordSet.java index c4e710bd0365..dc6d956406c3 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/RecordSet.java @@ -35,28 +35,28 @@ /** * A class that represents a Google Cloud DNS record set. * - *

      A {@code DnsRecord} is the unit of data that will be returned by the DNS servers upon a DNS - * request for a specific domain. The {@code DnsRecord} holds the current state of the DNS records + *

      A {@code RecordSet} is the unit of data that will be returned by the DNS servers upon a DNS + * request for a specific domain. The {@code RecordSet} holds the current state of the DNS records * that make up a zone. You can read the records but you cannot modify them directly. Rather, you - * edit the records in a zone by creating a ChangeRequest. + * edit the records in a zone by creating a {@link ChangeRequest}. * * @see Google Cloud DNS * documentation */ -public class DnsRecord implements Serializable { +public class RecordSet implements Serializable { - static final Function FROM_PB_FUNCTION = - new Function() { + static final Function FROM_PB_FUNCTION = + new Function() { @Override - public DnsRecord apply(com.google.api.services.dns.model.ResourceRecordSet pb) { - return DnsRecord.fromPb(pb); + public RecordSet apply(ResourceRecordSet pb) { + return RecordSet.fromPb(pb); } }; - static final Function TO_PB_FUNCTION = - new Function() { + static final Function TO_PB_FUNCTION = + new Function() { @Override - public com.google.api.services.dns.model.ResourceRecordSet apply(DnsRecord error) { - return error.toPb(); + public ResourceRecordSet apply(RecordSet recordSet) { + return recordSet.toPb(); } }; private static final long serialVersionUID = 8148009870800115261L; @@ -124,7 +124,7 @@ public enum Type { } /** - * A builder of {@link DnsRecord}. + * A builder for {@link RecordSet}. */ public static class Builder { @@ -140,9 +140,9 @@ private Builder(String name, Type type) { /** * Creates a builder and pre-populates attributes with the values from the provided {@code - * DnsRecord} instance. + * RecordSet} instance. */ - private Builder(DnsRecord record) { + private Builder(RecordSet record) { this.name = record.name; this.ttl = record.ttl; this.type = record.type; @@ -186,7 +186,7 @@ public Builder records(List records) { } /** - * Sets name for this DNS record set. For example, www.example.com. + * Sets the name for this record set. For example, www.example.com. */ public Builder name(String name) { this.name = checkNotNull(name); @@ -198,7 +198,7 @@ public Builder name(String name) { * The maximum duration must be equivalent to at most {@link Integer#MAX_VALUE} seconds. * * @param duration A non-negative number of time units - * @param unit The unit of the ttl parameter + * @param unit The unit of the ttl parameter */ public Builder ttl(int duration, TimeUnit unit) { checkArgument(duration >= 0, @@ -219,14 +219,14 @@ public Builder type(Type type) { } /** - * Builds the DNS record. + * Builds the record set. */ - public DnsRecord build() { - return new DnsRecord(this); + public RecordSet build() { + return new RecordSet(this); } } - private DnsRecord(Builder builder) { + private RecordSet(Builder builder) { this.name = builder.name; this.rrdatas = ImmutableList.copyOf(builder.rrdatas); this.ttl = builder.ttl; @@ -241,35 +241,35 @@ public Builder toBuilder() { } /** - * Creates a {@code DnsRecord} builder for the given {@code name} and {@code type}. + * Creates a {@code RecordSet} builder for the given {@code name} and {@code type}. */ public static Builder builder(String name, Type type) { return new Builder(name, type); } /** - * Returns the user-assigned name of this DNS record. + * Returns the user-assigned name of this record set. */ public String name() { return name; } /** - * Returns a list of DNS record stored in this record set. + * Returns a list of records stored in this record set. */ public List records() { return rrdatas; } /** - * Returns the number of seconds that this DnsResource can be cached by resolvers. + * Returns the number of seconds that this record set can be cached by resolvers. */ public Integer ttl() { return ttl; } /** - * Returns the type of this DNS record. + * Returns the type of this record set. */ public Type type() { return type; @@ -282,7 +282,7 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return (obj instanceof DnsRecord) && Objects.equals(this.toPb(), ((DnsRecord) obj).toPb()); + return obj instanceof RecordSet && Objects.equals(this.toPb(), ((RecordSet) obj).toPb()); } com.google.api.services.dns.model.ResourceRecordSet toPb() { @@ -295,7 +295,7 @@ com.google.api.services.dns.model.ResourceRecordSet toPb() { return pb; } - static DnsRecord fromPb(com.google.api.services.dns.model.ResourceRecordSet pb) { + static RecordSet fromPb(com.google.api.services.dns.model.ResourceRecordSet pb) { Builder builder = builder(pb.getName(), Type.valueOf(pb.getType())); if (pb.getRrdatas() != null) { builder.records(pb.getRrdatas()); diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java index 41507647543a..aed99dbd0001 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java @@ -28,10 +28,10 @@ /** * A Google Cloud DNS Zone object. * - *

      A zone is the container for all of your DNS records that share the same DNS name prefix, for + *

      A zone is the container for all of your record sets that share the same DNS name prefix, for * example, example.com. Zones are automatically assigned a set of name servers when they are * created to handle responding to DNS queries for that zone. A zone has quotas for the number of - * resource records that it can include. + * record sets that it can include. * * @see Google Cloud DNS managed zone * documentation @@ -135,14 +135,14 @@ public boolean delete() { } /** - * Lists all {@link DnsRecord}s associated with this zone. The method searches for zone by name. + * Lists all {@link RecordSet}s associated with this zone. The method searches for zone by name. * - * @param options optional restriction on listing and fields of {@link DnsRecord}s returned - * @return a page of DNS records + * @param options optional restriction on listing and fields of {@link RecordSet}s returned + * @return a page of record sets * @throws DnsException upon failure or if the zone is not found */ - public Page listDnsRecords(Dns.DnsRecordListOption... options) { - return dns.listDnsRecords(name(), options); + public Page listRecordSets(Dns.RecordSetListOption... options) { + return dns.listRecordSets(name(), options); } /** diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/package-info.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/package-info.java index 8a137285c357..69bee930df62 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/package-info.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/package-info.java @@ -42,7 +42,7 @@ * String zoneName = "my-unique-zone"; * Zone zone = dns.getZone(zoneName); * String ip = "12.13.14.15"; - * DnsRecord toCreate = DnsRecord.builder("www.someexampledomain.com.", DnsRecord.Type.A) + * RecordSet toCreate = RecordSet.builder("www.someexampledomain.com.", RecordSet.Type.A) * .ttl(24, TimeUnit.HOURS) * .addRecord(ip) * .build(); diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DefaultDnsRpc.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DefaultDnsRpc.java index f8b8adb87ada..cbebd19d0d73 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DefaultDnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DefaultDnsRpc.java @@ -112,7 +112,7 @@ public boolean deleteZone(String zoneName) throws DnsException { } @Override - public ListResult listDnsRecords(String zoneName, Map options) + public ListResult listRecordSets(String zoneName, Map options) throws DnsException { // options are fields, page token, dns name, type try { diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DnsRpc.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DnsRpc.java index bde93b99bfdd..c7478016db27 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DnsRpc.java @@ -120,13 +120,13 @@ public String pageToken() { boolean deleteZone(String zoneName) throws DnsException; /** - * Lists DNS records for a given zone. + * Lists record sets for a given zone. * * @param zoneName name of the zone to be listed * @param options a map of options for the service call * @throws DnsException upon failure or if zone was not found */ - ListResult listDnsRecords(String zoneName, Map options) + ListResult listRecordSets(String zoneName, Map options) throws DnsException; /** diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/LocalDnsHelper.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/LocalDnsHelper.java index 3b18ec5ce55b..0ae2c37b9b4d 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/LocalDnsHelper.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/LocalDnsHelper.java @@ -90,8 +90,8 @@ * privileges to manipulate any project. Similarly, the local simulation does not require * verification of domain name ownership. Any request for creating a managed zone will be approved. * The mock does not track quota and will allow the user to exceed it. The mock provides only basic - * validation of the DNS data for records of type A and AAAA. It does not validate any other record - * types. + * validation of the DNS data for record sets of type A and AAAA. It does not validate any other + * record set types. */ public class LocalDnsHelper { @@ -470,7 +470,7 @@ static Response toListResponse(List serializedObjects, String context, S } /** - * Prepares DNS records that are created by default for each zone. + * Prepares record sets that are created by default for each zone. */ private static ImmutableSortedMap defaultRecords(ManagedZone zone) { ResourceRecordSet soa = new ResourceRecordSet(); @@ -508,7 +508,7 @@ static List randomNameservers() { } /** - * Returns a hex string id (used for a dns record) unique within the set of ids. + * Returns a hex string id (used for a record set) unique within the set of ids. */ @VisibleForTesting static String getUniqueId(Set ids) { @@ -521,14 +521,14 @@ static String getUniqueId(Set ids) { } /** - * Tests if a DNS record matches name and type (if provided). Used for filtering. + * Tests if a record set matches name and type (if provided). Used for filtering. */ @VisibleForTesting - static boolean matchesCriteria(ResourceRecordSet record, String name, String type) { - if (type != null && !record.getType().equals(type)) { + static boolean matchesCriteria(ResourceRecordSet recordSet, String name, String type) { + if (type != null && !recordSet.getType().equals(type)) { return false; } - return name == null || record.getName().equals(name); + return name == null || recordSet.getName().equals(name); } /** @@ -871,7 +871,7 @@ Response listZones(String projectId, String query) { } /** - * Lists DNS records for a zone. Next page token is the ID of the last record listed. + * Lists record sets for a zone. Next page token is the ID of the last record listed. */ @VisibleForTesting Response listDnsRecords(String projectId, String zoneName, String query) { @@ -898,18 +898,18 @@ Response listDnsRecords(String projectId, String zoneName, String query) { boolean hasMorePages = false; LinkedList serializedRrsets = new LinkedList<>(); String lastRecordId = null; - for (String recordId : fragment.keySet()) { - ResourceRecordSet record = fragment.get(recordId); - if (matchesCriteria(record, name, type)) { + for (String recordSetId : fragment.keySet()) { + ResourceRecordSet recordSet = fragment.get(recordSetId); + if (matchesCriteria(recordSet, name, type)) { if (sizeReached) { // we do not add this, just note that there would be more and there should be a token hasMorePages = true; break; } else { - lastRecordId = recordId; + lastRecordId = recordSetId; try { serializedRrsets.addLast(jsonFactory.toString( - OptionParsers.extractFields(record, fields))); + OptionParsers.extractFields(recordSet, fields))); } catch (IOException e) { return Error.INTERNAL_ERROR.response(String.format( "Error when serializing resource record set in managed zone %s in project %s", @@ -1128,8 +1128,8 @@ static Response checkRrset(ResourceRecordSet rrset, ZoneContainer zone, int inde } /** - * Checks against duplicate additions (for each record to be added that already exists, we must - * have a matching deletion. Furthermore, check that mandatory SOA and NS records stay. + * Checks against duplicate additions (for each record set to be added that already exists, we + * must have a matching deletion. Furthermore, check that mandatory SOA and NS records stay. */ static Response checkAdditionsDeletions(List additions, List deletions, ZoneContainer zone) { @@ -1139,7 +1139,7 @@ static Response checkAdditionsDeletions(List additions, for (ResourceRecordSet wrappedRrset : zone.dnsRecords().get().values()) { if (rrset.getName().equals(wrappedRrset.getName()) && rrset.getType().equals(wrappedRrset.getType()) - // such a record exist and we must have a deletion + // such a record set exists and we must have a deletion && (deletions == null || !deletions.contains(wrappedRrset))) { return Error.ALREADY_EXISTS.response(String.format( "The 'entity.change.additions[%s]' resource named '%s (%s)' already exists.", @@ -1181,10 +1181,10 @@ static Response checkAdditionsDeletions(List additions, /** * Helper for searching rrsets in a collection. */ - private static ResourceRecordSet findByNameAndType(Iterable records, + private static ResourceRecordSet findByNameAndType(Iterable recordSets, String name, String type) { - if (records != null) { - for (ResourceRecordSet rrset : records) { + if (recordSets != null) { + for (ResourceRecordSet rrset : recordSets) { if ((name == null || name.equals(rrset.getName())) && (type == null || type.equals(rrset.getType()))) { return rrset; @@ -1195,7 +1195,7 @@ private static ResourceRecordSet findByNameAndType(Iterable r } /** - * We only provide the most basic validation for A and AAAA records. + * We only provide the most basic validation for A and AAAA record sets. */ static boolean checkRrData(String data, String type) { switch (type) { @@ -1233,7 +1233,7 @@ static Response checkListOptions(Map options) { return Error.INVALID.response(String.format( "Invalid value for 'parameters.dnsName': '%s'", dnsName)); } - // for listing dns records, name must be fully qualified + // for listing record sets, name must be fully qualified String name = (String) options.get("name"); if (name != null && !name.endsWith(".")) { return Error.INVALID.response(String.format( diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/OptionParsers.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/OptionParsers.java index ecd7e8179efe..578a0b52db3d 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/OptionParsers.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/OptionParsers.java @@ -166,26 +166,26 @@ static ResourceRecordSet extractFields(ResourceRecordSet fullRecord, String... f if (fields == null || fields.length == 0) { return fullRecord; } - ResourceRecordSet record = new ResourceRecordSet(); + ResourceRecordSet recordSet = new ResourceRecordSet(); for (String field : fields) { switch (field) { case "name": - record.setName(fullRecord.getName()); + recordSet.setName(fullRecord.getName()); break; case "rrdatas": - record.setRrdatas(fullRecord.getRrdatas()); + recordSet.setRrdatas(fullRecord.getRrdatas()); break; case "type": - record.setType(fullRecord.getType()); + recordSet.setType(fullRecord.getType()); break; case "ttl": - record.setTtl(fullRecord.getTtl()); + recordSet.setTtl(fullRecord.getTtl()); break; default: break; } } - return record; + return recordSet; } static Map parseListChangesOptions(String query) { diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java index 8b40a4dcff34..fe726acb7c10 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java @@ -35,16 +35,16 @@ public class ChangeRequestTest { private static final Long START_TIME_MILLIS = 12334567890L; private static final ChangeRequest.Status STATUS = ChangeRequest.Status.PENDING; private static final String NAME1 = "dns1"; - private static final DnsRecord.Type TYPE1 = DnsRecord.Type.A; + private static final RecordSet.Type TYPE1 = RecordSet.Type.A; private static final String NAME2 = "dns2"; - private static final DnsRecord.Type TYPE2 = DnsRecord.Type.AAAA; + private static final RecordSet.Type TYPE2 = RecordSet.Type.AAAA; private static final String NAME3 = "dns3"; - private static final DnsRecord.Type TYPE3 = DnsRecord.Type.MX; - private static final DnsRecord RECORD1 = DnsRecord.builder(NAME1, TYPE1).build(); - private static final DnsRecord RECORD2 = DnsRecord.builder(NAME2, TYPE2).build(); - private static final DnsRecord RECORD3 = DnsRecord.builder(NAME3, TYPE3).build(); - private static final List ADDITIONS = ImmutableList.of(RECORD1, RECORD2); - private static final List DELETIONS = ImmutableList.of(RECORD3); + private static final RecordSet.Type TYPE3 = RecordSet.Type.MX; + private static final RecordSet RECORD1 = RecordSet.builder(NAME1, TYPE1).build(); + private static final RecordSet RECORD2 = RecordSet.builder(NAME2, TYPE2).build(); + private static final RecordSet RECORD3 = RecordSet.builder(NAME3, TYPE3).build(); + private static final List ADDITIONS = ImmutableList.of(RECORD1, RECORD2); + private static final List DELETIONS = ImmutableList.of(RECORD3); private static final ChangeRequest CHANGE = ChangeRequest.builder() .add(RECORD1) .add(RECORD2) @@ -70,7 +70,7 @@ public void testBuilder() { assertEquals(START_TIME_MILLIS, CHANGE.startTimeMillis()); assertEquals(ADDITIONS, CHANGE.additions()); assertEquals(DELETIONS, CHANGE.deletions()); - List recordList = ImmutableList.of(RECORD1); + List recordList = ImmutableList.of(RECORD1); ChangeRequest another = CHANGE.toBuilder().additions(recordList).build(); assertEquals(recordList, another.additions()); assertEquals(CHANGE.deletions(), another.deletions()); @@ -160,7 +160,7 @@ public void testClearAdditions() { public void testAddAddition() { try { CHANGE.toBuilder().add(null); - fail("Should not be able to add null DnsRecord."); + fail("Should not be able to add null RecordSet."); } catch (NullPointerException e) { // expected } @@ -172,7 +172,7 @@ public void testAddAddition() { public void testAddDeletion() { try { CHANGE.toBuilder().delete(null); - fail("Should not be able to delete null DnsRecord."); + fail("Should not be able to delete null RecordSet."); } catch (NullPointerException e) { // expected } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java index a97c9c408036..ab2dba0a566c 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java @@ -21,7 +21,6 @@ import com.google.api.services.dns.model.Change; import com.google.api.services.dns.model.ManagedZone; -import com.google.api.services.dns.model.ResourceRecordSet; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; @@ -46,10 +45,10 @@ public class DnsImplTest { private static final String DNS_NAME = "example.com."; private static final String DESCRIPTION = "desc"; private static final String CHANGE_ID = "some change id"; - private static final DnsRecord DNS_RECORD1 = DnsRecord.builder("Something", DnsRecord.Type.AAAA) - .build(); - private static final DnsRecord DNS_RECORD2 = DnsRecord.builder("Different", DnsRecord.Type.AAAA) - .build(); + private static final RecordSet DNS_RECORD1 = + RecordSet.builder("Something", RecordSet.Type.AAAA).build(); + private static final RecordSet DNS_RECORD2 = + RecordSet.builder("Different", RecordSet.Type.AAAA).build(); private static final Integer MAX_SIZE = 20; private static final String PAGE_TOKEN = "some token"; private static final ZoneInfo ZONE_INFO = ZoneInfo.of(ZONE_NAME, DNS_NAME, DESCRIPTION); @@ -70,7 +69,8 @@ public class DnsImplTest { CHANGE_REQUEST_PARTIAL.toPb())); private static final DnsRpc.ListResult LIST_RESULT_OF_PB_ZONES = DnsRpc.ListResult.of("cursor", ImmutableList.of(ZONE_INFO.toPb())); - private static final DnsRpc.ListResult LIST_OF_PB_DNS_RECORDS = + private static final DnsRpc.ListResult + LIST_OF_PB_DNS_RECORDS = DnsRpc.ListResult.of("cursor", ImmutableList.of(DNS_RECORD1.toPb(), DNS_RECORD2.toPb())); // Field options @@ -91,12 +91,12 @@ public class DnsImplTest { Dns.ChangeRequestListOption.pageToken(PAGE_TOKEN), Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.STATUS), Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING)}; - private static final Dns.DnsRecordListOption[] DNS_RECORD_LIST_OPTIONS = { - Dns.DnsRecordListOption.pageSize(MAX_SIZE), - Dns.DnsRecordListOption.pageToken(PAGE_TOKEN), - Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TTL), - Dns.DnsRecordListOption.dnsName(DNS_NAME), - Dns.DnsRecordListOption.type(DnsRecord.Type.AAAA)}; + private static final Dns.RecordSetListOption[] DNS_RECORD_LIST_OPTIONS = { + Dns.RecordSetListOption.pageSize(MAX_SIZE), + Dns.RecordSetListOption.pageToken(PAGE_TOKEN), + Dns.RecordSetListOption.fields(Dns.RecordSetField.TTL), + Dns.RecordSetListOption.dnsName(DNS_NAME), + Dns.RecordSetListOption.type(RecordSet.Type.AAAA)}; // Other private static final Map EMPTY_RPC_OPTIONS = ImmutableMap.of(); @@ -338,11 +338,11 @@ public void testListZonesWithOptions() { @Test public void testListDnsRecords() { - EasyMock.expect(dnsRpcMock.listDnsRecords(ZONE_INFO.name(), EMPTY_RPC_OPTIONS)) + EasyMock.expect(dnsRpcMock.listRecordSets(ZONE_INFO.name(), EMPTY_RPC_OPTIONS)) .andReturn(LIST_OF_PB_DNS_RECORDS); EasyMock.replay(dnsRpcMock); dns = options.service(); // creates DnsImpl - Page dnsPage = dns.listDnsRecords(ZONE_INFO.name()); + Page dnsPage = dns.listRecordSets(ZONE_INFO.name()); assertEquals(2, Lists.newArrayList(dnsPage.values()).size()); assertTrue(Lists.newArrayList(dnsPage.values()).contains(DNS_RECORD1)); assertTrue(Lists.newArrayList(dnsPage.values()).contains(DNS_RECORD2)); @@ -351,11 +351,11 @@ public void testListDnsRecords() { @Test public void testListDnsRecordsWithOptions() { Capture> capturedOptions = Capture.newInstance(); - EasyMock.expect(dnsRpcMock.listDnsRecords(EasyMock.eq(ZONE_NAME), + EasyMock.expect(dnsRpcMock.listRecordSets(EasyMock.eq(ZONE_NAME), EasyMock.capture(capturedOptions))).andReturn(LIST_OF_PB_DNS_RECORDS); EasyMock.replay(dnsRpcMock); dns = options.service(); // creates DnsImpl - Page dnsPage = dns.listDnsRecords(ZONE_NAME, DNS_RECORD_LIST_OPTIONS); + Page dnsPage = dns.listRecordSets(ZONE_NAME, DNS_RECORD_LIST_OPTIONS); assertEquals(2, Lists.newArrayList(dnsPage.values()).size()); assertTrue(Lists.newArrayList(dnsPage.values()).contains(DNS_RECORD1)); assertTrue(Lists.newArrayList(dnsPage.values()).contains(DNS_RECORD2)); @@ -365,8 +365,8 @@ public void testListDnsRecordsWithOptions() { .get(DNS_RECORD_LIST_OPTIONS[1].rpcOption()); assertEquals(PAGE_TOKEN, selector); selector = (String) capturedOptions.getValue().get(DNS_RECORD_LIST_OPTIONS[2].rpcOption()); - assertTrue(selector.contains(Dns.DnsRecordField.NAME.selector())); - assertTrue(selector.contains(Dns.DnsRecordField.TTL.selector())); + assertTrue(selector.contains(Dns.RecordSetField.NAME.selector())); + assertTrue(selector.contains(Dns.RecordSetField.TTL.selector())); selector = (String) capturedOptions.getValue().get(DNS_RECORD_LIST_OPTIONS[3].rpcOption()); assertEquals(DNS_RECORD_LIST_OPTIONS[3].value(), selector); String type = (String) capturedOptions.getValue().get(DNS_RECORD_LIST_OPTIONS[4] diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java index 2e233e2df62a..df86d6ebd495 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java @@ -30,36 +30,36 @@ public class DnsTest { private static final String DNS_NAME = "www.example.com."; @Test - public void testDnsRecordListOption() { + public void testRecordSetListOption() { // dns name String dnsName = "some name"; - Dns.DnsRecordListOption dnsRecordListOption = Dns.DnsRecordListOption.dnsName(dnsName); - assertEquals(dnsName, dnsRecordListOption.value()); - assertEquals(DnsRpc.Option.NAME, dnsRecordListOption.rpcOption()); + Dns.RecordSetListOption recordSetListOption = Dns.RecordSetListOption.dnsName(dnsName); + assertEquals(dnsName, recordSetListOption.value()); + assertEquals(DnsRpc.Option.NAME, recordSetListOption.rpcOption()); // page token - dnsRecordListOption = Dns.DnsRecordListOption.pageToken(PAGE_TOKEN); - assertEquals(PAGE_TOKEN, dnsRecordListOption.value()); - assertEquals(DnsRpc.Option.PAGE_TOKEN, dnsRecordListOption.rpcOption()); + recordSetListOption = Dns.RecordSetListOption.pageToken(PAGE_TOKEN); + assertEquals(PAGE_TOKEN, recordSetListOption.value()); + assertEquals(DnsRpc.Option.PAGE_TOKEN, recordSetListOption.rpcOption()); // page size - dnsRecordListOption = Dns.DnsRecordListOption.pageSize(PAGE_SIZE); - assertEquals(PAGE_SIZE, dnsRecordListOption.value()); - assertEquals(DnsRpc.Option.PAGE_SIZE, dnsRecordListOption.rpcOption()); + recordSetListOption = Dns.RecordSetListOption.pageSize(PAGE_SIZE); + assertEquals(PAGE_SIZE, recordSetListOption.value()); + assertEquals(DnsRpc.Option.PAGE_SIZE, recordSetListOption.rpcOption()); // record type - DnsRecord.Type recordType = DnsRecord.Type.AAAA; - dnsRecordListOption = Dns.DnsRecordListOption.type(recordType); - assertEquals(recordType.name(), dnsRecordListOption.value()); - assertEquals(DnsRpc.Option.DNS_TYPE, dnsRecordListOption.rpcOption()); + RecordSet.Type recordType = RecordSet.Type.AAAA; + recordSetListOption = Dns.RecordSetListOption.type(recordType); + assertEquals(recordType.name(), recordSetListOption.value()); + assertEquals(DnsRpc.Option.DNS_TYPE, recordSetListOption.rpcOption()); // fields - dnsRecordListOption = Dns.DnsRecordListOption.fields(Dns.DnsRecordField.NAME, - Dns.DnsRecordField.TTL); - assertEquals(DnsRpc.Option.FIELDS, dnsRecordListOption.rpcOption()); - assertTrue(dnsRecordListOption.value() instanceof String); - assertTrue(((String) dnsRecordListOption.value()).contains( - Dns.DnsRecordField.NAME.selector())); - assertTrue(((String) dnsRecordListOption.value()).contains( - Dns.DnsRecordField.TTL.selector())); - assertTrue(((String) dnsRecordListOption.value()).contains( - Dns.DnsRecordField.NAME.selector())); + recordSetListOption = Dns.RecordSetListOption.fields(Dns.RecordSetField.NAME, + Dns.RecordSetField.TTL); + assertEquals(DnsRpc.Option.FIELDS, recordSetListOption.rpcOption()); + assertTrue(recordSetListOption.value() instanceof String); + assertTrue(((String) recordSetListOption.value()).contains( + Dns.RecordSetField.NAME.selector())); + assertTrue(((String) recordSetListOption.value()).contains( + Dns.RecordSetField.TTL.selector())); + assertTrue(((String) recordSetListOption.value()).contains( + Dns.RecordSetField.NAME.selector())); } @Test diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/RecordSetTest.java similarity index 63% rename from gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java rename to gcloud-java-dns/src/test/java/com/google/gcloud/dns/RecordSetTest.java index 5fc972cede78..369e078a48c7 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/RecordSetTest.java @@ -16,7 +16,7 @@ package com.google.gcloud.dns; -import static com.google.gcloud.dns.DnsRecord.builder; +import static com.google.gcloud.dns.RecordSet.builder; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; @@ -26,35 +26,35 @@ import java.util.concurrent.TimeUnit; -public class DnsRecordTest { +public class RecordSetTest { private static final String NAME = "example.com."; private static final Integer TTL = 3600; private static final TimeUnit UNIT = TimeUnit.HOURS; private static final Integer UNIT_TTL = 1; - private static final DnsRecord.Type TYPE = DnsRecord.Type.AAAA; - private static final DnsRecord record = builder(NAME, TYPE) + private static final RecordSet.Type TYPE = RecordSet.Type.AAAA; + private static final RecordSet recordSet = builder(NAME, TYPE) .ttl(UNIT_TTL, UNIT) .build(); @Test public void testDefaultDnsRecord() { - DnsRecord record = builder(NAME, TYPE).build(); - assertEquals(0, record.records().size()); - assertEquals(TYPE, record.type()); - assertEquals(NAME, record.name()); + RecordSet recordSet = builder(NAME, TYPE).build(); + assertEquals(0, recordSet.records().size()); + assertEquals(TYPE, recordSet.type()); + assertEquals(NAME, recordSet.name()); } @Test public void testBuilder() { - assertEquals(NAME, record.name()); - assertEquals(TTL, record.ttl()); - assertEquals(TYPE, record.type()); - assertEquals(0, record.records().size()); + assertEquals(NAME, recordSet.name()); + assertEquals(TTL, recordSet.ttl()); + assertEquals(TYPE, recordSet.type()); + assertEquals(0, recordSet.records().size()); // verify that one can add records to the record set - String testingRecord = "Testing record"; - String anotherTestingRecord = "Another record 123"; - DnsRecord anotherRecord = record.toBuilder() + String testingRecord = "Testing recordSet"; + String anotherTestingRecord = "Another recordSet 123"; + RecordSet anotherRecord = recordSet.toBuilder() .addRecord(testingRecord) .addRecord(anotherTestingRecord) .build(); @@ -79,47 +79,47 @@ public void testValidTtl() { } catch (IllegalArgumentException e) { // expected } - DnsRecord record = DnsRecord.builder(NAME, TYPE).ttl(UNIT_TTL, UNIT).build(); + RecordSet record = RecordSet.builder(NAME, TYPE).ttl(UNIT_TTL, UNIT).build(); assertEquals(TTL, record.ttl()); } @Test public void testEqualsAndNotEquals() { - DnsRecord clone = record.toBuilder().build(); - assertEquals(record, clone); - clone = record.toBuilder().addRecord("another record").build(); - assertNotEquals(record, clone); + RecordSet clone = recordSet.toBuilder().build(); + assertEquals(recordSet, clone); + clone = recordSet.toBuilder().addRecord("another recordSet").build(); + assertNotEquals(recordSet, clone); String differentName = "totally different name"; - clone = record.toBuilder().name(differentName).build(); - assertNotEquals(record, clone); - clone = record.toBuilder().ttl(record.ttl() + 1, TimeUnit.SECONDS).build(); - assertNotEquals(record, clone); - clone = record.toBuilder().type(DnsRecord.Type.TXT).build(); - assertNotEquals(record, clone); + clone = recordSet.toBuilder().name(differentName).build(); + assertNotEquals(recordSet, clone); + clone = recordSet.toBuilder().ttl(recordSet.ttl() + 1, TimeUnit.SECONDS).build(); + assertNotEquals(recordSet, clone); + clone = recordSet.toBuilder().type(RecordSet.Type.TXT).build(); + assertNotEquals(recordSet, clone); } @Test public void testSameHashCodeOnEquals() { - int hash = record.hashCode(); - DnsRecord clone = record.toBuilder().build(); + int hash = recordSet.hashCode(); + RecordSet clone = recordSet.toBuilder().build(); assertEquals(clone.hashCode(), hash); } @Test public void testToAndFromPb() { - assertEquals(record, DnsRecord.fromPb(record.toPb())); - DnsRecord partial = builder(NAME, TYPE).build(); - assertEquals(partial, DnsRecord.fromPb(partial.toPb())); + assertEquals(recordSet, RecordSet.fromPb(recordSet.toPb())); + RecordSet partial = builder(NAME, TYPE).build(); + assertEquals(partial, RecordSet.fromPb(partial.toPb())); partial = builder(NAME, TYPE).addRecord("test").build(); - assertEquals(partial, DnsRecord.fromPb(partial.toPb())); + assertEquals(partial, RecordSet.fromPb(partial.toPb())); partial = builder(NAME, TYPE).ttl(15, TimeUnit.SECONDS).build(); - assertEquals(partial, DnsRecord.fromPb(partial.toPb())); + assertEquals(partial, RecordSet.fromPb(partial.toPb())); } @Test public void testToBuilder() { - assertEquals(record, record.toBuilder().build()); - DnsRecord partial = builder(NAME, TYPE).build(); + assertEquals(recordSet, recordSet.toBuilder().build()); + RecordSet partial = builder(NAME, TYPE).build(); assertEquals(partial, partial.toBuilder().build()); partial = builder(NAME, TYPE).addRecord("test").build(); assertEquals(partial, partial.toBuilder().build()); @@ -130,7 +130,8 @@ public void testToBuilder() { @Test public void clearRecordSet() { // make sure that we are starting not empty - DnsRecord clone = record.toBuilder().addRecord("record").addRecord("another").build(); + RecordSet clone = + recordSet.toBuilder().addRecord("record").addRecord("another").build(); assertNotEquals(0, clone.records().size()); clone = clone.toBuilder().clearRecords().build(); assertEquals(0, clone.records().size()); @@ -141,7 +142,7 @@ public void clearRecordSet() { public void removeFromRecordSet() { String recordString = "record"; // make sure that we are starting not empty - DnsRecord clone = record.toBuilder().addRecord(recordString).build(); + RecordSet clone = recordSet.toBuilder().addRecord(recordString).build(); assertNotEquals(0, clone.records().size()); clone = clone.toBuilder().removeRecord(recordString).build(); assertEquals(0, clone.records().size()); diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java index 7a0c32036878..c06cd096bf1e 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java @@ -45,8 +45,8 @@ public class SerializationTest extends BaseSerializationTest { .build(); private static final Dns.ZoneListOption ZONE_LIST_OPTION = Dns.ZoneListOption.dnsName("www.example.com."); - private static final Dns.DnsRecordListOption DNS_REOCRD_LIST_OPTION = - Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TTL); + private static final Dns.RecordSetListOption RECORD_SET_LIST_OPTION = + Dns.RecordSetListOption.fields(Dns.RecordSetField.TTL); private static final Dns.ChangeRequestListOption CHANGE_REQUEST_LIST_OPTION = Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.STATUS); private static final Dns.ZoneOption ZONE_OPTION = @@ -64,16 +64,16 @@ public class SerializationTest extends BaseSerializationTest { private static final Zone PARTIAL_ZONE = new Zone(DNS, new ZoneInfo.BuilderImpl(PARTIAL_ZONE_INFO)); private static final ChangeRequest CHANGE_REQUEST_PARTIAL = ChangeRequest.builder().build(); - private static final DnsRecord DNS_RECORD_PARTIAL = - DnsRecord.builder("www.www.com", DnsRecord.Type.AAAA).build(); - private static final DnsRecord DNS_RECORD_COMPLETE = - DnsRecord.builder("www.sadfa.com", DnsRecord.Type.A) + private static final RecordSet RECORD_SET_PARTIAL = + RecordSet.builder("www.www.com", RecordSet.Type.AAAA).build(); + private static final RecordSet RECORD_SET_COMPLETE = + RecordSet.builder("www.sadfa.com", RecordSet.Type.A) .ttl(12, TimeUnit.HOURS) .addRecord("record") .build(); private static final ChangeRequest CHANGE_REQUEST_COMPLETE = ChangeRequest.builder() - .add(DNS_RECORD_COMPLETE) - .delete(DNS_RECORD_PARTIAL) + .add(RECORD_SET_COMPLETE) + .delete(RECORD_SET_PARTIAL) .status(ChangeRequest.Status.PENDING) .id("some id") .startTimeMillis(132L) @@ -89,9 +89,9 @@ protected Serializable[] serializableObjects() { .authCredentials(null) .build(); return new Serializable[]{FULL_ZONE_INFO, PARTIAL_ZONE_INFO, ZONE_LIST_OPTION, - DNS_REOCRD_LIST_OPTION, CHANGE_REQUEST_LIST_OPTION, ZONE_OPTION, CHANGE_REQUEST_OPTION, + RECORD_SET_LIST_OPTION, CHANGE_REQUEST_LIST_OPTION, ZONE_OPTION, CHANGE_REQUEST_OPTION, PROJECT_OPTION, PARTIAL_PROJECT_INFO, FULL_PROJECT_INFO, OPTIONS, FULL_ZONE, PARTIAL_ZONE, - OPTIONS, CHANGE_REQUEST_PARTIAL, DNS_RECORD_PARTIAL, DNS_RECORD_COMPLETE, + OPTIONS, CHANGE_REQUEST_PARTIAL, RECORD_SET_PARTIAL, RECORD_SET_COMPLETE, CHANGE_REQUEST_COMPLETE, options, otherOptions}; } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java index 759c34fc1167..bd59f8c140e9 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java @@ -50,12 +50,12 @@ public class ZoneTest { .build(); private static final ZoneInfo NO_ID_INFO = ZoneInfo.of(ZONE_NAME, "another-example.com", "description").toBuilder() - .creationTimeMillis(893123464L) - .build(); + .creationTimeMillis(893123464L) + .build(); private static final Dns.ZoneOption ZONE_FIELD_OPTIONS = Dns.ZoneOption.fields(Dns.ZoneField.CREATION_TIME); - private static final Dns.DnsRecordListOption DNS_RECORD_OPTIONS = - Dns.DnsRecordListOption.dnsName("some-dns"); + private static final Dns.RecordSetListOption DNS_RECORD_OPTIONS = + Dns.RecordSetListOption.dnsName("some-dns"); private static final Dns.ChangeRequestOption CHANGE_REQUEST_FIELD_OPTIONS = Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME); private static final Dns.ChangeRequestListOption CHANGE_REQUEST_LIST_OPTIONS = @@ -120,51 +120,51 @@ public void deleteByNameAndNotFound() { @Test public void listDnsRecordsByNameAndFound() { @SuppressWarnings("unchecked") - Page pageMock = createStrictMock(Page.class); + Page pageMock = createStrictMock(Page.class); replay(pageMock); - expect(dns.listDnsRecords(ZONE_NAME)).andReturn(pageMock); - expect(dns.listDnsRecords(ZONE_NAME)).andReturn(pageMock); + expect(dns.listRecordSets(ZONE_NAME)).andReturn(pageMock); + expect(dns.listRecordSets(ZONE_NAME)).andReturn(pageMock); // again for options - expect(dns.listDnsRecords(ZONE_NAME, DNS_RECORD_OPTIONS)).andReturn(pageMock); - expect(dns.listDnsRecords(ZONE_NAME, DNS_RECORD_OPTIONS)).andReturn(pageMock); + expect(dns.listRecordSets(ZONE_NAME, DNS_RECORD_OPTIONS)).andReturn(pageMock); + expect(dns.listRecordSets(ZONE_NAME, DNS_RECORD_OPTIONS)).andReturn(pageMock); replay(dns); - Page result = zone.listDnsRecords(); + Page result = zone.listRecordSets(); assertSame(pageMock, result); - result = zoneNoId.listDnsRecords(); + result = zoneNoId.listRecordSets(); assertSame(pageMock, result); verify(pageMock); - zone.listDnsRecords(DNS_RECORD_OPTIONS); // check options - zoneNoId.listDnsRecords(DNS_RECORD_OPTIONS); // check options + zone.listRecordSets(DNS_RECORD_OPTIONS); // check options + zoneNoId.listRecordSets(DNS_RECORD_OPTIONS); // check options } @Test public void listDnsRecordsByNameAndNotFound() { - expect(dns.listDnsRecords(ZONE_NAME)).andThrow(EXCEPTION); - expect(dns.listDnsRecords(ZONE_NAME)).andThrow(EXCEPTION); + expect(dns.listRecordSets(ZONE_NAME)).andThrow(EXCEPTION); + expect(dns.listRecordSets(ZONE_NAME)).andThrow(EXCEPTION); // again for options - expect(dns.listDnsRecords(ZONE_NAME, DNS_RECORD_OPTIONS)).andThrow(EXCEPTION); - expect(dns.listDnsRecords(ZONE_NAME, DNS_RECORD_OPTIONS)).andThrow(EXCEPTION); + expect(dns.listRecordSets(ZONE_NAME, DNS_RECORD_OPTIONS)).andThrow(EXCEPTION); + expect(dns.listRecordSets(ZONE_NAME, DNS_RECORD_OPTIONS)).andThrow(EXCEPTION); replay(dns); try { - zoneNoId.listDnsRecords(); + zoneNoId.listRecordSets(); fail("Parent container not found, should throw an exception."); } catch (DnsException e) { // expected } try { - zone.listDnsRecords(); + zone.listRecordSets(); fail("Parent container not found, should throw an exception."); } catch (DnsException e) { // expected } try { - zoneNoId.listDnsRecords(DNS_RECORD_OPTIONS); // check options + zoneNoId.listRecordSets(DNS_RECORD_OPTIONS); // check options fail("Parent container not found, should throw an exception."); } catch (DnsException e) { // expected } try { - zone.listDnsRecords(DNS_RECORD_OPTIONS); // check options + zone.listRecordSets(DNS_RECORD_OPTIONS); // check options fail("Parent container not found, should throw an exception."); } catch (DnsException e) { // expected diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java index bfea46dfe039..8f7626a5ae0a 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java @@ -29,8 +29,8 @@ import com.google.gcloud.dns.Dns; import com.google.gcloud.dns.DnsException; import com.google.gcloud.dns.DnsOptions; -import com.google.gcloud.dns.DnsRecord; import com.google.gcloud.dns.ProjectInfo; +import com.google.gcloud.dns.RecordSet; import com.google.gcloud.dns.Zone; import com.google.gcloud.dns.ZoneInfo; @@ -66,13 +66,13 @@ public class ITDnsTest { ZoneInfo.of(ZONE_NAME_TOO_LONG, ZONE_DNS_NAME1, ZONE_DESCRIPTION1); private static final ZoneInfo ZONE_DNS_NO_PERIOD = ZoneInfo.of(ZONE_NAME1, ZONE_DNS_NAME_NO_PERIOD, ZONE_DESCRIPTION1); - private static final DnsRecord A_RECORD_ZONE1 = - DnsRecord.builder("www." + ZONE1.dnsName(), DnsRecord.Type.A) + private static final RecordSet A_RECORD_ZONE1 = + RecordSet.builder("www." + ZONE1.dnsName(), RecordSet.Type.A) .records(ImmutableList.of("123.123.55.1")) .ttl(25, TimeUnit.SECONDS) .build(); - private static final DnsRecord AAAA_RECORD_ZONE1 = - DnsRecord.builder("www." + ZONE1.dnsName(), DnsRecord.Type.AAAA) + private static final RecordSet AAAA_RECORD_ZONE1 = + RecordSet.builder("www." + ZONE1.dnsName(), RecordSet.Type.AAAA) .records(ImmutableList.of("ed:ed:12:aa:36:3:3:105")) .ttl(25, TimeUnit.SECONDS) .build(); @@ -98,12 +98,13 @@ private static void clear() { while (iterator.hasNext()) { waitForChangeToComplete(zoneName, iterator.next().id()); } - Iterator recordIterator = zone.listDnsRecords().iterateAll(); - List toDelete = new LinkedList<>(); - while (recordIterator.hasNext()) { - DnsRecord record = recordIterator.next(); - if (!ImmutableList.of(DnsRecord.Type.NS, DnsRecord.Type.SOA).contains(record.type())) { - toDelete.add(record); + Iterator recordSetIterator = zone.listRecordSets().iterateAll(); + List toDelete = new LinkedList<>(); + while (recordSetIterator.hasNext()) { + RecordSet recordSet = recordSetIterator.next(); + if (!ImmutableList.of(RecordSet.Type.NS, RecordSet.Type.SOA) + .contains(recordSet.type())) { + toDelete.add(recordSet); } } if (!toDelete.isEmpty()) { @@ -587,41 +588,42 @@ public void testCreateChange() { @Test public void testInvalidChangeRequest() { Zone zone = DNS.create(ZONE1); - DnsRecord validA = DnsRecord.builder("subdomain." + zone.dnsName(), DnsRecord.Type.A) - .records(ImmutableList.of("0.255.1.5")) - .build(); + RecordSet validA = + RecordSet.builder("subdomain." + zone.dnsName(), RecordSet.Type.A) + .records(ImmutableList.of("0.255.1.5")) + .build(); try { ChangeRequest validChange = ChangeRequest.builder().add(validA).build(); zone.applyChangeRequest(validChange); try { zone.applyChangeRequest(validChange); - fail("Created a record which already exists."); + fail("Created a record set which already exists."); } catch (DnsException ex) { // expected assertFalse(ex.retryable()); assertEquals(409, ex.code()); } // delete with field mismatch - DnsRecord mismatch = validA.toBuilder().ttl(20, TimeUnit.SECONDS).build(); + RecordSet mismatch = validA.toBuilder().ttl(20, TimeUnit.SECONDS).build(); ChangeRequest deletion = ChangeRequest.builder().delete(mismatch).build(); try { zone.applyChangeRequest(deletion); - fail("Deleted a record without a complete match."); + fail("Deleted a record set without a complete match."); } catch (DnsException ex) { // expected assertEquals(412, ex.code()); assertFalse(ex.retryable()); } // delete and add SOA - Iterator recordIterator = zone.listDnsRecords().iterateAll(); - LinkedList deletions = new LinkedList<>(); - LinkedList additions = new LinkedList<>(); - while (recordIterator.hasNext()) { - DnsRecord record = recordIterator.next(); - if (record.type() == DnsRecord.Type.SOA) { - deletions.add(record); + Iterator recordSetIterator = zone.listRecordSets().iterateAll(); + LinkedList deletions = new LinkedList<>(); + LinkedList additions = new LinkedList<>(); + while (recordSetIterator.hasNext()) { + RecordSet recordSet = recordSetIterator.next(); + if (recordSet.type() == RecordSet.Type.SOA) { + deletions.add(recordSet); // the subdomain is necessary to get 400 instead of 412 - DnsRecord copy = record.toBuilder().name("x." + record.name()).build(); + RecordSet copy = recordSet.toBuilder().name("x." + recordSet.name()).build(); additions.add(copy); break; } @@ -831,92 +833,93 @@ public void testGetProject() { public void testListDnsRecords() { try { Zone zone = DNS.create(ZONE1); - ImmutableList dnsRecords = ImmutableList.copyOf( - DNS.listDnsRecords(zone.name()).iterateAll()); - assertEquals(2, dnsRecords.size()); - ImmutableList defaultRecords = - ImmutableList.of(DnsRecord.Type.NS, DnsRecord.Type.SOA); - for (DnsRecord record : dnsRecords) { - assertTrue(defaultRecords.contains(record.type())); + ImmutableList recordSets = ImmutableList.copyOf( + DNS.listRecordSets(zone.name()).iterateAll()); + assertEquals(2, recordSets.size()); + ImmutableList defaultRecords = + ImmutableList.of(RecordSet.Type.NS, RecordSet.Type.SOA); + for (RecordSet recordSet : recordSets) { + assertTrue(defaultRecords.contains(recordSet.type())); } // field options - Iterator dnsRecordIterator = DNS.listDnsRecords(zone.name(), - Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TTL)).iterateAll(); + Iterator recordSetIterator = DNS.listRecordSets(zone.name(), + Dns.RecordSetListOption.fields(Dns.RecordSetField.TTL)).iterateAll(); int counter = 0; - while (dnsRecordIterator.hasNext()) { - DnsRecord record = dnsRecordIterator.next(); - assertEquals(dnsRecords.get(counter).ttl(), record.ttl()); - assertEquals(dnsRecords.get(counter).name(), record.name()); - assertEquals(dnsRecords.get(counter).type(), record.type()); - assertTrue(record.records().isEmpty()); + while (recordSetIterator.hasNext()) { + RecordSet recordSet = recordSetIterator.next(); + assertEquals(recordSets.get(counter).ttl(), recordSet.ttl()); + assertEquals(recordSets.get(counter).name(), recordSet.name()); + assertEquals(recordSets.get(counter).type(), recordSet.type()); + assertTrue(recordSet.records().isEmpty()); counter++; } assertEquals(2, counter); - dnsRecordIterator = DNS.listDnsRecords(zone.name(), - Dns.DnsRecordListOption.fields(Dns.DnsRecordField.NAME)).iterateAll(); + recordSetIterator = DNS.listRecordSets(zone.name(), + Dns.RecordSetListOption.fields(Dns.RecordSetField.NAME)).iterateAll(); counter = 0; - while (dnsRecordIterator.hasNext()) { - DnsRecord record = dnsRecordIterator.next(); - assertEquals(dnsRecords.get(counter).name(), record.name()); - assertEquals(dnsRecords.get(counter).type(), record.type()); - assertTrue(record.records().isEmpty()); - assertNull(record.ttl()); + while (recordSetIterator.hasNext()) { + RecordSet recordSet = recordSetIterator.next(); + assertEquals(recordSets.get(counter).name(), recordSet.name()); + assertEquals(recordSets.get(counter).type(), recordSet.type()); + assertTrue(recordSet.records().isEmpty()); + assertNull(recordSet.ttl()); counter++; } assertEquals(2, counter); - dnsRecordIterator = DNS.listDnsRecords(zone.name(), - Dns.DnsRecordListOption.fields(Dns.DnsRecordField.DNS_RECORDS)).iterateAll(); + recordSetIterator = DNS.listRecordSets(zone.name(), + Dns.RecordSetListOption.fields(Dns.RecordSetField.DNS_RECORDS)) + .iterateAll(); counter = 0; - while (dnsRecordIterator.hasNext()) { - DnsRecord record = dnsRecordIterator.next(); - assertEquals(dnsRecords.get(counter).records(), record.records()); - assertEquals(dnsRecords.get(counter).name(), record.name()); - assertEquals(dnsRecords.get(counter).type(), record.type()); - assertNull(record.ttl()); + while (recordSetIterator.hasNext()) { + RecordSet recordSet = recordSetIterator.next(); + assertEquals(recordSets.get(counter).records(), recordSet.records()); + assertEquals(recordSets.get(counter).name(), recordSet.name()); + assertEquals(recordSets.get(counter).type(), recordSet.type()); + assertNull(recordSet.ttl()); counter++; } assertEquals(2, counter); - dnsRecordIterator = DNS.listDnsRecords(zone.name(), - Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TYPE), - Dns.DnsRecordListOption.pageSize(1)).iterateAll(); // also test paging + recordSetIterator = DNS.listRecordSets(zone.name(), + Dns.RecordSetListOption.fields(Dns.RecordSetField.TYPE), + Dns.RecordSetListOption.pageSize(1)).iterateAll(); // also test paging counter = 0; - while (dnsRecordIterator.hasNext()) { - DnsRecord record = dnsRecordIterator.next(); - assertEquals(dnsRecords.get(counter).type(), record.type()); - assertEquals(dnsRecords.get(counter).name(), record.name()); - assertTrue(record.records().isEmpty()); - assertNull(record.ttl()); + while (recordSetIterator.hasNext()) { + RecordSet recordSet = recordSetIterator.next(); + assertEquals(recordSets.get(counter).type(), recordSet.type()); + assertEquals(recordSets.get(counter).name(), recordSet.name()); + assertTrue(recordSet.records().isEmpty()); + assertNull(recordSet.ttl()); counter++; } assertEquals(2, counter); // test page size - Page dnsRecordPage = DNS.listDnsRecords(zone.name(), - Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TYPE), - Dns.DnsRecordListOption.pageSize(1)); - assertEquals(1, ImmutableList.copyOf(dnsRecordPage.values().iterator()).size()); + Page recordSetPage = DNS.listRecordSets(zone.name(), + Dns.RecordSetListOption.fields(Dns.RecordSetField.TYPE), + Dns.RecordSetListOption.pageSize(1)); + assertEquals(1, ImmutableList.copyOf(recordSetPage.values().iterator()).size()); // test name filter ChangeRequest change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); waitForChangeToComplete(ZONE1.name(), change.id()); - dnsRecordIterator = DNS.listDnsRecords(ZONE1.name(), - Dns.DnsRecordListOption.dnsName(A_RECORD_ZONE1.name())).iterateAll(); + recordSetIterator = DNS.listRecordSets(ZONE1.name(), + Dns.RecordSetListOption.dnsName(A_RECORD_ZONE1.name())).iterateAll(); counter = 0; - while (dnsRecordIterator.hasNext()) { - DnsRecord record = dnsRecordIterator.next(); + while (recordSetIterator.hasNext()) { + RecordSet recordSet = recordSetIterator.next(); assertTrue(ImmutableList.of(A_RECORD_ZONE1.type(), AAAA_RECORD_ZONE1.type()) - .contains(record.type())); + .contains(recordSet.type())); counter++; } assertEquals(2, counter); // test type filter waitForChangeToComplete(ZONE1.name(), change.id()); - dnsRecordIterator = DNS.listDnsRecords(ZONE1.name(), - Dns.DnsRecordListOption.dnsName(A_RECORD_ZONE1.name()), - Dns.DnsRecordListOption.type(A_RECORD_ZONE1.type())) + recordSetIterator = DNS.listRecordSets(ZONE1.name(), + Dns.RecordSetListOption.dnsName(A_RECORD_ZONE1.name()), + Dns.RecordSetListOption.type(A_RECORD_ZONE1.type())) .iterateAll(); counter = 0; - while (dnsRecordIterator.hasNext()) { - DnsRecord record = dnsRecordIterator.next(); - assertEquals(A_RECORD_ZONE1, record); + while (recordSetIterator.hasNext()) { + RecordSet recordSet = recordSetIterator.next(); + assertEquals(A_RECORD_ZONE1, recordSet); counter++; } assertEquals(1, counter); @@ -924,7 +927,8 @@ public void testListDnsRecords() { // check wrong arguments try { // name is not set - DNS.listDnsRecords(ZONE1.name(), Dns.DnsRecordListOption.type(A_RECORD_ZONE1.type())); + DNS.listRecordSets(ZONE1.name(), + Dns.RecordSetListOption.type(A_RECORD_ZONE1.type())); fail(); } catch (DnsException ex) { // expected @@ -932,7 +936,7 @@ public void testListDnsRecords() { assertFalse(ex.retryable()); } try { - DNS.listDnsRecords(ZONE1.name(), Dns.DnsRecordListOption.pageSize(0)); + DNS.listRecordSets(ZONE1.name(), Dns.RecordSetListOption.pageSize(0)); fail(); } catch (DnsException ex) { // expected @@ -940,7 +944,7 @@ public void testListDnsRecords() { assertFalse(ex.retryable()); } try { - DNS.listDnsRecords(ZONE1.name(), Dns.DnsRecordListOption.pageSize(-1)); + DNS.listRecordSets(ZONE1.name(), Dns.RecordSetListOption.pageSize(-1)); fail(); } catch (DnsException ex) { // expected diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/testing/LocalDnsHelperTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/testing/LocalDnsHelperTest.java index 59002131cc9d..44516f47c657 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/testing/LocalDnsHelperTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/testing/LocalDnsHelperTest.java @@ -131,7 +131,7 @@ public void testCreateZone() { ManagedZone created = RPC.create(ZONE1, EMPTY_RPC_OPTIONS); // check that default records were created DnsRpc.ListResult listResult - = RPC.listDnsRecords(ZONE1.getName(), EMPTY_RPC_OPTIONS); + = RPC.listRecordSets(ZONE1.getName(), EMPTY_RPC_OPTIONS); ImmutableList defaultTypes = ImmutableList.of("SOA", "NS"); Iterator iterator = listResult.results().iterator(); assertTrue(defaultTypes.contains(iterator.next().getType())); @@ -395,7 +395,7 @@ private static void executeCreateAndApplyChangeTest(DnsRpc rpc) { rpc.applyChangeRequest(ZONE1.getName(), CHANGE_KEEP, EMPTY_RPC_OPTIONS); waitForChangeToComplete(rpc, ZONE1.getName(), "3"); Iterable results = - rpc.listDnsRecords(ZONE1.getName(), EMPTY_RPC_OPTIONS).results(); + rpc.listRecordSets(ZONE1.getName(), EMPTY_RPC_OPTIONS).results(); List defaults = ImmutableList.of("SOA", "NS"); boolean rrsetKeep = false; boolean rrset1 = false; @@ -692,7 +692,7 @@ public void testListZones() { public void testListDnsRecords() { // no zone exists try { - RPC.listDnsRecords(ZONE_NAME1, EMPTY_RPC_OPTIONS); + RPC.listRecordSets(ZONE_NAME1, EMPTY_RPC_OPTIONS); fail(); } catch (DnsException ex) { // expected @@ -702,19 +702,19 @@ public void testListDnsRecords() { // zone exists but has no records RPC.create(ZONE1, EMPTY_RPC_OPTIONS); Iterable results = - RPC.listDnsRecords(ZONE_NAME1, EMPTY_RPC_OPTIONS).results(); + RPC.listRecordSets(ZONE_NAME1, EMPTY_RPC_OPTIONS).results(); ImmutableList records = ImmutableList.copyOf(results); assertEquals(2, records.size()); // contains default NS and SOA // zone has records RPC.applyChangeRequest(ZONE_NAME1, CHANGE_KEEP, EMPTY_RPC_OPTIONS); - results = RPC.listDnsRecords(ZONE_NAME1, EMPTY_RPC_OPTIONS).results(); + results = RPC.listRecordSets(ZONE_NAME1, EMPTY_RPC_OPTIONS).results(); records = ImmutableList.copyOf(results); assertEquals(3, records.size()); // error in options Map options = new HashMap<>(); options.put(DnsRpc.Option.PAGE_SIZE, 0); try { - RPC.listDnsRecords(ZONE1.getName(), options); + RPC.listRecordSets(ZONE1.getName(), options); fail(); } catch (DnsException ex) { // expected @@ -723,7 +723,7 @@ public void testListDnsRecords() { } options.put(DnsRpc.Option.PAGE_SIZE, -1); try { - RPC.listDnsRecords(ZONE1.getName(), options); + RPC.listRecordSets(ZONE1.getName(), options); fail(); } catch (DnsException ex) { // expected @@ -731,14 +731,14 @@ public void testListDnsRecords() { assertTrue(ex.getMessage().contains("parameters.maxResults")); } options.put(DnsRpc.Option.PAGE_SIZE, 15); - results = RPC.listDnsRecords(ZONE1.getName(), options).results(); + results = RPC.listRecordSets(ZONE1.getName(), options).results(); records = ImmutableList.copyOf(results); assertEquals(3, records.size()); // dnsName filter options = new HashMap<>(); options.put(DnsRpc.Option.NAME, "aaa"); try { - RPC.listDnsRecords(ZONE1.getName(), options); + RPC.listRecordSets(ZONE1.getName(), options); fail(); } catch (DnsException ex) { // expected @@ -746,13 +746,13 @@ public void testListDnsRecords() { assertTrue(ex.getMessage().contains("parameters.name")); } options.put(DnsRpc.Option.NAME, "aaa."); - results = RPC.listDnsRecords(ZONE1.getName(), options).results(); + results = RPC.listRecordSets(ZONE1.getName(), options).results(); records = ImmutableList.copyOf(results); assertEquals(0, records.size()); options.put(DnsRpc.Option.NAME, null); options.put(DnsRpc.Option.DNS_TYPE, "A"); try { - RPC.listDnsRecords(ZONE1.getName(), options); + RPC.listRecordSets(ZONE1.getName(), options); fail(); } catch (DnsException ex) { // expected @@ -762,7 +762,7 @@ public void testListDnsRecords() { options.put(DnsRpc.Option.NAME, "aaa."); options.put(DnsRpc.Option.DNS_TYPE, "a"); try { - RPC.listDnsRecords(ZONE1.getName(), options); + RPC.listRecordSets(ZONE1.getName(), options); fail(); } catch (DnsException ex) { // expected @@ -771,14 +771,14 @@ public void testListDnsRecords() { } options.put(DnsRpc.Option.NAME, DNS_NAME); options.put(DnsRpc.Option.DNS_TYPE, "SOA"); - results = RPC.listDnsRecords(ZONE1.getName(), options).results(); + results = RPC.listRecordSets(ZONE1.getName(), options).results(); records = ImmutableList.copyOf(results); assertEquals(1, records.size()); // field options options = new HashMap<>(); options.put(DnsRpc.Option.FIELDS, "rrsets(name)"); DnsRpc.ListResult listResult = - RPC.listDnsRecords(ZONE1.getName(), options); + RPC.listRecordSets(ZONE1.getName(), options); records = ImmutableList.copyOf(listResult.results()); ResourceRecordSet record = records.get(0); assertNotNull(record.getName()); @@ -787,7 +787,7 @@ public void testListDnsRecords() { assertNull(record.getTtl()); assertNull(listResult.pageToken()); options.put(DnsRpc.Option.FIELDS, "rrsets(rrdatas)"); - listResult = RPC.listDnsRecords(ZONE1.getName(), options); + listResult = RPC.listRecordSets(ZONE1.getName(), options); records = ImmutableList.copyOf(listResult.results()); record = records.get(0); assertNull(record.getName()); @@ -796,7 +796,7 @@ record = records.get(0); assertNull(record.getTtl()); assertNull(listResult.pageToken()); options.put(DnsRpc.Option.FIELDS, "rrsets(ttl)"); - listResult = RPC.listDnsRecords(ZONE1.getName(), options); + listResult = RPC.listRecordSets(ZONE1.getName(), options); records = ImmutableList.copyOf(listResult.results()); record = records.get(0); assertNull(record.getName()); @@ -805,7 +805,7 @@ record = records.get(0); assertNotNull(record.getTtl()); assertNull(listResult.pageToken()); options.put(DnsRpc.Option.FIELDS, "rrsets(type)"); - listResult = RPC.listDnsRecords(ZONE1.getName(), options); + listResult = RPC.listRecordSets(ZONE1.getName(), options); records = ImmutableList.copyOf(listResult.results()); record = records.get(0); assertNull(record.getName()); @@ -814,7 +814,7 @@ record = records.get(0); assertNull(record.getTtl()); assertNull(listResult.pageToken()); options.put(DnsRpc.Option.FIELDS, "nextPageToken"); - listResult = RPC.listDnsRecords(ZONE1.getName(), options); + listResult = RPC.listRecordSets(ZONE1.getName(), options); records = ImmutableList.copyOf(listResult.results()); record = records.get(0); assertNull(record.getName()); @@ -824,7 +824,7 @@ record = records.get(0); assertNull(listResult.pageToken()); options.put(DnsRpc.Option.FIELDS, "nextPageToken,rrsets(name,rrdatas)"); options.put(DnsRpc.Option.PAGE_SIZE, 1); - listResult = RPC.listDnsRecords(ZONE1.getName(), options); + listResult = RPC.listRecordSets(ZONE1.getName(), options); records = ImmutableList.copyOf(listResult.results()); assertEquals(1, records.size()); record = records.get(0); @@ -973,15 +973,15 @@ public void testListChanges() { public void testDnsRecordPaging() { RPC.create(ZONE1, EMPTY_RPC_OPTIONS); List complete = ImmutableList.copyOf( - RPC.listDnsRecords(ZONE1.getName(), EMPTY_RPC_OPTIONS).results()); + RPC.listRecordSets(ZONE1.getName(), EMPTY_RPC_OPTIONS).results()); Map options = new HashMap<>(); options.put(DnsRpc.Option.PAGE_SIZE, 1); - DnsRpc.ListResult listResult = RPC.listDnsRecords(ZONE1.getName(), options); + DnsRpc.ListResult listResult = RPC.listRecordSets(ZONE1.getName(), options); ImmutableList records = ImmutableList.copyOf(listResult.results()); assertEquals(1, records.size()); assertEquals(complete.get(0), records.get(0)); options.put(DnsRpc.Option.PAGE_TOKEN, listResult.pageToken()); - listResult = RPC.listDnsRecords(ZONE1.getName(), options); + listResult = RPC.listRecordSets(ZONE1.getName(), options); records = ImmutableList.copyOf(listResult.results()); assertEquals(1, records.size()); assertEquals(complete.get(1), records.get(0)); diff --git a/gcloud-java-examples/README.md b/gcloud-java-examples/README.md index fc9ce9ef653d..8084cee562f0 100644 --- a/gcloud-java-examples/README.md +++ b/gcloud-java-examples/README.md @@ -75,7 +75,7 @@ To run examples from your command line: Note that you have to enable the Google Cloud DNS API on the [Google Developers Console][developers-console] before running the following commands. You will need to replace the domain name `elaborateexample.com` with your own domain name with [verified ownership] (https://www.google.com/webmasters/verification/home). - Also, note that the example creates and deletes DNS records of type A only. Operations with other record types are not implemented in the example. + Also, note that the example creates and deletes record sets of type A only. Operations with other record types are not implemented in the example. ``` mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.dns.DnsExample" -Dexec.args="create some-sample-zone elaborateexample.com. description" mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.dns.DnsExample" -Dexec.args="list" diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java index 1b6ba8f179da..40ce61b07281 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java @@ -21,8 +21,8 @@ import com.google.gcloud.dns.ChangeRequest; import com.google.gcloud.dns.Dns; import com.google.gcloud.dns.DnsOptions; -import com.google.gcloud.dns.DnsRecord; import com.google.gcloud.dns.ProjectInfo; +import com.google.gcloud.dns.RecordSet; import com.google.gcloud.dns.Zone; import com.google.gcloud.dns.ZoneInfo; @@ -38,8 +38,8 @@ /** * An example of using Google Cloud DNS. * - *

      This example creates, deletes, gets, and lists zones. It also creates and deletes DNS records - * of type A, and lists DNS records. + *

      This example creates, deletes, gets, and lists zones. It also creates and deletes + * record sets of type A, and lists record sets. * *

      Steps needed for running the example: *

        @@ -203,12 +203,12 @@ public void run(Dns dns, String... args) { if (args.length > 3) { ttl = Integer.parseInt(args[3]); } - DnsRecord record = DnsRecord.builder(recordName, DnsRecord.Type.A) + RecordSet recordSet = RecordSet.builder(recordName, RecordSet.Type.A) .records(ImmutableList.of(ip)) .ttl(ttl, TimeUnit.SECONDS) .build(); ChangeRequest changeRequest = ChangeRequest.builder() - .delete(record) + .delete(recordSet) .build(); changeRequest = dns.applyChangeRequest(zoneName, changeRequest); System.out.printf("The request for deleting A record %s for zone %s was successfully " @@ -238,7 +238,7 @@ public boolean check(String... args) { private static class AddDnsRecordAction implements DnsAction { /** - * Adds a DNS record of type A. The last parameter is ttl and is not required. If ttl is not + * Adds a record set of type A. The last parameter is ttl and is not required. If ttl is not * provided, a default value of 0 will be used. */ @Override @@ -250,11 +250,11 @@ public void run(Dns dns, String... args) { if (args.length > 3) { ttl = Integer.parseInt(args[3]); } - DnsRecord record = DnsRecord.builder(recordName, DnsRecord.Type.A) + RecordSet recordSet = RecordSet.builder(recordName, RecordSet.Type.A) .records(ImmutableList.of(ip)) .ttl(ttl, TimeUnit.SECONDS) .build(); - ChangeRequest changeRequest = ChangeRequest.builder().add(record).build(); + ChangeRequest changeRequest = ChangeRequest.builder().add(recordSet).build(); changeRequest = dns.applyChangeRequest(zoneName, changeRequest); System.out.printf("The request for adding A record %s for zone %s was successfully " + "submitted and assigned ID %s.%n", recordName, zoneName, changeRequest.id()); @@ -283,21 +283,21 @@ public boolean check(String... args) { private static class ListDnsRecordsAction implements DnsAction { /** - * Lists all the DNS records in the given zone. + * Lists all the record sets in the given zone. */ @Override public void run(Dns dns, String... args) { String zoneName = args[0]; - Iterator iterator = dns.listDnsRecords(zoneName).iterateAll(); + Iterator iterator = dns.listRecordSets(zoneName).iterateAll(); if (iterator.hasNext()) { - System.out.printf("DNS records for zone %s:%n", zoneName); + System.out.printf("Record sets for zone %s:%n", zoneName); while (iterator.hasNext()) { - DnsRecord record = iterator.next(); - System.out.printf("%nRecord name: %s%nTTL: %s%nRecords: %s%n", record.name(), - record.ttl(), Joiner.on(", ").join(record.records())); + RecordSet recordSet = iterator.next(); + System.out.printf("%nRecord name: %s%nTTL: %s%nRecords: %s%n", recordSet.name(), + recordSet.ttl(), Joiner.on(", ").join(recordSet.records())); } } else { - System.out.printf("Zone %s has no DNS records.%n", zoneName); + System.out.printf("Zone %s has no record sets records.%n", zoneName); } } @@ -361,8 +361,8 @@ private static class ListAction implements DnsAction { /** * Invokes a list action. If no parameter is provided, lists all zones. If zone name is the only - * parameter provided, lists both DNS records and changes. Otherwise, invokes listing changes or - * zones based on the parameter provided. + * parameter provided, lists both record sets and changes. Otherwise, invokes listing + * changes or zones based on the parameter provided. */ @Override public void run(Dns dns, String... args) { @@ -406,7 +406,7 @@ public void run(Dns dns, String... args) { ProjectInfo.Quota quota = project.quota(); System.out.printf("Project id: %s%nQuota:%n", dns.options().projectId()); System.out.printf("\tZones: %d%n", quota.zones()); - System.out.printf("\tDNS records per zone: %d%n", quota.rrsetsPerZone()); + System.out.printf("\tRecord sets per zone: %d%n", quota.rrsetsPerZone()); System.out.printf("\tRecord sets per DNS record: %d%n", quota.resourceRecordsPerRrset()); System.out.printf("\tAdditions per change: %d%n", quota.rrsetAdditionsPerChange()); diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateDnsRecords.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateRecordSets.java similarity index 83% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateDnsRecords.java rename to gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateRecordSets.java index 71327ba98a96..74647daf666e 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateDnsRecords.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateRecordSets.java @@ -25,16 +25,16 @@ import com.google.gcloud.dns.ChangeRequest; import com.google.gcloud.dns.Dns; import com.google.gcloud.dns.DnsOptions; -import com.google.gcloud.dns.DnsRecord; +import com.google.gcloud.dns.RecordSet; import com.google.gcloud.dns.Zone; import java.util.Iterator; import java.util.concurrent.TimeUnit; /** - * A snippet for Google Cloud DNS showing how to create and update a DNS record. + * A snippet for Google Cloud DNS showing how to create and update a resource record set. */ -public class CreateOrUpdateDnsRecords { +public class CreateOrUpdateRecordSets { public static void main(String... args) { // Create a service object. @@ -47,9 +47,9 @@ public static void main(String... args) { // Get zone from the service Zone zone = dns.getZone(zoneName); - // Prepare a www.. type A record with ttl of 24 hours + // Prepare a www.. type A record set with ttl of 24 hours String ip = "12.13.14.15"; - DnsRecord toCreate = DnsRecord.builder("www." + zone.dnsName(), DnsRecord.Type.A) + RecordSet toCreate = RecordSet.builder("www." + zone.dnsName(), RecordSet.Type.A) .ttl(24, TimeUnit.HOURS) .addRecord(ip) .build(); @@ -59,9 +59,9 @@ public static void main(String... args) { // Verify a www.. type A record does not exist yet. // If it does exist, we will overwrite it with our prepared record. - Iterator recordIterator = zone.listDnsRecords().iterateAll(); - while (recordIterator.hasNext()) { - DnsRecord current = recordIterator.next(); + Iterator recordSetIterator = zone.listRecordSets().iterateAll(); + while (recordSetIterator.hasNext()) { + RecordSet current = recordSetIterator.next(); if (toCreate.name().equals(current.name()) && toCreate.type().equals(current.type())) { changeBuilder.delete(current); } diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java index e841a4cd54ed..27377345b62f 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java @@ -25,7 +25,7 @@ import com.google.gcloud.dns.ChangeRequest; import com.google.gcloud.dns.Dns; import com.google.gcloud.dns.DnsOptions; -import com.google.gcloud.dns.DnsRecord; +import com.google.gcloud.dns.RecordSet; import java.util.Iterator; @@ -43,15 +43,15 @@ public static void main(String... args) { // Change this to a zone name that exists within your project and that you want to delete. String zoneName = "my-unique-zone"; - // Get iterator for the existing records which have to be deleted before deleting the zone - Iterator recordIterator = dns.listDnsRecords(zoneName).iterateAll(); + // Get iterator for the existing record sets which have to be deleted before deleting the zone + Iterator recordIterator = dns.listRecordSets(zoneName).iterateAll(); // Make a change for deleting the records ChangeRequest.Builder changeBuilder = ChangeRequest.builder(); while (recordIterator.hasNext()) { - DnsRecord current = recordIterator.next(); + RecordSet current = recordIterator.next(); // SOA and NS records cannot be deleted - if (!DnsRecord.Type.SOA.equals(current.type()) && !DnsRecord.Type.NS.equals(current.type())) { + if (!RecordSet.Type.SOA.equals(current.type()) && !RecordSet.Type.NS.equals(current.type())) { changeBuilder.delete(current); } } diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecords.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java similarity index 84% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecords.java rename to gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java index 4de262386d53..6d9d09d704a6 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecords.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java @@ -25,7 +25,7 @@ import com.google.gcloud.dns.ChangeRequest; import com.google.gcloud.dns.Dns; import com.google.gcloud.dns.DnsOptions; -import com.google.gcloud.dns.DnsRecord; +import com.google.gcloud.dns.RecordSet; import com.google.gcloud.dns.Zone; import com.google.gcloud.dns.ZoneInfo; @@ -35,9 +35,9 @@ /** * A complete snippet for Google Cloud DNS showing how to create and delete a zone. It also shows - * how to create, list and delete DNS records, and how to list changes. + * how to create, list and delete record sets, and how to list changes. */ -public class ManipulateZonesAndRecords { +public class ManipulateZonesAndRecordSets { public static void main(String... args) { Dns dns = DnsOptions.defaultInstance().service(); @@ -60,7 +60,7 @@ public static void main(String... args) { // Prepare a www.someexampledomain.com. type A record with ttl of 24 hours String ip = "12.13.14.15"; - DnsRecord toCreate = DnsRecord.builder("www.someexampledomain.com.", DnsRecord.Type.A) + RecordSet toCreate = RecordSet.builder("www.someexampledomain.com.", RecordSet.Type.A) .ttl(24, TimeUnit.HOURS) .addRecord(ip) .build(); @@ -70,9 +70,9 @@ public static void main(String... args) { // Verify the type A record does not exist yet. // If it does exist, we will overwrite it with our prepared record. - Iterator recordIterator = zone.listDnsRecords().iterateAll(); - while (recordIterator.hasNext()) { - DnsRecord current = recordIterator.next(); + Iterator recordSetIterator = zone.listRecordSets().iterateAll(); + while (recordSetIterator.hasNext()) { + RecordSet current = recordSetIterator.next(); if (toCreate.name().equals(current.name()) && toCreate.type().equals(current.type())) { changeBuilder.delete(current); } @@ -100,11 +100,11 @@ public static void main(String... args) { counter++; } - // List the DNS records in a particular zone - recordIterator = zone.listDnsRecords().iterateAll(); - System.out.println(String.format("DNS records inside %s:", zone.name())); - while (recordIterator.hasNext()) { - System.out.println(recordIterator.next()); + // List the record sets in a particular zone + recordSetIterator = zone.listRecordSets().iterateAll(); + System.out.println(String.format("Record sets inside %s:", zone.name())); + while (recordSetIterator.hasNext()) { + System.out.println(recordSetIterator.next()); } // List the change requests applied to a particular zone @@ -114,12 +114,12 @@ public static void main(String... args) { System.out.println(changeIterator.next()); } - // Make a change for deleting the records + // Make a change for deleting the record sets changeBuilder = ChangeRequest.builder(); - while (recordIterator.hasNext()) { - DnsRecord current = recordIterator.next(); + while (recordSetIterator.hasNext()) { + RecordSet current = recordSetIterator.next(); // SOA and NS records cannot be deleted - if (!DnsRecord.Type.SOA.equals(current.type()) && !DnsRecord.Type.NS.equals(current.type())) { + if (!RecordSet.Type.SOA.equals(current.type()) && !RecordSet.Type.NS.equals(current.type())) { changeBuilder.delete(current); } } From 01e23100fb12bf855f31b2ab8c4d12e43de9aab8 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Thu, 24 Mar 2016 16:46:09 -0700 Subject: [PATCH 198/375] Turned ChangeRequest into a functional object. --- .../com/google/gcloud/dns/ChangeRequest.java | 265 ++++--------- .../google/gcloud/dns/ChangeRequestInfo.java | 347 ++++++++++++++++++ .../main/java/com/google/gcloud/dns/Dns.java | 4 +- .../java/com/google/gcloud/dns/DnsImpl.java | 11 +- .../main/java/com/google/gcloud/dns/Zone.java | 2 +- .../gcloud/dns/ChangeRequestInfoTest.java | 218 +++++++++++ .../google/gcloud/dns/ChangeRequestTest.java | 269 +++++--------- .../com/google/gcloud/dns/DnsImplTest.java | 4 +- .../google/gcloud/dns/SerializationTest.java | 14 +- .../java/com/google/gcloud/dns/ZoneTest.java | 44 ++- .../com/google/gcloud/dns/it/ITDnsTest.java | 13 +- 11 files changed, 791 insertions(+), 400 deletions(-) create mode 100644 gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequestInfo.java create mode 100644 gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestInfoTest.java diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java index 757d844cc3da..ad1c65f7cb0f 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java @@ -16,19 +16,11 @@ package com.google.gcloud.dns; -import static com.google.common.base.Preconditions.checkNotNull; - import com.google.api.services.dns.model.Change; import com.google.common.base.Function; -import com.google.common.base.MoreObjects; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; - -import org.joda.time.DateTime; -import org.joda.time.format.ISODateTimeFormat; -import java.io.Serializable; -import java.util.LinkedList; +import java.io.IOException; +import java.io.ObjectInputStream; import java.util.List; import java.util.Objects; @@ -38,21 +30,12 @@ * * @see Google Cloud DNS documentation */ -public class ChangeRequest implements Serializable { +public class ChangeRequest extends ChangeRequestInfo { - static final Function FROM_PB_FUNCTION = - new Function() { - @Override - public ChangeRequest apply(com.google.api.services.dns.model.Change pb) { - return ChangeRequest.fromPb(pb); - } - }; private static final long serialVersionUID = -9027378042756366333L; - private final List additions; - private final List deletions; - private final String id; - private final Long startTimeMillis; - private final Status status; + private final DnsOptions options; + private final String zoneName; + private transient Dns dns; /** * This enumerates the possible states of a {@code ChangeRequest}. @@ -68,250 +51,152 @@ public enum Status { /** * A builder for {@code ChangeRequest}s. */ - public static class Builder { + public static class Builder extends ChangeRequestInfo.Builder { - private List additions = new LinkedList<>(); - private List deletions = new LinkedList<>(); - private String id; - private Long startTimeMillis; - private Status status; + private final Dns dns; + private final String zoneName; + private final ChangeRequestInfo.BuilderImpl infoBuilder; private Builder(ChangeRequest cr) { - this.additions = Lists.newLinkedList(cr.additions()); - this.deletions = Lists.newLinkedList(cr.deletions()); - this.id = cr.id(); - this.startTimeMillis = cr.startTimeMillis(); - this.status = cr.status(); + this.dns = cr.dns; + this.zoneName = cr.zoneName; + this.infoBuilder = new ChangeRequestInfo.BuilderImpl(cr); } - private Builder() { - } - - /** - * Sets a collection of {@link RecordSet}s which are to be added to the zone upon executing this - * {@code ChangeRequest}. - */ + @Override public Builder additions(List additions) { - this.additions = Lists.newLinkedList(checkNotNull(additions)); + infoBuilder.additions(additions); return this; } - /** - * Sets a collection of {@link RecordSet}s which are to be deleted from the zone upon executing - * this {@code ChangeRequest}. - */ + @Override public Builder deletions(List deletions) { - this.deletions = Lists.newLinkedList(checkNotNull(deletions)); + infoBuilder.deletions(deletions); return this; } - /** - * Adds a {@link RecordSet} to be added to the zone upon executing this {@code - * ChangeRequest}. - */ + @Override public Builder add(RecordSet recordSet) { - this.additions.add(checkNotNull(recordSet)); + infoBuilder.add(recordSet); return this; } - /** - * Adds a {@link RecordSet} to be deleted to the zone upon executing this - * {@code ChangeRequest}. - */ + @Override public Builder delete(RecordSet recordSet) { - this.deletions.add(checkNotNull(recordSet)); + infoBuilder.delete(recordSet); return this; } - /** - * Clears the collection of {@link RecordSet}s which are to be added to the zone upon executing - * this {@code ChangeRequest}. - */ + @Override public Builder clearAdditions() { - this.additions.clear(); + infoBuilder.clearAdditions(); return this; } - /** - * Clears the collection of {@link RecordSet}s which are to be deleted from the zone upon - * executing this {@code ChangeRequest}. - */ + @Override public Builder clearDeletions() { - this.deletions.clear(); + infoBuilder.clearDeletions(); return this; } - /** - * Removes a single {@link RecordSet} from the collection of records to be - * added to the zone upon executing this {@code ChangeRequest}. - */ + @Override public Builder removeAddition(RecordSet recordSet) { - this.additions.remove(recordSet); + infoBuilder.removeAddition(recordSet); return this; } - /** - * Removes a single {@link RecordSet} from the collection of records to be - * deleted from the zone upon executing this {@code ChangeRequest}. - */ + @Override public Builder removeDeletion(RecordSet recordSet) { - this.deletions.remove(recordSet); + infoBuilder.removeDeletion(recordSet); return this; } - /** - * Associates a server-assigned id to this {@code ChangeRequest}. - */ + @Override Builder id(String id) { - this.id = checkNotNull(id); + infoBuilder.id(id); return this; } - /** - * Sets the time when this {@code ChangeRequest} was started by a server. - */ + @Override Builder startTimeMillis(long startTimeMillis) { - this.startTimeMillis = startTimeMillis; + infoBuilder.startTimeMillis(startTimeMillis); return this; } - /** - * Sets the current status of this {@code ChangeRequest}. - */ + @Override Builder status(Status status) { - this.status = checkNotNull(status); + infoBuilder.status(status); return this; } - /** - * Creates a {@code ChangeRequest} instance populated by the values associated with this - * builder. - */ + @Override public ChangeRequest build() { - return new ChangeRequest(this); + return new ChangeRequest(dns, zoneName, infoBuilder); } } - private ChangeRequest(Builder builder) { - this.additions = ImmutableList.copyOf(builder.additions); - this.deletions = ImmutableList.copyOf(builder.deletions); - this.id = builder.id; - this.startTimeMillis = builder.startTimeMillis; - this.status = builder.status; - } - - /** - * Returns an empty builder for the {@code ChangeRequest} class. - */ - public static Builder builder() { - return new Builder(); - } - - /** - * Creates a builder populated with values of this {@code ChangeRequest}. - */ - public Builder toBuilder() { - return new Builder(this); - } - - /** - * Returns the list of {@link RecordSet}s to be added to the zone upon submitting this {@code - * ChangeRequest}. - */ - public List additions() { - return additions; + ChangeRequest(Dns dns, String zoneName, ChangeRequest.BuilderImpl infoBuilder) { + super(infoBuilder); + this.zoneName = zoneName; + this.dns = dns; + this.options = dns.options(); } - /** - * Returns the list of {@link RecordSet}s to be deleted from the zone upon submitting this {@code - * ChangeRequest}. - */ - public List deletions() { - return deletions; + static Function fromPbFunction(final Dns dns, final String zoneName) { + return new Function() { + @Override + public ChangeRequest apply(com.google.api.services.dns.model.Change pb) { + return ChangeRequest.fromPb(dns, zoneName, pb); + } + }; } /** - * Returns the id assigned to this {@code ChangeRequest} by the server. + * Returns the name of the {@link Zone} associated with this change request. */ - public String id() { - return id; + public String zoneName() { + return this.zoneName; } /** - * Returns the time when this {@code ChangeRequest} was started by the server. + * Returns the {@link Dns} service object associated with this change request. */ - public Long startTimeMillis() { - return startTimeMillis; + public Dns dns() { + return dns; } /** - * Returns the status of this {@code ChangeRequest}. + * Applies this change request to a zone that it is associated with. */ - public Status status() { - return status; + public ChangeRequest applyTo(Dns.ChangeRequestOption... options) { + return dns.applyChangeRequest(zoneName, this, options); } - com.google.api.services.dns.model.Change toPb() { - com.google.api.services.dns.model.Change pb = - new com.google.api.services.dns.model.Change(); - // set id - if (id() != null) { - pb.setId(id()); - } - // set timestamp - if (startTimeMillis() != null) { - pb.setStartTime(ISODateTimeFormat.dateTime().withZoneUTC().print(startTimeMillis())); - } - // set status - if (status() != null) { - pb.setStatus(status().name().toLowerCase()); - } - // set a list of additions - pb.setAdditions(Lists.transform(additions(), RecordSet.TO_PB_FUNCTION)); - // set a list of deletions - pb.setDeletions(Lists.transform(deletions(), RecordSet.TO_PB_FUNCTION)); - return pb; - } - - static ChangeRequest fromPb(com.google.api.services.dns.model.Change pb) { - Builder builder = builder(); - if (pb.getId() != null) { - builder.id(pb.getId()); - } - if (pb.getStartTime() != null) { - builder.startTimeMillis(DateTime.parse(pb.getStartTime()).getMillis()); - } - if (pb.getStatus() != null) { - // we are assuming that status indicated in pb is a lower case version of the enum name - builder.status(ChangeRequest.Status.valueOf(pb.getStatus().toUpperCase())); - } - if (pb.getDeletions() != null) { - builder.deletions(Lists.transform(pb.getDeletions(), RecordSet.FROM_PB_FUNCTION)); - } - if (pb.getAdditions() != null) { - builder.additions(Lists.transform(pb.getAdditions(), RecordSet.FROM_PB_FUNCTION)); - } - return builder.build(); + @Override + public Builder toBuilder() { + return new Builder(this); } @Override - public boolean equals(Object other) { - return (other instanceof ChangeRequest) && toPb().equals(((ChangeRequest) other).toPb()); + public boolean equals(Object obj) { + return obj instanceof ChangeRequest && Objects.equals(toPb(), ((ChangeRequest) obj).toPb()) + && Objects.equals(options, ((ChangeRequest) obj).options) + && Objects.equals(zoneName, ((ChangeRequest) obj).zoneName); } @Override public int hashCode() { - return Objects.hash(additions, deletions, id, startTimeMillis, status); + return Objects.hash(super.hashCode(), options, zoneName); } - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("additions", additions) - .add("deletions", deletions) - .add("id", id) - .add("startTimeMillis", startTimeMillis) - .add("status", status) - .toString(); + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + this.dns = options.service(); + } + + static ChangeRequest fromPb(Dns dns, String zoneName, + com.google.api.services.dns.model.Change pb) { + ChangeRequestInfo info = ChangeRequestInfo.fromPb(pb); + return new ChangeRequest(dns, zoneName, new ChangeRequestInfo.BuilderImpl(info)); } } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequestInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequestInfo.java new file mode 100644 index 000000000000..25b915521b13 --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequestInfo.java @@ -0,0 +1,347 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.dns; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.api.services.dns.model.Change; +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + +import org.joda.time.DateTime; +import org.joda.time.format.ISODateTimeFormat; + +import java.io.Serializable; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; + +/** + * A class representing an atomic update to a collection of {@link RecordSet}s within a {@code + * Zone}. + * + * @see Google Cloud DNS documentation + */ +public class ChangeRequestInfo implements Serializable { + + static final Function FROM_PB_FUNCTION = + new Function() { + @Override + public ChangeRequestInfo apply(Change pb) { + return ChangeRequestInfo.fromPb(pb); + } + }; + private static final long serialVersionUID = -9027378042756366333L; + private final List additions; + private final List deletions; + private final String id; + private final Long startTimeMillis; + private final ChangeRequest.Status status; + + /** + * A builder for {@code ChangeRequestInfo}. + */ + public abstract static class Builder { + + /** + * Sets a collection of {@link RecordSet}s which are to be added to the zone upon executing this + * {@code ChangeRequestInfo}. + */ + public abstract Builder additions(List additions); + + /** + * Sets a collection of {@link RecordSet}s which are to be deleted from the zone upon executing + * this {@code ChangeRequestInfo}. + */ + public abstract Builder deletions(List deletions); + + /** + * Adds a {@link RecordSet} to be added to the zone upon executing this {@code + * ChangeRequestInfo}. + */ + public abstract Builder add(RecordSet recordSet); + + /** + * Adds a {@link RecordSet} to be deleted to the zone upon executing this + * {@code ChangeRequestInfo}. + */ + public abstract Builder delete(RecordSet recordSet); + + /** + * Clears the collection of {@link RecordSet}s which are to be added to the zone upon executing + * this {@code ChangeRequestInfo}. + */ + public abstract Builder clearAdditions(); + + /** + * Clears the collection of {@link RecordSet}s which are to be deleted from the zone upon + * executing this {@code ChangeRequestInfo}. + */ + public abstract Builder clearDeletions(); + + /** + * Removes a single {@link RecordSet} from the collection of records to be + * added to the zone upon executing this {@code ChangeRequestInfo}. + */ + public abstract Builder removeAddition(RecordSet recordSet); + + /** + * Removes a single {@link RecordSet} from the collection of records to be + * deleted from the zone upon executing this {@code ChangeRequestInfo}. + */ + public abstract Builder removeDeletion(RecordSet recordSet); + + /** + * Associates a server-assigned id to this {@code ChangeRequestInfo}. + */ + abstract Builder id(String id); + + /** + * Sets the time when this change request was started by a server. + */ + abstract Builder startTimeMillis(long startTimeMillis); + + /** + * Sets the current status of this {@code ChangeRequest}. + */ + abstract Builder status(ChangeRequest.Status status); + + /** + * Creates a {@code ChangeRequestInfo} instance populated by the values associated with this + * builder. + */ + public abstract ChangeRequestInfo build(); + } + + static class BuilderImpl extends Builder { + private List additions; + private List deletions; + private String id; + private Long startTimeMillis; + private ChangeRequest.Status status; + + BuilderImpl() { + this.additions = new LinkedList<>(); + this.deletions = new LinkedList<>(); + } + + BuilderImpl(ChangeRequestInfo info) { + this.additions = Lists.newLinkedList(info.additions()); + this.deletions = Lists.newLinkedList(info.deletions()); + this.id = info.id(); + this.startTimeMillis = info.startTimeMillis; + this.status = info.status; + } + + @Override + public Builder additions(List additions) { + this.additions = Lists.newLinkedList(checkNotNull(additions)); + return this; + } + + @Override + public Builder deletions(List deletions) { + this.deletions = Lists.newLinkedList(checkNotNull(deletions)); + return this; + } + + @Override + public Builder add(RecordSet recordSet) { + this.additions.add(checkNotNull(recordSet)); + return this; + } + + @Override + public Builder delete(RecordSet recordSet) { + this.deletions.add(checkNotNull(recordSet)); + return this; + } + + @Override + public Builder clearAdditions() { + this.additions.clear(); + return this; + } + + @Override + public Builder clearDeletions() { + this.deletions.clear(); + return this; + } + + @Override + public Builder removeAddition(RecordSet recordSet) { + this.additions.remove(recordSet); + return this; + } + + @Override + public Builder removeDeletion(RecordSet recordSet) { + this.deletions.remove(recordSet); + return this; + } + + @Override + public ChangeRequestInfo build() { + return new ChangeRequestInfo(this); + } + + @Override + Builder id(String id) { + this.id = checkNotNull(id); + return this; + } + + @Override + Builder startTimeMillis(long startTimeMillis) { + this.startTimeMillis = startTimeMillis; + return this; + } + + @Override + Builder status(ChangeRequest.Status status) { + this.status = checkNotNull(status); + return this; + } + } + + ChangeRequestInfo(BuilderImpl builder) { + this.additions = ImmutableList.copyOf(builder.additions); + this.deletions = ImmutableList.copyOf(builder.deletions); + this.id = builder.id; + this.startTimeMillis = builder.startTimeMillis; + this.status = builder.status; + } + + /** + * Returns an empty builder for the {@code ChangeRequestInfo} class. + */ + public static Builder builder() { + return new BuilderImpl(); + } + + /** + * Creates a builder populated with values of this {@code ChangeRequestInfo}. + */ + public Builder toBuilder() { + return new BuilderImpl(this); + } + + /** + * Returns the list of {@link RecordSet}s to be added to the zone upon submitting this change + * request. + */ + public List additions() { + return additions; + } + + /** + * Returns the list of {@link RecordSet}s to be deleted from the zone upon submitting this change + * request. + */ + public List deletions() { + return deletions; + } + + /** + * Returns the id assigned to this {@code ChangeRequest} by the server. + */ + public String id() { + return id; + } + + /** + * Returns the time when this {@code ChangeRequest} was started by the server. + */ + public Long startTimeMillis() { + return startTimeMillis; + } + + /** + * Returns the status of this {@code ChangeRequest}. + */ + public ChangeRequest.Status status() { + return status; + } + + com.google.api.services.dns.model.Change toPb() { + com.google.api.services.dns.model.Change pb = + new com.google.api.services.dns.model.Change(); + // set id + if (id() != null) { + pb.setId(id()); + } + // set timestamp + if (startTimeMillis() != null) { + pb.setStartTime(ISODateTimeFormat.dateTime().withZoneUTC().print(startTimeMillis())); + } + // set status + if (status() != null) { + pb.setStatus(status().name().toLowerCase()); + } + // set a list of additions + pb.setAdditions(Lists.transform(additions(), RecordSet.TO_PB_FUNCTION)); + // set a list of deletions + pb.setDeletions(Lists.transform(deletions(), RecordSet.TO_PB_FUNCTION)); + return pb; + } + + static ChangeRequestInfo fromPb(com.google.api.services.dns.model.Change pb) { + Builder builder = builder(); + if (pb.getId() != null) { + builder.id(pb.getId()); + } + if (pb.getStartTime() != null) { + builder.startTimeMillis(DateTime.parse(pb.getStartTime()).getMillis()); + } + if (pb.getStatus() != null) { + // we are assuming that status indicated in pb is a lower case version of the enum name + builder.status(ChangeRequest.Status.valueOf(pb.getStatus().toUpperCase())); + } + if (pb.getDeletions() != null) { + builder.deletions(Lists.transform(pb.getDeletions(), RecordSet.FROM_PB_FUNCTION)); + } + if (pb.getAdditions() != null) { + builder.additions(Lists.transform(pb.getAdditions(), RecordSet.FROM_PB_FUNCTION)); + } + return builder.build(); + } + + @Override + public boolean equals(Object other) { + return (other instanceof ChangeRequestInfo) + && toPb().equals(((ChangeRequestInfo) other).toPb()); + } + + @Override + public int hashCode() { + return Objects.hash(additions, deletions, id, startTimeMillis, status); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("additions", additions) + .add("deletions", deletions) + .add("id", id) + .add("startTimeMillis", startTimeMillis) + .add("status", status) + .toString(); + } +} diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index f8614a8d6169..f2b42f30a9f6 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -138,7 +138,7 @@ static String selector(RecordSetField... fields) { * The fields of a change request. * *

        These values can be used to specify the fields to include in a partial response when calling - * {@link Dns#applyChangeRequest(String, ChangeRequest, ChangeRequestOption...)} The ID is always + * {@link Dns#applyChangeRequest(String, ChangeRequestInfo, ChangeRequestOption...)} The ID is always * returned even if not selected. */ enum ChangeRequestField { @@ -508,7 +508,7 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) { * @throws DnsException upon failure if zone is not found * @see Cloud DNS Changes: create */ - ChangeRequest applyChangeRequest(String zoneName, ChangeRequest changeRequest, + ChangeRequest applyChangeRequest(String zoneName, ChangeRequestInfo changeRequest, ChangeRequestOption... options); /** diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java index 2fbf4e8b5a79..4e2bd1b207d5 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java @@ -169,7 +169,8 @@ public DnsRpc.ListResult call() { // transform that list into change request objects Iterable changes = result.results() == null ? ImmutableList.of() - : Iterables.transform(result.results(), ChangeRequest.FROM_PB_FUNCTION); + : Iterables.transform(result.results(), + ChangeRequest.fromPbFunction(serviceOptions.service(), zoneName)); return new PageImpl<>(new ChangeRequestPageFetcher(zoneName, serviceOptions, cursor, optionsMap), cursor, changes); } catch (RetryHelperException e) { @@ -272,8 +273,8 @@ public com.google.api.services.dns.model.Project call() { } @Override - public ChangeRequest applyChangeRequest(final String zoneName, final ChangeRequest changeRequest, - Dns.ChangeRequestOption... options) { + public ChangeRequest applyChangeRequest(final String zoneName, + final ChangeRequestInfo changeRequest, ChangeRequestOption... options) { final Map optionsMap = optionMap(options); try { com.google.api.services.dns.model.Change answer = @@ -284,7 +285,7 @@ public com.google.api.services.dns.model.Change call() { return dnsRpc.applyChangeRequest(zoneName, changeRequest.toPb(), optionsMap); } }, options().retryParams(), EXCEPTION_HANDLER); - return answer == null ? null : fromPb(answer); // should never be null + return answer == null ? null : fromPb(this, zoneName, answer); // should never be null } catch (RetryHelper.RetryHelperException ex) { throw DnsException.translateAndThrow(ex); } @@ -303,7 +304,7 @@ public com.google.api.services.dns.model.Change call() { return dnsRpc.getChangeRequest(zoneName, changeRequestId, optionsMap); } }, options().retryParams(), EXCEPTION_HANDLER); - return answer == null ? null : fromPb(answer); + return answer == null ? null : ChangeRequest.fromPb(this, zoneName, answer); } catch (RetryHelper.RetryHelperException ex) { throw DnsException.translateAndThrow(ex); } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java index aed99dbd0001..88b9e7273e9c 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java @@ -153,7 +153,7 @@ public Page listRecordSets(Dns.RecordSetListOption... options) { * @return ChangeRequest with server-assigned ID * @throws DnsException upon failure or if the zone is not found */ - public ChangeRequest applyChangeRequest(ChangeRequest changeRequest, + public ChangeRequest applyChangeRequest(ChangeRequestInfo changeRequest, Dns.ChangeRequestOption... options) { checkNotNull(changeRequest); return dns.applyChangeRequest(name(), changeRequest, options); diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestInfoTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestInfoTest.java new file mode 100644 index 000000000000..55f2af0824ec --- /dev/null +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestInfoTest.java @@ -0,0 +1,218 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.dns; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.google.common.collect.ImmutableList; + +import org.junit.Test; + +import java.util.List; + +public class ChangeRequestInfoTest { + + private static final String ID = "cr-id-1"; + private static final Long START_TIME_MILLIS = 12334567890L; + private static final ChangeRequest.Status STATUS = ChangeRequest.Status.PENDING; + private static final String NAME1 = "dns1"; + private static final RecordSet.Type TYPE1 = RecordSet.Type.A; + private static final String NAME2 = "dns2"; + private static final RecordSet.Type TYPE2 = RecordSet.Type.AAAA; + private static final String NAME3 = "dns3"; + private static final RecordSet.Type TYPE3 = RecordSet.Type.MX; + private static final RecordSet RECORD1 = RecordSet.builder(NAME1, TYPE1).build(); + private static final RecordSet RECORD2 = RecordSet.builder(NAME2, TYPE2).build(); + private static final RecordSet RECORD3 = RecordSet.builder(NAME3, TYPE3).build(); + private static final List ADDITIONS = ImmutableList.of(RECORD1, RECORD2); + private static final List DELETIONS = ImmutableList.of(RECORD3); + private static final ChangeRequestInfo CHANGE = ChangeRequest.builder() + .add(RECORD1) + .add(RECORD2) + .delete(RECORD3) + .startTimeMillis(START_TIME_MILLIS) + .status(STATUS) + .id(ID) + .build(); + + @Test + public void testEmptyBuilder() { + ChangeRequestInfo cr = ChangeRequest.builder().build(); + assertNotNull(cr.deletions()); + assertTrue(cr.deletions().isEmpty()); + assertNotNull(cr.additions()); + assertTrue(cr.additions().isEmpty()); + } + + @Test + public void testBuilder() { + assertEquals(ID, CHANGE.id()); + assertEquals(STATUS, CHANGE.status()); + assertEquals(START_TIME_MILLIS, CHANGE.startTimeMillis()); + assertEquals(ADDITIONS, CHANGE.additions()); + assertEquals(DELETIONS, CHANGE.deletions()); + List recordList = ImmutableList.of(RECORD1); + ChangeRequestInfo another = CHANGE.toBuilder().additions(recordList).build(); + assertEquals(recordList, another.additions()); + assertEquals(CHANGE.deletions(), another.deletions()); + another = CHANGE.toBuilder().deletions(recordList).build(); + assertEquals(recordList, another.deletions()); + assertEquals(CHANGE.additions(), another.additions()); + } + + @Test + public void testEqualsAndNotEquals() { + ChangeRequestInfo clone = CHANGE.toBuilder().build(); + assertEquals(CHANGE, clone); + clone = ChangeRequest.fromPb(CHANGE.toPb()); + assertEquals(CHANGE, clone); + clone = CHANGE.toBuilder().id("some-other-id").build(); + assertNotEquals(CHANGE, clone); + clone = CHANGE.toBuilder().startTimeMillis(CHANGE.startTimeMillis() + 1).build(); + assertNotEquals(CHANGE, clone); + clone = CHANGE.toBuilder().add(RECORD3).build(); + assertNotEquals(CHANGE, clone); + clone = CHANGE.toBuilder().delete(RECORD1).build(); + assertNotEquals(CHANGE, clone); + ChangeRequestInfo empty = ChangeRequest.builder().build(); + assertNotEquals(CHANGE, empty); + assertEquals(empty, ChangeRequest.builder().build()); + } + + @Test + public void testSameHashCodeOnEquals() { + ChangeRequestInfo clone = CHANGE.toBuilder().build(); + assertEquals(CHANGE, clone); + assertEquals(CHANGE.hashCode(), clone.hashCode()); + ChangeRequestInfo empty = ChangeRequest.builder().build(); + assertEquals(empty.hashCode(), ChangeRequest.builder().build().hashCode()); + } + + @Test + public void testToAndFromPb() { + assertEquals(CHANGE, ChangeRequest.fromPb(CHANGE.toPb())); + ChangeRequestInfo partial = ChangeRequest.builder().build(); + assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); + partial = ChangeRequest.builder().id(ID).build(); + assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); + partial = ChangeRequest.builder().add(RECORD1).build(); + assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); + partial = ChangeRequest.builder().delete(RECORD1).build(); + assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); + partial = ChangeRequest.builder().additions(ADDITIONS).build(); + assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); + partial = ChangeRequest.builder().deletions(DELETIONS).build(); + assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); + partial = ChangeRequest.builder().startTimeMillis(START_TIME_MILLIS).build(); + assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); + partial = ChangeRequest.builder().status(STATUS).build(); + assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); + } + + @Test + public void testToBuilder() { + assertEquals(CHANGE, CHANGE.toBuilder().build()); + ChangeRequestInfo partial = ChangeRequest.builder().build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ChangeRequest.builder().id(ID).build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ChangeRequest.builder().add(RECORD1).build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ChangeRequest.builder().delete(RECORD1).build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ChangeRequest.builder().additions(ADDITIONS).build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ChangeRequest.builder().deletions(DELETIONS).build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ChangeRequest.builder().startTimeMillis(START_TIME_MILLIS).build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ChangeRequest.builder().status(STATUS).build(); + assertEquals(partial, partial.toBuilder().build()); + } + + @Test + public void testClearAdditions() { + ChangeRequestInfo clone = CHANGE.toBuilder().clearAdditions().build(); + assertTrue(clone.additions().isEmpty()); + assertFalse(clone.deletions().isEmpty()); + } + + @Test + public void testAddAddition() { + try { + CHANGE.toBuilder().add(null); + fail("Should not be able to add null RecordSet."); + } catch (NullPointerException e) { + // expected + } + ChangeRequestInfo clone = CHANGE.toBuilder().add(RECORD1).build(); + assertEquals(CHANGE.additions().size() + 1, clone.additions().size()); + } + + @Test + public void testAddDeletion() { + try { + CHANGE.toBuilder().delete(null); + fail("Should not be able to delete null RecordSet."); + } catch (NullPointerException e) { + // expected + } + ChangeRequestInfo clone = CHANGE.toBuilder().delete(RECORD1).build(); + assertEquals(CHANGE.deletions().size() + 1, clone.deletions().size()); + } + + @Test + public void testClearDeletions() { + ChangeRequestInfo clone = CHANGE.toBuilder().clearDeletions().build(); + assertTrue(clone.deletions().isEmpty()); + assertFalse(clone.additions().isEmpty()); + } + + @Test + public void testRemoveAddition() { + ChangeRequestInfo clone = CHANGE.toBuilder().removeAddition(RECORD1).build(); + assertTrue(clone.additions().contains(RECORD2)); + assertFalse(clone.additions().contains(RECORD1)); + assertTrue(clone.deletions().contains(RECORD3)); + clone = CHANGE.toBuilder().removeAddition(RECORD2).removeAddition(RECORD1).build(); + assertFalse(clone.additions().contains(RECORD2)); + assertFalse(clone.additions().contains(RECORD1)); + assertTrue(clone.additions().isEmpty()); + assertTrue(clone.deletions().contains(RECORD3)); + } + + @Test + public void testRemoveDeletion() { + ChangeRequestInfo clone = CHANGE.toBuilder().removeDeletion(RECORD3).build(); + assertTrue(clone.deletions().isEmpty()); + } + + @Test + public void testDateParsing() { + String startTime = "2016-01-26T18:33:43.512Z"; // obtained from service + com.google.api.services.dns.model.Change change = CHANGE.toPb().setStartTime(startTime); + ChangeRequestInfo converted = ChangeRequest.fromPb(change); + assertNotNull(converted.startTimeMillis()); + assertEquals(change, converted.toPb()); + assertEquals(change.getStartTime(), converted.toPb().getStartTime()); + } +} diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java index fe726acb7c10..8d6cc799cad8 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java @@ -16,203 +16,132 @@ package com.google.gcloud.dns; +import static org.easymock.EasyMock.createStrictMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.reset; +import static org.easymock.EasyMock.verify; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import com.google.common.collect.ImmutableList; +import org.junit.After; +import org.junit.Before; import org.junit.Test; -import java.util.List; - public class ChangeRequestTest { - private static final String ID = "cr-id-1"; - private static final Long START_TIME_MILLIS = 12334567890L; - private static final ChangeRequest.Status STATUS = ChangeRequest.Status.PENDING; - private static final String NAME1 = "dns1"; - private static final RecordSet.Type TYPE1 = RecordSet.Type.A; - private static final String NAME2 = "dns2"; - private static final RecordSet.Type TYPE2 = RecordSet.Type.AAAA; - private static final String NAME3 = "dns3"; - private static final RecordSet.Type TYPE3 = RecordSet.Type.MX; - private static final RecordSet RECORD1 = RecordSet.builder(NAME1, TYPE1).build(); - private static final RecordSet RECORD2 = RecordSet.builder(NAME2, TYPE2).build(); - private static final RecordSet RECORD3 = RecordSet.builder(NAME3, TYPE3).build(); - private static final List ADDITIONS = ImmutableList.of(RECORD1, RECORD2); - private static final List DELETIONS = ImmutableList.of(RECORD3); - private static final ChangeRequest CHANGE = ChangeRequest.builder() - .add(RECORD1) - .add(RECORD2) - .delete(RECORD3) - .startTimeMillis(START_TIME_MILLIS) - .status(STATUS) - .id(ID) + private static final String ZONE_NAME = "dns-zone-name"; + private static final ChangeRequestInfo CHANGE_REQUEST_INFO = ChangeRequest.builder() + .add(RecordSet.builder("name", RecordSet.Type.A).build()) + .delete(RecordSet.builder("othername", RecordSet.Type.AAAA).build()) .build(); - - @Test - public void testEmptyBuilder() { - ChangeRequest cr = ChangeRequest.builder().build(); - assertNotNull(cr.deletions()); - assertTrue(cr.deletions().isEmpty()); - assertNotNull(cr.additions()); - assertTrue(cr.additions().isEmpty()); - } - - @Test - public void testBuilder() { - assertEquals(ID, CHANGE.id()); - assertEquals(STATUS, CHANGE.status()); - assertEquals(START_TIME_MILLIS, CHANGE.startTimeMillis()); - assertEquals(ADDITIONS, CHANGE.additions()); - assertEquals(DELETIONS, CHANGE.deletions()); - List recordList = ImmutableList.of(RECORD1); - ChangeRequest another = CHANGE.toBuilder().additions(recordList).build(); - assertEquals(recordList, another.additions()); - assertEquals(CHANGE.deletions(), another.deletions()); - another = CHANGE.toBuilder().deletions(recordList).build(); - assertEquals(recordList, another.deletions()); - assertEquals(CHANGE.additions(), another.additions()); - } - - @Test - public void testEqualsAndNotEquals() { - ChangeRequest clone = CHANGE.toBuilder().build(); - assertEquals(CHANGE, clone); - clone = ChangeRequest.fromPb(CHANGE.toPb()); - assertEquals(CHANGE, clone); - clone = CHANGE.toBuilder().id("some-other-id").build(); - assertNotEquals(CHANGE, clone); - clone = CHANGE.toBuilder().startTimeMillis(CHANGE.startTimeMillis() + 1).build(); - assertNotEquals(CHANGE, clone); - clone = CHANGE.toBuilder().add(RECORD3).build(); - assertNotEquals(CHANGE, clone); - clone = CHANGE.toBuilder().delete(RECORD1).build(); - assertNotEquals(CHANGE, clone); - ChangeRequest empty = ChangeRequest.builder().build(); - assertNotEquals(CHANGE, empty); - assertEquals(empty, ChangeRequest.builder().build()); - } - - @Test - public void testSameHashCodeOnEquals() { - ChangeRequest clone = CHANGE.toBuilder().build(); - assertEquals(CHANGE, clone); - assertEquals(CHANGE.hashCode(), clone.hashCode()); - ChangeRequest empty = ChangeRequest.builder().build(); - assertEquals(empty.hashCode(), ChangeRequest.builder().build().hashCode()); - } - - @Test - public void testToAndFromPb() { - assertEquals(CHANGE, ChangeRequest.fromPb(CHANGE.toPb())); - ChangeRequest partial = ChangeRequest.builder().build(); - assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); - partial = ChangeRequest.builder().id(ID).build(); - assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); - partial = ChangeRequest.builder().add(RECORD1).build(); - assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); - partial = ChangeRequest.builder().delete(RECORD1).build(); - assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); - partial = ChangeRequest.builder().additions(ADDITIONS).build(); - assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); - partial = ChangeRequest.builder().deletions(DELETIONS).build(); - assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); - partial = ChangeRequest.builder().startTimeMillis(START_TIME_MILLIS).build(); - assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); - partial = ChangeRequest.builder().status(STATUS).build(); - assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); - } - - @Test - public void testToBuilder() { - assertEquals(CHANGE, CHANGE.toBuilder().build()); - ChangeRequest partial = ChangeRequest.builder().build(); - assertEquals(partial, partial.toBuilder().build()); - partial = ChangeRequest.builder().id(ID).build(); - assertEquals(partial, partial.toBuilder().build()); - partial = ChangeRequest.builder().add(RECORD1).build(); - assertEquals(partial, partial.toBuilder().build()); - partial = ChangeRequest.builder().delete(RECORD1).build(); - assertEquals(partial, partial.toBuilder().build()); - partial = ChangeRequest.builder().additions(ADDITIONS).build(); - assertEquals(partial, partial.toBuilder().build()); - partial = ChangeRequest.builder().deletions(DELETIONS).build(); - assertEquals(partial, partial.toBuilder().build()); - partial = ChangeRequest.builder().startTimeMillis(START_TIME_MILLIS).build(); - assertEquals(partial, partial.toBuilder().build()); - partial = ChangeRequest.builder().status(STATUS).build(); - assertEquals(partial, partial.toBuilder().build()); - } - - @Test - public void testClearAdditions() { - ChangeRequest clone = CHANGE.toBuilder().clearAdditions().build(); - assertTrue(clone.additions().isEmpty()); - assertFalse(clone.deletions().isEmpty()); + private static final DnsOptions OPTIONS = createStrictMock(DnsOptions.class); + + private Dns dns; + private ChangeRequest changeRequest; + private ChangeRequest changeRequestPartial; + + @Before + public void setUp() throws Exception { + dns = createStrictMock(Dns.class); + expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS); + replay(dns); + changeRequest = new ChangeRequest(dns, ZONE_NAME, new ChangeRequestInfo.BuilderImpl( + CHANGE_REQUEST_INFO.toBuilder() + .startTimeMillis(132L) + .id("12") + .status(ChangeRequest.Status.DONE) + .build())); + changeRequestPartial = new ChangeRequest(dns, ZONE_NAME, + new ChangeRequest.BuilderImpl(CHANGE_REQUEST_INFO)); + reset(dns); } - @Test - public void testAddAddition() { - try { - CHANGE.toBuilder().add(null); - fail("Should not be able to add null RecordSet."); - } catch (NullPointerException e) { - // expected - } - ChangeRequest clone = CHANGE.toBuilder().add(RECORD1).build(); - assertEquals(CHANGE.additions().size() + 1, clone.additions().size()); + @After + public void tearDown() throws Exception { + verify(dns); } @Test - public void testAddDeletion() { - try { - CHANGE.toBuilder().delete(null); - fail("Should not be able to delete null RecordSet."); - } catch (NullPointerException e) { - // expected - } - ChangeRequest clone = CHANGE.toBuilder().delete(RECORD1).build(); - assertEquals(CHANGE.deletions().size() + 1, clone.deletions().size()); + public void testConstructor() { + replay(dns); + assertEquals(CHANGE_REQUEST_INFO.toPb(), changeRequestPartial.toPb()); + assertNotNull(changeRequest.dns()); + assertEquals(ZONE_NAME, changeRequest.zoneName()); + assertNotNull(changeRequestPartial.dns()); + assertEquals(ZONE_NAME, changeRequestPartial.zoneName()); } @Test - public void testClearDeletions() { - ChangeRequest clone = CHANGE.toBuilder().clearDeletions().build(); - assertTrue(clone.deletions().isEmpty()); - assertFalse(clone.additions().isEmpty()); + public void testFromPb() { + expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS); + replay(dns); + assertEquals(ChangeRequest.fromPb(dns, ZONE_NAME, changeRequest.toPb()), changeRequest); + assertEquals(ChangeRequest.fromPb(dns, ZONE_NAME, changeRequestPartial.toPb()), + changeRequestPartial); } @Test - public void testRemoveAddition() { - ChangeRequest clone = CHANGE.toBuilder().removeAddition(RECORD1).build(); - assertTrue(clone.additions().contains(RECORD2)); - assertFalse(clone.additions().contains(RECORD1)); - assertTrue(clone.deletions().contains(RECORD3)); - clone = CHANGE.toBuilder().removeAddition(RECORD2).removeAddition(RECORD1).build(); - assertFalse(clone.additions().contains(RECORD2)); - assertFalse(clone.additions().contains(RECORD1)); - assertTrue(clone.additions().isEmpty()); - assertTrue(clone.deletions().contains(RECORD3)); + public void testEqualsAndToBuilder() { + expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS); + replay(dns); + ChangeRequest compare = changeRequest.toBuilder().build(); + assertEquals(changeRequest, compare); + assertEquals(changeRequest.hashCode(), compare.hashCode()); + compare = changeRequestPartial.toBuilder().build(); + assertEquals(changeRequestPartial, compare); + assertEquals(changeRequestPartial.hashCode(), compare.hashCode()); } @Test - public void testRemoveDeletion() { - ChangeRequest clone = CHANGE.toBuilder().removeDeletion(RECORD3).build(); - assertTrue(clone.deletions().isEmpty()); + public void testBuilder() { + // one for each build() call because it invokes a constructor + expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS); + replay(dns); + String id = changeRequest.id() + "aaa"; + assertEquals(id, changeRequest.toBuilder().id(id).build().id()); + ChangeRequest modified = + changeRequest.toBuilder().status(ChangeRequest.Status.PENDING).build(); + assertEquals(ChangeRequest.Status.PENDING, modified.status()); + modified = changeRequest.toBuilder().clearDeletions().build(); + assertTrue(modified.deletions().isEmpty()); + modified = changeRequest.toBuilder().clearAdditions().build(); + assertTrue(modified.additions().isEmpty()); + modified = changeRequest.toBuilder().additions(ImmutableList.of()).build(); + assertTrue(modified.additions().isEmpty()); + modified = changeRequest.toBuilder().deletions(ImmutableList.of()).build(); + assertTrue(modified.deletions().isEmpty()); + RecordSet cname = RecordSet.builder("last", RecordSet.Type.CNAME).build(); + modified = changeRequest.toBuilder().add(cname).build(); + assertTrue(modified.additions().contains(cname)); + modified = changeRequest.toBuilder().delete(cname).build(); + assertTrue(modified.deletions().contains(cname)); + modified = changeRequest.toBuilder().startTimeMillis(0L).build(); + assertEquals(new Long(0), modified.startTimeMillis()); } @Test - public void testDateParsing() { - String startTime = "2016-01-26T18:33:43.512Z"; // obtained from service - com.google.api.services.dns.model.Change change = CHANGE.toPb().setStartTime(startTime); - ChangeRequest converted = ChangeRequest.fromPb(change); - assertNotNull(converted.startTimeMillis()); - assertEquals(change, converted.toPb()); - assertEquals(change.getStartTime(), converted.toPb().getStartTime()); + public void testApplyTo() { + expect(dns.applyChangeRequest(ZONE_NAME, changeRequest)).andReturn(changeRequest); + expect(dns.applyChangeRequest(ZONE_NAME, changeRequest, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME))) + .andReturn(changeRequest); + replay(dns); + changeRequest.applyTo(); + changeRequest.applyTo(Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); } } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java index ab2dba0a566c..73548e9cbb91 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java @@ -53,10 +53,10 @@ public class DnsImplTest { private static final String PAGE_TOKEN = "some token"; private static final ZoneInfo ZONE_INFO = ZoneInfo.of(ZONE_NAME, DNS_NAME, DESCRIPTION); private static final ProjectInfo PROJECT_INFO = ProjectInfo.builder().build(); - private static final ChangeRequest CHANGE_REQUEST_PARTIAL = ChangeRequest.builder() + private static final ChangeRequestInfo CHANGE_REQUEST_PARTIAL = ChangeRequest.builder() .add(DNS_RECORD1) .build(); - private static final ChangeRequest CHANGE_REQUEST_COMPLETE = ChangeRequest.builder() + private static final ChangeRequestInfo CHANGE_REQUEST_COMPLETE = ChangeRequest.builder() .add(DNS_RECORD1) .startTimeMillis(123L) .status(ChangeRequest.Status.PENDING) diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java index c06cd096bf1e..4e492eff3526 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java @@ -63,7 +63,10 @@ public class SerializationTest extends BaseSerializationTest { private static final Zone FULL_ZONE = new Zone(DNS, new ZoneInfo.BuilderImpl(FULL_ZONE_INFO)); private static final Zone PARTIAL_ZONE = new Zone(DNS, new ZoneInfo.BuilderImpl(PARTIAL_ZONE_INFO)); - private static final ChangeRequest CHANGE_REQUEST_PARTIAL = ChangeRequest.builder().build(); + private static final ChangeRequestInfo CHANGE_REQUEST_INFO_PARTIAL = + ChangeRequest.builder().build(); + private static final ChangeRequest CHANGE_REQUEST_PARTIAL = new ChangeRequest(DNS, "name", + new ChangeRequestInfo.BuilderImpl(CHANGE_REQUEST_INFO_PARTIAL)); private static final RecordSet RECORD_SET_PARTIAL = RecordSet.builder("www.www.com", RecordSet.Type.AAAA).build(); private static final RecordSet RECORD_SET_COMPLETE = @@ -71,13 +74,15 @@ public class SerializationTest extends BaseSerializationTest { .ttl(12, TimeUnit.HOURS) .addRecord("record") .build(); - private static final ChangeRequest CHANGE_REQUEST_COMPLETE = ChangeRequest.builder() + private static final ChangeRequestInfo CHANGE_REQUEST_INFO_COMPLETE = ChangeRequest.builder() .add(RECORD_SET_COMPLETE) .delete(RECORD_SET_PARTIAL) .status(ChangeRequest.Status.PENDING) .id("some id") .startTimeMillis(132L) .build(); + private static final ChangeRequest CHANGE_REQUEST_COMPLETE = new ChangeRequest(DNS, "name", + new ChangeRequestInfo.BuilderImpl(CHANGE_REQUEST_INFO_COMPLETE)); @Override protected Serializable[] serializableObjects() { @@ -91,8 +96,9 @@ protected Serializable[] serializableObjects() { return new Serializable[]{FULL_ZONE_INFO, PARTIAL_ZONE_INFO, ZONE_LIST_OPTION, RECORD_SET_LIST_OPTION, CHANGE_REQUEST_LIST_OPTION, ZONE_OPTION, CHANGE_REQUEST_OPTION, PROJECT_OPTION, PARTIAL_PROJECT_INFO, FULL_PROJECT_INFO, OPTIONS, FULL_ZONE, PARTIAL_ZONE, - OPTIONS, CHANGE_REQUEST_PARTIAL, RECORD_SET_PARTIAL, RECORD_SET_COMPLETE, - CHANGE_REQUEST_COMPLETE, options, otherOptions}; + OPTIONS, CHANGE_REQUEST_INFO_PARTIAL, CHANGE_REQUEST_PARTIAL, RECORD_SET_PARTIAL, + RECORD_SET_COMPLETE, CHANGE_REQUEST_INFO_COMPLETE, CHANGE_REQUEST_COMPLETE, options, + otherOptions}; } @Override diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java index bd59f8c140e9..3ed395bf6881 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java @@ -60,25 +60,29 @@ public class ZoneTest { Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME); private static final Dns.ChangeRequestListOption CHANGE_REQUEST_LIST_OPTIONS = Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.START_TIME); - private static final ChangeRequest CHANGE_REQUEST = ChangeRequest.builder().id("someid").build(); - private static final ChangeRequest CHANGE_REQUEST_AFTER = CHANGE_REQUEST.toBuilder() - .startTimeMillis(123465L).build(); - private static final ChangeRequest CHANGE_REQUEST_NO_ID = ChangeRequest.builder().build(); + private static final ChangeRequestInfo CHANGE_REQUEST = + ChangeRequest.builder().id("someid").build(); + private static final ChangeRequestInfo CHANGE_REQUEST_NO_ID = + ChangeRequest.builder().build(); private static final DnsException EXCEPTION = createStrictMock(DnsException.class); private static final DnsOptions OPTIONS = createStrictMock(DnsOptions.class); private Dns dns; private Zone zone; private Zone zoneNoId; + private ChangeRequest changeRequestAfter; @Before public void setUp() throws Exception { dns = createStrictMock(Dns.class); expect(dns.options()).andReturn(OPTIONS); expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS); replay(dns); zone = new Zone(dns, new ZoneInfo.BuilderImpl(ZONE_INFO)); zoneNoId = new Zone(dns, new ZoneInfo.BuilderImpl(NO_ID_INFO)); + changeRequestAfter = new ChangeRequest(dns, ZONE_NAME, new ChangeRequestInfo.BuilderImpl( + CHANGE_REQUEST.toBuilder().startTimeMillis(123465L).build())); reset(dns); } @@ -208,24 +212,24 @@ public void reloadByNameAndNotFound() { @Test public void applyChangeByNameAndFound() { expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST)) - .andReturn(CHANGE_REQUEST_AFTER); + .andReturn(changeRequestAfter); expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST)) - .andReturn(CHANGE_REQUEST_AFTER); + .andReturn(changeRequestAfter); // again for options expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS)) - .andReturn(CHANGE_REQUEST_AFTER); + .andReturn(changeRequestAfter); expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS)) - .andReturn(CHANGE_REQUEST_AFTER); + .andReturn(changeRequestAfter); replay(dns); ChangeRequest result = zoneNoId.applyChangeRequest(CHANGE_REQUEST); - assertEquals(CHANGE_REQUEST_AFTER, result); + assertEquals(changeRequestAfter, result); result = zone.applyChangeRequest(CHANGE_REQUEST); - assertEquals(CHANGE_REQUEST_AFTER, result); + assertEquals(changeRequestAfter, result); // check options result = zoneNoId.applyChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); - assertEquals(CHANGE_REQUEST_AFTER, result); + assertEquals(changeRequestAfter, result); result = zone.applyChangeRequest(CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS); - assertEquals(CHANGE_REQUEST_AFTER, result); + assertEquals(changeRequestAfter, result); } @Test @@ -298,24 +302,24 @@ public void applyNullChangeRequest() { @Test public void getChangeAndZoneFoundByName() { expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())) - .andReturn(CHANGE_REQUEST_AFTER); + .andReturn(changeRequestAfter); expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())) - .andReturn(CHANGE_REQUEST_AFTER); + .andReturn(changeRequestAfter); // again for options expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) - .andReturn(CHANGE_REQUEST_AFTER); + .andReturn(changeRequestAfter); expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) - .andReturn(CHANGE_REQUEST_AFTER); + .andReturn(changeRequestAfter); replay(dns); ChangeRequest result = zoneNoId.getChangeRequest(CHANGE_REQUEST.id()); - assertEquals(CHANGE_REQUEST_AFTER, result); + assertEquals(changeRequestAfter, result); result = zone.getChangeRequest(CHANGE_REQUEST.id()); - assertEquals(CHANGE_REQUEST_AFTER, result); + assertEquals(changeRequestAfter, result); // check options result = zoneNoId.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS); - assertEquals(CHANGE_REQUEST_AFTER, result); + assertEquals(changeRequestAfter, result); result = zone.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS); - assertEquals(CHANGE_REQUEST_AFTER, result); + assertEquals(changeRequestAfter, result); } @Test diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java index 8f7626a5ae0a..dd8e21043181 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java @@ -26,6 +26,7 @@ import com.google.common.collect.ImmutableList; import com.google.gcloud.Page; import com.google.gcloud.dns.ChangeRequest; +import com.google.gcloud.dns.ChangeRequestInfo; import com.google.gcloud.dns.Dns; import com.google.gcloud.dns.DnsException; import com.google.gcloud.dns.DnsOptions; @@ -76,11 +77,11 @@ public class ITDnsTest { .records(ImmutableList.of("ed:ed:12:aa:36:3:3:105")) .ttl(25, TimeUnit.SECONDS) .build(); - private static final ChangeRequest CHANGE_ADD_ZONE1 = ChangeRequest.builder() + private static final ChangeRequestInfo CHANGE_ADD_ZONE1 = ChangeRequest.builder() .add(A_RECORD_ZONE1) .add(AAAA_RECORD_ZONE1) .build(); - private static final ChangeRequest CHANGE_DELETE_ZONE1 = ChangeRequest.builder() + private static final ChangeRequestInfo CHANGE_DELETE_ZONE1 = ChangeRequest.builder() .delete(A_RECORD_ZONE1) .delete(AAAA_RECORD_ZONE1) .build(); @@ -593,7 +594,7 @@ public void testInvalidChangeRequest() { .records(ImmutableList.of("0.255.1.5")) .build(); try { - ChangeRequest validChange = ChangeRequest.builder().add(validA).build(); + ChangeRequestInfo validChange = ChangeRequest.builder().add(validA).build(); zone.applyChangeRequest(validChange); try { zone.applyChangeRequest(validChange); @@ -605,7 +606,7 @@ public void testInvalidChangeRequest() { } // delete with field mismatch RecordSet mismatch = validA.toBuilder().ttl(20, TimeUnit.SECONDS).build(); - ChangeRequest deletion = ChangeRequest.builder().delete(mismatch).build(); + ChangeRequestInfo deletion = ChangeRequest.builder().delete(mismatch).build(); try { zone.applyChangeRequest(deletion); fail("Deleted a record set without a complete match."); @@ -629,7 +630,7 @@ public void testInvalidChangeRequest() { } } deletion = deletion.toBuilder().deletions(deletions).build(); - ChangeRequest addition = ChangeRequest.builder().additions(additions).build(); + ChangeRequestInfo addition = ChangeRequest.builder().additions(additions).build(); try { zone.applyChangeRequest(deletion); fail("Deleted SOA."); @@ -647,7 +648,7 @@ public void testInvalidChangeRequest() { assertEquals(400, ex.code()); } } finally { - ChangeRequest deletion = ChangeRequest.builder().delete(validA).build(); + ChangeRequestInfo deletion = ChangeRequest.builder().delete(validA).build(); ChangeRequest request = zone.applyChangeRequest(deletion); waitForChangeToComplete(zone.name(), request.id()); zone.delete(); From de8bf4bad79ffe422688fd69d12fa388bfb8b44d Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Fri, 25 Mar 2016 09:49:23 -0700 Subject: [PATCH 199/375] Addressed comments. This includes: - Moved Status enum to ChangeRequestInfo. - Switching from ChangeRequest.builer() to ChangeRequestInfo.builder() - Fixing README accordingly - Used times() for mocking instead of repeated expect() - Snippets and documentation work with ChangeRequestInfo. Fixes #788. - Equals uses getClass instead if instanceof. - Removed unnecessary imports. --- README.md | 6 +- gcloud-java-dns/README.md | 26 ++++-- .../com/google/gcloud/dns/ChangeRequest.java | 81 ++++++++--------- .../google/gcloud/dns/ChangeRequestInfo.java | 35 +++++--- .../java/com/google/gcloud/dns/DnsImpl.java | 5 +- .../main/java/com/google/gcloud/dns/Zone.java | 2 +- .../com/google/gcloud/dns/package-info.java | 2 +- .../google/gcloud/dns/ChangeRequestTest.java | 43 ++++----- .../com/google/gcloud/dns/DnsImplTest.java | 32 ++++--- .../google/gcloud/dns/SerializationTest.java | 2 +- .../java/com/google/gcloud/dns/ZoneTest.java | 90 ++++++------------- .../gcloud/examples/dns/DnsExample.java | 11 +-- .../snippets/CreateOrUpdateRecordSets.java | 6 +- .../examples/dns/snippets/DeleteZone.java | 8 +- .../ManipulateZonesAndRecordSets.java | 9 +- 15 files changed, 171 insertions(+), 187 deletions(-) diff --git a/README.md b/README.md index 52229f6d5d34..6061d9dd4c8f 100644 --- a/README.md +++ b/README.md @@ -252,7 +252,7 @@ Zone zone = dns.create(zoneInfo); The second snippet shows how to create records inside a zone. The complete code can be found on [CreateOrUpdateRecordSets.java](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateRecordSets.java). ```java -import com.google.gcloud.dns.ChangeRequest; +import com.google.gcloud.dns.ChangeRequestInfo; import com.google.gcloud.dns.Dns; import com.google.gcloud.dns.DnsOptions; import com.google.gcloud.dns.RecordSet; @@ -269,7 +269,7 @@ RecordSet toCreate = RecordSet.builder("www.someexampledomain.com.", RecordSet.T .ttl(24, TimeUnit.HOURS) .addRecord(ip) .build(); -ChangeRequest.Builder changeBuilder = ChangeRequest.builder().add(toCreate); +ChangeRequestInfo.Builder changeBuilder = ChangeRequestInfo.builder().add(toCreate); // Verify that the record does not exist yet. // If it does exist, we will overwrite it with our prepared record. @@ -282,7 +282,7 @@ while (recordSetIterator.hasNext()) { } } -ChangeRequest changeRequest = changeBuilder.build(); +ChangeRequestInfo changeRequest = changeBuilder.build(); zone.applyChangeRequest(changeRequest); ``` diff --git a/gcloud-java-dns/README.md b/gcloud-java-dns/README.md index a2c3238d1f8f..d2e4c85b3b76 100644 --- a/gcloud-java-dns/README.md +++ b/gcloud-java-dns/README.md @@ -159,7 +159,7 @@ our zone that creates a record set of type A and points URL www.someexampledomai IP address 12.13.14.15. Start by adding ```java -import com.google.gcloud.dns.ChangeRequest; +import com.google.gcloud.dns.ChangeRequestInfo; import com.google.gcloud.dns.RecordSet; import java.util.concurrent.TimeUnit; @@ -176,7 +176,7 @@ RecordSet toCreate = RecordSet.builder("www." + zone.dnsName(), RecordSet.Type.A .build(); // Make a change -ChangeRequest changeRequest = ChangeRequest.builder().add(toCreate).build(); +ChangeRequestInfo changeRequest = ChangeRequestInfo.builder().add(toCreate).build(); // Build and apply the change request to our zone changeRequest = zone.applyChangeRequest(changeRequest); @@ -198,7 +198,7 @@ and in the code ```java // Make a change -ChangeRequest.Builder changeBuilder = ChangeRequest.builder().add(toCreate); +ChangeRequestInfo.Builder changeBuilder = ChangeRequestInfo.builder().add(toCreate); // Verify the type A record does not exist yet. // If it does exist, we will overwrite it with our prepared record. @@ -211,7 +211,7 @@ while (recordSetIterator.hasNext()) { } // Build and apply the change request to our zone -ChangeRequest changeRequest = changeBuilder.build(); +ChangeRequestInfo changeRequest = changeBuilder.build(); zone.applyChangeRequest(changeRequest); ``` You can find more information about changes in the [Cloud DNS documentation] (https://cloud.google.com/dns/what-is-cloud-dns#cloud_dns_api_concepts). @@ -220,7 +220,7 @@ When the change request is applied, it is registered with the Cloud DNS service can wait for its completion as follows: ```java -while (ChangeRequest.Status.PENDING.equals(changeRequest.status())) { +while (ChangeRequestInfo.Status.PENDING.equals(changeRequest.status())) { try { Thread.sleep(500L); } catch (InterruptedException e) { @@ -262,9 +262,17 @@ while (recordSetIterator.hasNext()) { } ``` -You can also list the history of change requests that were applied to a zone: +You can also list the history of change requests that were applied to a zone. +First add: ```java +import java.util.ChangeRequest; +``` + +and then: + +```java + // List the change requests applied to a particular zone Iterator changeIterator = zone.listChangeRequests().iterateAll(); System.out.println(String.format("The history of changes in %s:", zone.name())); @@ -280,7 +288,7 @@ First, you need to empty the zone by deleting all its records except for the def ```java // Make a change for deleting the record sets -changeBuilder = ChangeRequest.builder(); +changeBuilder = ChangeRequestInfo.builder(); while (recordIterator.hasNext()) { RecordSet current = recordIterator.next(); // SOA and NS records cannot be deleted @@ -290,14 +298,14 @@ while (recordIterator.hasNext()) { } // Build and apply the change request to our zone if it contains records to delete -ChangeRequest changeRequest = changeBuilder.build(); +ChangeRequestInfo changeRequest = changeBuilder.build(); if (!changeRequest.deletions().isEmpty()) { changeRequest = dns.applyChangeRequest(zoneName, changeRequest); // Wait for change to finish, but save data traffic by transferring only ID and status Dns.ChangeRequestOption option = Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS); - while (ChangeRequest.Status.PENDING.equals(changeRequest.status())) { + while (ChangeRequestInfo.Status.PENDING.equals(changeRequest.status())) { System.out.println("Waiting for change to complete. Going to sleep for 500ms..."); try { Thread.sleep(500); diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java index ad1c65f7cb0f..4b6369976ca6 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java @@ -16,6 +16,8 @@ package com.google.gcloud.dns; +import static com.google.common.base.Preconditions.checkNotNull; + import com.google.api.services.dns.model.Change; import com.google.common.base.Function; @@ -25,41 +27,30 @@ import java.util.Objects; /** - * A class representing an atomic update to a collection of {@link RecordSet}s within a {@code - * Zone}. + * An immutable class representing an atomic update to a collection of {@link RecordSet}s within a + * {@code Zone}. * * @see Google Cloud DNS documentation */ public class ChangeRequest extends ChangeRequestInfo { - private static final long serialVersionUID = -9027378042756366333L; + private static final long serialVersionUID = 5335667200595081449L; private final DnsOptions options; - private final String zoneName; + private final String zone; private transient Dns dns; - /** - * This enumerates the possible states of a {@code ChangeRequest}. - * - * @see Google Cloud DNS - * documentation - */ - public enum Status { - PENDING, - DONE - } - /** * A builder for {@code ChangeRequest}s. */ public static class Builder extends ChangeRequestInfo.Builder { private final Dns dns; - private final String zoneName; + private final String zone; private final ChangeRequestInfo.BuilderImpl infoBuilder; private Builder(ChangeRequest cr) { this.dns = cr.dns; - this.zoneName = cr.zoneName; + this.zone = cr.zone; this.infoBuilder = new ChangeRequestInfo.BuilderImpl(cr); } @@ -131,45 +122,36 @@ Builder status(Status status) { @Override public ChangeRequest build() { - return new ChangeRequest(dns, zoneName, infoBuilder); + return new ChangeRequest(dns, zone, infoBuilder); } } - ChangeRequest(Dns dns, String zoneName, ChangeRequest.BuilderImpl infoBuilder) { + ChangeRequest(Dns dns, String zone, ChangeRequest.BuilderImpl infoBuilder) { super(infoBuilder); - this.zoneName = zoneName; - this.dns = dns; + this.zone = checkNotNull(zone); + this.dns = checkNotNull(dns); this.options = dns.options(); } - static Function fromPbFunction(final Dns dns, final String zoneName) { - return new Function() { - @Override - public ChangeRequest apply(com.google.api.services.dns.model.Change pb) { - return ChangeRequest.fromPb(dns, zoneName, pb); - } - }; - } - /** * Returns the name of the {@link Zone} associated with this change request. */ - public String zoneName() { - return this.zoneName; + public String zone() { + return this.zone; } /** - * Returns the {@link Dns} service object associated with this change request. + * Returns the change request's {@code Dns} object used to issue requests. */ public Dns dns() { return dns; } /** - * Applies this change request to a zone that it is associated with. + * Applies this change request to the associated zone. */ public ChangeRequest applyTo(Dns.ChangeRequestOption... options) { - return dns.applyChangeRequest(zoneName, this, options); + return dns.applyChangeRequest(zone, this, options); } @Override @@ -179,24 +161,37 @@ public Builder toBuilder() { @Override public boolean equals(Object obj) { - return obj instanceof ChangeRequest && Objects.equals(toPb(), ((ChangeRequest) obj).toPb()) - && Objects.equals(options, ((ChangeRequest) obj).options) - && Objects.equals(zoneName, ((ChangeRequest) obj).zoneName); + if (obj == null || !obj.getClass().equals(ChangeRequest.class)) { + return false; + } else { + ChangeRequest other = (ChangeRequest) obj; + return Objects.equals(options, other.options) + && Objects.equals(zone, other.zone) + && Objects.equals(toPb(), other.toPb()); + } } @Override public int hashCode() { - return Objects.hash(super.hashCode(), options, zoneName); + return Objects.hash(super.hashCode(), options, zone); } - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - in.defaultReadObject(); + private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { + input.defaultReadObject(); this.dns = options.service(); } - static ChangeRequest fromPb(Dns dns, String zoneName, - com.google.api.services.dns.model.Change pb) { + static ChangeRequest fromPb(Dns dns, String zoneName, Change pb) { ChangeRequestInfo info = ChangeRequestInfo.fromPb(pb); return new ChangeRequest(dns, zoneName, new ChangeRequestInfo.BuilderImpl(info)); } + + static Function fromPbFunction(final Dns dns, final String zoneName) { + return new Function() { + @Override + public ChangeRequest apply(com.google.api.services.dns.model.Change pb) { + return ChangeRequest.fromPb(dns, zoneName, pb); + } + }; + } } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequestInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequestInfo.java index 25b915521b13..b63b4f4a0788 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequestInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequestInfo.java @@ -52,7 +52,18 @@ public ChangeRequestInfo apply(Change pb) { private final List deletions; private final String id; private final Long startTimeMillis; - private final ChangeRequest.Status status; + private final ChangeRequestInfo.Status status; + + /** + * This enumerates the possible states of a change request. + * + * @see Google Cloud DNS + * documentation + */ + public enum Status { + PENDING, + DONE + } /** * A builder for {@code ChangeRequestInfo}. @@ -110,7 +121,7 @@ public abstract static class Builder { /** * Associates a server-assigned id to this {@code ChangeRequestInfo}. */ - abstract Builder id(String id); + abstract Builder id(String id); /** * Sets the time when this change request was started by a server. @@ -134,7 +145,7 @@ static class BuilderImpl extends Builder { private List deletions; private String id; private Long startTimeMillis; - private ChangeRequest.Status status; + private ChangeRequestInfo.Status status; BuilderImpl() { this.additions = new LinkedList<>(); @@ -215,7 +226,7 @@ Builder startTimeMillis(long startTimeMillis) { } @Override - Builder status(ChangeRequest.Status status) { + Builder status(ChangeRequestInfo.Status status) { this.status = checkNotNull(status); return this; } @@ -274,15 +285,15 @@ public Long startTimeMillis() { } /** - * Returns the status of this {@code ChangeRequest}. + * Returns the status of this {@code ChangeRequest}. If the change request has not been applied + * yet, the status is {@code PENDING}. */ - public ChangeRequest.Status status() { + public ChangeRequestInfo.Status status() { return status; } - com.google.api.services.dns.model.Change toPb() { - com.google.api.services.dns.model.Change pb = - new com.google.api.services.dns.model.Change(); + Change toPb() { + Change pb = new Change(); // set id if (id() != null) { pb.setId(id()); @@ -302,7 +313,7 @@ com.google.api.services.dns.model.Change toPb() { return pb; } - static ChangeRequestInfo fromPb(com.google.api.services.dns.model.Change pb) { + static ChangeRequestInfo fromPb(Change pb) { Builder builder = builder(); if (pb.getId() != null) { builder.id(pb.getId()); @@ -325,8 +336,8 @@ static ChangeRequestInfo fromPb(com.google.api.services.dns.model.Change pb) { @Override public boolean equals(Object other) { - return (other instanceof ChangeRequestInfo) - && toPb().equals(((ChangeRequestInfo) other).toPb()); + return other != null && other.getClass().equals(ChangeRequestInfo.class) + && other instanceof ChangeRequestInfo && toPb().equals(((ChangeRequestInfo) other).toPb()); } @Override diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java index 4e2bd1b207d5..51ab0bd92720 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java @@ -19,7 +19,6 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.gcloud.RetryHelper.RetryHelperException; import static com.google.gcloud.RetryHelper.runWithRetries; -import static com.google.gcloud.dns.ChangeRequest.fromPb; import com.google.api.services.dns.model.Change; import com.google.api.services.dns.model.ManagedZone; @@ -170,7 +169,7 @@ public DnsRpc.ListResult call() { Iterable changes = result.results() == null ? ImmutableList.of() : Iterables.transform(result.results(), - ChangeRequest.fromPbFunction(serviceOptions.service(), zoneName)); + ChangeRequest.fromPbFunction(serviceOptions.service(), zoneName)); return new PageImpl<>(new ChangeRequestPageFetcher(zoneName, serviceOptions, cursor, optionsMap), cursor, changes); } catch (RetryHelperException e) { @@ -285,7 +284,7 @@ public com.google.api.services.dns.model.Change call() { return dnsRpc.applyChangeRequest(zoneName, changeRequest.toPb(), optionsMap); } }, options().retryParams(), EXCEPTION_HANDLER); - return answer == null ? null : fromPb(this, zoneName, answer); // should never be null + return answer == null ? null : ChangeRequest.fromPb(this, zoneName, answer); // not null } catch (RetryHelper.RetryHelperException ex) { throw DnsException.translateAndThrow(ex); } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java index 88b9e7273e9c..9930bfdbad67 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java @@ -146,7 +146,7 @@ public Page listRecordSets(Dns.RecordSetListOption... options) { } /** - * Submits {@link ChangeRequest} to the service for it to applied to this zone. The method + * Submits {@link ChangeRequestInfo} to the service for it to applied to this zone. The method * searches for zone by name. * * @param options optional restriction on what fields of {@link ChangeRequest} should be returned diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/package-info.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/package-info.java index 69bee930df62..36f41852400c 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/package-info.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/package-info.java @@ -46,7 +46,7 @@ * .ttl(24, TimeUnit.HOURS) * .addRecord(ip) * .build(); - * ChangeRequest changeRequest = ChangeRequest.builder().add(toCreate).build(); + * ChangeRequestInfo changeRequest = ChangeRequestInfo.builder().add(toCreate).build(); * zone.applyChangeRequest(changeRequest); * }

    5. * diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java index 8d6cc799cad8..bfd1d0f512f4 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java @@ -23,6 +23,7 @@ import static org.easymock.EasyMock.verify; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import com.google.common.collect.ImmutableList; @@ -47,8 +48,7 @@ public class ChangeRequestTest { @Before public void setUp() throws Exception { dns = createStrictMock(Dns.class); - expect(dns.options()).andReturn(OPTIONS); - expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS).times(2); replay(dns); changeRequest = new ChangeRequest(dns, ZONE_NAME, new ChangeRequestInfo.BuilderImpl( CHANGE_REQUEST_INFO.toBuilder() @@ -68,28 +68,28 @@ public void tearDown() throws Exception { @Test public void testConstructor() { + expect(dns.options()).andReturn(OPTIONS); replay(dns); - assertEquals(CHANGE_REQUEST_INFO.toPb(), changeRequestPartial.toPb()); + assertEquals(new ChangeRequest(dns, ZONE_NAME, + new ChangeRequestInfo.BuilderImpl(CHANGE_REQUEST_INFO)), changeRequestPartial); assertNotNull(changeRequest.dns()); - assertEquals(ZONE_NAME, changeRequest.zoneName()); - assertNotNull(changeRequestPartial.dns()); - assertEquals(ZONE_NAME, changeRequestPartial.zoneName()); + assertEquals(ZONE_NAME, changeRequest.zone()); + assertSame(dns, changeRequestPartial.dns()); + assertEquals(ZONE_NAME, changeRequestPartial.zone()); } @Test public void testFromPb() { - expect(dns.options()).andReturn(OPTIONS); - expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS).times(2); replay(dns); - assertEquals(ChangeRequest.fromPb(dns, ZONE_NAME, changeRequest.toPb()), changeRequest); - assertEquals(ChangeRequest.fromPb(dns, ZONE_NAME, changeRequestPartial.toPb()), - changeRequestPartial); + assertEquals(changeRequest, ChangeRequest.fromPb(dns, ZONE_NAME, changeRequest.toPb())); + assertEquals(changeRequestPartial, + ChangeRequest.fromPb(dns, ZONE_NAME, changeRequestPartial.toPb())); } @Test public void testEqualsAndToBuilder() { - expect(dns.options()).andReturn(OPTIONS); - expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS).times(2); replay(dns); ChangeRequest compare = changeRequest.toBuilder().build(); assertEquals(changeRequest, compare); @@ -102,15 +102,7 @@ public void testEqualsAndToBuilder() { @Test public void testBuilder() { // one for each build() call because it invokes a constructor - expect(dns.options()).andReturn(OPTIONS); - expect(dns.options()).andReturn(OPTIONS); - expect(dns.options()).andReturn(OPTIONS); - expect(dns.options()).andReturn(OPTIONS); - expect(dns.options()).andReturn(OPTIONS); - expect(dns.options()).andReturn(OPTIONS); - expect(dns.options()).andReturn(OPTIONS); - expect(dns.options()).andReturn(OPTIONS); - expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS).times(9); replay(dns); String id = changeRequest.id() + "aaa"; assertEquals(id, changeRequest.toBuilder().id(id).build().id()); @@ -131,7 +123,7 @@ public void testBuilder() { modified = changeRequest.toBuilder().delete(cname).build(); assertTrue(modified.deletions().contains(cname)); modified = changeRequest.toBuilder().startTimeMillis(0L).build(); - assertEquals(new Long(0), modified.startTimeMillis()); + assertEquals(Long.valueOf(0), modified.startTimeMillis()); } @Test @@ -141,7 +133,8 @@ public void testApplyTo() { Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME))) .andReturn(changeRequest); replay(dns); - changeRequest.applyTo(); - changeRequest.applyTo(Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); + assertSame(changeRequest, changeRequest.applyTo()); + assertSame(changeRequest, + changeRequest.applyTo(Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME))); } } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java index 73548e9cbb91..94ed4a3da3f7 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java @@ -53,10 +53,10 @@ public class DnsImplTest { private static final String PAGE_TOKEN = "some token"; private static final ZoneInfo ZONE_INFO = ZoneInfo.of(ZONE_NAME, DNS_NAME, DESCRIPTION); private static final ProjectInfo PROJECT_INFO = ProjectInfo.builder().build(); - private static final ChangeRequestInfo CHANGE_REQUEST_PARTIAL = ChangeRequest.builder() + private static final ChangeRequestInfo CHANGE_REQUEST_PARTIAL = ChangeRequestInfo.builder() .add(DNS_RECORD1) .build(); - private static final ChangeRequestInfo CHANGE_REQUEST_COMPLETE = ChangeRequest.builder() + private static final ChangeRequestInfo CHANGE_REQUEST_COMPLETE = ChangeRequestInfo.builder() .add(DNS_RECORD1) .startTimeMillis(123L) .status(ChangeRequest.Status.PENDING) @@ -221,7 +221,8 @@ public void testGetChangeRequest() { dns = options.service(); // creates DnsImpl ChangeRequest changeRequest = dns.getChangeRequest(ZONE_INFO.name(), CHANGE_REQUEST_COMPLETE.id()); - assertEquals(CHANGE_REQUEST_COMPLETE, changeRequest); + assertEquals(new ChangeRequest(dns, ZONE_INFO.name(), + new ChangeRequestInfo.BuilderImpl(CHANGE_REQUEST_COMPLETE)), changeRequest); } @Test @@ -235,7 +236,8 @@ public void testGetChangeRequestWithOptions() { ChangeRequest changeRequest = dns.getChangeRequest(ZONE_INFO.name(), CHANGE_REQUEST_COMPLETE.id(), CHANGE_GET_FIELDS); String selector = (String) capturedOptions.getValue().get(CHANGE_GET_FIELDS.rpcOption()); - assertEquals(CHANGE_REQUEST_COMPLETE, changeRequest); + assertEquals(new ChangeRequest(dns, ZONE_INFO.name(), + new ChangeRequestInfo.BuilderImpl(CHANGE_REQUEST_COMPLETE)), changeRequest); assertTrue(selector.contains(Dns.ChangeRequestField.STATUS.selector())); assertTrue(selector.contains(Dns.ChangeRequestField.ID.selector())); } @@ -248,7 +250,8 @@ public void testApplyChangeRequest() { dns = options.service(); // creates DnsImpl ChangeRequest changeRequest = dns.applyChangeRequest(ZONE_INFO.name(), CHANGE_REQUEST_PARTIAL); - assertEquals(CHANGE_REQUEST_COMPLETE, changeRequest); + assertEquals(new ChangeRequest(dns, ZONE_INFO.name(), + new ChangeRequestInfo.BuilderImpl(CHANGE_REQUEST_COMPLETE)), changeRequest); } @Test @@ -262,7 +265,8 @@ public void testApplyChangeRequestWithOptions() { ChangeRequest changeRequest = dns.applyChangeRequest(ZONE_INFO.name(), CHANGE_REQUEST_PARTIAL, CHANGE_GET_FIELDS); String selector = (String) capturedOptions.getValue().get(CHANGE_GET_FIELDS.rpcOption()); - assertEquals(CHANGE_REQUEST_COMPLETE, changeRequest); + assertEquals(new ChangeRequest(dns, ZONE_INFO.name(), + new ChangeRequestInfo.BuilderImpl(CHANGE_REQUEST_COMPLETE)), changeRequest); assertTrue(selector.contains(Dns.ChangeRequestField.STATUS.selector())); assertTrue(selector.contains(Dns.ChangeRequestField.ID.selector())); } @@ -275,8 +279,12 @@ public void testListChangeRequests() { EasyMock.replay(dnsRpcMock); dns = options.service(); // creates DnsImpl Page changeRequestPage = dns.listChangeRequests(ZONE_INFO.name()); - assertTrue(Lists.newArrayList(changeRequestPage.values()).contains(CHANGE_REQUEST_COMPLETE)); - assertTrue(Lists.newArrayList(changeRequestPage.values()).contains(CHANGE_REQUEST_PARTIAL)); + assertTrue(Lists.newArrayList(changeRequestPage.values()).contains( + new ChangeRequest(dns, ZONE_INFO.name(), + new ChangeRequestInfo.BuilderImpl(CHANGE_REQUEST_COMPLETE)))); + assertTrue(Lists.newArrayList(changeRequestPage.values()).contains( + new ChangeRequest(dns, ZONE_INFO.name(), + new ChangeRequestInfo.BuilderImpl(CHANGE_REQUEST_PARTIAL)))); assertEquals(2, Lists.newArrayList(changeRequestPage.values()).size()); } @@ -288,8 +296,12 @@ public void testListChangeRequestsWithOptions() { EasyMock.replay(dnsRpcMock); dns = options.service(); // creates DnsImpl Page changeRequestPage = dns.listChangeRequests(ZONE_NAME, CHANGE_LIST_OPTIONS); - assertTrue(Lists.newArrayList(changeRequestPage.values()).contains(CHANGE_REQUEST_COMPLETE)); - assertTrue(Lists.newArrayList(changeRequestPage.values()).contains(CHANGE_REQUEST_PARTIAL)); + assertTrue(Lists.newArrayList(changeRequestPage.values()).contains( + new ChangeRequest(dns, ZONE_INFO.name(), + new ChangeRequestInfo.BuilderImpl(CHANGE_REQUEST_COMPLETE)))); + assertTrue(Lists.newArrayList(changeRequestPage.values()).contains( + new ChangeRequest(dns, ZONE_INFO.name(), + new ChangeRequestInfo.BuilderImpl(CHANGE_REQUEST_PARTIAL)))); assertEquals(2, Lists.newArrayList(changeRequestPage.values()).size()); Integer size = (Integer) capturedOptions.getValue().get(CHANGE_LIST_OPTIONS[0].rpcOption()); assertEquals(MAX_SIZE, size); diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java index 4e492eff3526..ad25b31068dd 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java @@ -74,7 +74,7 @@ public class SerializationTest extends BaseSerializationTest { .ttl(12, TimeUnit.HOURS) .addRecord("record") .build(); - private static final ChangeRequestInfo CHANGE_REQUEST_INFO_COMPLETE = ChangeRequest.builder() + private static final ChangeRequestInfo CHANGE_REQUEST_INFO_COMPLETE = ChangeRequestInfo.builder() .add(RECORD_SET_COMPLETE) .delete(RECORD_SET_PARTIAL) .status(ChangeRequest.Status.PENDING) diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java index 3ed395bf6881..ba4493abfca8 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java @@ -61,9 +61,9 @@ public class ZoneTest { private static final Dns.ChangeRequestListOption CHANGE_REQUEST_LIST_OPTIONS = Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.START_TIME); private static final ChangeRequestInfo CHANGE_REQUEST = - ChangeRequest.builder().id("someid").build(); + ChangeRequestInfo.builder().id("someid").build(); private static final ChangeRequestInfo CHANGE_REQUEST_NO_ID = - ChangeRequest.builder().build(); + ChangeRequestInfo.builder().build(); private static final DnsException EXCEPTION = createStrictMock(DnsException.class); private static final DnsOptions OPTIONS = createStrictMock(DnsOptions.class); @@ -75,9 +75,7 @@ public class ZoneTest { @Before public void setUp() throws Exception { dns = createStrictMock(Dns.class); - expect(dns.options()).andReturn(OPTIONS); - expect(dns.options()).andReturn(OPTIONS); - expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS).times(3); replay(dns); zone = new Zone(dns, new ZoneInfo.BuilderImpl(ZONE_INFO)); zoneNoId = new Zone(dns, new ZoneInfo.BuilderImpl(NO_ID_INFO)); @@ -101,8 +99,7 @@ public void testConstructor() { @Test public void deleteByNameAndFound() { - expect(dns.delete(ZONE_NAME)).andReturn(true); - expect(dns.delete(ZONE_NAME)).andReturn(true); + expect(dns.delete(ZONE_NAME)).andReturn(true).times(2); replay(dns); boolean result = zone.delete(); assertTrue(result); @@ -112,8 +109,7 @@ public void deleteByNameAndFound() { @Test public void deleteByNameAndNotFound() { - expect(dns.delete(ZONE_NAME)).andReturn(false); - expect(dns.delete(ZONE_NAME)).andReturn(false); + expect(dns.delete(ZONE_NAME)).andReturn(false).times(2); replay(dns); boolean result = zoneNoId.delete(); assertFalse(result); @@ -126,11 +122,9 @@ public void listDnsRecordsByNameAndFound() { @SuppressWarnings("unchecked") Page pageMock = createStrictMock(Page.class); replay(pageMock); - expect(dns.listRecordSets(ZONE_NAME)).andReturn(pageMock); - expect(dns.listRecordSets(ZONE_NAME)).andReturn(pageMock); + expect(dns.listRecordSets(ZONE_NAME)).andReturn(pageMock).times(2); // again for options - expect(dns.listRecordSets(ZONE_NAME, DNS_RECORD_OPTIONS)).andReturn(pageMock); - expect(dns.listRecordSets(ZONE_NAME, DNS_RECORD_OPTIONS)).andReturn(pageMock); + expect(dns.listRecordSets(ZONE_NAME, DNS_RECORD_OPTIONS)).andReturn(pageMock).times(2); replay(dns); Page result = zone.listRecordSets(); assertSame(pageMock, result); @@ -143,11 +137,9 @@ public void listDnsRecordsByNameAndFound() { @Test public void listDnsRecordsByNameAndNotFound() { - expect(dns.listRecordSets(ZONE_NAME)).andThrow(EXCEPTION); - expect(dns.listRecordSets(ZONE_NAME)).andThrow(EXCEPTION); + expect(dns.listRecordSets(ZONE_NAME)).andThrow(EXCEPTION).times(2); // again for options - expect(dns.listRecordSets(ZONE_NAME, DNS_RECORD_OPTIONS)).andThrow(EXCEPTION); - expect(dns.listRecordSets(ZONE_NAME, DNS_RECORD_OPTIONS)).andThrow(EXCEPTION); + expect(dns.listRecordSets(ZONE_NAME, DNS_RECORD_OPTIONS)).andThrow(EXCEPTION).times(2); replay(dns); try { zoneNoId.listRecordSets(); @@ -177,8 +169,7 @@ public void listDnsRecordsByNameAndNotFound() { @Test public void reloadByNameAndFound() { - expect(dns.getZone(ZONE_NAME)).andReturn(zone); - expect(dns.getZone(ZONE_NAME)).andReturn(zone); + expect(dns.getZone(ZONE_NAME)).andReturn(zone).times(2); // again for options expect(dns.getZone(ZONE_NAME, ZONE_FIELD_OPTIONS)).andReturn(zoneNoId); expect(dns.getZone(ZONE_NAME, ZONE_FIELD_OPTIONS)).andReturn(zone); @@ -195,11 +186,9 @@ public void reloadByNameAndFound() { @Test public void reloadByNameAndNotFound() { - expect(dns.getZone(ZONE_NAME)).andReturn(null); - expect(dns.getZone(ZONE_NAME)).andReturn(null); + expect(dns.getZone(ZONE_NAME)).andReturn(null).times(2); // again for options - expect(dns.getZone(ZONE_NAME, ZONE_FIELD_OPTIONS)).andReturn(null); - expect(dns.getZone(ZONE_NAME, ZONE_FIELD_OPTIONS)).andReturn(null); + expect(dns.getZone(ZONE_NAME, ZONE_FIELD_OPTIONS)).andReturn(null).times(2); replay(dns); Zone result = zoneNoId.reload(); assertNull(result); @@ -235,13 +224,10 @@ public void applyChangeByNameAndFound() { @Test public void applyChangeByNameAndNotFound() { // ID is not set - expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST)).andThrow(EXCEPTION); - expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST)).andThrow(EXCEPTION); + expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST)).andThrow(EXCEPTION).times(2); // again for options expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS)) - .andThrow(EXCEPTION); - expect(dns.applyChangeRequest(ZONE_NAME, CHANGE_REQUEST, CHANGE_REQUEST_FIELD_OPTIONS)) - .andThrow(EXCEPTION); + .andThrow(EXCEPTION).times(2); replay(dns); try { zoneNoId.applyChangeRequest(CHANGE_REQUEST); @@ -302,14 +288,10 @@ public void applyNullChangeRequest() { @Test public void getChangeAndZoneFoundByName() { expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())) - .andReturn(changeRequestAfter); - expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())) - .andReturn(changeRequestAfter); + .andReturn(changeRequestAfter).times(2); // again for options expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) - .andReturn(changeRequestAfter); - expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) - .andReturn(changeRequestAfter); + .andReturn(changeRequestAfter).times(2); replay(dns); ChangeRequest result = zoneNoId.getChangeRequest(CHANGE_REQUEST.id()); assertEquals(changeRequestAfter, result); @@ -324,13 +306,10 @@ public void getChangeAndZoneFoundByName() { @Test public void getChangeAndZoneNotFoundByName() { - expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())).andThrow(EXCEPTION); - expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())).andThrow(EXCEPTION); + expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())).andThrow(EXCEPTION).times(2); // again for options expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) - .andThrow(EXCEPTION); - expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) - .andThrow(EXCEPTION); + .andThrow(EXCEPTION).times(2); replay(dns); try { zoneNoId.getChangeRequest(CHANGE_REQUEST.id()); @@ -361,13 +340,10 @@ public void getChangeAndZoneNotFoundByName() { @Test public void getChangedWhichDoesNotExistZoneFound() { - expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())).andReturn(null); - expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())).andReturn(null); + expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())).andReturn(null).times(2); // again for options expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) - .andReturn(null); - expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) - .andReturn(null); + .andReturn(null).times(2); replay(dns); assertNull(zoneNoId.getChangeRequest(CHANGE_REQUEST.id())); assertNull(zone.getChangeRequest(CHANGE_REQUEST.id())); @@ -438,13 +414,10 @@ public void listChangeRequestsAndZoneFound() { @SuppressWarnings("unchecked") Page pageMock = createStrictMock(Page.class); replay(pageMock); - expect(dns.listChangeRequests(ZONE_NAME)).andReturn(pageMock); - expect(dns.listChangeRequests(ZONE_NAME)).andReturn(pageMock); + expect(dns.listChangeRequests(ZONE_NAME)).andReturn(pageMock).times(2); // again for options expect(dns.listChangeRequests(ZONE_NAME, CHANGE_REQUEST_LIST_OPTIONS)) - .andReturn(pageMock); - expect(dns.listChangeRequests(ZONE_NAME, CHANGE_REQUEST_LIST_OPTIONS)) - .andReturn(pageMock); + .andReturn(pageMock).times(2); replay(dns); Page result = zoneNoId.listChangeRequests(); assertSame(pageMock, result); @@ -457,11 +430,10 @@ public void listChangeRequestsAndZoneFound() { @Test public void listChangeRequestsAndZoneNotFound() { - expect(dns.listChangeRequests(ZONE_NAME)).andThrow(EXCEPTION); - expect(dns.listChangeRequests(ZONE_NAME)).andThrow(EXCEPTION); + expect(dns.listChangeRequests(ZONE_NAME)).andThrow(EXCEPTION).times(2); // again for options - expect(dns.listChangeRequests(ZONE_NAME, CHANGE_REQUEST_LIST_OPTIONS)).andThrow(EXCEPTION); - expect(dns.listChangeRequests(ZONE_NAME, CHANGE_REQUEST_LIST_OPTIONS)).andThrow(EXCEPTION); + expect(dns.listChangeRequests(ZONE_NAME, CHANGE_REQUEST_LIST_OPTIONS)).andThrow(EXCEPTION) + .times(2); replay(dns); try { zoneNoId.listChangeRequests(); @@ -498,8 +470,7 @@ public void testFromPb() { @Test public void testEqualsAndToBuilder() { - expect(dns.options()).andReturn(OPTIONS); - expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS).times(2); replay(dns); assertEquals(zone, zone.toBuilder().build()); assertEquals(zone.hashCode(), zone.toBuilder().build().hashCode()); @@ -508,14 +479,7 @@ public void testEqualsAndToBuilder() { @Test public void testBuilder() { // one for each build() call because it invokes a constructor - expect(dns.options()).andReturn(OPTIONS); - expect(dns.options()).andReturn(OPTIONS); - expect(dns.options()).andReturn(OPTIONS); - expect(dns.options()).andReturn(OPTIONS); - expect(dns.options()).andReturn(OPTIONS); - expect(dns.options()).andReturn(OPTIONS); - expect(dns.options()).andReturn(OPTIONS); - expect(dns.options()).andReturn(OPTIONS); + expect(dns.options()).andReturn(OPTIONS).times(8); replay(dns); assertNotEquals(zone, zone.toBuilder() .id((new BigInteger(zone.id())).add(BigInteger.ONE).toString()) diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java index 40ce61b07281..a9e5c5d25377 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java @@ -19,6 +19,7 @@ import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; import com.google.gcloud.dns.ChangeRequest; +import com.google.gcloud.dns.ChangeRequestInfo; import com.google.gcloud.dns.Dns; import com.google.gcloud.dns.DnsOptions; import com.google.gcloud.dns.ProjectInfo; @@ -207,7 +208,7 @@ public void run(Dns dns, String... args) { .records(ImmutableList.of(ip)) .ttl(ttl, TimeUnit.SECONDS) .build(); - ChangeRequest changeRequest = ChangeRequest.builder() + ChangeRequestInfo changeRequest = ChangeRequest.builder() .delete(recordSet) .build(); changeRequest = dns.applyChangeRequest(zoneName, changeRequest); @@ -254,7 +255,7 @@ public void run(Dns dns, String... args) { .records(ImmutableList.of(ip)) .ttl(ttl, TimeUnit.SECONDS) .build(); - ChangeRequest changeRequest = ChangeRequest.builder().add(recordSet).build(); + ChangeRequestInfo changeRequest = ChangeRequest.builder().add(recordSet).build(); changeRequest = dns.applyChangeRequest(zoneName, changeRequest); System.out.printf("The request for adding A record %s for zone %s was successfully " + "submitted and assigned ID %s.%n", recordName, zoneName, changeRequest.id()); @@ -444,9 +445,9 @@ private static void printZone(Zone zone) { System.out.printf("Name servers: %s%n", Joiner.on(", ").join(zone.nameServers())); } - private static ChangeRequest waitForChangeToFinish(Dns dns, String zoneName, - ChangeRequest request) { - ChangeRequest current = request; + private static ChangeRequestInfo waitForChangeToFinish(Dns dns, String zoneName, + ChangeRequestInfo request) { + ChangeRequestInfo current = request; while (current.status().equals(ChangeRequest.Status.PENDING)) { System.out.print("."); try { diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateRecordSets.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateRecordSets.java index 74647daf666e..e3ddbb10fc0f 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateRecordSets.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateRecordSets.java @@ -22,7 +22,7 @@ package com.google.gcloud.examples.dns.snippets; -import com.google.gcloud.dns.ChangeRequest; +import com.google.gcloud.dns.ChangeRequestInfo; import com.google.gcloud.dns.Dns; import com.google.gcloud.dns.DnsOptions; import com.google.gcloud.dns.RecordSet; @@ -55,7 +55,7 @@ public static void main(String... args) { .build(); // Make a change - ChangeRequest.Builder changeBuilder = ChangeRequest.builder().add(toCreate); + ChangeRequestInfo.Builder changeBuilder = ChangeRequestInfo.builder().add(toCreate); // Verify a www.. type A record does not exist yet. // If it does exist, we will overwrite it with our prepared record. @@ -68,7 +68,7 @@ public static void main(String... args) { } // Build and apply the change request to our zone - ChangeRequest changeRequest = changeBuilder.build(); + ChangeRequestInfo changeRequest = changeBuilder.build(); zone.applyChangeRequest(changeRequest); } } diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java index 27377345b62f..63f26eeebb2a 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java @@ -22,7 +22,7 @@ package com.google.gcloud.examples.dns.snippets; -import com.google.gcloud.dns.ChangeRequest; +import com.google.gcloud.dns.ChangeRequestInfo; import com.google.gcloud.dns.Dns; import com.google.gcloud.dns.DnsOptions; import com.google.gcloud.dns.RecordSet; @@ -47,7 +47,7 @@ public static void main(String... args) { Iterator recordIterator = dns.listRecordSets(zoneName).iterateAll(); // Make a change for deleting the records - ChangeRequest.Builder changeBuilder = ChangeRequest.builder(); + ChangeRequestInfo.Builder changeBuilder = ChangeRequestInfo.builder(); while (recordIterator.hasNext()) { RecordSet current = recordIterator.next(); // SOA and NS records cannot be deleted @@ -57,14 +57,14 @@ public static void main(String... args) { } // Build and apply the change request to our zone if it contains records to delete - ChangeRequest changeRequest = changeBuilder.build(); + ChangeRequestInfo changeRequest = changeBuilder.build(); if (!changeRequest.deletions().isEmpty()) { changeRequest = dns.applyChangeRequest(zoneName, changeRequest); // Wait for change to finish, but save data traffic by transferring only ID and status Dns.ChangeRequestOption option = Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS); - while (ChangeRequest.Status.PENDING.equals(changeRequest.status())) { + while (ChangeRequestInfo.Status.PENDING.equals(changeRequest.status())) { System.out.println("Waiting for change to complete. Going to sleep for 500ms..."); try { Thread.sleep(500); diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java index 6d9d09d704a6..9c9a9e77289c 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java @@ -23,6 +23,7 @@ package com.google.gcloud.examples.dns.snippets; import com.google.gcloud.dns.ChangeRequest; +import com.google.gcloud.dns.ChangeRequestInfo; import com.google.gcloud.dns.Dns; import com.google.gcloud.dns.DnsOptions; import com.google.gcloud.dns.RecordSet; @@ -66,7 +67,7 @@ public static void main(String... args) { .build(); // Make a change - ChangeRequest.Builder changeBuilder = ChangeRequest.builder().add(toCreate); + ChangeRequestInfo.Builder changeBuilder = ChangeRequestInfo.builder().add(toCreate); // Verify the type A record does not exist yet. // If it does exist, we will overwrite it with our prepared record. @@ -79,10 +80,10 @@ public static void main(String... args) { } // Build and apply the change request to our zone - ChangeRequest changeRequest = changeBuilder.build(); + ChangeRequestInfo changeRequest = changeBuilder.build(); zone.applyChangeRequest(changeRequest); - while (ChangeRequest.Status.PENDING.equals(changeRequest.status())) { + while (ChangeRequestInfo.Status.PENDING.equals(changeRequest.status())) { try { Thread.sleep(500L); } catch (InterruptedException e) { @@ -115,7 +116,7 @@ public static void main(String... args) { } // Make a change for deleting the record sets - changeBuilder = ChangeRequest.builder(); + changeBuilder = ChangeRequestInfo.builder(); while (recordSetIterator.hasNext()) { RecordSet current = recordSetIterator.next(); // SOA and NS records cannot be deleted From f2f93bcfa3c07bb0bb415441e1cd3544ec21e084 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 28 Mar 2016 17:36:19 -0700 Subject: [PATCH 200/375] Release v0.1.6 --- gcloud-java-bigquery/pom.xml | 2 +- gcloud-java-contrib/pom.xml | 2 +- gcloud-java-core/pom.xml | 2 +- gcloud-java-datastore/pom.xml | 2 +- gcloud-java-dns/pom.xml | 2 +- gcloud-java-examples/pom.xml | 2 +- gcloud-java-resourcemanager/pom.xml | 2 +- gcloud-java-storage/pom.xml | 2 +- gcloud-java/pom.xml | 2 +- pom.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/gcloud-java-bigquery/pom.xml b/gcloud-java-bigquery/pom.xml index 5c79f150c722..cd7883bccaab 100644 --- a/gcloud-java-bigquery/pom.xml +++ b/gcloud-java-bigquery/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.6-SNAPSHOT + 0.1.6 gcloud-java-bigquery diff --git a/gcloud-java-contrib/pom.xml b/gcloud-java-contrib/pom.xml index bd4a6458dc38..33cdb552411c 100644 --- a/gcloud-java-contrib/pom.xml +++ b/gcloud-java-contrib/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.6-SNAPSHOT + 0.1.6 gcloud-java-contrib diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml index 6d0ed675b423..51d6baf213a9 100644 --- a/gcloud-java-core/pom.xml +++ b/gcloud-java-core/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.6-SNAPSHOT + 0.1.6 gcloud-java-core diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index f3b46e22b3c8..e97a2b943582 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.6-SNAPSHOT + 0.1.6 gcloud-java-datastore diff --git a/gcloud-java-dns/pom.xml b/gcloud-java-dns/pom.xml index b55200b8fc7d..68c46c909f2a 100644 --- a/gcloud-java-dns/pom.xml +++ b/gcloud-java-dns/pom.xml @@ -13,7 +13,7 @@ com.google.gcloud gcloud-java-pom - 0.1.6-SNAPSHOT + 0.1.6 gcloud-java-dns diff --git a/gcloud-java-examples/pom.xml b/gcloud-java-examples/pom.xml index 111308658c2e..7b23f7ebe48d 100644 --- a/gcloud-java-examples/pom.xml +++ b/gcloud-java-examples/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.6-SNAPSHOT + 0.1.6 gcloud-java-examples diff --git a/gcloud-java-resourcemanager/pom.xml b/gcloud-java-resourcemanager/pom.xml index c0c48af48f1e..d428d4a937fc 100644 --- a/gcloud-java-resourcemanager/pom.xml +++ b/gcloud-java-resourcemanager/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.6-SNAPSHOT + 0.1.6 gcloud-java-resourcemanager diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml index 16427d50de3a..59b4f9a55245 100644 --- a/gcloud-java-storage/pom.xml +++ b/gcloud-java-storage/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.6-SNAPSHOT + 0.1.6 gcloud-java-storage diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml index 654b34f92056..2e6249a20b1a 100644 --- a/gcloud-java/pom.xml +++ b/gcloud-java/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.6-SNAPSHOT + 0.1.6 diff --git a/pom.xml b/pom.xml index d73956f506ee..02061658a8be 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.gcloud gcloud-java-pom pom - 0.1.6-SNAPSHOT + 0.1.6 GCloud Java https://github.com/GoogleCloudPlatform/gcloud-java From a1b6c65ebdd269a48ef8121babec54fed26ebac2 Mon Sep 17 00:00:00 2001 From: Shin Fan Date: Mon, 28 Mar 2016 17:37:55 -0700 Subject: [PATCH 201/375] Update pom version to fix the build. --- gcloud-java-pubsub/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcloud-java-pubsub/pom.xml b/gcloud-java-pubsub/pom.xml index 2bd755f63a8c..2014b483b17e 100644 --- a/gcloud-java-pubsub/pom.xml +++ b/gcloud-java-pubsub/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.4-SNAPSHOT + 0.1.5 gcloud-java-pubsub From 0fcafa5937cf173b4add7144bd5b436ee33d2e3b Mon Sep 17 00:00:00 2001 From: Shin Fan Date: Mon, 28 Mar 2016 18:07:38 -0700 Subject: [PATCH 202/375] Update with latest surface fixes based Java export review. Refactorings: - Remove section headers from comments - Remove innerClass and move util methods to top level. - Rename ApiCallableBuilder to just Builder - Rename XPath into XName - Rename XMethod into XCallSettings in XSettings classe Improvements: - Let the user decide whether to auto-close provided channel - Make all generated methods final - Use Duration instead of long to avoid time unit confusion - Support bundling limits configuration Others: - Update unit tests - Update pom and dependency --- .../gcloud/pubsub/spi/v1/PublisherApi.java | 219 ++++++++--------- .../pubsub/spi/v1/PublisherSettings.java | 76 +++--- .../gcloud/pubsub/spi/v1/SubscriberApi.java | 225 ++++++++---------- .../pubsub/spi/v1/SubscriberSettings.java | 76 +++--- gcloud-java-pubsub/pom.xml | 19 +- .../gcloud/pubsub/spi/v1/PublisherApi.java | 219 ++++++++--------- .../pubsub/spi/v1/PublisherSettings.java | 76 +++--- .../gcloud/pubsub/spi/v1/SubscriberApi.java | 225 ++++++++---------- .../pubsub/spi/v1/SubscriberSettings.java | 76 +++--- .../pubsub/spi/v1/PublisherApiTest.java | 66 ++--- 10 files changed, 577 insertions(+), 700 deletions(-) diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java index fa6da27a72bd..8394e5ae74ed 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java @@ -66,10 +66,6 @@ */ @javax.annotation.Generated("by GAPIC") public class PublisherApi implements AutoCloseable { - // ======== - // Members - // ======== - private final ManagedChannel channel; private final List closeables = new ArrayList<>(); @@ -84,97 +80,80 @@ public class PublisherApi implements AutoCloseable { listTopicSubscriptionsIterableCallable; private final ApiCallable deleteTopicCallable; - public static class ResourceNames { - - // ======================= - // ResourceNames Constants - // ======================= - - /** - * A PathTemplate representing the fully-qualified path to represent - * a project resource. - * - * - * - */ - private static final PathTemplate PROJECT_PATH_TEMPLATE = - PathTemplate.create("projects/{project}"); - - /** - * A PathTemplate representing the fully-qualified path to represent - * a topic resource. - * - * - * - */ - private static final PathTemplate TOPIC_PATH_TEMPLATE = - PathTemplate.create("projects/{project}/topics/{topic}"); - - private ResourceNames() {} - - // ============================== - // Resource Name Helper Functions - // ============================== - - /** - * Formats a string containing the fully-qualified path to represent - * a project resource. - * - * - * - */ - public static final String formatProjectPath(String project) { - return PROJECT_PATH_TEMPLATE.instantiate("project", project); - } + /** + * A PathTemplate representing the fully-qualified path to represent + * a project resource. + * + * + * + */ + private static final PathTemplate PROJECT_PATH_TEMPLATE = + PathTemplate.create("projects/{project}"); - /** - * Formats a string containing the fully-qualified path to represent - * a topic resource. - * - * - * - */ - public static final String formatTopicPath(String project, String topic) { - return TOPIC_PATH_TEMPLATE.instantiate("project", project, "topic", topic); - } + /** + * A PathTemplate representing the fully-qualified path to represent + * a topic resource. + * + * + * + */ + private static final PathTemplate TOPIC_PATH_TEMPLATE = + PathTemplate.create("projects/{project}/topics/{topic}"); - /** - * Parses the project from the given fully-qualified path which - * represents a project resource. - * - * - * - */ - public static final String parseProjectFromProjectPath(String projectPath) { - return PROJECT_PATH_TEMPLATE.parse(projectPath).get("project"); - } + /** + * Formats a string containing the fully-qualified path to represent + * a project resource. + * + * + * + */ + public static final String formatProjectName(String project) { + return PROJECT_PATH_TEMPLATE.instantiate("project", project); + } - /** - * Parses the project from the given fully-qualified path which - * represents a topic resource. - * - * - * - */ - public static final String parseProjectFromTopicPath(String topicPath) { - return TOPIC_PATH_TEMPLATE.parse(topicPath).get("project"); - } + /** + * Formats a string containing the fully-qualified path to represent + * a topic resource. + * + * + * + */ + public static final String formatTopicName(String project, String topic) { + return TOPIC_PATH_TEMPLATE.instantiate("project", project, "topic", topic); + } - /** - * Parses the topic from the given fully-qualified path which - * represents a topic resource. - * - * - * - */ - public static final String parseTopicFromTopicPath(String topicPath) { - return TOPIC_PATH_TEMPLATE.parse(topicPath).get("topic"); - } + /** + * Parses the project from the given fully-qualified path which + * represents a project resource. + * + * + * + */ + public static final String parseProjectFromProjectName(String projectName) { + return PROJECT_PATH_TEMPLATE.parse(projectName).get("project"); + } + + /** + * Parses the project from the given fully-qualified path which + * represents a topic resource. + * + * + * + */ + public static final String parseProjectFromTopicName(String topicName) { + return TOPIC_PATH_TEMPLATE.parse(topicName).get("project"); } - // =============== - // Factory Methods - // =============== + /** + * Parses the topic from the given fully-qualified path which + * represents a topic resource. + * + * + * + */ + public static final String parseTopicFromTopicName(String topicName) { + return TOPIC_PATH_TEMPLATE.parse(topicName).get("topic"); + } /** * Constructs an instance of PublisherApi with default settings. @@ -182,7 +161,7 @@ public static final String parseTopicFromTopicPath(String topicPath) { * * */ - public static PublisherApi create() throws IOException { + public static final PublisherApi create() throws IOException { return create(PublisherSettings.create()); } @@ -194,7 +173,7 @@ public static PublisherApi create() throws IOException { * * */ - public static PublisherApi create(PublisherSettings settings) throws IOException { + public static final PublisherApi create(PublisherSettings settings) throws IOException { return new PublisherApi(settings); } @@ -226,19 +205,17 @@ protected PublisherApi(PublisherSettings settings) throws IOException { settings.listTopicSubscriptionsMethod().buildPageStreaming(settings); this.deleteTopicCallable = settings.deleteTopicMethod().build(settings); - closeables.add( - new Closeable() { - @Override - public void close() throws IOException { - channel.shutdown(); - } - }); + if (settings.shouldAutoCloseChannel()) { + closeables.add( + new Closeable() { + @Override + public void close() throws IOException { + channel.shutdown(); + } + }); + } } - // ============= - // Service Calls - // ============= - // ----- createTopic ----- // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. @@ -255,7 +232,7 @@ public void close() throws IOException { * signs (`%`). It must be between 3 and 255 characters in length, and it * must not start with `"goog"`. */ - public Topic createTopic(String name) { + public final Topic createTopic(String name) { Topic request = Topic.newBuilder().setName(name).build(); return createTopic(request); @@ -281,7 +258,7 @@ private Topic createTopic(Topic request) { * * */ - public ApiCallable createTopicCallable() { + public final ApiCallable createTopicCallable() { return createTopicCallable; } @@ -299,7 +276,7 @@ public ApiCallable createTopicCallable() { * @param topic The messages in the request will be published on this topic. * @param messages The messages to publish. */ - public PublishResponse publish(String topic, List messages) { + public final PublishResponse publish(String topic, List messages) { PublishRequest request = PublishRequest.newBuilder().setTopic(topic).addAllMessages(messages).build(); @@ -330,7 +307,7 @@ public PublishResponse publish(PublishRequest request) { * * */ - public ApiCallable publishCallable() { + public final ApiCallable publishCallable() { return publishCallable; } @@ -345,7 +322,7 @@ public ApiCallable publishCallable() { * * @param topic The name of the topic to get. */ - public Topic getTopic(String topic) { + public final Topic getTopic(String topic) { GetTopicRequest request = GetTopicRequest.newBuilder().setTopic(topic).build(); return getTopic(request); @@ -371,7 +348,7 @@ private Topic getTopic(GetTopicRequest request) { * * */ - public ApiCallable getTopicCallable() { + public final ApiCallable getTopicCallable() { return getTopicCallable; } @@ -384,7 +361,7 @@ public ApiCallable getTopicCallable() { * * */ - public Iterable listTopics(String project) { + public final Iterable listTopics(String project) { ListTopicsRequest request = ListTopicsRequest.newBuilder().setProject(project).build(); return listTopics(request); } @@ -398,7 +375,7 @@ public Iterable listTopics(String project) { * * @param request The request object containing all of the parameters for the API call. */ - public Iterable listTopics(ListTopicsRequest request) { + public final Iterable listTopics(ListTopicsRequest request) { return listTopicsIterableCallable().call(request); } @@ -409,7 +386,7 @@ public Iterable listTopics(ListTopicsRequest request) { * * */ - public ApiCallable> listTopicsIterableCallable() { + public final ApiCallable> listTopicsIterableCallable() { return listTopicsIterableCallable; } @@ -420,7 +397,7 @@ public ApiCallable> listTopicsIterableCallabl * * */ - public ApiCallable listTopicsCallable() { + public final ApiCallable listTopicsCallable() { return listTopicsCallable; } @@ -433,7 +410,7 @@ public ApiCallable listTopicsCallable() { * * */ - public Iterable listTopicSubscriptions(String topic) { + public final Iterable listTopicSubscriptions(String topic) { ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder().setTopic(topic).build(); return listTopicSubscriptions(request); @@ -448,7 +425,7 @@ public Iterable listTopicSubscriptions(String topic) { * * @param request The request object containing all of the parameters for the API call. */ - public Iterable listTopicSubscriptions(ListTopicSubscriptionsRequest request) { + public final Iterable listTopicSubscriptions(ListTopicSubscriptionsRequest request) { return listTopicSubscriptionsIterableCallable().call(request); } @@ -459,7 +436,7 @@ public Iterable listTopicSubscriptions(ListTopicSubscriptionsRequest req * * */ - public ApiCallable> + public final ApiCallable> listTopicSubscriptionsIterableCallable() { return listTopicSubscriptionsIterableCallable; } @@ -471,7 +448,7 @@ public Iterable listTopicSubscriptions(ListTopicSubscriptionsRequest req * * */ - public ApiCallable + public final ApiCallable listTopicSubscriptionsCallable() { return listTopicSubscriptionsCallable; } @@ -491,7 +468,7 @@ public Iterable listTopicSubscriptions(ListTopicSubscriptionsRequest req * * @param topic Name of the topic to delete. */ - public void deleteTopic(String topic) { + public final void deleteTopic(String topic) { DeleteTopicRequest request = DeleteTopicRequest.newBuilder().setTopic(topic).build(); deleteTopic(request); @@ -525,14 +502,10 @@ private void deleteTopic(DeleteTopicRequest request) { * * */ - public ApiCallable deleteTopicCallable() { + public final ApiCallable deleteTopicCallable() { return deleteTopicCallable; } - // ======== - // Cleanup - // ======== - /** * Initiates an orderly shutdown in which preexisting calls continue but new calls are immediately * cancelled. @@ -541,7 +514,7 @@ public ApiCallable deleteTopicCallable() { * */ @Override - public void close() throws Exception { + public final void close() throws Exception { for (AutoCloseable closeable : closeables) { closeable.close(); } diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java index 11566404546f..8b3d434b8e49 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java @@ -37,10 +37,12 @@ import com.google.api.gax.core.ConnectionSettings; import com.google.api.gax.core.RetryParams; import com.google.api.gax.grpc.ApiCallSettings; -import com.google.api.gax.grpc.ApiCallable.ApiCallableBuilder; -import com.google.api.gax.grpc.ApiCallable.BundlableApiCallableBuilder; -import com.google.api.gax.grpc.ApiCallable.PageStreamingApiCallableBuilder; +import com.google.api.gax.grpc.ApiCallable; +import com.google.api.gax.grpc.ApiCallable.Builder; +import com.google.api.gax.grpc.ApiCallable.BundlableBuilder; +import com.google.api.gax.grpc.ApiCallable.PageStreamingBuilder; import com.google.api.gax.grpc.BundlingDescriptor; +import com.google.api.gax.grpc.BundlingSettings; import com.google.api.gax.grpc.PageStreamingDescriptor; import com.google.api.gax.grpc.RequestIssuer; import com.google.api.gax.grpc.ServiceApiSettings; @@ -65,6 +67,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import org.joda.time.Duration; // Manually-added imports: add custom (non-generated) imports after this point. @@ -72,10 +75,6 @@ @javax.annotation.Generated("by GAPIC") public class PublisherSettings extends ServiceApiSettings { - // ========= - // Constants - // ========= - /** * The default address of the service. * @@ -123,17 +122,17 @@ public class PublisherSettings extends ServiceApiSettings { RetryParams.newBuilder() .setRetryBackoff( BackoffParams.newBuilder() - .setInitialDelayMillis(100L) + .setInitialDelay(Duration.millis(100L)) .setDelayMultiplier(1.2) - .setMaxDelayMillis(1000L) + .setMaxDelay(Duration.millis(1000L)) .build()) .setTimeoutBackoff( BackoffParams.newBuilder() - .setInitialDelayMillis(300L) - .setDelayMultiplier(1.3) - .setMaxDelayMillis(3000L) + .setInitialDelay(Duration.millis(2000L)) + .setDelayMultiplier(1.5) + .setMaxDelay(Duration.millis(30000L)) .build()) - .setTotalTimeout(30000L) + .setTotalTimeout(Duration.millis(45000L)) .build(); definitions.put("default", params); RETRY_PARAM_DEFINITIONS = definitions.build(); @@ -142,45 +141,54 @@ public class PublisherSettings extends ServiceApiSettings { private final MethodBuilders methods; private static class MethodBuilders { - private final ApiCallableBuilder createTopicMethod; - private final BundlableApiCallableBuilder publishMethod; - private final ApiCallableBuilder getTopicMethod; - private final PageStreamingApiCallableBuilder + private final ApiCallable.Builder createTopicMethod; + private final ApiCallable.BundlableBuilder publishMethod; + private final ApiCallable.Builder getTopicMethod; + private final ApiCallable.PageStreamingBuilder listTopicsMethod; - private final PageStreamingApiCallableBuilder< + private final ApiCallable.PageStreamingBuilder< ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> listTopicSubscriptionsMethod; - private final ApiCallableBuilder deleteTopicMethod; + private final ApiCallable.Builder deleteTopicMethod; private final ImmutableList allMethods; public MethodBuilders() { - createTopicMethod = new ApiCallableBuilder<>(PublisherGrpc.METHOD_CREATE_TOPIC); + createTopicMethod = new Builder<>(PublisherGrpc.METHOD_CREATE_TOPIC); createTopicMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); createTopicMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + BundlingSettings publishBundlingSettings = + BundlingSettings.newBuilder() + .setElementCountThreshold(800) + .setElementCountLimit(1000) + .setRequestByteThreshold(8388608) + .setRequestByteLimit(10485760) + .setDelayThreshold(Duration.millis(100)) + .setBlockingCallCountThreshold(1) + .build(); publishMethod = - new BundlableApiCallableBuilder<>(PublisherGrpc.METHOD_PUBLISH, PUBLISH_BUNDLING_DESC); + new BundlableBuilder<>( + PublisherGrpc.METHOD_PUBLISH, PUBLISH_BUNDLING_DESC, publishBundlingSettings); publishMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); publishMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - getTopicMethod = new ApiCallableBuilder<>(PublisherGrpc.METHOD_GET_TOPIC); + getTopicMethod = new Builder<>(PublisherGrpc.METHOD_GET_TOPIC); getTopicMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); getTopicMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); listTopicsMethod = - new PageStreamingApiCallableBuilder<>( - PublisherGrpc.METHOD_LIST_TOPICS, LIST_TOPICS_PAGE_STR_DESC); + new PageStreamingBuilder<>(PublisherGrpc.METHOD_LIST_TOPICS, LIST_TOPICS_PAGE_STR_DESC); listTopicsMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); listTopicsMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); listTopicSubscriptionsMethod = - new PageStreamingApiCallableBuilder<>( + new PageStreamingBuilder<>( PublisherGrpc.METHOD_LIST_TOPIC_SUBSCRIPTIONS, LIST_TOPIC_SUBSCRIPTIONS_PAGE_STR_DESC); listTopicSubscriptionsMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); listTopicSubscriptionsMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - deleteTopicMethod = new ApiCallableBuilder<>(PublisherGrpc.METHOD_DELETE_TOPIC); + deleteTopicMethod = new Builder<>(PublisherGrpc.METHOD_DELETE_TOPIC); deleteTopicMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); deleteTopicMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); @@ -197,10 +205,6 @@ public MethodBuilders() { } } - // =============== - // Factory Methods - // =============== - /** * Constructs an instance of PublisherSettings with default settings. * @@ -237,7 +241,7 @@ protected PublisherSettings(MethodBuilders methods) { * * */ - public ApiCallableBuilder createTopicMethod() { + public final ApiCallable.Builder createTopicMethod() { return methods.createTopicMethod; } @@ -247,7 +251,7 @@ public ApiCallableBuilder createTopicMethod() { * * */ - public BundlableApiCallableBuilder publishMethod() { + public final ApiCallable.BundlableBuilder publishMethod() { return methods.publishMethod; } @@ -257,7 +261,7 @@ public BundlableApiCallableBuilder publishMetho * * */ - public ApiCallableBuilder getTopicMethod() { + public final ApiCallable.Builder getTopicMethod() { return methods.getTopicMethod; } @@ -267,7 +271,7 @@ public ApiCallableBuilder getTopicMethod() { * * */ - public PageStreamingApiCallableBuilder + public final ApiCallable.PageStreamingBuilder listTopicsMethod() { return methods.listTopicsMethod; } @@ -278,7 +282,7 @@ public ApiCallableBuilder getTopicMethod() { * * */ - public PageStreamingApiCallableBuilder< + public final ApiCallable.PageStreamingBuilder< ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> listTopicSubscriptionsMethod() { return methods.listTopicSubscriptionsMethod; @@ -290,7 +294,7 @@ public ApiCallableBuilder getTopicMethod() { * * */ - public ApiCallableBuilder deleteTopicMethod() { + public final ApiCallable.Builder deleteTopicMethod() { return methods.deleteTopicMethod; } diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java index d53dca7f8885..3040af41efd8 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java @@ -65,10 +65,6 @@ */ @javax.annotation.Generated("by GAPIC") public class SubscriberApi implements AutoCloseable { - // ======== - // Members - // ======== - private final ManagedChannel channel; private final List closeables = new ArrayList<>(); @@ -84,98 +80,80 @@ public class SubscriberApi implements AutoCloseable { private final ApiCallable pullCallable; private final ApiCallable modifyPushConfigCallable; - public static class ResourceNames { - - // ======================= - // ResourceNames Constants - // ======================= - - /** - * A PathTemplate representing the fully-qualified path to represent - * a project resource. - * - * - * - */ - private static final PathTemplate PROJECT_PATH_TEMPLATE = - PathTemplate.create("projects/{project}"); - - /** - * A PathTemplate representing the fully-qualified path to represent - * a subscription resource. - * - * - * - */ - private static final PathTemplate SUBSCRIPTION_PATH_TEMPLATE = - PathTemplate.create("projects/{project}/subscriptions/{subscription}"); - - private ResourceNames() {} - - // ============================== - // Resource Name Helper Functions - // ============================== - - /** - * Formats a string containing the fully-qualified path to represent - * a project resource. - * - * - * - */ - public static final String formatProjectPath(String project) { - return PROJECT_PATH_TEMPLATE.instantiate("project", project); - } + /** + * A PathTemplate representing the fully-qualified path to represent + * a project resource. + * + * + * + */ + private static final PathTemplate PROJECT_PATH_TEMPLATE = + PathTemplate.create("projects/{project}"); - /** - * Formats a string containing the fully-qualified path to represent - * a subscription resource. - * - * - * - */ - public static final String formatSubscriptionPath(String project, String subscription) { - return SUBSCRIPTION_PATH_TEMPLATE.instantiate( - "project", project, "subscription", subscription); - } + /** + * A PathTemplate representing the fully-qualified path to represent + * a subscription resource. + * + * + * + */ + private static final PathTemplate SUBSCRIPTION_PATH_TEMPLATE = + PathTemplate.create("projects/{project}/subscriptions/{subscription}"); - /** - * Parses the project from the given fully-qualified path which - * represents a project resource. - * - * - * - */ - public static final String parseProjectFromProjectPath(String projectPath) { - return PROJECT_PATH_TEMPLATE.parse(projectPath).get("project"); - } + /** + * Formats a string containing the fully-qualified path to represent + * a project resource. + * + * + * + */ + public static final String formatProjectName(String project) { + return PROJECT_PATH_TEMPLATE.instantiate("project", project); + } - /** - * Parses the project from the given fully-qualified path which - * represents a subscription resource. - * - * - * - */ - public static final String parseProjectFromSubscriptionPath(String subscriptionPath) { - return SUBSCRIPTION_PATH_TEMPLATE.parse(subscriptionPath).get("project"); - } + /** + * Formats a string containing the fully-qualified path to represent + * a subscription resource. + * + * + * + */ + public static final String formatSubscriptionName(String project, String subscription) { + return SUBSCRIPTION_PATH_TEMPLATE.instantiate("project", project, "subscription", subscription); + } - /** - * Parses the subscription from the given fully-qualified path which - * represents a subscription resource. - * - * - * - */ - public static final String parseSubscriptionFromSubscriptionPath(String subscriptionPath) { - return SUBSCRIPTION_PATH_TEMPLATE.parse(subscriptionPath).get("subscription"); - } + /** + * Parses the project from the given fully-qualified path which + * represents a project resource. + * + * + * + */ + public static final String parseProjectFromProjectName(String projectName) { + return PROJECT_PATH_TEMPLATE.parse(projectName).get("project"); + } + + /** + * Parses the project from the given fully-qualified path which + * represents a subscription resource. + * + * + * + */ + public static final String parseProjectFromSubscriptionName(String subscriptionName) { + return SUBSCRIPTION_PATH_TEMPLATE.parse(subscriptionName).get("project"); } - // =============== - // Factory Methods - // =============== + /** + * Parses the subscription from the given fully-qualified path which + * represents a subscription resource. + * + * + * + */ + public static final String parseSubscriptionFromSubscriptionName(String subscriptionName) { + return SUBSCRIPTION_PATH_TEMPLATE.parse(subscriptionName).get("subscription"); + } /** * Constructs an instance of SubscriberApi with default settings. @@ -183,7 +161,7 @@ public static final String parseSubscriptionFromSubscriptionPath(String subscrip * * */ - public static SubscriberApi create() throws IOException { + public static final SubscriberApi create() throws IOException { return create(SubscriberSettings.create()); } @@ -195,7 +173,7 @@ public static SubscriberApi create() throws IOException { * * */ - public static SubscriberApi create(SubscriberSettings settings) throws IOException { + public static final SubscriberApi create(SubscriberSettings settings) throws IOException { return new SubscriberApi(settings); } @@ -221,19 +199,17 @@ protected SubscriberApi(SubscriberSettings settings) throws IOException { this.pullCallable = settings.pullMethod().build(settings); this.modifyPushConfigCallable = settings.modifyPushConfigMethod().build(settings); - closeables.add( - new Closeable() { - @Override - public void close() throws IOException { - channel.shutdown(); - } - }); + if (settings.shouldAutoCloseChannel()) { + closeables.add( + new Closeable() { + @Override + public void close() throws IOException { + channel.shutdown(); + } + }); + } } - // ============= - // Service Calls - // ============= - // ----- createSubscription ----- // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. @@ -277,7 +253,7 @@ public void close() throws IOException { * * If this parameter is not set, the default value of 10 seconds is used. */ - public Subscription createSubscription( + public final Subscription createSubscription( String name, String topic, PushConfig pushConfig, int ackDeadlineSeconds) { Subscription request = Subscription.newBuilder() @@ -320,7 +296,7 @@ public Subscription createSubscription(Subscription request) { * * */ - public ApiCallable createSubscriptionCallable() { + public final ApiCallable createSubscriptionCallable() { return createSubscriptionCallable; } @@ -338,7 +314,7 @@ public ApiCallable createSubscriptionCallable() { * * @param subscription The name of the subscription to get. */ - public Subscription getSubscription(String subscription) { + public final Subscription getSubscription(String subscription) { GetSubscriptionRequest request = GetSubscriptionRequest.newBuilder().setSubscription(subscription).build(); @@ -371,7 +347,7 @@ private Subscription getSubscription(GetSubscriptionRequest request) { * * */ - public ApiCallable getSubscriptionCallable() { + public final ApiCallable getSubscriptionCallable() { return getSubscriptionCallable; } @@ -387,7 +363,7 @@ public ApiCallable getSubscriptionCallable * * */ - public Iterable listSubscriptions(String project) { + public final Iterable listSubscriptions(String project) { ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder().setProject(project).build(); return listSubscriptions(request); @@ -405,7 +381,7 @@ public Iterable listSubscriptions(String project) { * * @param request The request object containing all of the parameters for the API call. */ - public Iterable listSubscriptions(ListSubscriptionsRequest request) { + public final Iterable listSubscriptions(ListSubscriptionsRequest request) { return listSubscriptionsIterableCallable().call(request); } @@ -419,7 +395,7 @@ public Iterable listSubscriptions(ListSubscriptionsRequest request * * */ - public ApiCallable> + public final ApiCallable> listSubscriptionsIterableCallable() { return listSubscriptionsIterableCallable; } @@ -434,7 +410,7 @@ public Iterable listSubscriptions(ListSubscriptionsRequest request * * */ - public ApiCallable + public final ApiCallable listSubscriptionsCallable() { return listSubscriptionsCallable; } @@ -454,7 +430,7 @@ public Iterable listSubscriptions(ListSubscriptionsRequest request * * @param subscription The subscription to delete. */ - public void deleteSubscription(String subscription) { + public final void deleteSubscription(String subscription) { DeleteSubscriptionRequest request = DeleteSubscriptionRequest.newBuilder().setSubscription(subscription).build(); @@ -489,7 +465,7 @@ private void deleteSubscription(DeleteSubscriptionRequest request) { * * */ - public ApiCallable deleteSubscriptionCallable() { + public final ApiCallable deleteSubscriptionCallable() { return deleteSubscriptionCallable; } @@ -513,7 +489,8 @@ public ApiCallable deleteSubscriptionCallable( * was made. Specifying zero may immediately make the message available for * another pull request. */ - public void modifyAckDeadline(String subscription, List ackIds, int ackDeadlineSeconds) { + public final void modifyAckDeadline( + String subscription, List ackIds, int ackDeadlineSeconds) { ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() .setSubscription(subscription) @@ -550,7 +527,7 @@ public void modifyAckDeadline(ModifyAckDeadlineRequest request) { * * */ - public ApiCallable modifyAckDeadlineCallable() { + public final ApiCallable modifyAckDeadlineCallable() { return modifyAckDeadlineCallable; } @@ -573,7 +550,7 @@ public ApiCallable modifyAckDeadlineCallable() * @param ackIds The acknowledgment ID for the messages being acknowledged that was returned * by the Pub/Sub system in the `Pull` response. Must not be empty. */ - public void acknowledge(String subscription, List ackIds) { + public final void acknowledge(String subscription, List ackIds) { AcknowledgeRequest request = AcknowledgeRequest.newBuilder().setSubscription(subscription).addAllAckIds(ackIds).build(); @@ -612,7 +589,7 @@ public void acknowledge(AcknowledgeRequest request) { * * */ - public ApiCallable acknowledgeCallable() { + public final ApiCallable acknowledgeCallable() { return acknowledgeCallable; } @@ -636,7 +613,7 @@ public ApiCallable acknowledgeCallable() { * @param maxMessages The maximum number of messages returned for this request. The Pub/Sub * system may return fewer than the number specified. */ - public PullResponse pull(String subscription, boolean returnImmediately, int maxMessages) { + public final PullResponse pull(String subscription, boolean returnImmediately, int maxMessages) { PullRequest request = PullRequest.newBuilder() .setSubscription(subscription) @@ -673,7 +650,7 @@ public PullResponse pull(PullRequest request) { * * */ - public ApiCallable pullCallable() { + public final ApiCallable pullCallable() { return pullCallable; } @@ -699,7 +676,7 @@ public ApiCallable pullCallable() { * messages to be pulled and acknowledged - effectively pausing * the subscription if `Pull` is not called. */ - public void modifyPushConfig(String subscription, PushConfig pushConfig) { + public final void modifyPushConfig(String subscription, PushConfig pushConfig) { ModifyPushConfigRequest request = ModifyPushConfigRequest.newBuilder() .setSubscription(subscription) @@ -739,14 +716,10 @@ public void modifyPushConfig(ModifyPushConfigRequest request) { * * */ - public ApiCallable modifyPushConfigCallable() { + public final ApiCallable modifyPushConfigCallable() { return modifyPushConfigCallable; } - // ======== - // Cleanup - // ======== - /** * Initiates an orderly shutdown in which preexisting calls continue but new calls are immediately * cancelled. @@ -755,7 +728,7 @@ public ApiCallable modifyPushConfigCallable() { * */ @Override - public void close() throws Exception { + public final void close() throws Exception { for (AutoCloseable closeable : closeables) { closeable.close(); } diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java index d9da44aa81f7..e0204a4171f8 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java @@ -37,8 +37,9 @@ import com.google.api.gax.core.ConnectionSettings; import com.google.api.gax.core.RetryParams; import com.google.api.gax.grpc.ApiCallSettings; -import com.google.api.gax.grpc.ApiCallable.ApiCallableBuilder; -import com.google.api.gax.grpc.ApiCallable.PageStreamingApiCallableBuilder; +import com.google.api.gax.grpc.ApiCallable; +import com.google.api.gax.grpc.ApiCallable.Builder; +import com.google.api.gax.grpc.ApiCallable.PageStreamingBuilder; import com.google.api.gax.grpc.PageStreamingDescriptor; import com.google.api.gax.grpc.ServiceApiSettings; import com.google.common.collect.ImmutableList; @@ -59,6 +60,7 @@ import com.google.pubsub.v1.SubscriberGrpc; import com.google.pubsub.v1.Subscription; import io.grpc.Status; +import org.joda.time.Duration; // Manually-added imports: add custom (non-generated) imports after this point. @@ -66,10 +68,6 @@ @javax.annotation.Generated("by GAPIC") public class SubscriberSettings extends ServiceApiSettings { - // ========= - // Constants - // ========= - /** * The default address of the service. * @@ -117,17 +115,17 @@ public class SubscriberSettings extends ServiceApiSettings { RetryParams.newBuilder() .setRetryBackoff( BackoffParams.newBuilder() - .setInitialDelayMillis(100L) + .setInitialDelay(Duration.millis(100L)) .setDelayMultiplier(1.2) - .setMaxDelayMillis(1000L) + .setMaxDelay(Duration.millis(1000L)) .build()) .setTimeoutBackoff( BackoffParams.newBuilder() - .setInitialDelayMillis(300L) - .setDelayMultiplier(1.3) - .setMaxDelayMillis(3000L) + .setInitialDelay(Duration.millis(2000L)) + .setDelayMultiplier(1.5) + .setMaxDelay(Duration.millis(30000L)) .build()) - .setTotalTimeout(30000L) + .setTotalTimeout(Duration.millis(45000L)) .build(); definitions.put("default", params); RETRY_PARAM_DEFINITIONS = definitions.build(); @@ -136,52 +134,50 @@ public class SubscriberSettings extends ServiceApiSettings { private final MethodBuilders methods; private static class MethodBuilders { - private final ApiCallableBuilder createSubscriptionMethod; - private final ApiCallableBuilder getSubscriptionMethod; - private final PageStreamingApiCallableBuilder< + private final ApiCallable.Builder createSubscriptionMethod; + private final ApiCallable.Builder getSubscriptionMethod; + private final ApiCallable.PageStreamingBuilder< ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> listSubscriptionsMethod; - private final ApiCallableBuilder deleteSubscriptionMethod; - private final ApiCallableBuilder modifyAckDeadlineMethod; - private final ApiCallableBuilder acknowledgeMethod; - private final ApiCallableBuilder pullMethod; - private final ApiCallableBuilder modifyPushConfigMethod; + private final ApiCallable.Builder deleteSubscriptionMethod; + private final ApiCallable.Builder modifyAckDeadlineMethod; + private final ApiCallable.Builder acknowledgeMethod; + private final ApiCallable.Builder pullMethod; + private final ApiCallable.Builder modifyPushConfigMethod; private final ImmutableList allMethods; public MethodBuilders() { - createSubscriptionMethod = - new ApiCallableBuilder<>(SubscriberGrpc.METHOD_CREATE_SUBSCRIPTION); + createSubscriptionMethod = new Builder<>(SubscriberGrpc.METHOD_CREATE_SUBSCRIPTION); createSubscriptionMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); createSubscriptionMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - getSubscriptionMethod = new ApiCallableBuilder<>(SubscriberGrpc.METHOD_GET_SUBSCRIPTION); + getSubscriptionMethod = new Builder<>(SubscriberGrpc.METHOD_GET_SUBSCRIPTION); getSubscriptionMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); getSubscriptionMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); listSubscriptionsMethod = - new PageStreamingApiCallableBuilder<>( + new PageStreamingBuilder<>( SubscriberGrpc.METHOD_LIST_SUBSCRIPTIONS, LIST_SUBSCRIPTIONS_PAGE_STR_DESC); listSubscriptionsMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); listSubscriptionsMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - deleteSubscriptionMethod = - new ApiCallableBuilder<>(SubscriberGrpc.METHOD_DELETE_SUBSCRIPTION); + deleteSubscriptionMethod = new Builder<>(SubscriberGrpc.METHOD_DELETE_SUBSCRIPTION); deleteSubscriptionMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); deleteSubscriptionMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - modifyAckDeadlineMethod = new ApiCallableBuilder<>(SubscriberGrpc.METHOD_MODIFY_ACK_DEADLINE); + modifyAckDeadlineMethod = new Builder<>(SubscriberGrpc.METHOD_MODIFY_ACK_DEADLINE); modifyAckDeadlineMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); modifyAckDeadlineMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - acknowledgeMethod = new ApiCallableBuilder<>(SubscriberGrpc.METHOD_ACKNOWLEDGE); + acknowledgeMethod = new Builder<>(SubscriberGrpc.METHOD_ACKNOWLEDGE); acknowledgeMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); acknowledgeMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - pullMethod = new ApiCallableBuilder<>(SubscriberGrpc.METHOD_PULL); + pullMethod = new Builder<>(SubscriberGrpc.METHOD_PULL); pullMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); pullMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - modifyPushConfigMethod = new ApiCallableBuilder<>(SubscriberGrpc.METHOD_MODIFY_PUSH_CONFIG); + modifyPushConfigMethod = new Builder<>(SubscriberGrpc.METHOD_MODIFY_PUSH_CONFIG); modifyPushConfigMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); modifyPushConfigMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); @@ -200,10 +196,6 @@ public MethodBuilders() { } } - // =============== - // Factory Methods - // =============== - /** * Constructs an instance of SubscriberSettings with default settings. * @@ -240,7 +232,7 @@ protected SubscriberSettings(MethodBuilders methods) { * * */ - public ApiCallableBuilder createSubscriptionMethod() { + public final ApiCallable.Builder createSubscriptionMethod() { return methods.createSubscriptionMethod; } @@ -250,7 +242,7 @@ public ApiCallableBuilder createSubscriptionMethod() * * */ - public ApiCallableBuilder getSubscriptionMethod() { + public final ApiCallable.Builder getSubscriptionMethod() { return methods.getSubscriptionMethod; } @@ -260,7 +252,7 @@ public ApiCallableBuilder getSubscriptionM * * */ - public PageStreamingApiCallableBuilder< + public final ApiCallable.PageStreamingBuilder< ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> listSubscriptionsMethod() { return methods.listSubscriptionsMethod; @@ -272,7 +264,7 @@ public ApiCallableBuilder getSubscriptionM * * */ - public ApiCallableBuilder deleteSubscriptionMethod() { + public final ApiCallable.Builder deleteSubscriptionMethod() { return methods.deleteSubscriptionMethod; } @@ -282,7 +274,7 @@ public ApiCallableBuilder deleteSubscriptionMe * * */ - public ApiCallableBuilder modifyAckDeadlineMethod() { + public final ApiCallable.Builder modifyAckDeadlineMethod() { return methods.modifyAckDeadlineMethod; } @@ -292,7 +284,7 @@ public ApiCallableBuilder modifyAckDeadlineMeth * * */ - public ApiCallableBuilder acknowledgeMethod() { + public final ApiCallable.Builder acknowledgeMethod() { return methods.acknowledgeMethod; } @@ -302,7 +294,7 @@ public ApiCallableBuilder acknowledgeMethod() { * * */ - public ApiCallableBuilder pullMethod() { + public final ApiCallable.Builder pullMethod() { return methods.pullMethod; } @@ -312,7 +304,7 @@ public ApiCallableBuilder pullMethod() { * * */ - public ApiCallableBuilder modifyPushConfigMethod() { + public final ApiCallable.Builder modifyPushConfigMethod() { return methods.modifyPushConfigMethod; } diff --git a/gcloud-java-pubsub/pom.xml b/gcloud-java-pubsub/pom.xml index 2014b483b17e..a695947e3e2c 100644 --- a/gcloud-java-pubsub/pom.xml +++ b/gcloud-java-pubsub/pom.xml @@ -1,6 +1,8 @@ 4.0.0 + com.google.gcloud + 0.1.5 gcloud-java-pubsub jar GCloud Java Pub/Sub @@ -19,12 +21,12 @@ com.google.api gax - 0.0.5 + 0.0.6 com.google.api.grpc grpc-pubsub-v1 - 0.0.0 + 0.0.1 io.grpc @@ -89,6 +91,19 @@
      + + maven-compiler-plugin + + + + 3.1 + + 1.7 + 1.7 + UTF-8 + -Xlint:unchecked + + diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java index fa6da27a72bd..8394e5ae74ed 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java @@ -66,10 +66,6 @@ */ @javax.annotation.Generated("by GAPIC") public class PublisherApi implements AutoCloseable { - // ======== - // Members - // ======== - private final ManagedChannel channel; private final List closeables = new ArrayList<>(); @@ -84,97 +80,80 @@ public class PublisherApi implements AutoCloseable { listTopicSubscriptionsIterableCallable; private final ApiCallable deleteTopicCallable; - public static class ResourceNames { - - // ======================= - // ResourceNames Constants - // ======================= - - /** - * A PathTemplate representing the fully-qualified path to represent - * a project resource. - * - * - * - */ - private static final PathTemplate PROJECT_PATH_TEMPLATE = - PathTemplate.create("projects/{project}"); - - /** - * A PathTemplate representing the fully-qualified path to represent - * a topic resource. - * - * - * - */ - private static final PathTemplate TOPIC_PATH_TEMPLATE = - PathTemplate.create("projects/{project}/topics/{topic}"); - - private ResourceNames() {} - - // ============================== - // Resource Name Helper Functions - // ============================== - - /** - * Formats a string containing the fully-qualified path to represent - * a project resource. - * - * - * - */ - public static final String formatProjectPath(String project) { - return PROJECT_PATH_TEMPLATE.instantiate("project", project); - } + /** + * A PathTemplate representing the fully-qualified path to represent + * a project resource. + * + * + * + */ + private static final PathTemplate PROJECT_PATH_TEMPLATE = + PathTemplate.create("projects/{project}"); - /** - * Formats a string containing the fully-qualified path to represent - * a topic resource. - * - * - * - */ - public static final String formatTopicPath(String project, String topic) { - return TOPIC_PATH_TEMPLATE.instantiate("project", project, "topic", topic); - } + /** + * A PathTemplate representing the fully-qualified path to represent + * a topic resource. + * + * + * + */ + private static final PathTemplate TOPIC_PATH_TEMPLATE = + PathTemplate.create("projects/{project}/topics/{topic}"); - /** - * Parses the project from the given fully-qualified path which - * represents a project resource. - * - * - * - */ - public static final String parseProjectFromProjectPath(String projectPath) { - return PROJECT_PATH_TEMPLATE.parse(projectPath).get("project"); - } + /** + * Formats a string containing the fully-qualified path to represent + * a project resource. + * + * + * + */ + public static final String formatProjectName(String project) { + return PROJECT_PATH_TEMPLATE.instantiate("project", project); + } - /** - * Parses the project from the given fully-qualified path which - * represents a topic resource. - * - * - * - */ - public static final String parseProjectFromTopicPath(String topicPath) { - return TOPIC_PATH_TEMPLATE.parse(topicPath).get("project"); - } + /** + * Formats a string containing the fully-qualified path to represent + * a topic resource. + * + * + * + */ + public static final String formatTopicName(String project, String topic) { + return TOPIC_PATH_TEMPLATE.instantiate("project", project, "topic", topic); + } - /** - * Parses the topic from the given fully-qualified path which - * represents a topic resource. - * - * - * - */ - public static final String parseTopicFromTopicPath(String topicPath) { - return TOPIC_PATH_TEMPLATE.parse(topicPath).get("topic"); - } + /** + * Parses the project from the given fully-qualified path which + * represents a project resource. + * + * + * + */ + public static final String parseProjectFromProjectName(String projectName) { + return PROJECT_PATH_TEMPLATE.parse(projectName).get("project"); + } + + /** + * Parses the project from the given fully-qualified path which + * represents a topic resource. + * + * + * + */ + public static final String parseProjectFromTopicName(String topicName) { + return TOPIC_PATH_TEMPLATE.parse(topicName).get("project"); } - // =============== - // Factory Methods - // =============== + /** + * Parses the topic from the given fully-qualified path which + * represents a topic resource. + * + * + * + */ + public static final String parseTopicFromTopicName(String topicName) { + return TOPIC_PATH_TEMPLATE.parse(topicName).get("topic"); + } /** * Constructs an instance of PublisherApi with default settings. @@ -182,7 +161,7 @@ public static final String parseTopicFromTopicPath(String topicPath) { * * */ - public static PublisherApi create() throws IOException { + public static final PublisherApi create() throws IOException { return create(PublisherSettings.create()); } @@ -194,7 +173,7 @@ public static PublisherApi create() throws IOException { * * */ - public static PublisherApi create(PublisherSettings settings) throws IOException { + public static final PublisherApi create(PublisherSettings settings) throws IOException { return new PublisherApi(settings); } @@ -226,19 +205,17 @@ protected PublisherApi(PublisherSettings settings) throws IOException { settings.listTopicSubscriptionsMethod().buildPageStreaming(settings); this.deleteTopicCallable = settings.deleteTopicMethod().build(settings); - closeables.add( - new Closeable() { - @Override - public void close() throws IOException { - channel.shutdown(); - } - }); + if (settings.shouldAutoCloseChannel()) { + closeables.add( + new Closeable() { + @Override + public void close() throws IOException { + channel.shutdown(); + } + }); + } } - // ============= - // Service Calls - // ============= - // ----- createTopic ----- // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. @@ -255,7 +232,7 @@ public void close() throws IOException { * signs (`%`). It must be between 3 and 255 characters in length, and it * must not start with `"goog"`. */ - public Topic createTopic(String name) { + public final Topic createTopic(String name) { Topic request = Topic.newBuilder().setName(name).build(); return createTopic(request); @@ -281,7 +258,7 @@ private Topic createTopic(Topic request) { * * */ - public ApiCallable createTopicCallable() { + public final ApiCallable createTopicCallable() { return createTopicCallable; } @@ -299,7 +276,7 @@ public ApiCallable createTopicCallable() { * @param topic The messages in the request will be published on this topic. * @param messages The messages to publish. */ - public PublishResponse publish(String topic, List messages) { + public final PublishResponse publish(String topic, List messages) { PublishRequest request = PublishRequest.newBuilder().setTopic(topic).addAllMessages(messages).build(); @@ -330,7 +307,7 @@ public PublishResponse publish(PublishRequest request) { * * */ - public ApiCallable publishCallable() { + public final ApiCallable publishCallable() { return publishCallable; } @@ -345,7 +322,7 @@ public ApiCallable publishCallable() { * * @param topic The name of the topic to get. */ - public Topic getTopic(String topic) { + public final Topic getTopic(String topic) { GetTopicRequest request = GetTopicRequest.newBuilder().setTopic(topic).build(); return getTopic(request); @@ -371,7 +348,7 @@ private Topic getTopic(GetTopicRequest request) { * * */ - public ApiCallable getTopicCallable() { + public final ApiCallable getTopicCallable() { return getTopicCallable; } @@ -384,7 +361,7 @@ public ApiCallable getTopicCallable() { * * */ - public Iterable listTopics(String project) { + public final Iterable listTopics(String project) { ListTopicsRequest request = ListTopicsRequest.newBuilder().setProject(project).build(); return listTopics(request); } @@ -398,7 +375,7 @@ public Iterable listTopics(String project) { * * @param request The request object containing all of the parameters for the API call. */ - public Iterable listTopics(ListTopicsRequest request) { + public final Iterable listTopics(ListTopicsRequest request) { return listTopicsIterableCallable().call(request); } @@ -409,7 +386,7 @@ public Iterable listTopics(ListTopicsRequest request) { * * */ - public ApiCallable> listTopicsIterableCallable() { + public final ApiCallable> listTopicsIterableCallable() { return listTopicsIterableCallable; } @@ -420,7 +397,7 @@ public ApiCallable> listTopicsIterableCallabl * * */ - public ApiCallable listTopicsCallable() { + public final ApiCallable listTopicsCallable() { return listTopicsCallable; } @@ -433,7 +410,7 @@ public ApiCallable listTopicsCallable() { * * */ - public Iterable listTopicSubscriptions(String topic) { + public final Iterable listTopicSubscriptions(String topic) { ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder().setTopic(topic).build(); return listTopicSubscriptions(request); @@ -448,7 +425,7 @@ public Iterable listTopicSubscriptions(String topic) { * * @param request The request object containing all of the parameters for the API call. */ - public Iterable listTopicSubscriptions(ListTopicSubscriptionsRequest request) { + public final Iterable listTopicSubscriptions(ListTopicSubscriptionsRequest request) { return listTopicSubscriptionsIterableCallable().call(request); } @@ -459,7 +436,7 @@ public Iterable listTopicSubscriptions(ListTopicSubscriptionsRequest req * * */ - public ApiCallable> + public final ApiCallable> listTopicSubscriptionsIterableCallable() { return listTopicSubscriptionsIterableCallable; } @@ -471,7 +448,7 @@ public Iterable listTopicSubscriptions(ListTopicSubscriptionsRequest req * * */ - public ApiCallable + public final ApiCallable listTopicSubscriptionsCallable() { return listTopicSubscriptionsCallable; } @@ -491,7 +468,7 @@ public Iterable listTopicSubscriptions(ListTopicSubscriptionsRequest req * * @param topic Name of the topic to delete. */ - public void deleteTopic(String topic) { + public final void deleteTopic(String topic) { DeleteTopicRequest request = DeleteTopicRequest.newBuilder().setTopic(topic).build(); deleteTopic(request); @@ -525,14 +502,10 @@ private void deleteTopic(DeleteTopicRequest request) { * * */ - public ApiCallable deleteTopicCallable() { + public final ApiCallable deleteTopicCallable() { return deleteTopicCallable; } - // ======== - // Cleanup - // ======== - /** * Initiates an orderly shutdown in which preexisting calls continue but new calls are immediately * cancelled. @@ -541,7 +514,7 @@ public ApiCallable deleteTopicCallable() { * */ @Override - public void close() throws Exception { + public final void close() throws Exception { for (AutoCloseable closeable : closeables) { closeable.close(); } diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java index 11566404546f..8b3d434b8e49 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java @@ -37,10 +37,12 @@ import com.google.api.gax.core.ConnectionSettings; import com.google.api.gax.core.RetryParams; import com.google.api.gax.grpc.ApiCallSettings; -import com.google.api.gax.grpc.ApiCallable.ApiCallableBuilder; -import com.google.api.gax.grpc.ApiCallable.BundlableApiCallableBuilder; -import com.google.api.gax.grpc.ApiCallable.PageStreamingApiCallableBuilder; +import com.google.api.gax.grpc.ApiCallable; +import com.google.api.gax.grpc.ApiCallable.Builder; +import com.google.api.gax.grpc.ApiCallable.BundlableBuilder; +import com.google.api.gax.grpc.ApiCallable.PageStreamingBuilder; import com.google.api.gax.grpc.BundlingDescriptor; +import com.google.api.gax.grpc.BundlingSettings; import com.google.api.gax.grpc.PageStreamingDescriptor; import com.google.api.gax.grpc.RequestIssuer; import com.google.api.gax.grpc.ServiceApiSettings; @@ -65,6 +67,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; +import org.joda.time.Duration; // Manually-added imports: add custom (non-generated) imports after this point. @@ -72,10 +75,6 @@ @javax.annotation.Generated("by GAPIC") public class PublisherSettings extends ServiceApiSettings { - // ========= - // Constants - // ========= - /** * The default address of the service. * @@ -123,17 +122,17 @@ public class PublisherSettings extends ServiceApiSettings { RetryParams.newBuilder() .setRetryBackoff( BackoffParams.newBuilder() - .setInitialDelayMillis(100L) + .setInitialDelay(Duration.millis(100L)) .setDelayMultiplier(1.2) - .setMaxDelayMillis(1000L) + .setMaxDelay(Duration.millis(1000L)) .build()) .setTimeoutBackoff( BackoffParams.newBuilder() - .setInitialDelayMillis(300L) - .setDelayMultiplier(1.3) - .setMaxDelayMillis(3000L) + .setInitialDelay(Duration.millis(2000L)) + .setDelayMultiplier(1.5) + .setMaxDelay(Duration.millis(30000L)) .build()) - .setTotalTimeout(30000L) + .setTotalTimeout(Duration.millis(45000L)) .build(); definitions.put("default", params); RETRY_PARAM_DEFINITIONS = definitions.build(); @@ -142,45 +141,54 @@ public class PublisherSettings extends ServiceApiSettings { private final MethodBuilders methods; private static class MethodBuilders { - private final ApiCallableBuilder createTopicMethod; - private final BundlableApiCallableBuilder publishMethod; - private final ApiCallableBuilder getTopicMethod; - private final PageStreamingApiCallableBuilder + private final ApiCallable.Builder createTopicMethod; + private final ApiCallable.BundlableBuilder publishMethod; + private final ApiCallable.Builder getTopicMethod; + private final ApiCallable.PageStreamingBuilder listTopicsMethod; - private final PageStreamingApiCallableBuilder< + private final ApiCallable.PageStreamingBuilder< ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> listTopicSubscriptionsMethod; - private final ApiCallableBuilder deleteTopicMethod; + private final ApiCallable.Builder deleteTopicMethod; private final ImmutableList allMethods; public MethodBuilders() { - createTopicMethod = new ApiCallableBuilder<>(PublisherGrpc.METHOD_CREATE_TOPIC); + createTopicMethod = new Builder<>(PublisherGrpc.METHOD_CREATE_TOPIC); createTopicMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); createTopicMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + BundlingSettings publishBundlingSettings = + BundlingSettings.newBuilder() + .setElementCountThreshold(800) + .setElementCountLimit(1000) + .setRequestByteThreshold(8388608) + .setRequestByteLimit(10485760) + .setDelayThreshold(Duration.millis(100)) + .setBlockingCallCountThreshold(1) + .build(); publishMethod = - new BundlableApiCallableBuilder<>(PublisherGrpc.METHOD_PUBLISH, PUBLISH_BUNDLING_DESC); + new BundlableBuilder<>( + PublisherGrpc.METHOD_PUBLISH, PUBLISH_BUNDLING_DESC, publishBundlingSettings); publishMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); publishMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - getTopicMethod = new ApiCallableBuilder<>(PublisherGrpc.METHOD_GET_TOPIC); + getTopicMethod = new Builder<>(PublisherGrpc.METHOD_GET_TOPIC); getTopicMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); getTopicMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); listTopicsMethod = - new PageStreamingApiCallableBuilder<>( - PublisherGrpc.METHOD_LIST_TOPICS, LIST_TOPICS_PAGE_STR_DESC); + new PageStreamingBuilder<>(PublisherGrpc.METHOD_LIST_TOPICS, LIST_TOPICS_PAGE_STR_DESC); listTopicsMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); listTopicsMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); listTopicSubscriptionsMethod = - new PageStreamingApiCallableBuilder<>( + new PageStreamingBuilder<>( PublisherGrpc.METHOD_LIST_TOPIC_SUBSCRIPTIONS, LIST_TOPIC_SUBSCRIPTIONS_PAGE_STR_DESC); listTopicSubscriptionsMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); listTopicSubscriptionsMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - deleteTopicMethod = new ApiCallableBuilder<>(PublisherGrpc.METHOD_DELETE_TOPIC); + deleteTopicMethod = new Builder<>(PublisherGrpc.METHOD_DELETE_TOPIC); deleteTopicMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); deleteTopicMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); @@ -197,10 +205,6 @@ public MethodBuilders() { } } - // =============== - // Factory Methods - // =============== - /** * Constructs an instance of PublisherSettings with default settings. * @@ -237,7 +241,7 @@ protected PublisherSettings(MethodBuilders methods) { * * */ - public ApiCallableBuilder createTopicMethod() { + public final ApiCallable.Builder createTopicMethod() { return methods.createTopicMethod; } @@ -247,7 +251,7 @@ public ApiCallableBuilder createTopicMethod() { * * */ - public BundlableApiCallableBuilder publishMethod() { + public final ApiCallable.BundlableBuilder publishMethod() { return methods.publishMethod; } @@ -257,7 +261,7 @@ public BundlableApiCallableBuilder publishMetho * * */ - public ApiCallableBuilder getTopicMethod() { + public final ApiCallable.Builder getTopicMethod() { return methods.getTopicMethod; } @@ -267,7 +271,7 @@ public ApiCallableBuilder getTopicMethod() { * * */ - public PageStreamingApiCallableBuilder + public final ApiCallable.PageStreamingBuilder listTopicsMethod() { return methods.listTopicsMethod; } @@ -278,7 +282,7 @@ public ApiCallableBuilder getTopicMethod() { * * */ - public PageStreamingApiCallableBuilder< + public final ApiCallable.PageStreamingBuilder< ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> listTopicSubscriptionsMethod() { return methods.listTopicSubscriptionsMethod; @@ -290,7 +294,7 @@ public ApiCallableBuilder getTopicMethod() { * * */ - public ApiCallableBuilder deleteTopicMethod() { + public final ApiCallable.Builder deleteTopicMethod() { return methods.deleteTopicMethod; } diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java index d53dca7f8885..3040af41efd8 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java @@ -65,10 +65,6 @@ */ @javax.annotation.Generated("by GAPIC") public class SubscriberApi implements AutoCloseable { - // ======== - // Members - // ======== - private final ManagedChannel channel; private final List closeables = new ArrayList<>(); @@ -84,98 +80,80 @@ public class SubscriberApi implements AutoCloseable { private final ApiCallable pullCallable; private final ApiCallable modifyPushConfigCallable; - public static class ResourceNames { - - // ======================= - // ResourceNames Constants - // ======================= - - /** - * A PathTemplate representing the fully-qualified path to represent - * a project resource. - * - * - * - */ - private static final PathTemplate PROJECT_PATH_TEMPLATE = - PathTemplate.create("projects/{project}"); - - /** - * A PathTemplate representing the fully-qualified path to represent - * a subscription resource. - * - * - * - */ - private static final PathTemplate SUBSCRIPTION_PATH_TEMPLATE = - PathTemplate.create("projects/{project}/subscriptions/{subscription}"); - - private ResourceNames() {} - - // ============================== - // Resource Name Helper Functions - // ============================== - - /** - * Formats a string containing the fully-qualified path to represent - * a project resource. - * - * - * - */ - public static final String formatProjectPath(String project) { - return PROJECT_PATH_TEMPLATE.instantiate("project", project); - } + /** + * A PathTemplate representing the fully-qualified path to represent + * a project resource. + * + * + * + */ + private static final PathTemplate PROJECT_PATH_TEMPLATE = + PathTemplate.create("projects/{project}"); - /** - * Formats a string containing the fully-qualified path to represent - * a subscription resource. - * - * - * - */ - public static final String formatSubscriptionPath(String project, String subscription) { - return SUBSCRIPTION_PATH_TEMPLATE.instantiate( - "project", project, "subscription", subscription); - } + /** + * A PathTemplate representing the fully-qualified path to represent + * a subscription resource. + * + * + * + */ + private static final PathTemplate SUBSCRIPTION_PATH_TEMPLATE = + PathTemplate.create("projects/{project}/subscriptions/{subscription}"); - /** - * Parses the project from the given fully-qualified path which - * represents a project resource. - * - * - * - */ - public static final String parseProjectFromProjectPath(String projectPath) { - return PROJECT_PATH_TEMPLATE.parse(projectPath).get("project"); - } + /** + * Formats a string containing the fully-qualified path to represent + * a project resource. + * + * + * + */ + public static final String formatProjectName(String project) { + return PROJECT_PATH_TEMPLATE.instantiate("project", project); + } - /** - * Parses the project from the given fully-qualified path which - * represents a subscription resource. - * - * - * - */ - public static final String parseProjectFromSubscriptionPath(String subscriptionPath) { - return SUBSCRIPTION_PATH_TEMPLATE.parse(subscriptionPath).get("project"); - } + /** + * Formats a string containing the fully-qualified path to represent + * a subscription resource. + * + * + * + */ + public static final String formatSubscriptionName(String project, String subscription) { + return SUBSCRIPTION_PATH_TEMPLATE.instantiate("project", project, "subscription", subscription); + } - /** - * Parses the subscription from the given fully-qualified path which - * represents a subscription resource. - * - * - * - */ - public static final String parseSubscriptionFromSubscriptionPath(String subscriptionPath) { - return SUBSCRIPTION_PATH_TEMPLATE.parse(subscriptionPath).get("subscription"); - } + /** + * Parses the project from the given fully-qualified path which + * represents a project resource. + * + * + * + */ + public static final String parseProjectFromProjectName(String projectName) { + return PROJECT_PATH_TEMPLATE.parse(projectName).get("project"); + } + + /** + * Parses the project from the given fully-qualified path which + * represents a subscription resource. + * + * + * + */ + public static final String parseProjectFromSubscriptionName(String subscriptionName) { + return SUBSCRIPTION_PATH_TEMPLATE.parse(subscriptionName).get("project"); } - // =============== - // Factory Methods - // =============== + /** + * Parses the subscription from the given fully-qualified path which + * represents a subscription resource. + * + * + * + */ + public static final String parseSubscriptionFromSubscriptionName(String subscriptionName) { + return SUBSCRIPTION_PATH_TEMPLATE.parse(subscriptionName).get("subscription"); + } /** * Constructs an instance of SubscriberApi with default settings. @@ -183,7 +161,7 @@ public static final String parseSubscriptionFromSubscriptionPath(String subscrip * * */ - public static SubscriberApi create() throws IOException { + public static final SubscriberApi create() throws IOException { return create(SubscriberSettings.create()); } @@ -195,7 +173,7 @@ public static SubscriberApi create() throws IOException { * * */ - public static SubscriberApi create(SubscriberSettings settings) throws IOException { + public static final SubscriberApi create(SubscriberSettings settings) throws IOException { return new SubscriberApi(settings); } @@ -221,19 +199,17 @@ protected SubscriberApi(SubscriberSettings settings) throws IOException { this.pullCallable = settings.pullMethod().build(settings); this.modifyPushConfigCallable = settings.modifyPushConfigMethod().build(settings); - closeables.add( - new Closeable() { - @Override - public void close() throws IOException { - channel.shutdown(); - } - }); + if (settings.shouldAutoCloseChannel()) { + closeables.add( + new Closeable() { + @Override + public void close() throws IOException { + channel.shutdown(); + } + }); + } } - // ============= - // Service Calls - // ============= - // ----- createSubscription ----- // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. @@ -277,7 +253,7 @@ public void close() throws IOException { * * If this parameter is not set, the default value of 10 seconds is used. */ - public Subscription createSubscription( + public final Subscription createSubscription( String name, String topic, PushConfig pushConfig, int ackDeadlineSeconds) { Subscription request = Subscription.newBuilder() @@ -320,7 +296,7 @@ public Subscription createSubscription(Subscription request) { * * */ - public ApiCallable createSubscriptionCallable() { + public final ApiCallable createSubscriptionCallable() { return createSubscriptionCallable; } @@ -338,7 +314,7 @@ public ApiCallable createSubscriptionCallable() { * * @param subscription The name of the subscription to get. */ - public Subscription getSubscription(String subscription) { + public final Subscription getSubscription(String subscription) { GetSubscriptionRequest request = GetSubscriptionRequest.newBuilder().setSubscription(subscription).build(); @@ -371,7 +347,7 @@ private Subscription getSubscription(GetSubscriptionRequest request) { * * */ - public ApiCallable getSubscriptionCallable() { + public final ApiCallable getSubscriptionCallable() { return getSubscriptionCallable; } @@ -387,7 +363,7 @@ public ApiCallable getSubscriptionCallable * * */ - public Iterable listSubscriptions(String project) { + public final Iterable listSubscriptions(String project) { ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder().setProject(project).build(); return listSubscriptions(request); @@ -405,7 +381,7 @@ public Iterable listSubscriptions(String project) { * * @param request The request object containing all of the parameters for the API call. */ - public Iterable listSubscriptions(ListSubscriptionsRequest request) { + public final Iterable listSubscriptions(ListSubscriptionsRequest request) { return listSubscriptionsIterableCallable().call(request); } @@ -419,7 +395,7 @@ public Iterable listSubscriptions(ListSubscriptionsRequest request * * */ - public ApiCallable> + public final ApiCallable> listSubscriptionsIterableCallable() { return listSubscriptionsIterableCallable; } @@ -434,7 +410,7 @@ public Iterable listSubscriptions(ListSubscriptionsRequest request * * */ - public ApiCallable + public final ApiCallable listSubscriptionsCallable() { return listSubscriptionsCallable; } @@ -454,7 +430,7 @@ public Iterable listSubscriptions(ListSubscriptionsRequest request * * @param subscription The subscription to delete. */ - public void deleteSubscription(String subscription) { + public final void deleteSubscription(String subscription) { DeleteSubscriptionRequest request = DeleteSubscriptionRequest.newBuilder().setSubscription(subscription).build(); @@ -489,7 +465,7 @@ private void deleteSubscription(DeleteSubscriptionRequest request) { * * */ - public ApiCallable deleteSubscriptionCallable() { + public final ApiCallable deleteSubscriptionCallable() { return deleteSubscriptionCallable; } @@ -513,7 +489,8 @@ public ApiCallable deleteSubscriptionCallable( * was made. Specifying zero may immediately make the message available for * another pull request. */ - public void modifyAckDeadline(String subscription, List ackIds, int ackDeadlineSeconds) { + public final void modifyAckDeadline( + String subscription, List ackIds, int ackDeadlineSeconds) { ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() .setSubscription(subscription) @@ -550,7 +527,7 @@ public void modifyAckDeadline(ModifyAckDeadlineRequest request) { * * */ - public ApiCallable modifyAckDeadlineCallable() { + public final ApiCallable modifyAckDeadlineCallable() { return modifyAckDeadlineCallable; } @@ -573,7 +550,7 @@ public ApiCallable modifyAckDeadlineCallable() * @param ackIds The acknowledgment ID for the messages being acknowledged that was returned * by the Pub/Sub system in the `Pull` response. Must not be empty. */ - public void acknowledge(String subscription, List ackIds) { + public final void acknowledge(String subscription, List ackIds) { AcknowledgeRequest request = AcknowledgeRequest.newBuilder().setSubscription(subscription).addAllAckIds(ackIds).build(); @@ -612,7 +589,7 @@ public void acknowledge(AcknowledgeRequest request) { * * */ - public ApiCallable acknowledgeCallable() { + public final ApiCallable acknowledgeCallable() { return acknowledgeCallable; } @@ -636,7 +613,7 @@ public ApiCallable acknowledgeCallable() { * @param maxMessages The maximum number of messages returned for this request. The Pub/Sub * system may return fewer than the number specified. */ - public PullResponse pull(String subscription, boolean returnImmediately, int maxMessages) { + public final PullResponse pull(String subscription, boolean returnImmediately, int maxMessages) { PullRequest request = PullRequest.newBuilder() .setSubscription(subscription) @@ -673,7 +650,7 @@ public PullResponse pull(PullRequest request) { * * */ - public ApiCallable pullCallable() { + public final ApiCallable pullCallable() { return pullCallable; } @@ -699,7 +676,7 @@ public ApiCallable pullCallable() { * messages to be pulled and acknowledged - effectively pausing * the subscription if `Pull` is not called. */ - public void modifyPushConfig(String subscription, PushConfig pushConfig) { + public final void modifyPushConfig(String subscription, PushConfig pushConfig) { ModifyPushConfigRequest request = ModifyPushConfigRequest.newBuilder() .setSubscription(subscription) @@ -739,14 +716,10 @@ public void modifyPushConfig(ModifyPushConfigRequest request) { * * */ - public ApiCallable modifyPushConfigCallable() { + public final ApiCallable modifyPushConfigCallable() { return modifyPushConfigCallable; } - // ======== - // Cleanup - // ======== - /** * Initiates an orderly shutdown in which preexisting calls continue but new calls are immediately * cancelled. @@ -755,7 +728,7 @@ public ApiCallable modifyPushConfigCallable() { * */ @Override - public void close() throws Exception { + public final void close() throws Exception { for (AutoCloseable closeable : closeables) { closeable.close(); } diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java index d9da44aa81f7..e0204a4171f8 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java @@ -37,8 +37,9 @@ import com.google.api.gax.core.ConnectionSettings; import com.google.api.gax.core.RetryParams; import com.google.api.gax.grpc.ApiCallSettings; -import com.google.api.gax.grpc.ApiCallable.ApiCallableBuilder; -import com.google.api.gax.grpc.ApiCallable.PageStreamingApiCallableBuilder; +import com.google.api.gax.grpc.ApiCallable; +import com.google.api.gax.grpc.ApiCallable.Builder; +import com.google.api.gax.grpc.ApiCallable.PageStreamingBuilder; import com.google.api.gax.grpc.PageStreamingDescriptor; import com.google.api.gax.grpc.ServiceApiSettings; import com.google.common.collect.ImmutableList; @@ -59,6 +60,7 @@ import com.google.pubsub.v1.SubscriberGrpc; import com.google.pubsub.v1.Subscription; import io.grpc.Status; +import org.joda.time.Duration; // Manually-added imports: add custom (non-generated) imports after this point. @@ -66,10 +68,6 @@ @javax.annotation.Generated("by GAPIC") public class SubscriberSettings extends ServiceApiSettings { - // ========= - // Constants - // ========= - /** * The default address of the service. * @@ -117,17 +115,17 @@ public class SubscriberSettings extends ServiceApiSettings { RetryParams.newBuilder() .setRetryBackoff( BackoffParams.newBuilder() - .setInitialDelayMillis(100L) + .setInitialDelay(Duration.millis(100L)) .setDelayMultiplier(1.2) - .setMaxDelayMillis(1000L) + .setMaxDelay(Duration.millis(1000L)) .build()) .setTimeoutBackoff( BackoffParams.newBuilder() - .setInitialDelayMillis(300L) - .setDelayMultiplier(1.3) - .setMaxDelayMillis(3000L) + .setInitialDelay(Duration.millis(2000L)) + .setDelayMultiplier(1.5) + .setMaxDelay(Duration.millis(30000L)) .build()) - .setTotalTimeout(30000L) + .setTotalTimeout(Duration.millis(45000L)) .build(); definitions.put("default", params); RETRY_PARAM_DEFINITIONS = definitions.build(); @@ -136,52 +134,50 @@ public class SubscriberSettings extends ServiceApiSettings { private final MethodBuilders methods; private static class MethodBuilders { - private final ApiCallableBuilder createSubscriptionMethod; - private final ApiCallableBuilder getSubscriptionMethod; - private final PageStreamingApiCallableBuilder< + private final ApiCallable.Builder createSubscriptionMethod; + private final ApiCallable.Builder getSubscriptionMethod; + private final ApiCallable.PageStreamingBuilder< ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> listSubscriptionsMethod; - private final ApiCallableBuilder deleteSubscriptionMethod; - private final ApiCallableBuilder modifyAckDeadlineMethod; - private final ApiCallableBuilder acknowledgeMethod; - private final ApiCallableBuilder pullMethod; - private final ApiCallableBuilder modifyPushConfigMethod; + private final ApiCallable.Builder deleteSubscriptionMethod; + private final ApiCallable.Builder modifyAckDeadlineMethod; + private final ApiCallable.Builder acknowledgeMethod; + private final ApiCallable.Builder pullMethod; + private final ApiCallable.Builder modifyPushConfigMethod; private final ImmutableList allMethods; public MethodBuilders() { - createSubscriptionMethod = - new ApiCallableBuilder<>(SubscriberGrpc.METHOD_CREATE_SUBSCRIPTION); + createSubscriptionMethod = new Builder<>(SubscriberGrpc.METHOD_CREATE_SUBSCRIPTION); createSubscriptionMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); createSubscriptionMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - getSubscriptionMethod = new ApiCallableBuilder<>(SubscriberGrpc.METHOD_GET_SUBSCRIPTION); + getSubscriptionMethod = new Builder<>(SubscriberGrpc.METHOD_GET_SUBSCRIPTION); getSubscriptionMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); getSubscriptionMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); listSubscriptionsMethod = - new PageStreamingApiCallableBuilder<>( + new PageStreamingBuilder<>( SubscriberGrpc.METHOD_LIST_SUBSCRIPTIONS, LIST_SUBSCRIPTIONS_PAGE_STR_DESC); listSubscriptionsMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); listSubscriptionsMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - deleteSubscriptionMethod = - new ApiCallableBuilder<>(SubscriberGrpc.METHOD_DELETE_SUBSCRIPTION); + deleteSubscriptionMethod = new Builder<>(SubscriberGrpc.METHOD_DELETE_SUBSCRIPTION); deleteSubscriptionMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); deleteSubscriptionMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - modifyAckDeadlineMethod = new ApiCallableBuilder<>(SubscriberGrpc.METHOD_MODIFY_ACK_DEADLINE); + modifyAckDeadlineMethod = new Builder<>(SubscriberGrpc.METHOD_MODIFY_ACK_DEADLINE); modifyAckDeadlineMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); modifyAckDeadlineMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - acknowledgeMethod = new ApiCallableBuilder<>(SubscriberGrpc.METHOD_ACKNOWLEDGE); + acknowledgeMethod = new Builder<>(SubscriberGrpc.METHOD_ACKNOWLEDGE); acknowledgeMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); acknowledgeMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - pullMethod = new ApiCallableBuilder<>(SubscriberGrpc.METHOD_PULL); + pullMethod = new Builder<>(SubscriberGrpc.METHOD_PULL); pullMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); pullMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - modifyPushConfigMethod = new ApiCallableBuilder<>(SubscriberGrpc.METHOD_MODIFY_PUSH_CONFIG); + modifyPushConfigMethod = new Builder<>(SubscriberGrpc.METHOD_MODIFY_PUSH_CONFIG); modifyPushConfigMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); modifyPushConfigMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); @@ -200,10 +196,6 @@ public MethodBuilders() { } } - // =============== - // Factory Methods - // =============== - /** * Constructs an instance of SubscriberSettings with default settings. * @@ -240,7 +232,7 @@ protected SubscriberSettings(MethodBuilders methods) { * * */ - public ApiCallableBuilder createSubscriptionMethod() { + public final ApiCallable.Builder createSubscriptionMethod() { return methods.createSubscriptionMethod; } @@ -250,7 +242,7 @@ public ApiCallableBuilder createSubscriptionMethod() * * */ - public ApiCallableBuilder getSubscriptionMethod() { + public final ApiCallable.Builder getSubscriptionMethod() { return methods.getSubscriptionMethod; } @@ -260,7 +252,7 @@ public ApiCallableBuilder getSubscriptionM * * */ - public PageStreamingApiCallableBuilder< + public final ApiCallable.PageStreamingBuilder< ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> listSubscriptionsMethod() { return methods.listSubscriptionsMethod; @@ -272,7 +264,7 @@ public ApiCallableBuilder getSubscriptionM * * */ - public ApiCallableBuilder deleteSubscriptionMethod() { + public final ApiCallable.Builder deleteSubscriptionMethod() { return methods.deleteSubscriptionMethod; } @@ -282,7 +274,7 @@ public ApiCallableBuilder deleteSubscriptionMe * * */ - public ApiCallableBuilder modifyAckDeadlineMethod() { + public final ApiCallable.Builder modifyAckDeadlineMethod() { return methods.modifyAckDeadlineMethod; } @@ -292,7 +284,7 @@ public ApiCallableBuilder modifyAckDeadlineMeth * * */ - public ApiCallableBuilder acknowledgeMethod() { + public final ApiCallable.Builder acknowledgeMethod() { return methods.acknowledgeMethod; } @@ -302,7 +294,7 @@ public ApiCallableBuilder acknowledgeMethod() { * * */ - public ApiCallableBuilder pullMethod() { + public final ApiCallable.Builder pullMethod() { return methods.pullMethod; } @@ -312,7 +304,7 @@ public ApiCallableBuilder pullMethod() { * * */ - public ApiCallableBuilder modifyPushConfigMethod() { + public final ApiCallable.Builder modifyPushConfigMethod() { return methods.modifyPushConfigMethod; } diff --git a/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/v1/PublisherApiTest.java b/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/v1/PublisherApiTest.java index c25ca51ee713..dac4be9ae8fc 100644 --- a/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/v1/PublisherApiTest.java +++ b/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/v1/PublisherApiTest.java @@ -14,8 +14,6 @@ package com.google.gcloud.pubsub.spi.v1; -import com.google.api.gax.core.BackoffParams; -import com.google.api.gax.core.RetryParams; import com.google.api.gax.grpc.BundlingSettings; import com.google.gcloud.pubsub.testing.LocalPubsubHelper; import com.google.protobuf.ByteString; @@ -24,13 +22,6 @@ import com.google.pubsub.v1.PushConfig; import com.google.pubsub.v1.Topic; -import io.grpc.ManagedChannel; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - import org.joda.time.Duration; import org.junit.After; import org.junit.AfterClass; @@ -39,6 +30,13 @@ import org.junit.BeforeClass; import org.junit.Test; +import io.grpc.ManagedChannel; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + public class PublisherApiTest { private static LocalPubsubHelper pubsubHelper; private PublisherApi publisherApi; @@ -60,26 +58,8 @@ public static void stopServer() throws IOException, InterruptedException { public void setUp() throws Exception { ManagedChannel channel = pubsubHelper.createChannel(); - RetryParams retryParams = - RetryParams.newBuilder() - .setRetryBackoff( - BackoffParams.newBuilder() - .setInitialDelayMillis(1000L) - .setDelayMultiplier(1.2) - .setMaxDelayMillis(10000L) - .build()) - .setTimeoutBackoff( - BackoffParams.newBuilder() - .setInitialDelayMillis(3000L) - .setDelayMultiplier(1.3) - .setMaxDelayMillis(30000L) - .build()) - .setTotalTimeout(30000L) - .build(); - PublisherSettings publisherSettings = PublisherSettings.create(); - publisherSettings.setRetryParamsOnAllMethods(retryParams); - publisherSettings.provideChannelWith(channel); + publisherSettings.provideChannelWith(channel, true); publisherApi = PublisherApi.create(publisherSettings); BundlingSettings bundlingSettings = @@ -89,14 +69,12 @@ public void setUp() throws Exception { .build(); PublisherSettings bundledPublisherSettings = PublisherSettings.create(); - bundledPublisherSettings.setRetryParamsOnAllMethods(retryParams); - bundledPublisherSettings.provideChannelWith(channel); + bundledPublisherSettings.provideChannelWith(channel, true); bundledPublisherSettings.publishMethod().setBundlingSettings(bundlingSettings); bundledPublisherApi = PublisherApi.create(bundledPublisherSettings); SubscriberSettings subscriberSettings = SubscriberSettings.create(); - subscriberSettings.setRetryParamsOnAllMethods(retryParams); - subscriberSettings.provideChannelWith(channel); + subscriberSettings.provideChannelWith(channel, true); subscriberApi = SubscriberApi.create(subscriberSettings); } @@ -116,18 +94,18 @@ public void tearDown() throws Exception { @Test public void testCreateTopic() throws Exception { - String topicName = PublisherApi.ResourceNames.formatTopicPath("my-project", "my-topic"); + String topicName = PublisherApi.formatTopicName("my-project", "my-topic"); Topic result = publisherApi.createTopic(topicName); Assert.assertEquals(topicName, result.getName()); } @Test public void testPublish() throws Exception { - String topicName = PublisherApi.ResourceNames.formatTopicPath("my-project", "publish-topic"); + String topicName = PublisherApi.formatTopicName("my-project", "publish-topic"); publisherApi.createTopic(topicName); String subscriberName = - SubscriberApi.ResourceNames.formatSubscriptionPath("my-project", "my-subscribe"); + SubscriberApi.formatSubscriptionName("my-project", "my-subscribe"); PushConfig config = PushConfig.getDefaultInstance(); subscriberApi.createSubscription(subscriberName, topicName, config, 5); @@ -143,11 +121,11 @@ public void testPublish() throws Exception { @Test public void testBundledPublish() throws Exception { - String topicName = PublisherApi.ResourceNames.formatTopicPath("my-project", "publish-topic"); + String topicName = PublisherApi.formatTopicName("my-project", "publish-topic"); bundledPublisherApi.createTopic(topicName); String subscriberName = - SubscriberApi.ResourceNames.formatSubscriptionPath("my-project", "my-subscribe"); + SubscriberApi.formatSubscriptionName("my-project", "my-subscribe"); PushConfig config = PushConfig.getDefaultInstance(); subscriberApi.createSubscription(subscriberName, topicName, config, 5); @@ -164,7 +142,7 @@ public void testBundledPublish() throws Exception { @Test public void testGetTopic() throws Exception { - String topicName = PublisherApi.ResourceNames.formatTopicPath("my-project", "fun-topic"); + String topicName = PublisherApi.formatTopicName("my-project", "fun-topic"); publisherApi.createTopic(topicName); Topic result = publisherApi.getTopic(topicName); Assert.assertNotNull(result); @@ -173,10 +151,10 @@ public void testGetTopic() throws Exception { @Test public void testListTopics() throws Exception { - String project1 = PublisherApi.ResourceNames.formatProjectPath("project.1"); - String topicName1 = PublisherApi.ResourceNames.formatTopicPath("project.1", "topic.1"); - String topicName2 = PublisherApi.ResourceNames.formatTopicPath("project.1", "topic.2"); - String topicName3 = PublisherApi.ResourceNames.formatTopicPath("project.2", "topic.3"); + String project1 = PublisherApi.formatProjectName("project.1"); + String topicName1 = PublisherApi.formatTopicName("project.1", "topic.1"); + String topicName2 = PublisherApi.formatTopicName("project.1", "topic.2"); + String topicName3 = PublisherApi.formatTopicName("project.2", "topic.3"); publisherApi.createTopic(topicName1); publisherApi.createTopic(topicName2); publisherApi.createTopic(topicName3); @@ -191,8 +169,8 @@ public void testListTopics() throws Exception { @Test public void testDeleteTopic() throws Exception { - String project = PublisherApi.ResourceNames.formatProjectPath("project.1"); - String topicName = PublisherApi.ResourceNames.formatTopicPath("my-project", "fun-topic"); + String project = PublisherApi.formatProjectName("project.1"); + String topicName = PublisherApi.formatTopicName("my-project", "fun-topic"); publisherApi.createTopic(topicName); publisherApi.deleteTopic(topicName); List topics = new ArrayList<>(); From 700491864f4fb5c1edb975677741b9592523559b Mon Sep 17 00:00:00 2001 From: travis-ci Date: Tue, 29 Mar 2016 01:10:21 +0000 Subject: [PATCH 203/375] Updating version in README files. [ci skip] --- README.md | 6 +++--- gcloud-java-bigquery/README.md | 6 +++--- gcloud-java-contrib/README.md | 6 +++--- gcloud-java-core/README.md | 6 +++--- gcloud-java-datastore/README.md | 6 +++--- gcloud-java-dns/README.md | 6 +++--- gcloud-java-examples/README.md | 6 +++--- gcloud-java-resourcemanager/README.md | 6 +++--- gcloud-java-storage/README.md | 6 +++--- gcloud-java/README.md | 6 +++--- 10 files changed, 30 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 6061d9dd4c8f..d5604dddbbff 100644 --- a/README.md +++ b/README.md @@ -30,16 +30,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java - 0.1.5 + 0.1.6 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java:0.1.5' +compile 'com.google.gcloud:gcloud-java:0.1.6' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java" % "0.1.5" +libraryDependencies += "com.google.gcloud" % "gcloud-java" % "0.1.6" ``` Example Applications diff --git a/gcloud-java-bigquery/README.md b/gcloud-java-bigquery/README.md index 81b5db71bcac..f81cccd5ad44 100644 --- a/gcloud-java-bigquery/README.md +++ b/gcloud-java-bigquery/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-bigquery - 0.1.5 + 0.1.6 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-bigquery:0.1.5' +compile 'com.google.gcloud:gcloud-java-bigquery:0.1.6' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-bigquery" % "0.1.5" +libraryDependencies += "com.google.gcloud" % "gcloud-java-bigquery" % "0.1.6" ``` Example Application diff --git a/gcloud-java-contrib/README.md b/gcloud-java-contrib/README.md index 426417d54e87..b41467934690 100644 --- a/gcloud-java-contrib/README.md +++ b/gcloud-java-contrib/README.md @@ -16,16 +16,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-contrib - 0.1.5 + 0.1.6 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-contrib:0.1.5' +compile 'com.google.gcloud:gcloud-java-contrib:0.1.6' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-contrib" % "0.1.5" +libraryDependencies += "com.google.gcloud" % "gcloud-java-contrib" % "0.1.6" ``` Java Versions diff --git a/gcloud-java-core/README.md b/gcloud-java-core/README.md index fc5f481f8ec3..1ee96b950471 100644 --- a/gcloud-java-core/README.md +++ b/gcloud-java-core/README.md @@ -19,16 +19,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-core - 0.1.5 + 0.1.6 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-core:0.1.5' +compile 'com.google.gcloud:gcloud-java-core:0.1.6' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-core" % "0.1.5" +libraryDependencies += "com.google.gcloud" % "gcloud-java-core" % "0.1.6" ``` Troubleshooting diff --git a/gcloud-java-datastore/README.md b/gcloud-java-datastore/README.md index 0d89a0a07e3e..1025de79f63d 100644 --- a/gcloud-java-datastore/README.md +++ b/gcloud-java-datastore/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-datastore - 0.1.5 + 0.1.6 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-datastore:0.1.5' +compile 'com.google.gcloud:gcloud-java-datastore:0.1.6' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-datastore" % "0.1.5" +libraryDependencies += "com.google.gcloud" % "gcloud-java-datastore" % "0.1.6" ``` Example Application diff --git a/gcloud-java-dns/README.md b/gcloud-java-dns/README.md index d2e4c85b3b76..a01282f16c5d 100644 --- a/gcloud-java-dns/README.md +++ b/gcloud-java-dns/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-dns - 0.1.5 + 0.1.6 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-dns:0.1.5' +compile 'com.google.gcloud:gcloud-java-dns:0.1.6' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-dns" % "0.1.5" +libraryDependencies += "com.google.gcloud" % "gcloud-java-dns" % "0.1.6" ``` Example Application diff --git a/gcloud-java-examples/README.md b/gcloud-java-examples/README.md index 8084cee562f0..45658e37323e 100644 --- a/gcloud-java-examples/README.md +++ b/gcloud-java-examples/README.md @@ -19,16 +19,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-examples - 0.1.5 + 0.1.6 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-examples:0.1.5' +compile 'com.google.gcloud:gcloud-java-examples:0.1.6' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-examples" % "0.1.5" +libraryDependencies += "com.google.gcloud" % "gcloud-java-examples" % "0.1.6" ``` To run examples from your command line: diff --git a/gcloud-java-resourcemanager/README.md b/gcloud-java-resourcemanager/README.md index a2539df7adab..9d142fc558ea 100644 --- a/gcloud-java-resourcemanager/README.md +++ b/gcloud-java-resourcemanager/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-resourcemanager - 0.1.5 + 0.1.6 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-resourcemanager:0.1.5' +compile 'com.google.gcloud:gcloud-java-resourcemanager:0.1.6' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-resourcemanager" % "0.1.5" +libraryDependencies += "com.google.gcloud" % "gcloud-java-resourcemanager" % "0.1.6" ``` Example Application diff --git a/gcloud-java-storage/README.md b/gcloud-java-storage/README.md index 0ee05b31c10c..962b90c82b34 100644 --- a/gcloud-java-storage/README.md +++ b/gcloud-java-storage/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-storage - 0.1.5 + 0.1.6 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-storage:0.1.5' +compile 'com.google.gcloud:gcloud-java-storage:0.1.6' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-storage" % "0.1.5" +libraryDependencies += "com.google.gcloud" % "gcloud-java-storage" % "0.1.6" ``` Example Application diff --git a/gcloud-java/README.md b/gcloud-java/README.md index e296d0c0c565..c898da5d5f72 100644 --- a/gcloud-java/README.md +++ b/gcloud-java/README.md @@ -27,16 +27,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java - 0.1.5 + 0.1.6 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java:0.1.5' +compile 'com.google.gcloud:gcloud-java:0.1.6' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java" % "0.1.5" +libraryDependencies += "com.google.gcloud" % "gcloud-java" % "0.1.6" ``` Troubleshooting From d2dc5e73dbc5484d0014074c27265e294e3b8bbf Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 28 Mar 2016 18:33:20 -0700 Subject: [PATCH 204/375] Update version to 0.1.7-SNAPSHOT --- gcloud-java-bigquery/pom.xml | 2 +- gcloud-java-contrib/pom.xml | 2 +- gcloud-java-core/pom.xml | 2 +- gcloud-java-datastore/pom.xml | 2 +- gcloud-java-dns/pom.xml | 2 +- gcloud-java-examples/pom.xml | 2 +- gcloud-java-resourcemanager/pom.xml | 2 +- gcloud-java-storage/pom.xml | 2 +- gcloud-java/pom.xml | 2 +- pom.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/gcloud-java-bigquery/pom.xml b/gcloud-java-bigquery/pom.xml index cd7883bccaab..952e75899de7 100644 --- a/gcloud-java-bigquery/pom.xml +++ b/gcloud-java-bigquery/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.6 + 0.1.7-SNAPSHOT gcloud-java-bigquery diff --git a/gcloud-java-contrib/pom.xml b/gcloud-java-contrib/pom.xml index 33cdb552411c..c1a0eaad9008 100644 --- a/gcloud-java-contrib/pom.xml +++ b/gcloud-java-contrib/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.6 + 0.1.7-SNAPSHOT gcloud-java-contrib diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml index 51d6baf213a9..13e170e061ee 100644 --- a/gcloud-java-core/pom.xml +++ b/gcloud-java-core/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.6 + 0.1.7-SNAPSHOT gcloud-java-core diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index e97a2b943582..7110d8de3947 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.6 + 0.1.7-SNAPSHOT gcloud-java-datastore diff --git a/gcloud-java-dns/pom.xml b/gcloud-java-dns/pom.xml index 68c46c909f2a..66dc1e54752e 100644 --- a/gcloud-java-dns/pom.xml +++ b/gcloud-java-dns/pom.xml @@ -13,7 +13,7 @@ com.google.gcloud gcloud-java-pom - 0.1.6 + 0.1.7-SNAPSHOT gcloud-java-dns diff --git a/gcloud-java-examples/pom.xml b/gcloud-java-examples/pom.xml index 7b23f7ebe48d..15bb536916f4 100644 --- a/gcloud-java-examples/pom.xml +++ b/gcloud-java-examples/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.6 + 0.1.7-SNAPSHOT gcloud-java-examples diff --git a/gcloud-java-resourcemanager/pom.xml b/gcloud-java-resourcemanager/pom.xml index d428d4a937fc..f8a2697c23b5 100644 --- a/gcloud-java-resourcemanager/pom.xml +++ b/gcloud-java-resourcemanager/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.6 + 0.1.7-SNAPSHOT gcloud-java-resourcemanager diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml index 59b4f9a55245..37f4d00991a3 100644 --- a/gcloud-java-storage/pom.xml +++ b/gcloud-java-storage/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.6 + 0.1.7-SNAPSHOT gcloud-java-storage diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml index 2e6249a20b1a..2a1720fcd300 100644 --- a/gcloud-java/pom.xml +++ b/gcloud-java/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.6 + 0.1.7-SNAPSHOT diff --git a/pom.xml b/pom.xml index 02061658a8be..7b1c7d31a069 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.gcloud gcloud-java-pom pom - 0.1.6 + 0.1.7-SNAPSHOT GCloud Java https://github.com/GoogleCloudPlatform/gcloud-java From 4ee0e3201df3da62f8d7a4a01a8453ccaacebddd Mon Sep 17 00:00:00 2001 From: Arie Ozarov Date: Mon, 28 Mar 2016 19:28:25 -0700 Subject: [PATCH 205/375] update pom.xml to include DNS in javadoc groups --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 7b1c7d31a069..4c53e54560c2 100644 --- a/pom.xml +++ b/pom.xml @@ -404,7 +404,7 @@ Test helpers packages - com.google.gcloud.bigquery.testing:com.google.gcloud.datastore.testing:com.google.gcloud.resourcemanager.testing:com.google.gcloud.storage.testing + com.google.gcloud.bigquery.testing:com.google.gcloud.datastore.testing:com.google.gcloud.dns.testing:com.google.gcloud.resourcemanager.testing:com.google.gcloud.storage.testing Example packages @@ -412,7 +412,7 @@ SPI packages - com.google.gcloud.spi:com.google.gcloud.bigquery.spi:com.google.gcloud.datastore.spi:com.google.gcloud.resourcemanager.spi:com.google.gcloud.storage.spi + com.google.gcloud.spi:com.google.gcloud.bigquery.spi:com.google.gcloud.datastore.spi:com.google.gcloud.dns.spi:com.google.gcloud.resourcemanager.spi:com.google.gcloud.storage.spi From 7849e6ea7dcbb5c4d38fe7c6278e67ed308a6177 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 29 Mar 2016 08:10:33 -0700 Subject: [PATCH 206/375] Add pkg info for dns --- .../gcloud/dns/testing/package-info.java | 36 +++++++++++++++++++ .../resourcemanager/testing/package-info.java | 5 +-- 2 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/package-info.java diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/package-info.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/package-info.java new file mode 100644 index 000000000000..a0a0c593c2b7 --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/package-info.java @@ -0,0 +1,36 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +/** + * A testing helper for Google Cloud DNS. + * + *

      A simple usage example: + * Before the test: + *

       {@code
      + * // Minimum delay before processing change requests (in ms). Setting the delay to 0 makes change
      + * // request processing synchronous.
      + * long delay = 0;
      + * LocalDnsHelper dnsHelper = LocalDnsHelper.create(delay);
      + * Dns dns = dnsHelper.options().service();
      + * dnsHelper.start();
      + * }
      + * + *

      After the test: + *

       {@code
      + * dnsHelper.stop();
      + * }
      + */ +package com.google.gcloud.dns.testing; diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/package-info.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/package-info.java index 7e5519f7d085..b0165c1ddd9d 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/package-info.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/package-info.java @@ -22,11 +22,12 @@ *
       {@code
        * LocalResourceManagerHelper resourceManagerHelper = LocalResourceManagerHelper.create();
        * ResourceManager resourceManager = resourceManagerHelper.options().service();
      - * } 
      + * resourceManagerHelper.start(); + * }
    * *

    After the test: *

     {@code
      * resourceManagerHelper.stop();
    - * } 
    + * }
    */ package com.google.gcloud.resourcemanager.testing; From 712b255f40bfd67128edd4f2b287c7a7193156fa Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 29 Mar 2016 17:57:35 +0200 Subject: [PATCH 207/375] Add common interface for field selectors --- .../com/google/gcloud/bigquery/BigQuery.java | 66 +++++-------- .../com/google/gcloud/bigquery/Option.java | 24 ++++- .../java/com/google/gcloud/FieldSelector.java | 30 ++++++ .../com/google/gcloud/dns/AbstractOption.java | 21 ++++ .../main/java/com/google/gcloud/dns/Dns.java | 97 +++++++------------ .../google/gcloud/resourcemanager/Option.java | 21 ++++ .../resourcemanager/ResourceManager.java | 27 +++--- .../com/google/gcloud/storage/Option.java | 21 ++++ .../com/google/gcloud/storage/Storage.java | 50 ++++------ 9 files changed, 205 insertions(+), 152 deletions(-) create mode 100644 gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java index 14e324a43370..a0724b2026b2 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java @@ -19,16 +19,14 @@ import static com.google.common.base.Preconditions.checkArgument; import com.google.common.base.Function; -import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; -import com.google.common.collect.Sets; +import com.google.gcloud.FieldSelector; import com.google.gcloud.Page; import com.google.gcloud.Service; import com.google.gcloud.bigquery.spi.BigQueryRpc; import java.util.List; -import java.util.Set; /** * An interface for Google Cloud BigQuery. @@ -43,7 +41,7 @@ public interface BigQuery extends Service { * @see Dataset * Resource */ - enum DatasetField { + enum DatasetField implements FieldSelector { ACCESS("access"), CREATION_TIME("creationTime"), DATASET_REFERENCE("datasetReference"), @@ -56,24 +54,19 @@ enum DatasetField { LOCATION("location"), SELF_LINK("selfLink"); + static final List REQUIRED_FIELDS = + ImmutableList.of(DATASET_REFERENCE); + private final String selector; DatasetField(String selector) { this.selector = selector; } + @Override public String selector() { return selector; } - - static String selector(DatasetField... fields) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); - fieldStrings.add(DATASET_REFERENCE.selector()); - for (DatasetField field : fields) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } } /** @@ -82,7 +75,7 @@ static String selector(DatasetField... fields) { * @see Table * Resource */ - enum TableField { + enum TableField implements FieldSelector { CREATION_TIME("creationTime"), DESCRIPTION("description"), ETAG("etag"), @@ -101,25 +94,19 @@ enum TableField { TYPE("type"), VIEW("view"); + static final List REQUIRED_FIELDS = + ImmutableList.of(TABLE_REFERENCE, TYPE); + private final String selector; TableField(String selector) { this.selector = selector; } + @Override public String selector() { return selector; } - - static String selector(TableField... fields) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 2); - fieldStrings.add(TABLE_REFERENCE.selector()); - fieldStrings.add(TYPE.selector()); - for (TableField field : fields) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } } /** @@ -128,7 +115,7 @@ static String selector(TableField... fields) { * @see Job Resource * */ - enum JobField { + enum JobField implements FieldSelector { CONFIGURATION("configuration"), ETAG("etag"), ID("id"), @@ -138,25 +125,19 @@ enum JobField { STATUS("status"), USER_EMAIL("user_email"); + static final List REQUIRED_FIELDS = + ImmutableList.of(JOB_REFERENCE, CONFIGURATION); + private final String selector; JobField(String selector) { this.selector = selector; } + @Override public String selector() { return selector; } - - static String selector(JobField... fields) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 2); - fieldStrings.add(JOB_REFERENCE.selector()); - fieldStrings.add(CONFIGURATION.selector()); - for (JobField field : fields) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } } /** @@ -210,7 +191,8 @@ private DatasetOption(BigQueryRpc.Option option, Object value) { * returned, even if not specified. */ public static DatasetOption fields(DatasetField... fields) { - return new DatasetOption(BigQueryRpc.Option.FIELDS, DatasetField.selector(fields)); + return new DatasetOption(BigQueryRpc.Option.FIELDS, + selector(DatasetField.REQUIRED_FIELDS, fields)); } } @@ -279,7 +261,8 @@ private TableOption(BigQueryRpc.Option option, Object value) { * of {@link Table#definition()}) are always returned, even if not specified. */ public static TableOption fields(TableField... fields) { - return new TableOption(BigQueryRpc.Option.FIELDS, TableField.selector(fields)); + return new TableOption(BigQueryRpc.Option.FIELDS, + selector(TableField.REQUIRED_FIELDS, fields)); } } @@ -376,9 +359,9 @@ public static JobListOption pageToken(String pageToken) { * listing jobs. */ public static JobListOption fields(JobField... fields) { - String selector = JobField.selector(fields); - StringBuilder builder = new StringBuilder(); - builder.append("etag,jobs(").append(selector).append(",state,errorResult),nextPageToken"); + StringBuilder builder = + selector(new StringBuilder().append("etag,jobs("), JobField.REQUIRED_FIELDS, fields) + .append(",state,errorResult),nextPageToken"); return new JobListOption(BigQueryRpc.Option.FIELDS, builder.toString()); } } @@ -402,7 +385,8 @@ private JobOption(BigQueryRpc.Option option, Object value) { * returned, even if not specified. */ public static JobOption fields(JobField... fields) { - return new JobOption(BigQueryRpc.Option.FIELDS, JobField.selector(fields)); + return new JobOption(BigQueryRpc.Option.FIELDS, + Option.selector(JobField.REQUIRED_FIELDS, fields)); } } diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Option.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Option.java index 3fdc27ecab99..9b123fc1c89c 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Option.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Option.java @@ -18,11 +18,16 @@ import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.base.Joiner; import com.google.common.base.MoreObjects; +import com.google.common.collect.Sets; +import com.google.gcloud.FieldSelector; import com.google.gcloud.bigquery.spi.BigQueryRpc; import java.io.Serializable; +import java.util.List; import java.util.Objects; +import java.util.Set; /** * Base class for BigQuery operation option. @@ -53,8 +58,7 @@ public boolean equals(Object obj) { return false; } Option other = (Option) obj; - return Objects.equals(rpcOption, other.rpcOption) - && Objects.equals(value, other.value); + return Objects.equals(rpcOption, other.rpcOption) && Objects.equals(value, other.value); } @Override @@ -69,4 +73,20 @@ public String toString() { .add("value", value) .toString(); } + + static String selector(List required, FieldSelector... others) { + Set fieldStrings = Sets.newHashSetWithExpectedSize(required.size() + others.length); + for (FieldSelector field : required) { + fieldStrings.add(field.selector()); + } + for (FieldSelector field : others) { + fieldStrings.add(field.selector()); + } + return Joiner.on(',').join(fieldStrings); + } + + static StringBuilder selector(StringBuilder partialSelector, List required, + FieldSelector... others) { + return partialSelector.append(selector(required, others)); + } } diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java b/gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java new file mode 100644 index 000000000000..358c4d4798f6 --- /dev/null +++ b/gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java @@ -0,0 +1,30 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud; + +/** + * Interface for Google Cloud resource's fields. Implementations of this interface can be used to + * select only desired fields when getting or listing Google Cloud resources. + */ +public interface FieldSelector { + + /** + * Returns a string selector. This selector is passed to a Google Cloud service (possibly with + * other field selectors) to specify which resource fields should be returned by an API call. + */ + String selector(); +} diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/AbstractOption.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/AbstractOption.java index e12f7412e687..43dfe69df213 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/AbstractOption.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/AbstractOption.java @@ -18,11 +18,16 @@ import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.base.Joiner; import com.google.common.base.MoreObjects; +import com.google.common.collect.Sets; +import com.google.gcloud.FieldSelector; import com.google.gcloud.dns.spi.DnsRpc; import java.io.Serializable; +import java.util.List; import java.util.Objects; +import java.util.Set; /** * A base class for options. @@ -67,4 +72,20 @@ public String toString() { .add("rpcOption", rpcOption) .toString(); } + + static String selector(List required, FieldSelector... others) { + Set fieldStrings = Sets.newHashSetWithExpectedSize(required.size() + others.length); + for (FieldSelector field : required) { + fieldStrings.add(field.selector()); + } + for (FieldSelector field : others) { + fieldStrings.add(field.selector()); + } + return Joiner.on(',').join(fieldStrings); + } + + static StringBuilder selector(StringBuilder partialSelector, List required, + FieldSelector... others) { + return partialSelector.append(selector(required, others)); + } } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index f2b42f30a9f6..ee0611279d27 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -16,14 +16,14 @@ package com.google.gcloud.dns; -import com.google.common.base.Joiner; -import com.google.common.collect.Sets; +import com.google.common.collect.ImmutableList; +import com.google.gcloud.FieldSelector; import com.google.gcloud.Page; import com.google.gcloud.Service; import com.google.gcloud.dns.spi.DnsRpc; import java.io.Serializable; -import java.util.Set; +import java.util.List; /** * An interface for the Google Cloud DNS service. @@ -39,29 +39,23 @@ public interface Dns extends Service { * {@link Dns#getProject(ProjectOption...)}. Project ID is always returned, even if not * specified. */ - enum ProjectField { + enum ProjectField implements FieldSelector { PROJECT_ID("id"), PROJECT_NUMBER("number"), QUOTA("quota"); + static final List REQUIRED_FIELDS = ImmutableList.of(PROJECT_ID); + private final String selector; ProjectField(String selector) { this.selector = selector; } - String selector() { + @Override + public String selector() { return selector; } - - static String selector(ProjectField... fields) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); - fieldStrings.add(PROJECT_ID.selector()); - for (ProjectField field : fields) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } } /** @@ -71,7 +65,7 @@ static String selector(ProjectField... fields) { * {@link Dns#getZone(String, ZoneOption...)}. The name is always returned, even if not * specified. */ - enum ZoneField { + enum ZoneField implements FieldSelector { CREATION_TIME("creationTime"), DESCRIPTION("description"), DNS_NAME("dnsName"), @@ -80,24 +74,18 @@ enum ZoneField { NAME_SERVER_SET("nameServerSet"), NAME_SERVERS("nameServers"); + static final List REQUIRED_FIELDS = ImmutableList.of(NAME); + private final String selector; ZoneField(String selector) { this.selector = selector; } - String selector() { + @Override + public String selector() { return selector; } - - static String selector(ZoneField... fields) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); - fieldStrings.add(NAME.selector()); - for (ZoneField field : fields) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } } /** @@ -107,31 +95,24 @@ static String selector(ZoneField... fields) { * {@link Dns#listRecordSets(String, RecordSetListOption...)}. The name and type are always * returned even if not selected. */ - enum RecordSetField { + enum RecordSetField implements FieldSelector { DNS_RECORDS("rrdatas"), NAME("name"), TTL("ttl"), TYPE("type"); + static final List REQUIRED_FIELDS = ImmutableList.of(NAME, TYPE); + private final String selector; RecordSetField(String selector) { this.selector = selector; } - String selector() { + @Override + public String selector() { return selector; } - - static String selector(RecordSetField... fields) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); - fieldStrings.add(NAME.selector()); - fieldStrings.add(TYPE.selector()); - for (RecordSetField field : fields) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } } /** @@ -141,31 +122,25 @@ static String selector(RecordSetField... fields) { * {@link Dns#applyChangeRequest(String, ChangeRequestInfo, ChangeRequestOption...)} The ID is always * returned even if not selected. */ - enum ChangeRequestField { + enum ChangeRequestField implements FieldSelector { ID("id"), START_TIME("startTime"), STATUS("status"), ADDITIONS("additions"), DELETIONS("deletions"); + static final List REQUIRED_FIELDS = ImmutableList.of(ID); + private final String selector; ChangeRequestField(String selector) { this.selector = selector; } - String selector() { + @Override + public String selector() { return selector; } - - static String selector(ChangeRequestField... fields) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); - fieldStrings.add(ID.selector()); - for (ChangeRequestField field : fields) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } } /** @@ -199,9 +174,8 @@ class RecordSetListOption extends AbstractOption implements Serializable { * of fields that can be used. */ public static RecordSetListOption fields(RecordSetField... fields) { - StringBuilder builder = new StringBuilder(); - builder.append("nextPageToken,rrsets(").append(RecordSetField.selector(fields)) - .append(')'); + StringBuilder builder = selector(new StringBuilder().append("nextPageToken,rrsets("), + RecordSetField.REQUIRED_FIELDS, fields).append(')'); return new RecordSetListOption(DnsRpc.Option.FIELDS, builder.toString()); } @@ -260,7 +234,7 @@ class ZoneOption extends AbstractOption implements Serializable { * specified. {@link ZoneField} provides a list of fields that can be used. */ public static ZoneOption fields(ZoneField... fields) { - return new ZoneOption(DnsRpc.Option.FIELDS, ZoneField.selector(fields)); + return new ZoneOption(DnsRpc.Option.FIELDS, selector(ZoneField.REQUIRED_FIELDS, fields)); } } @@ -283,8 +257,8 @@ class ZoneListOption extends AbstractOption implements Serializable { * specified. {@link ZoneField} provides a list of fields that can be used. */ public static ZoneListOption fields(ZoneField... fields) { - StringBuilder builder = new StringBuilder(); - builder.append("nextPageToken,managedZones(").append(ZoneField.selector(fields)).append(')'); + StringBuilder builder = selector(new StringBuilder().append("nextPageToken,managedZones("), + ZoneField.REQUIRED_FIELDS, fields).append(')'); return new ZoneListOption(DnsRpc.Option.FIELDS, builder.toString()); } @@ -302,7 +276,6 @@ public static ZoneListOption pageToken(String pageToken) { * Restricts the list to only zone with this fully qualified domain name. */ public static ZoneListOption dnsName(String dnsName) { - StringBuilder builder = new StringBuilder(); return new ZoneListOption(DnsRpc.Option.DNS_NAME, dnsName); } @@ -337,7 +310,8 @@ class ProjectOption extends AbstractOption implements Serializable { * can be used. */ public static ProjectOption fields(ProjectField... fields) { - return new ProjectOption(DnsRpc.Option.FIELDS, ProjectField.selector(fields)); + return new ProjectOption(DnsRpc.Option.FIELDS, + selector(ProjectField.REQUIRED_FIELDS, fields)); } } @@ -362,10 +336,8 @@ class ChangeRequestOption extends AbstractOption implements Serializable { * a list of fields that can be used. */ public static ChangeRequestOption fields(ChangeRequestField... fields) { - return new ChangeRequestOption( - DnsRpc.Option.FIELDS, - ChangeRequestField.selector(fields) - ); + return new ChangeRequestOption(DnsRpc.Option.FIELDS, + selector(ChangeRequestField.REQUIRED_FIELDS, fields)); } } @@ -390,9 +362,8 @@ class ChangeRequestListOption extends AbstractOption implements Serializable { * a list of fields that can be used. */ public static ChangeRequestListOption fields(ChangeRequestField... fields) { - StringBuilder builder = new StringBuilder(); - builder.append("nextPageToken,changes(").append(ChangeRequestField.selector(fields)) - .append(')'); + StringBuilder builder = selector(new StringBuilder().append("nextPageToken,changes("), + ChangeRequestField.REQUIRED_FIELDS, fields).append(')'); return new ChangeRequestListOption(DnsRpc.Option.FIELDS, builder.toString()); } diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Option.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Option.java index 72d62d7fc224..3af167db71a5 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Option.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Option.java @@ -18,11 +18,16 @@ import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.base.Joiner; import com.google.common.base.MoreObjects; +import com.google.common.collect.Sets; +import com.google.gcloud.FieldSelector; import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc; import java.io.Serializable; +import java.util.List; import java.util.Objects; +import java.util.Set; /** * Base class for Resource Manager operation options. @@ -69,4 +74,20 @@ public String toString() { .add("value", value) .toString(); } + + static String selector(List required, FieldSelector... others) { + Set fieldStrings = Sets.newHashSetWithExpectedSize(required.size() + others.length); + for (FieldSelector field : required) { + fieldStrings.add(field.selector()); + } + for (FieldSelector field : others) { + fieldStrings.add(field.selector()); + } + return Joiner.on(',').join(fieldStrings); + } + + static StringBuilder selector(StringBuilder partialSelector, List required, + FieldSelector... others) { + return partialSelector.append(selector(required, others)); + } } diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java index 70eeb9c8eb50..595bfab556d6 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java @@ -16,15 +16,14 @@ package com.google.gcloud.resourcemanager; -import com.google.common.base.Joiner; -import com.google.common.collect.Sets; +import com.google.common.collect.ImmutableList; +import com.google.gcloud.FieldSelector; import com.google.gcloud.IamPolicy; import com.google.gcloud.Page; import com.google.gcloud.Service; import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc; import java.util.List; -import java.util.Set; /** * An interface for Google Cloud Resource Manager. @@ -42,7 +41,7 @@ public interface ResourceManager extends Service { * {@link ResourceManager#get} or {@link ResourceManager#list}. Project ID is always returned, * even if not specified. */ - enum ProjectField { + enum ProjectField implements FieldSelector { PROJECT_ID("projectId"), NAME("name"), LABELS("labels"), @@ -50,24 +49,18 @@ enum ProjectField { STATE("lifecycleState"), CREATE_TIME("createTime"); + static final List REQUIRED_FIELDS = ImmutableList.of(PROJECT_ID); + private final String selector; ProjectField(String selector) { this.selector = selector; } + @Override public String selector() { return selector; } - - static String selector(ProjectField... fields) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); - fieldStrings.add(PROJECT_ID.selector()); - for (ProjectField field : fields) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } } /** @@ -90,7 +83,8 @@ private ProjectGetOption(ResourceManagerRpc.Option option, Object value) { * that can be used. */ public static ProjectGetOption fields(ProjectField... fields) { - return new ProjectGetOption(ResourceManagerRpc.Option.FIELDS, ProjectField.selector(fields)); + return new ProjectGetOption(ResourceManagerRpc.Option.FIELDS, + selector(ProjectField.REQUIRED_FIELDS, fields)); } } @@ -163,8 +157,9 @@ public static ProjectListOption pageSize(int pageSize) { * that can be used. */ public static ProjectListOption fields(ProjectField... fields) { - StringBuilder builder = new StringBuilder(); - builder.append("projects(").append(ProjectField.selector(fields)).append("),nextPageToken"); + StringBuilder builder = + selector(new StringBuilder().append("projects("), ProjectField.REQUIRED_FIELDS, fields) + .append("),nextPageToken"); return new ProjectListOption(ResourceManagerRpc.Option.FIELDS, builder.toString()); } } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Option.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Option.java index 65c55da7efc8..1ea0c0561eaa 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Option.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Option.java @@ -18,11 +18,16 @@ import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.base.Joiner; import com.google.common.base.MoreObjects; +import com.google.common.collect.Sets; +import com.google.gcloud.FieldSelector; import com.google.gcloud.storage.spi.StorageRpc; import java.io.Serializable; +import java.util.List; import java.util.Objects; +import java.util.Set; /** * Base class for Storage operation option. @@ -69,4 +74,20 @@ public String toString() { .add("value", value) .toString(); } + + static String selector(List required, FieldSelector... others) { + Set fieldStrings = Sets.newHashSetWithExpectedSize(required.size() + others.length); + for (FieldSelector field : required) { + fieldStrings.add(field.selector()); + } + for (FieldSelector field : others) { + fieldStrings.add(field.selector()); + } + return Joiner.on(',').join(fieldStrings); + } + + static StringBuilder selector(StringBuilder partialSelector, List required, + FieldSelector... others) { + return partialSelector.append(selector(required, others)); + } } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index 78f421e94e52..eb51e9d0f6c1 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -19,13 +19,12 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; -import com.google.common.collect.Sets; import com.google.gcloud.AuthCredentials; import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials; +import com.google.gcloud.FieldSelector; import com.google.gcloud.Page; import com.google.gcloud.ReadChannel; import com.google.gcloud.Service; @@ -38,7 +37,6 @@ import java.net.URL; import java.util.Arrays; import java.util.Collections; -import java.util.HashSet; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; @@ -74,7 +72,7 @@ String entry() { } } - enum BucketField { + enum BucketField implements FieldSelector { ID("id"), SELF_LINK("selfLink"), NAME("name"), @@ -90,27 +88,21 @@ enum BucketField { STORAGE_CLASS("storageClass"), ETAG("etag"); + static final List REQUIRED_FIELDS = ImmutableList.of(NAME); + private final String selector; BucketField(String selector) { this.selector = selector; } + @Override public String selector() { return selector; } - - static String selector(BucketField... fields) { - HashSet fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); - fieldStrings.add(NAME.selector()); - for (BucketField field : fields) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } } - enum BlobField { + enum BlobField implements FieldSelector { ACL("acl"), BUCKET("bucket"), CACHE_CONTROL("cacheControl"), @@ -136,25 +128,19 @@ enum BlobField { TIME_DELETED("timeDeleted"), UPDATED("updated"); + static final List REQUIRED_FIELDS = + ImmutableList.of(BUCKET, NAME); + private final String selector; BlobField(String selector) { this.selector = selector; } + @Override public String selector() { return selector; } - - static String selector(BlobField... fields) { - HashSet fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 2); - fieldStrings.add(BUCKET.selector()); - fieldStrings.add(NAME.selector()); - for (BlobField field : fields) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } } /** @@ -269,7 +255,8 @@ public static BucketGetOption metagenerationNotMatch(long metageneration) { * specified. */ public static BucketGetOption fields(BucketField... fields) { - return new BucketGetOption(StorageRpc.Option.FIELDS, BucketField.selector(fields)); + return new BucketGetOption(StorageRpc.Option.FIELDS, + selector(BucketField.REQUIRED_FIELDS, fields)); } } @@ -609,7 +596,8 @@ public static BlobGetOption metagenerationNotMatch(long metageneration) { * specified. */ public static BlobGetOption fields(BlobField... fields) { - return new BlobGetOption(StorageRpc.Option.FIELDS, BlobField.selector(fields)); + return new BlobGetOption(StorageRpc.Option.FIELDS, + selector(BlobField.REQUIRED_FIELDS, fields)); } } @@ -653,8 +641,9 @@ public static BucketListOption prefix(String prefix) { * specified. */ public static BucketListOption fields(BucketField... fields) { - StringBuilder builder = new StringBuilder(); - builder.append("items(").append(BucketField.selector(fields)).append("),nextPageToken"); + StringBuilder builder = + selector(new StringBuilder().append("items("), BucketField.REQUIRED_FIELDS, fields) + .append("),nextPageToken"); return new BucketListOption(StorageRpc.Option.FIELDS, builder.toString()); } } @@ -722,8 +711,9 @@ public static BlobListOption versions(boolean versions) { * specified. */ public static BlobListOption fields(BlobField... fields) { - StringBuilder builder = new StringBuilder(); - builder.append("items(").append(BlobField.selector(fields)).append("),nextPageToken"); + StringBuilder builder = + selector(new StringBuilder().append("items("), BlobField.REQUIRED_FIELDS, fields) + .append("),nextPageToken"); return new BlobListOption(StorageRpc.Option.FIELDS, builder.toString()); } } From 69476eb1a3f0e952df5a750f691f36cd600c2d60 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 29 Mar 2016 08:19:12 -0700 Subject: [PATCH 208/375] Add comment about releasing new modules --- RELEASING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RELEASING.md b/RELEASING.md index 5e2d6202062e..81a7bcd06129 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -7,8 +7,8 @@ Most of the release process is handled by the `after_success.sh` script, trigger 1. Run `utilities/update_pom_version.sh` from the repository's base directory. This script takes an optional argument denoting the new version. By default, if the current version is X.Y.Z-SNAPSHOT, the script will update the version in all the pom.xml files to X.Y.Z. If desired, another version can be supplied via command line argument instead. -2. Create a PR to update the pom.xml version. -The PR should look something like [#225](https://github.com/GoogleCloudPlatform/gcloud-java/pull/225). After this PR is merged into GoogleCloudPlatform/gcloud-java, Travis CI will push a new website to GoogleCloudPlatform/gh-pages, push a new artifact to the Maven Central Repository, and update versions in the README files. +2. Create a PR to update the pom.xml version. If releasing a new client library, this PR should also update javadoc grouping in the base directory's [pom.xml](./pom.xml). +PRs that don't release new modules should look something like [#225](https://github.com/GoogleCloudPlatform/gcloud-java/pull/225). PRs that do release a new module should also add the appropriate packages to the javadoc groups "SPI" and "Test helpers", as shown in [#802](https://github.com/GoogleCloudPlatform/gcloud-java/pull/802) for `gcloud-java-dns`. After this PR is merged into GoogleCloudPlatform/gcloud-java, Travis CI will push a new website to GoogleCloudPlatform/gh-pages, push a new artifact to the Maven Central Repository, and update versions in the README files. 3. Before moving on, verify that the artifacts have successfully been pushed to the Maven Central Repository. Open Travis CI, click the ["Build History" tab](https://travis-ci.org/GoogleCloudPlatform/gcloud-java/builds), and open the second build's logs for Step 2's PR. Be sure that you are not opening the "Pull Request" build logs. When the build finishes, scroll to the end of the log and verify that the artifacts were successfully staged and deployed. You can also search for `gcloud-java` on the [Sonatype website](https://oss.sonatype.org/#nexus-search;quick~gcloud-java) and check the latest version number. If the deployment didn't succeed because of a flaky test, rerun the build. From 489aca2b90f3ecb01dbfa970acd409de3e2b70db Mon Sep 17 00:00:00 2001 From: Shin Fan Date: Tue, 29 Mar 2016 13:55:19 -0700 Subject: [PATCH 209/375] Update pom to fix the dependency issues. - Update grpc-pubsub-v1 version 0.0.2 - Update grpc version to 0.12.0 --- gcloud-java-pubsub/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcloud-java-pubsub/pom.xml b/gcloud-java-pubsub/pom.xml index a695947e3e2c..0723bad68bf3 100644 --- a/gcloud-java-pubsub/pom.xml +++ b/gcloud-java-pubsub/pom.xml @@ -26,7 +26,7 @@ com.google.api.grpc grpc-pubsub-v1 - 0.0.1 + 0.0.0 io.grpc From 24328ed9337ad5525ddeca3e1ab9b9673e15834a Mon Sep 17 00:00:00 2001 From: Shin Fan Date: Tue, 29 Mar 2016 16:53:32 -0700 Subject: [PATCH 210/375] Update the grpc dependency of pubsub java. --- gcloud-java-pubsub/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcloud-java-pubsub/pom.xml b/gcloud-java-pubsub/pom.xml index 0723bad68bf3..18738ac989cd 100644 --- a/gcloud-java-pubsub/pom.xml +++ b/gcloud-java-pubsub/pom.xml @@ -26,12 +26,12 @@ com.google.api.grpc grpc-pubsub-v1 - 0.0.0 + 0.0.2 io.grpc grpc-all - 0.9.0 + 0.12.0 com.google.auto.value From 4d7cb29c0b90a3684b291c1385e79a6024aff2a8 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 29 Mar 2016 19:11:04 -0700 Subject: [PATCH 211/375] Check if record added --- .../src/test/java/com/google/gcloud/dns/it/ITDnsTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java index dd8e21043181..38273cff49d6 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java @@ -593,9 +593,11 @@ public void testInvalidChangeRequest() { RecordSet.builder("subdomain." + zone.dnsName(), RecordSet.Type.A) .records(ImmutableList.of("0.255.1.5")) .build(); + boolean recordAdded = false; try { ChangeRequestInfo validChange = ChangeRequest.builder().add(validA).build(); zone.applyChangeRequest(validChange); + recordAdded = true; try { zone.applyChangeRequest(validChange); fail("Created a record set which already exists."); @@ -648,6 +650,7 @@ public void testInvalidChangeRequest() { assertEquals(400, ex.code()); } } finally { + assertTrue(recordAdded); ChangeRequestInfo deletion = ChangeRequest.builder().delete(validA).build(); ChangeRequest request = zone.applyChangeRequest(deletion); waitForChangeToComplete(zone.name(), request.id()); From 1710a4cc3907a53cec4d1335f8a6b56b3a92b392 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 30 Mar 2016 14:57:00 +0200 Subject: [PATCH 212/375] Refactor field selection and helpers - Add FieldSelector.SelectorHelper with static methods to create selectors - Add SelectorHelperTest - Rename dns.AbstractOption to Option, make other Option classes abstract - Add OptionTest class to resource manager and refactor other OptionTest classes --- .../com/google/gcloud/bigquery/BigQuery.java | 14 ++-- .../com/google/gcloud/bigquery/Option.java | 23 +----- .../gcloud/bigquery/BigQueryImplTest.java | 8 ++- .../google/gcloud/bigquery/OptionTest.java | 41 +++++++++-- .../java/com/google/gcloud/FieldSelector.java | 68 +++++++++++++++++- .../com/google/gcloud/SelectorHelperTest.java | 71 +++++++++++++++++++ .../main/java/com/google/gcloud/dns/Dns.java | 35 +++++---- .../java/com/google/gcloud/dns/DnsImpl.java | 4 +- .../dns/{AbstractOption.java => Option.java} | 29 ++------ ...bstractOptionTest.java => OptionTest.java} | 31 ++++---- .../google/gcloud/resourcemanager/Option.java | 23 +----- .../resourcemanager/ResourceManager.java | 9 ++- .../gcloud/resourcemanager/OptionTest.java | 66 +++++++++++++++++ .../com/google/gcloud/storage/Option.java | 23 +----- .../com/google/gcloud/storage/Storage.java | 17 ++--- .../com/google/gcloud/storage/OptionTest.java | 41 +++++++++-- 16 files changed, 337 insertions(+), 166 deletions(-) create mode 100644 gcloud-java-core/src/test/java/com/google/gcloud/SelectorHelperTest.java rename gcloud-java-dns/src/main/java/com/google/gcloud/dns/{AbstractOption.java => Option.java} (62%) rename gcloud-java-dns/src/test/java/com/google/gcloud/dns/{AbstractOptionTest.java => OptionTest.java} (66%) create mode 100644 gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/OptionTest.java diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java index a0724b2026b2..c23ee2844762 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java @@ -22,6 +22,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.gcloud.FieldSelector; +import com.google.gcloud.FieldSelector.SelectorHelper; import com.google.gcloud.Page; import com.google.gcloud.Service; import com.google.gcloud.bigquery.spi.BigQueryRpc; @@ -192,7 +193,7 @@ private DatasetOption(BigQueryRpc.Option option, Object value) { */ public static DatasetOption fields(DatasetField... fields) { return new DatasetOption(BigQueryRpc.Option.FIELDS, - selector(DatasetField.REQUIRED_FIELDS, fields)); + SelectorHelper.selector(DatasetField.REQUIRED_FIELDS, fields)); } } @@ -262,7 +263,7 @@ private TableOption(BigQueryRpc.Option option, Object value) { */ public static TableOption fields(TableField... fields) { return new TableOption(BigQueryRpc.Option.FIELDS, - selector(TableField.REQUIRED_FIELDS, fields)); + SelectorHelper.selector(TableField.REQUIRED_FIELDS, fields)); } } @@ -359,10 +360,9 @@ public static JobListOption pageToken(String pageToken) { * listing jobs. */ public static JobListOption fields(JobField... fields) { - StringBuilder builder = - selector(new StringBuilder().append("etag,jobs("), JobField.REQUIRED_FIELDS, fields) - .append(",state,errorResult),nextPageToken"); - return new JobListOption(BigQueryRpc.Option.FIELDS, builder.toString()); + return new JobListOption(BigQueryRpc.Option.FIELDS, + SelectorHelper.selector("jobs", JobField.REQUIRED_FIELDS, fields, "state", + "errorResult")); } } @@ -386,7 +386,7 @@ private JobOption(BigQueryRpc.Option option, Object value) { */ public static JobOption fields(JobField... fields) { return new JobOption(BigQueryRpc.Option.FIELDS, - Option.selector(JobField.REQUIRED_FIELDS, fields)); + SelectorHelper.selector(JobField.REQUIRED_FIELDS, fields)); } } diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Option.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Option.java index 9b123fc1c89c..e7ac0d0a8cc4 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Option.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Option.java @@ -18,21 +18,16 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.base.Joiner; import com.google.common.base.MoreObjects; -import com.google.common.collect.Sets; -import com.google.gcloud.FieldSelector; import com.google.gcloud.bigquery.spi.BigQueryRpc; import java.io.Serializable; -import java.util.List; import java.util.Objects; -import java.util.Set; /** * Base class for BigQuery operation option. */ -class Option implements Serializable { +abstract class Option implements Serializable { private static final long serialVersionUID = -6647817677804099207L; @@ -73,20 +68,4 @@ public String toString() { .add("value", value) .toString(); } - - static String selector(List required, FieldSelector... others) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(required.size() + others.length); - for (FieldSelector field : required) { - fieldStrings.add(field.selector()); - } - for (FieldSelector field : others) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } - - static StringBuilder selector(StringBuilder partialSelector, List required, - FieldSelector... others) { - return partialSelector.append(selector(required, others)); - } } diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java index a6f512800024..c7d7cf846ef2 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java @@ -886,12 +886,14 @@ public com.google.api.services.bigquery.model.Job apply(Job job) { assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(jobList.toArray(), Iterables.toArray(page.values(), Job.class)); String selector = (String) capturedOptions.getValue().get(JOB_OPTION_FIELDS.rpcOption()); - assertTrue(selector.contains("etag,jobs(")); + assertTrue(selector.contains("nextPageToken,jobs(")); assertTrue(selector.contains("configuration")); assertTrue(selector.contains("jobReference")); assertTrue(selector.contains("statistics")); - assertTrue(selector.contains("state,errorResult),nextPageToken")); - assertEquals(80, selector.length()); + assertTrue(selector.contains("state")); + assertTrue(selector.contains("errorResult")); + assertTrue(selector.contains(")")); + assertEquals(75, selector.length()); } @Test diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/OptionTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/OptionTest.java index 2c89ececedb8..42f19830fb6c 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/OptionTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/OptionTest.java @@ -17,22 +17,49 @@ package com.google.gcloud.bigquery; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; import com.google.gcloud.bigquery.spi.BigQueryRpc; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; public class OptionTest { + private static final BigQueryRpc.Option RPC_OPTION = BigQueryRpc.Option.PAGE_TOKEN; + private static final BigQueryRpc.Option ANOTHER_RPC_OPTION = BigQueryRpc.Option.FIELDS; + private static final String VALUE = "some value"; + private static final String OTHER_VALUE = "another value"; + private static final Option OPTION = new Option(RPC_OPTION, VALUE) {}; + private static final Option OPTION_EQUALS = new Option(RPC_OPTION, VALUE) {}; + private static final Option OPTION_NOT_EQUALS1 = new Option(RPC_OPTION, OTHER_VALUE) {}; + private static final Option OPTION_NOT_EQUALS2 = new Option(ANOTHER_RPC_OPTION, VALUE) {}; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testEquals() { + assertEquals(OPTION, OPTION_EQUALS); + assertNotEquals(OPTION, OPTION_NOT_EQUALS1); + assertNotEquals(OPTION, OPTION_NOT_EQUALS2); + } + @Test - public void testOption() { - Option option = new Option(BigQueryRpc.Option.PAGE_TOKEN, "token"); - assertEquals(BigQueryRpc.Option.PAGE_TOKEN, option.rpcOption()); - assertEquals("token", option.value()); + public void testHashCode() { + assertEquals(OPTION.hashCode(), OPTION_EQUALS.hashCode()); } - @Test(expected = NullPointerException.class) - public void testNullRpcOption() { - new Option(null, "token"); + @Test + public void testConstructor() { + assertEquals(RPC_OPTION, OPTION.rpcOption()); + assertEquals(VALUE, OPTION.value()); + Option option = new Option(RPC_OPTION, null) {}; + assertEquals(RPC_OPTION, option.rpcOption()); + assertNull(option.value()); + thrown.expect(NullPointerException.class); + new Option(null, VALUE) {}; } } diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java b/gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java index 358c4d4798f6..343f67e3381b 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java @@ -16,9 +16,18 @@ package com.google.gcloud; +import com.google.common.base.Function; +import com.google.common.base.Joiner; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; + +import java.util.Arrays; +import java.util.List; +import java.util.Set; + /** * Interface for Google Cloud resource's fields. Implementations of this interface can be used to - * select only desired fields when getting or listing Google Cloud resources. + * select only desired fields from a returned Google Cloud resource. */ public interface FieldSelector { @@ -27,4 +36,61 @@ public interface FieldSelector { * other field selectors) to specify which resource fields should be returned by an API call. */ String selector(); + + /** + * A helper class used to build composite selectors given a number of fields. This class is not + * supposed to be used directly by users. + */ + class SelectorHelper { + + private SelectorHelper() {} + + private static final Function FIELD_TO_STRING_FUNCTION = + new Function() { + @Override + public String apply(FieldSelector fieldSelector) { + return fieldSelector.selector(); + } + }; + + private static String selector(List required, FieldSelector[] others, + String... extraResourceFields) { + Set fieldStrings = Sets.newHashSetWithExpectedSize(required.size() + others.length); + fieldStrings.addAll(Lists.transform(required, FIELD_TO_STRING_FUNCTION)); + fieldStrings.addAll(Lists.transform(Arrays.asList(others), FIELD_TO_STRING_FUNCTION)); + fieldStrings.addAll(Arrays.asList(extraResourceFields)); + return Joiner.on(',').join(fieldStrings); + } + + /** + * Returns a composite selector given a number of fields. The string selector returned by this + * method can be used for field selection in API calls that return a single resource. This + * method is not supposed to be used directly by users. + */ + public static String selector(List required, FieldSelector... others) { + return selector(required, others, new String[]{}); + } + + /** + * Returns a composite selector given a number of fields and a container name. The string + * selector returned by this method can be used for field selection in API calls that return a + * list of resources. This method is not supposed to be used directly by users. + */ + public static String selector(String containerName, List required, + FieldSelector... others) { + return "nextPageToken," + containerName + '(' + selector(required, others) + ')'; + } + + /** + * Returns a composite selector given a number of fields and a container name. This methods also + * takes an {@code extraResourceFields} parameter to specify some extra fields as strings. The + * string selector returned by this method can be used for field selection in API calls that + * return a list of resources. This method is not supposed to be used directly by users. + */ + public static String selector(String containerName, List required, + FieldSelector[] others, String... extraResourceFields) { + return "nextPageToken," + containerName + '(' + + selector(required, others, extraResourceFields) + ')'; + } + } } diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/SelectorHelperTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/SelectorHelperTest.java new file mode 100644 index 000000000000..2279205539cc --- /dev/null +++ b/gcloud-java-core/src/test/java/com/google/gcloud/SelectorHelperTest.java @@ -0,0 +1,71 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import com.google.common.collect.ImmutableList; +import com.google.gcloud.FieldSelector.SelectorHelper; + +import org.junit.Test; + +import java.util.List; + +public class SelectorHelperTest { + + private static final FieldSelector FIELD1 = new FieldSelector() { + @Override + public String selector() { + return "field1"; + } + }; + private static final FieldSelector FIELD2 = new FieldSelector() { + @Override + public String selector() { + return "field2"; + } + }; + private static final FieldSelector FIELD3 = new FieldSelector() { + @Override + public String selector() { + return "field3"; + } + }; + private static final List REQUIRED_FIELDS = ImmutableList.of(FIELD1, FIELD2); + private static final String CONTAINER = "container"; + + @Test + public void testSelector() { + String selector = SelectorHelper.selector(REQUIRED_FIELDS, FIELD3); + assertTrue(selector.contains("field1")); + assertTrue(selector.contains("field2")); + assertTrue(selector.contains("field3")); + assertEquals(20, selector.length()); + } + + @Test + public void testListSelector() { + String selector = SelectorHelper.selector(CONTAINER, REQUIRED_FIELDS, FIELD3); + assertTrue(selector.startsWith("nextPageToken,container(")); + assertTrue(selector.contains("field1")); + assertTrue(selector.contains("field2")); + assertTrue(selector.contains("field3")); + assertTrue(selector.endsWith(")")); + assertEquals(45, selector.length()); + } +} diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index ee0611279d27..c4b08e31d533 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -18,6 +18,7 @@ import com.google.common.collect.ImmutableList; import com.google.gcloud.FieldSelector; +import com.google.gcloud.FieldSelector.SelectorHelper; import com.google.gcloud.Page; import com.google.gcloud.Service; import com.google.gcloud.dns.spi.DnsRpc; @@ -157,7 +158,7 @@ public String selector() { /** * Class for specifying record set listing options. */ - class RecordSetListOption extends AbstractOption implements Serializable { + class RecordSetListOption extends Option implements Serializable { private static final long serialVersionUID = 1009627025381096098L; @@ -174,9 +175,8 @@ class RecordSetListOption extends AbstractOption implements Serializable { * of fields that can be used. */ public static RecordSetListOption fields(RecordSetField... fields) { - StringBuilder builder = selector(new StringBuilder().append("nextPageToken,rrsets("), - RecordSetField.REQUIRED_FIELDS, fields).append(')'); - return new RecordSetListOption(DnsRpc.Option.FIELDS, builder.toString()); + return new RecordSetListOption(DnsRpc.Option.FIELDS, + SelectorHelper.selector("rrsets", RecordSetField.REQUIRED_FIELDS, fields)); } /** @@ -218,7 +218,7 @@ public static RecordSetListOption type(RecordSet.Type type) { /** * Class for specifying zone field options. */ - class ZoneOption extends AbstractOption implements Serializable { + class ZoneOption extends Option implements Serializable { private static final long serialVersionUID = -8065564464895945037L; @@ -234,14 +234,15 @@ class ZoneOption extends AbstractOption implements Serializable { * specified. {@link ZoneField} provides a list of fields that can be used. */ public static ZoneOption fields(ZoneField... fields) { - return new ZoneOption(DnsRpc.Option.FIELDS, selector(ZoneField.REQUIRED_FIELDS, fields)); + return new ZoneOption(DnsRpc.Option.FIELDS, + SelectorHelper.selector(ZoneField.REQUIRED_FIELDS, fields)); } } /** * Class for specifying zone listing options. */ - class ZoneListOption extends AbstractOption implements Serializable { + class ZoneListOption extends Option implements Serializable { private static final long serialVersionUID = -2830645032124504717L; @@ -257,9 +258,8 @@ class ZoneListOption extends AbstractOption implements Serializable { * specified. {@link ZoneField} provides a list of fields that can be used. */ public static ZoneListOption fields(ZoneField... fields) { - StringBuilder builder = selector(new StringBuilder().append("nextPageToken,managedZones("), - ZoneField.REQUIRED_FIELDS, fields).append(')'); - return new ZoneListOption(DnsRpc.Option.FIELDS, builder.toString()); + return new ZoneListOption(DnsRpc.Option.FIELDS, + SelectorHelper.selector("managedZones", ZoneField.REQUIRED_FIELDS, fields)); } /** @@ -293,7 +293,7 @@ public static ZoneListOption pageSize(int pageSize) { /** * Class for specifying project options. */ - class ProjectOption extends AbstractOption implements Serializable { + class ProjectOption extends Option implements Serializable { private static final long serialVersionUID = 6817937338218847748L; @@ -311,14 +311,14 @@ class ProjectOption extends AbstractOption implements Serializable { */ public static ProjectOption fields(ProjectField... fields) { return new ProjectOption(DnsRpc.Option.FIELDS, - selector(ProjectField.REQUIRED_FIELDS, fields)); + SelectorHelper.selector(ProjectField.REQUIRED_FIELDS, fields)); } } /** * Class for specifying change request field options. */ - class ChangeRequestOption extends AbstractOption implements Serializable { + class ChangeRequestOption extends Option implements Serializable { private static final long serialVersionUID = 1067273695061077782L; @@ -337,14 +337,14 @@ class ChangeRequestOption extends AbstractOption implements Serializable { */ public static ChangeRequestOption fields(ChangeRequestField... fields) { return new ChangeRequestOption(DnsRpc.Option.FIELDS, - selector(ChangeRequestField.REQUIRED_FIELDS, fields)); + SelectorHelper.selector(ChangeRequestField.REQUIRED_FIELDS, fields)); } } /** * Class for specifying change request listing options. */ - class ChangeRequestListOption extends AbstractOption implements Serializable { + class ChangeRequestListOption extends Option implements Serializable { private static final long serialVersionUID = -900209143895376089L; @@ -362,9 +362,8 @@ class ChangeRequestListOption extends AbstractOption implements Serializable { * a list of fields that can be used. */ public static ChangeRequestListOption fields(ChangeRequestField... fields) { - StringBuilder builder = selector(new StringBuilder().append("nextPageToken,changes("), - ChangeRequestField.REQUIRED_FIELDS, fields).append(')'); - return new ChangeRequestListOption(DnsRpc.Option.FIELDS, builder.toString()); + return new ChangeRequestListOption(DnsRpc.Option.FIELDS, + SelectorHelper.selector("changes", ChangeRequestField.REQUIRED_FIELDS, fields)); } /** diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java index 51ab0bd92720..9f4fa2a9d9d1 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java @@ -309,9 +309,9 @@ public com.google.api.services.dns.model.Change call() { } } - private Map optionMap(AbstractOption... options) { + private Map optionMap(Option... options) { Map temp = Maps.newEnumMap(DnsRpc.Option.class); - for (AbstractOption option : options) { + for (Option option : options) { Object prev = temp.put(option.rpcOption(), option.value()); checkArgument(prev == null, "Duplicate option %s", option); } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/AbstractOption.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Option.java similarity index 62% rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/AbstractOption.java rename to gcloud-java-dns/src/main/java/com/google/gcloud/dns/Option.java index 43dfe69df213..fee99898fb24 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/AbstractOption.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Option.java @@ -18,27 +18,22 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.base.Joiner; import com.google.common.base.MoreObjects; -import com.google.common.collect.Sets; -import com.google.gcloud.FieldSelector; import com.google.gcloud.dns.spi.DnsRpc; import java.io.Serializable; -import java.util.List; import java.util.Objects; -import java.util.Set; /** * A base class for options. */ -abstract class AbstractOption implements Serializable { +abstract class Option implements Serializable { private static final long serialVersionUID = -5912727967831484228L; private final Object value; private final DnsRpc.Option rpcOption; - AbstractOption(DnsRpc.Option rpcOption, Object value) { + Option(DnsRpc.Option rpcOption, Object value) { this.rpcOption = checkNotNull(rpcOption); this.value = value; } @@ -53,10 +48,10 @@ DnsRpc.Option rpcOption() { @Override public boolean equals(Object obj) { - if (!(obj instanceof AbstractOption)) { + if (!(obj instanceof Option)) { return false; } - AbstractOption other = (AbstractOption) obj; + Option other = (Option) obj; return Objects.equals(value, other.value) && Objects.equals(rpcOption, other.rpcOption); } @@ -72,20 +67,4 @@ public String toString() { .add("rpcOption", rpcOption) .toString(); } - - static String selector(List required, FieldSelector... others) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(required.size() + others.length); - for (FieldSelector field : required) { - fieldStrings.add(field.selector()); - } - for (FieldSelector field : others) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } - - static StringBuilder selector(StringBuilder partialSelector, List required, - FieldSelector... others) { - return partialSelector.append(selector(required, others)); - } } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/AbstractOptionTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/OptionTest.java similarity index 66% rename from gcloud-java-dns/src/test/java/com/google/gcloud/dns/AbstractOptionTest.java rename to gcloud-java-dns/src/test/java/com/google/gcloud/dns/OptionTest.java index d88ea85c5846..e9906354f963 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/AbstractOptionTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/OptionTest.java @@ -18,24 +18,27 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.fail; +import static org.junit.Assert.assertNull; import com.google.gcloud.dns.spi.DnsRpc; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; -public class AbstractOptionTest { +public class OptionTest { private static final DnsRpc.Option RPC_OPTION = DnsRpc.Option.DNS_TYPE; private static final DnsRpc.Option ANOTHER_RPC_OPTION = DnsRpc.Option.DNS_NAME; private static final String VALUE = "some value"; private static final String OTHER_VALUE = "another value"; - private static final AbstractOption OPTION = new AbstractOption(RPC_OPTION, VALUE) {}; - private static final AbstractOption OPTION_EQUALS = new AbstractOption(RPC_OPTION, VALUE) {}; - private static final AbstractOption OPTION_NOT_EQUALS1 = - new AbstractOption(RPC_OPTION, OTHER_VALUE) {}; - private static final AbstractOption OPTION_NOT_EQUALS2 = - new AbstractOption(ANOTHER_RPC_OPTION, VALUE) {}; + private static final Option OPTION = new Option(RPC_OPTION, VALUE) {}; + private static final Option OPTION_EQUALS = new Option(RPC_OPTION, VALUE) {}; + private static final Option OPTION_NOT_EQUALS1 = new Option(RPC_OPTION, OTHER_VALUE) {}; + private static final Option OPTION_NOT_EQUALS2 = new Option(ANOTHER_RPC_OPTION, VALUE) {}; + + @Rule + public ExpectedException thrown = ExpectedException.none(); @Test public void testEquals() { @@ -53,12 +56,10 @@ public void testHashCode() { public void testConstructor() { assertEquals(RPC_OPTION, OPTION.rpcOption()); assertEquals(VALUE, OPTION.value()); - try { - new AbstractOption(null, VALUE) {}; - fail("Cannot build with empty option."); - } catch (NullPointerException e) { - // expected - } - new AbstractOption(RPC_OPTION, null) {}; // null value is ok + Option option = new Option(RPC_OPTION, null) {}; + assertEquals(RPC_OPTION, option.rpcOption()); + assertNull(option.value()); + thrown.expect(NullPointerException.class); + new Option(null, VALUE) {}; } } diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Option.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Option.java index 3af167db71a5..3df68468f69f 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Option.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Option.java @@ -18,21 +18,16 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.base.Joiner; import com.google.common.base.MoreObjects; -import com.google.common.collect.Sets; -import com.google.gcloud.FieldSelector; import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc; import java.io.Serializable; -import java.util.List; import java.util.Objects; -import java.util.Set; /** * Base class for Resource Manager operation options. */ -class Option implements Serializable { +abstract class Option implements Serializable { private static final long serialVersionUID = 2655177550880762967L; @@ -74,20 +69,4 @@ public String toString() { .add("value", value) .toString(); } - - static String selector(List required, FieldSelector... others) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(required.size() + others.length); - for (FieldSelector field : required) { - fieldStrings.add(field.selector()); - } - for (FieldSelector field : others) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } - - static StringBuilder selector(StringBuilder partialSelector, List required, - FieldSelector... others) { - return partialSelector.append(selector(required, others)); - } } diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java index 595bfab556d6..e000ca69c359 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java @@ -18,6 +18,7 @@ import com.google.common.collect.ImmutableList; import com.google.gcloud.FieldSelector; +import com.google.gcloud.FieldSelector.SelectorHelper; import com.google.gcloud.IamPolicy; import com.google.gcloud.Page; import com.google.gcloud.Service; @@ -84,7 +85,7 @@ private ProjectGetOption(ResourceManagerRpc.Option option, Object value) { */ public static ProjectGetOption fields(ProjectField... fields) { return new ProjectGetOption(ResourceManagerRpc.Option.FIELDS, - selector(ProjectField.REQUIRED_FIELDS, fields)); + SelectorHelper.selector(ProjectField.REQUIRED_FIELDS, fields)); } } @@ -157,10 +158,8 @@ public static ProjectListOption pageSize(int pageSize) { * that can be used. */ public static ProjectListOption fields(ProjectField... fields) { - StringBuilder builder = - selector(new StringBuilder().append("projects("), ProjectField.REQUIRED_FIELDS, fields) - .append("),nextPageToken"); - return new ProjectListOption(ResourceManagerRpc.Option.FIELDS, builder.toString()); + return new ProjectListOption(ResourceManagerRpc.Option.FIELDS, + SelectorHelper.selector("projects", ProjectField.REQUIRED_FIELDS, fields)); } } diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/OptionTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/OptionTest.java new file mode 100644 index 000000000000..729c7a4b8911 --- /dev/null +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/OptionTest.java @@ -0,0 +1,66 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.resourcemanager; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; + +import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class OptionTest { + + private static final ResourceManagerRpc.Option RPC_OPTION = ResourceManagerRpc.Option.FILTER; + private static final ResourceManagerRpc.Option ANOTHER_RPC_OPTION = + ResourceManagerRpc.Option.FIELDS; + private static final String VALUE = "some value"; + private static final String OTHER_VALUE = "another value"; + private static final Option OPTION = new Option(RPC_OPTION, VALUE) {}; + private static final Option OPTION_EQUALS = new Option(RPC_OPTION, VALUE) {}; + private static final Option OPTION_NOT_EQUALS1 = new Option(RPC_OPTION, OTHER_VALUE) {}; + private static final Option OPTION_NOT_EQUALS2 = new Option(ANOTHER_RPC_OPTION, VALUE) {}; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testEquals() { + assertEquals(OPTION, OPTION_EQUALS); + assertNotEquals(OPTION, OPTION_NOT_EQUALS1); + assertNotEquals(OPTION, OPTION_NOT_EQUALS2); + } + + @Test + public void testHashCode() { + assertEquals(OPTION.hashCode(), OPTION_EQUALS.hashCode()); + } + + @Test + public void testConstructor() { + assertEquals(RPC_OPTION, OPTION.rpcOption()); + assertEquals(VALUE, OPTION.value()); + Option option = new Option(RPC_OPTION, null) {}; + assertEquals(RPC_OPTION, option.rpcOption()); + assertNull(option.value()); + thrown.expect(NullPointerException.class); + new Option(null, VALUE) {}; + } +} diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Option.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Option.java index 1ea0c0561eaa..774023eff78b 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Option.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Option.java @@ -18,21 +18,16 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.base.Joiner; import com.google.common.base.MoreObjects; -import com.google.common.collect.Sets; -import com.google.gcloud.FieldSelector; import com.google.gcloud.storage.spi.StorageRpc; import java.io.Serializable; -import java.util.List; import java.util.Objects; -import java.util.Set; /** * Base class for Storage operation option. */ -class Option implements Serializable { +abstract class Option implements Serializable { private static final long serialVersionUID = -73199088766477208L; @@ -74,20 +69,4 @@ public String toString() { .add("value", value) .toString(); } - - static String selector(List required, FieldSelector... others) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(required.size() + others.length); - for (FieldSelector field : required) { - fieldStrings.add(field.selector()); - } - for (FieldSelector field : others) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } - - static StringBuilder selector(StringBuilder partialSelector, List required, - FieldSelector... others) { - return partialSelector.append(selector(required, others)); - } } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index eb51e9d0f6c1..87d82aad686b 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -25,6 +25,7 @@ import com.google.gcloud.AuthCredentials; import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials; import com.google.gcloud.FieldSelector; +import com.google.gcloud.FieldSelector.SelectorHelper; import com.google.gcloud.Page; import com.google.gcloud.ReadChannel; import com.google.gcloud.Service; @@ -256,7 +257,7 @@ public static BucketGetOption metagenerationNotMatch(long metageneration) { */ public static BucketGetOption fields(BucketField... fields) { return new BucketGetOption(StorageRpc.Option.FIELDS, - selector(BucketField.REQUIRED_FIELDS, fields)); + SelectorHelper.selector(BucketField.REQUIRED_FIELDS, fields)); } } @@ -597,7 +598,7 @@ public static BlobGetOption metagenerationNotMatch(long metageneration) { */ public static BlobGetOption fields(BlobField... fields) { return new BlobGetOption(StorageRpc.Option.FIELDS, - selector(BlobField.REQUIRED_FIELDS, fields)); + SelectorHelper.selector(BlobField.REQUIRED_FIELDS, fields)); } } @@ -641,10 +642,8 @@ public static BucketListOption prefix(String prefix) { * specified. */ public static BucketListOption fields(BucketField... fields) { - StringBuilder builder = - selector(new StringBuilder().append("items("), BucketField.REQUIRED_FIELDS, fields) - .append("),nextPageToken"); - return new BucketListOption(StorageRpc.Option.FIELDS, builder.toString()); + return new BucketListOption(StorageRpc.Option.FIELDS, + SelectorHelper.selector("items", BucketField.REQUIRED_FIELDS, fields)); } } @@ -711,10 +710,8 @@ public static BlobListOption versions(boolean versions) { * specified. */ public static BlobListOption fields(BlobField... fields) { - StringBuilder builder = - selector(new StringBuilder().append("items("), BlobField.REQUIRED_FIELDS, fields) - .append("),nextPageToken"); - return new BlobListOption(StorageRpc.Option.FIELDS, builder.toString()); + return new BlobListOption(StorageRpc.Option.FIELDS, + SelectorHelper.selector("items", BlobField.REQUIRED_FIELDS, fields)); } } diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/OptionTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/OptionTest.java index 5924174ab138..08a8e79b2c3b 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/OptionTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/OptionTest.java @@ -17,22 +17,49 @@ package com.google.gcloud.storage; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; import com.google.gcloud.storage.spi.StorageRpc; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; public class OptionTest { + private static final StorageRpc.Option RPC_OPTION = StorageRpc.Option.DELIMITER; + private static final StorageRpc.Option ANOTHER_RPC_OPTION = StorageRpc.Option.FIELDS; + private static final String VALUE = "some value"; + private static final String OTHER_VALUE = "another value"; + private static final Option OPTION = new Option(RPC_OPTION, VALUE) {}; + private static final Option OPTION_EQUALS = new Option(RPC_OPTION, VALUE) {}; + private static final Option OPTION_NOT_EQUALS1 = new Option(RPC_OPTION, OTHER_VALUE) {}; + private static final Option OPTION_NOT_EQUALS2 = new Option(ANOTHER_RPC_OPTION, VALUE) {}; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testEquals() { + assertEquals(OPTION, OPTION_EQUALS); + assertNotEquals(OPTION, OPTION_NOT_EQUALS1); + assertNotEquals(OPTION, OPTION_NOT_EQUALS2); + } + @Test - public void testOption() { - Option option = new Option(StorageRpc.Option.DELIMITER, "/"); - assertEquals(StorageRpc.Option.DELIMITER, option.rpcOption()); - assertEquals("/", option.value()); + public void testHashCode() { + assertEquals(OPTION.hashCode(), OPTION_EQUALS.hashCode()); } - @Test(expected = NullPointerException.class) - public void testIndexOutOfBoundsException() { - new Option(null, "/"); + @Test + public void testConstructor() { + assertEquals(RPC_OPTION, OPTION.rpcOption()); + assertEquals(VALUE, OPTION.value()); + Option option = new Option(RPC_OPTION, null) {}; + assertEquals(RPC_OPTION, option.rpcOption()); + assertNull(option.value()); + thrown.expect(NullPointerException.class); + new Option(null, VALUE) {}; } } From 80268f7f4de379ff03f0b4dabea99d167f5084b2 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Wed, 30 Mar 2016 09:10:35 -0700 Subject: [PATCH 213/375] allow cleanup if record not added --- .../test/java/com/google/gcloud/dns/it/ITDnsTest.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java index 38273cff49d6..c9070f2eddde 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java @@ -650,10 +650,11 @@ public void testInvalidChangeRequest() { assertEquals(400, ex.code()); } } finally { - assertTrue(recordAdded); - ChangeRequestInfo deletion = ChangeRequest.builder().delete(validA).build(); - ChangeRequest request = zone.applyChangeRequest(deletion); - waitForChangeToComplete(zone.name(), request.id()); + if (recordAdded) { + ChangeRequestInfo deletion = ChangeRequest.builder().delete(validA).build(); + ChangeRequest request = zone.applyChangeRequest(deletion); + waitForChangeToComplete(zone.name(), request.id()); + } zone.delete(); } } From acacd1db03ae25c638b68629098cd678d516d65e Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 30 Mar 2016 19:11:07 +0200 Subject: [PATCH 214/375] Update codacy configuration - Disable "Avoid excessively long variable names like" test - Disable "JUnit tests should include assert() or fail()" test - Avoid applying underscore naming rule to test methods --- codacy-conf.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codacy-conf.json b/codacy-conf.json index e8c819684c9c..47998a3870d7 100644 --- a/codacy-conf.json +++ b/codacy-conf.json @@ -1 +1 @@ -{"patterns":[{"patternId":"Custom_Javascript_Scopes","enabled":true},{"patternId":"Custom_Javascript_EvalWith","enabled":true},{"patternId":"Custom_Javascript_TryCatch","enabled":true},{"patternId":"Custom_Scala_NonFatal","enabled":true},{"patternId":"bitwise","enabled":true},{"patternId":"maxparams","enabled":true},{"patternId":"CSSLint_universal_selector","enabled":true},{"patternId":"CSSLint_unqualified_attributes","enabled":true},{"patternId":"CSSLint_zero_units","enabled":true},{"patternId":"CSSLint_overqualified_elements","enabled":true},{"patternId":"CSSLint_shorthand","enabled":true},{"patternId":"CSSLint_duplicate_background_images","enabled":true},{"patternId":"CSSLint_box_model","enabled":true},{"patternId":"CSSLint_compatible_vendor_prefixes","enabled":true},{"patternId":"CSSLint_display_property_grouping","enabled":true},{"patternId":"CSSLint_duplicate_properties","enabled":true},{"patternId":"CSSLint_empty_rules","enabled":true},{"patternId":"CSSLint_errors","enabled":true},{"patternId":"CSSLint_gradients","enabled":true},{"patternId":"CSSLint_important","enabled":true},{"patternId":"CSSLint_known_properties","enabled":true},{"patternId":"CSSLint_text_indent","enabled":true},{"patternId":"CSSLint_unique_headings","enabled":true},{"patternId":"PyLint_E0100","enabled":true},{"patternId":"PyLint_E0101","enabled":true},{"patternId":"PyLint_E0102","enabled":true},{"patternId":"PyLint_E0103","enabled":true},{"patternId":"PyLint_E0104","enabled":true},{"patternId":"PyLint_E0105","enabled":true},{"patternId":"PyLint_E0106","enabled":true},{"patternId":"PyLint_E0107","enabled":true},{"patternId":"PyLint_E0108","enabled":true},{"patternId":"PyLint_E0202","enabled":true},{"patternId":"PyLint_E0203","enabled":true},{"patternId":"PyLint_E0211","enabled":true},{"patternId":"PyLint_E0601","enabled":true},{"patternId":"PyLint_E0603","enabled":true},{"patternId":"PyLint_E0604","enabled":true},{"patternId":"PyLint_E0701","enabled":true},{"patternId":"PyLint_E0702","enabled":true},{"patternId":"PyLint_E0710","enabled":true},{"patternId":"PyLint_E0711","enabled":true},{"patternId":"PyLint_E0712","enabled":true},{"patternId":"PyLint_E1003","enabled":true},{"patternId":"PyLint_E1102","enabled":true},{"patternId":"PyLint_E1111","enabled":true},{"patternId":"PyLint_E1120","enabled":true},{"patternId":"PyLint_E1121","enabled":true},{"patternId":"PyLint_E1123","enabled":true},{"patternId":"PyLint_E1124","enabled":true},{"patternId":"PyLint_E1200","enabled":true},{"patternId":"PyLint_E1201","enabled":true},{"patternId":"PyLint_E1205","enabled":true},{"patternId":"PyLint_E1206","enabled":true},{"patternId":"PyLint_E1300","enabled":true},{"patternId":"PyLint_E1301","enabled":true},{"patternId":"PyLint_E1302","enabled":true},{"patternId":"PyLint_E1303","enabled":true},{"patternId":"PyLint_E1304","enabled":true},{"patternId":"PyLint_E1305","enabled":true},{"patternId":"PyLint_E1306","enabled":true},{"patternId":"rulesets-codesize.xml-CyclomaticComplexity","enabled":true},{"patternId":"rulesets-codesize.xml-NPathComplexity","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessiveMethodLength","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessiveClassLength","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessiveParameterList","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessivePublicCount","enabled":true},{"patternId":"rulesets-codesize.xml-TooManyFields","enabled":true},{"patternId":"rulesets-codesize.xml-TooManyMethods","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessiveClassComplexity","enabled":true},{"patternId":"rulesets-controversial.xml-Superglobals","enabled":true},{"patternId":"rulesets-design.xml-ExitExpression","enabled":true},{"patternId":"rulesets-design.xml-EvalExpression","enabled":true},{"patternId":"rulesets-design.xml-GotoStatement","enabled":true},{"patternId":"rulesets-design.xml-NumberOfChildren","enabled":true},{"patternId":"rulesets-design.xml-DepthOfInheritance","enabled":true},{"patternId":"rulesets-unusedcode.xml-UnusedPrivateField","enabled":true},{"patternId":"rulesets-unusedcode.xml-UnusedLocalVariable","enabled":true},{"patternId":"rulesets-unusedcode.xml-UnusedPrivateMethod","enabled":true},{"patternId":"rulesets-unusedcode.xml-UnusedFormalParameter","enabled":true},{"patternId":"PyLint_C0303","enabled":true},{"patternId":"PyLint_C1001","enabled":true},{"patternId":"rulesets-naming.xml-ShortVariable","enabled":true},{"patternId":"rulesets-naming.xml-LongVariable","enabled":true},{"patternId":"rulesets-naming.xml-ShortMethodName","enabled":true},{"patternId":"rulesets-naming.xml-ConstantNamingConventions","enabled":true},{"patternId":"rulesets-naming.xml-BooleanGetMethodName","enabled":true},{"patternId":"PyLint_W0101","enabled":true},{"patternId":"PyLint_W0102","enabled":true},{"patternId":"PyLint_W0104","enabled":true},{"patternId":"PyLint_W0105","enabled":true},{"patternId":"Custom_Scala_GetCalls","enabled":true},{"patternId":"ScalaStyle_EqualsHashCodeChecker","enabled":true},{"patternId":"ScalaStyle_ParameterNumberChecker","enabled":true},{"patternId":"ScalaStyle_ReturnChecker","enabled":true},{"patternId":"ScalaStyle_NullChecker","enabled":true},{"patternId":"ScalaStyle_NoCloneChecker","enabled":true},{"patternId":"ScalaStyle_NoFinalizeChecker","enabled":true},{"patternId":"ScalaStyle_CovariantEqualsChecker","enabled":true},{"patternId":"ScalaStyle_StructuralTypeChecker","enabled":true},{"patternId":"ScalaStyle_MethodLengthChecker","enabled":true},{"patternId":"ScalaStyle_NumberOfMethodsInTypeChecker","enabled":true},{"patternId":"ScalaStyle_WhileChecker","enabled":true},{"patternId":"ScalaStyle_VarFieldChecker","enabled":true},{"patternId":"ScalaStyle_VarLocalChecker","enabled":true},{"patternId":"ScalaStyle_RedundantIfChecker","enabled":true},{"patternId":"ScalaStyle_DeprecatedJavaChecker","enabled":true},{"patternId":"ScalaStyle_EmptyClassChecker","enabled":true},{"patternId":"ScalaStyle_NotImplementedErrorUsage","enabled":true},{"patternId":"Custom_Scala_GroupImports","enabled":true},{"patternId":"Custom_Scala_ReservedKeywords","enabled":true},{"patternId":"Custom_Scala_ElseIf","enabled":true},{"patternId":"Custom_Scala_CallByNameAsLastArguments","enabled":true},{"patternId":"Custom_Scala_WildcardImportOnMany","enabled":true},{"patternId":"Custom_Scala_UtilTryForTryCatch","enabled":true},{"patternId":"Custom_Scala_ProhibitObjectName","enabled":true},{"patternId":"Custom_Scala_ImportsAtBeginningOfPackage","enabled":true},{"patternId":"Custom_Scala_NameResultsAndParameters","enabled":true},{"patternId":"Custom_Scala_IncompletePatternMatching","enabled":true},{"patternId":"Custom_Scala_UsefulTypeAlias","enabled":true},{"patternId":"Custom_Scala_JavaThreads","enabled":true},{"patternId":"Custom_Scala_DirectPromiseCreation","enabled":true},{"patternId":"Custom_Scala_StructuralTypes","enabled":true},{"patternId":"Custom_Scala_CollectionLastHead","enabled":true},{"patternId":"PyLint_W0106","enabled":true},{"patternId":"PyLint_W0107","enabled":true},{"patternId":"PyLint_W0108","enabled":true},{"patternId":"PyLint_W0109","enabled":true},{"patternId":"PyLint_W0110","enabled":true},{"patternId":"PyLint_W0120","enabled":true},{"patternId":"PyLint_W0122","enabled":true},{"patternId":"PyLint_W0150","enabled":true},{"patternId":"PyLint_W0199","enabled":true},{"patternId":"rulesets-cleancode.xml-ElseExpression","enabled":true},{"patternId":"rulesets-cleancode.xml-StaticAccess","enabled":true},{"patternId":"ScalaStyle_NonASCIICharacterChecker","enabled":true},{"patternId":"ScalaStyle_FieldNamesChecker","enabled":true},{"patternId":"Custom_Scala_WithNameCalls","enabled":true},{"patternId":"strictexception_AvoidRethrowingException","enabled":true},{"patternId":"strings_AppendCharacterWithChar","enabled":true},{"patternId":"braces_IfElseStmtsMustUseBraces","enabled":true},{"patternId":"basic_AvoidDecimalLiteralsInBigDecimalConstructor","enabled":true},{"patternId":"basic_CheckSkipResult","enabled":true},{"patternId":"javabeans_MissingSerialVersionUID","enabled":true},{"patternId":"migrating_ShortInstantiation","enabled":true},{"patternId":"design_AvoidInstanceofChecksInCatchClause","enabled":true},{"patternId":"naming_LongVariable","enabled":true},{"patternId":"migrating_ReplaceEnumerationWithIterator","enabled":true},{"patternId":"j2ee_DoNotCallSystemExit","enabled":true},{"patternId":"unusedcode_UnusedLocalVariable","enabled":true},{"patternId":"strings_InefficientStringBuffering","enabled":true},{"patternId":"basic_DontUseFloatTypeForLoopIndices","enabled":true},{"patternId":"basic_AvoidBranchingStatementAsLastInLoop","enabled":true},{"patternId":"migrating_JUnit4TestShouldUseTestAnnotation","enabled":true},{"patternId":"optimizations_AddEmptyString","enabled":true},{"patternId":"logging-jakarta-commons_ProperLogger","enabled":true},{"patternId":"optimizations_RedundantFieldInitializer","enabled":true},{"patternId":"logging-java_AvoidPrintStackTrace","enabled":true},{"patternId":"empty_EmptyFinallyBlock","enabled":true},{"patternId":"design_CompareObjectsWithEquals","enabled":true},{"patternId":"basic_ClassCastExceptionWithToArray","enabled":true},{"patternId":"strictexception_DoNotExtendJavaLangError","enabled":true},{"patternId":"junit_UnnecessaryBooleanAssertion","enabled":true},{"patternId":"design_SimplifyBooleanExpressions","enabled":true},{"patternId":"basic_ForLoopShouldBeWhileLoop","enabled":true},{"patternId":"basic_BigIntegerInstantiation","enabled":true},{"patternId":"optimizations_UseArrayListInsteadOfVector","enabled":true},{"patternId":"optimizations_UnnecessaryWrapperObjectCreation","enabled":true},{"patternId":"strings_StringBufferInstantiationWithChar","enabled":true},{"patternId":"basic_JumbledIncrementer","enabled":true},{"patternId":"design_SwitchStmtsShouldHaveDefault","enabled":true},{"patternId":"strictexception_AvoidThrowingRawExceptionTypes","enabled":true},{"patternId":"migrating_LongInstantiation","enabled":true},{"patternId":"design_SimplifyBooleanReturns","enabled":true},{"patternId":"empty_EmptyInitializer","enabled":true},{"patternId":"design_FieldDeclarationsShouldBeAtStartOfClass","enabled":true},{"patternId":"unnecessary_UnnecessaryConversionTemporary","enabled":true},{"patternId":"design_AvoidProtectedFieldInFinalClass","enabled":true},{"patternId":"junit_UseAssertTrueInsteadOfAssertEquals","enabled":true},{"patternId":"naming_PackageCase","enabled":true},{"patternId":"migrating_JUnitUseExpected","enabled":true},{"patternId":"controversial_UnnecessaryConstructor","enabled":true},{"patternId":"naming_MethodNamingConventions","enabled":true},{"patternId":"design_DefaultLabelNotLastInSwitchStmt","enabled":true},{"patternId":"basic_UnconditionalIfStatement","enabled":true},{"patternId":"design_SingularField","enabled":true},{"patternId":"design_AssignmentToNonFinalStatic","enabled":true},{"patternId":"braces_WhileLoopsMustUseBraces","enabled":true},{"patternId":"logging-java_SystemPrintln","enabled":true},{"patternId":"strings_UseStringBufferLength","enabled":true},{"patternId":"controversial_AvoidUsingNativeCode","enabled":true},{"patternId":"strictexception_AvoidLosingExceptionInformation","enabled":true},{"patternId":"imports_ImportFromSamePackage","enabled":true},{"patternId":"finalizers_AvoidCallingFinalize","enabled":true},{"patternId":"finalizers_FinalizeOverloaded","enabled":true},{"patternId":"naming_ClassNamingConventions","enabled":true},{"patternId":"logging-java_LoggerIsNotStaticFinal","enabled":true},{"patternId":"finalizers_FinalizeOnlyCallsSuperFinalize","enabled":true},{"patternId":"unnecessary_UselessOverridingMethod","enabled":true},{"patternId":"naming_SuspiciousConstantFieldName","enabled":true},{"patternId":"design_OptimizableToArrayCall","enabled":true},{"patternId":"imports_UnnecessaryFullyQualifiedName","enabled":true},{"patternId":"migrating_ReplaceHashtableWithMap","enabled":true},{"patternId":"unusedcode_UnusedPrivateField","enabled":true},{"patternId":"strings_UnnecessaryCaseChange","enabled":true},{"patternId":"migrating_IntegerInstantiation","enabled":true},{"patternId":"design_NonStaticInitializer","enabled":true},{"patternId":"design_MissingBreakInSwitch","enabled":true},{"patternId":"design_AvoidReassigningParameters","enabled":true},{"patternId":"basic_AvoidThreadGroup","enabled":true},{"patternId":"empty_EmptyCatchBlock","parameters":{"allowCommentedBlocks":"true"},"enabled":true},{"patternId":"codesize_ExcessiveParameterList","parameters":{"minimum":"8","violationSuppressRegex":"\"\"","violationSuppressXPath":"\"\""},"enabled":true},{"patternId":"naming_SuspiciousHashcodeMethodName","enabled":true},{"patternId":"migrating_JUnit4TestShouldUseBeforeAnnotation","enabled":true},{"patternId":"design_UncommentedEmptyMethodBody","enabled":true},{"patternId":"basic_BrokenNullCheck","enabled":true},{"patternId":"strings_ConsecutiveLiteralAppends","enabled":true},{"patternId":"strings_StringInstantiation","enabled":true},{"patternId":"design_EqualsNull","enabled":true},{"patternId":"basic_OverrideBothEqualsAndHashcode","enabled":true},{"patternId":"design_InstantiationToGetClass","enabled":true},{"patternId":"basic_BooleanInstantiation","enabled":true},{"patternId":"strings_AvoidStringBufferField","enabled":true},{"patternId":"basic_ReturnFromFinallyBlock","enabled":true},{"patternId":"empty_EmptyTryBlock","enabled":true},{"patternId":"naming_SuspiciousEqualsMethodName","enabled":true},{"patternId":"basic_ExtendsObject","enabled":true},{"patternId":"strings_UselessStringValueOf","enabled":true},{"patternId":"design_UnsynchronizedStaticDateFormatter","enabled":true},{"patternId":"design_UseCollectionIsEmpty","enabled":true},{"patternId":"controversial_AvoidFinalLocalVariable","enabled":true},{"patternId":"strictexception_AvoidThrowingNullPointerException","enabled":true},{"patternId":"design_AvoidProtectedMethodInFinalClassNotExtending","enabled":true},{"patternId":"optimizations_PrematureDeclaration","enabled":true},{"patternId":"empty_EmptySwitchStatements","enabled":true},{"patternId":"basic_MisplacedNullCheck","enabled":true},{"patternId":"optimizations_UseStringBufferForStringAppends","enabled":true},{"patternId":"strings_StringToString","enabled":true},{"patternId":"naming_MethodWithSameNameAsEnclosingClass","enabled":true},{"patternId":"migrating_ReplaceVectorWithList","enabled":true},{"patternId":"imports_UnusedImports","enabled":true},{"patternId":"unnecessary_UnnecessaryFinalModifier","enabled":true},{"patternId":"basic_AvoidMultipleUnaryOperators","enabled":true},{"patternId":"junit_SimplifyBooleanAssertion","enabled":true},{"patternId":"unnecessary_UselessParentheses","enabled":true},{"patternId":"design_IdempotentOperations","enabled":true},{"patternId":"braces_IfStmtsMustUseBraces","enabled":true},{"patternId":"strings_UseIndexOfChar","enabled":true},{"patternId":"naming_NoPackage","enabled":true},{"patternId":"finalizers_FinalizeDoesNotCallSuperFinalize","enabled":true},{"patternId":"design_UseVarargs","enabled":true},{"patternId":"unusedcode_UnusedFormalParameter","enabled":true},{"patternId":"design_ReturnEmptyArrayRatherThanNull","enabled":true},{"patternId":"junit_UseAssertNullInsteadOfAssertTrue","enabled":true},{"patternId":"design_UseUtilityClass","enabled":true},{"patternId":"design_AvoidDeeplyNestedIfStmts","enabled":true},{"patternId":"empty_EmptyStatementNotInLoop","enabled":true},{"patternId":"junit_UseAssertSameInsteadOfAssertTrue","enabled":true},{"patternId":"braces_ForLoopsMustUseBraces","enabled":true},{"patternId":"controversial_DoNotCallGarbageCollectionExplicitly","enabled":true},{"patternId":"naming_GenericsNaming","enabled":true},{"patternId":"strings_UseEqualsToCompareStrings","enabled":true},{"patternId":"optimizations_AvoidArrayLoops","enabled":true},{"patternId":"empty_EmptyStaticInitializer","enabled":true},{"patternId":"design_UncommentedEmptyConstructor","enabled":true},{"patternId":"empty_EmptyStatementBlock","enabled":true},{"patternId":"basic_CollapsibleIfStatements","enabled":true},{"patternId":"design_FinalFieldCouldBeStatic","enabled":true},{"patternId":"logging-java_MoreThanOneLogger","enabled":true},{"patternId":"codesize_ExcessiveClassLength","enabled":true},{"patternId":"design_ImmutableField","enabled":true},{"patternId":"controversial_OneDeclarationPerLine","enabled":true},{"patternId":"empty_EmptyWhileStmt","enabled":true},{"patternId":"unnecessary_UnnecessaryReturn","enabled":true},{"patternId":"strings_InefficientEmptyStringCheck","enabled":true},{"patternId":"design_UseNotifyAllInsteadOfNotify","enabled":true},{"patternId":"strictexception_DoNotThrowExceptionInFinally","enabled":true},{"patternId":"junit_UseAssertEqualsInsteadOfAssertTrue","enabled":true},{"patternId":"typeresolution_CloneMethodMustImplementCloneable","enabled":true},{"patternId":"codesize_NPathComplexity","enabled":true},{"patternId":"imports_DontImportJavaLang","enabled":true},{"patternId":"empty_EmptySynchronizedBlock","enabled":true},{"patternId":"migrating_JUnit4TestShouldUseAfterAnnotation","enabled":true},{"patternId":"design_AvoidConstantsInterface","enabled":true},{"patternId":"unnecessary_UselessOperationOnImmutable","enabled":true},{"patternId":"design_PositionLiteralsFirstInComparisons","enabled":true},{"patternId":"migrating_ByteInstantiation","enabled":true},{"patternId":"junit_JUnitSpelling","enabled":true},{"patternId":"junit_JUnitTestsShouldIncludeAssert","enabled":true},{"patternId":"finalizers_EmptyFinalizer","enabled":true},{"patternId":"design_NonCaseLabelInSwitchStatement","enabled":true},{"patternId":"android_DoNotHardCodeSDCard","enabled":true},{"patternId":"design_LogicInversion","enabled":true},{"patternId":"unusedcode_UnusedPrivateMethod","enabled":true},{"patternId":"naming_AvoidDollarSigns","enabled":true},{"patternId":"finalizers_FinalizeShouldBeProtected","enabled":true},{"patternId":"clone_ProperCloneImplementation","enabled":true},{"patternId":"basic_CheckResultSet","enabled":true},{"patternId":"controversial_AvoidPrefixingMethodParameters","enabled":true},{"patternId":"migrating_JUnit4SuitesShouldUseSuiteAnnotation","enabled":true},{"patternId":"empty_EmptyIfStmt","enabled":true},{"patternId":"basic_DontCallThreadRun","enabled":true},{"patternId":"junit_JUnitStaticSuite","enabled":true},{"patternId":"optimizations_UseArraysAsList","enabled":true},{"patternId":"design_MissingStaticMethodInNonInstantiatableClass","enabled":true},{"patternId":"unusedcode_UnusedModifier","enabled":true},{"patternId":"Style_MethodName","enabled":true},{"patternId":"Metrics_CyclomaticComplexity","enabled":true},{"patternId":"Lint_DuplicateMethods","enabled":true},{"patternId":"Style_Lambda","enabled":true},{"patternId":"Lint_UselessSetterCall","enabled":true},{"patternId":"Style_VariableName","enabled":true},{"patternId":"Lint_AmbiguousOperator","enabled":true},{"patternId":"Style_LeadingCommentSpace","enabled":true},{"patternId":"Style_CaseEquality","enabled":true},{"patternId":"Lint_StringConversionInInterpolation","enabled":true},{"patternId":"Performance_ReverseEach","enabled":true},{"patternId":"Lint_LiteralInCondition","enabled":true},{"patternId":"Performance_Sample","enabled":true},{"patternId":"Style_NonNilCheck","enabled":true},{"patternId":"Lint_RescueException","enabled":true},{"patternId":"Lint_UselessElseWithoutRescue","enabled":true},{"patternId":"Style_ConstantName","enabled":true},{"patternId":"Lint_LiteralInInterpolation","enabled":true},{"patternId":"Lint_NestedMethodDefinition","enabled":true},{"patternId":"Style_DoubleNegation","enabled":true},{"patternId":"Lint_SpaceBeforeFirstArg","enabled":true},{"patternId":"Lint_Debugger","enabled":true},{"patternId":"Style_ClassVars","enabled":true},{"patternId":"Lint_EmptyEnsure","enabled":true},{"patternId":"Style_MultilineBlockLayout","enabled":true},{"patternId":"Lint_UnusedBlockArgument","enabled":true},{"patternId":"Lint_UselessAccessModifier","enabled":true},{"patternId":"Performance_Size","enabled":true},{"patternId":"Lint_EachWithObjectArgument","enabled":true},{"patternId":"Style_Alias","enabled":true},{"patternId":"Lint_Loop","enabled":true},{"patternId":"Style_NegatedWhile","enabled":true},{"patternId":"Style_ColonMethodCall","enabled":true},{"patternId":"Lint_AmbiguousRegexpLiteral","enabled":true},{"patternId":"Lint_UnusedMethodArgument","enabled":true},{"patternId":"Style_MultilineIfThen","enabled":true},{"patternId":"Lint_EnsureReturn","enabled":true},{"patternId":"Style_NegatedIf","enabled":true},{"patternId":"Lint_Eval","enabled":true},{"patternId":"Style_NilComparison","enabled":true},{"patternId":"Style_ArrayJoin","enabled":true},{"patternId":"Lint_ConditionPosition","enabled":true},{"patternId":"Lint_UnreachableCode","enabled":true},{"patternId":"Performance_Count","enabled":true},{"patternId":"Lint_EmptyInterpolation","enabled":true},{"patternId":"Style_LambdaCall","enabled":true},{"patternId":"Lint_HandleExceptions","enabled":true},{"patternId":"Lint_ShadowingOuterLocalVariable","enabled":true},{"patternId":"Lint_EndAlignment","enabled":true},{"patternId":"Style_MultilineTernaryOperator","enabled":true},{"patternId":"Style_AutoResourceCleanup","enabled":true},{"patternId":"Lint_ElseLayout","enabled":true},{"patternId":"Style_NestedTernaryOperator","enabled":true},{"patternId":"Style_OneLineConditional","enabled":true},{"patternId":"Style_EmptyElse","enabled":true},{"patternId":"Lint_UselessComparison","enabled":true},{"patternId":"Metrics_PerceivedComplexity","enabled":true},{"patternId":"Style_InfiniteLoop","enabled":true},{"patternId":"Rails_Date","enabled":true},{"patternId":"Style_EvenOdd","enabled":true},{"patternId":"Style_IndentationConsistency","enabled":true},{"patternId":"Style_ModuleFunction","enabled":true},{"patternId":"Lint_UselessAssignment","enabled":true},{"patternId":"Style_EachWithObject","enabled":true},{"patternId":"Performance_Detect","enabled":true},{"patternId":"duplicate_key","enabled":true},{"patternId":"no_interpolation_in_single_quotes","enabled":true},{"patternId":"no_backticks","enabled":true},{"patternId":"no_unnecessary_fat_arrows","enabled":true},{"patternId":"indentation","enabled":true},{"patternId":"ensure_comprehensions","enabled":true},{"patternId":"no_stand_alone_at","enabled":true},{"patternId":"cyclomatic_complexity","enabled":true},{"patternId":"Deserialize","enabled":true},{"patternId":"SymbolDoS","enabled":true},{"patternId":"SkipBeforeFilter","enabled":true},{"patternId":"SanitizeMethods","enabled":true},{"patternId":"SelectTag","enabled":true},{"patternId":"XMLDoS","enabled":true},{"patternId":"SimpleFormat","enabled":true},{"patternId":"Evaluation","enabled":true},{"patternId":"BasicAuth","enabled":true},{"patternId":"JRubyXML","enabled":true},{"patternId":"RenderInline","enabled":true},{"patternId":"YAMLParsing","enabled":true},{"patternId":"Redirect","enabled":true},{"patternId":"UnsafeReflection","enabled":true},{"patternId":"SSLVerify","enabled":true},{"patternId":"HeaderDoS","enabled":true},{"patternId":"TranslateBug","enabled":true},{"patternId":"Execute","enabled":true},{"patternId":"JSONParsing","enabled":true},{"patternId":"LinkTo","enabled":true},{"patternId":"FileDisclosure","enabled":true},{"patternId":"SafeBufferManipulation","enabled":true},{"patternId":"ModelAttributes","enabled":true},{"patternId":"ResponseSplitting","enabled":true},{"patternId":"DigestDoS","enabled":true},{"patternId":"Send","enabled":true},{"patternId":"MailTo","enabled":true},{"patternId":"SymbolDoSCVE","enabled":true},{"patternId":"StripTags","enabled":true},{"patternId":"MassAssignment","enabled":true},{"patternId":"RegexDoS","enabled":true},{"patternId":"SelectVulnerability","enabled":true},{"patternId":"FileAccess","enabled":true},{"patternId":"ContentTag","enabled":true},{"patternId":"SessionSettings","enabled":true},{"patternId":"FilterSkipping","enabled":true},{"patternId":"CreateWith","enabled":true},{"patternId":"JSONEncoding","enabled":true},{"patternId":"SQLCVEs","enabled":true},{"patternId":"ForgerySetting","enabled":true},{"patternId":"QuoteTableName","enabled":true},{"patternId":"I18nXSS","enabled":true},{"patternId":"WithoutProtection","enabled":true},{"patternId":"CrossSiteScripting","enabled":true},{"patternId":"SingleQuotes","enabled":true},{"patternId":"NestedAttributes","enabled":true},{"patternId":"DetailedExceptions","enabled":true},{"patternId":"LinkToHref","enabled":true},{"patternId":"RenderDoS","enabled":true},{"patternId":"ModelSerialize","enabled":true},{"patternId":"SQL","enabled":true},{"patternId":"Render","enabled":true},{"patternId":"UnscopedFind","enabled":true},{"patternId":"ValidationRegex","enabled":true},{"patternId":"EscapeFunction","enabled":true},{"patternId":"Custom_Scala_FieldNamesChecker","enabled":true},{"patternId":"Custom_Scala_ObjDeserialization","enabled":true},{"patternId":"Custom_Scala_RSAPadding","enabled":true},{"patternId":"ESLint_no-extra-boolean-cast","enabled":true},{"patternId":"ESLint_no-iterator","enabled":true},{"patternId":"ESLint_no-invalid-regexp","enabled":true},{"patternId":"ESLint_no-obj-calls","enabled":true},{"patternId":"ESLint_no-sparse-arrays","enabled":true},{"patternId":"ESLint_no-unreachable","enabled":true},{"patternId":"ESLint_no-dupe-keys","enabled":true},{"patternId":"ESLint_no-multi-str","enabled":true},{"patternId":"ESLint_no-extend-native","enabled":true},{"patternId":"ESLint_guard-for-in","enabled":true},{"patternId":"ESLint_no-func-assign","enabled":true},{"patternId":"ESLint_no-extra-semi","enabled":true},{"patternId":"ESLint_camelcase","enabled":true},{"patternId":"ESLint_no-mixed-spaces-and-tabs","enabled":true},{"patternId":"ESLint_no-undef","enabled":true},{"patternId":"ESLint_semi","enabled":true},{"patternId":"ESLint_no-empty-character-class","enabled":true},{"patternId":"ESLint_complexity","enabled":true},{"patternId":"ESLint_no-dupe-class-members","enabled":true},{"patternId":"ESLint_no-debugger","enabled":true},{"patternId":"ESLint_block-scoped-var","enabled":true},{"patternId":"ESLint_no-loop-func","enabled":true},{"patternId":"ESLint_no-use-before-define","enabled":true},{"patternId":"ESLint_no-console","enabled":true},{"patternId":"ESLint_require-yield","enabled":true},{"patternId":"ESLint_no-redeclare","enabled":true},{"patternId":"ESLint_no-undefined","enabled":true},{"patternId":"ESLint_use-isnan","enabled":true},{"patternId":"ESLint_no-control-regex","enabled":true},{"patternId":"ESLint_no-const-assign","enabled":true},{"patternId":"ESLint_no-new","enabled":true},{"patternId":"ESLint_new-cap","enabled":true},{"patternId":"ESLint_no-irregular-whitespace","enabled":true},{"patternId":"ESLint_object-shorthand","enabled":true},{"patternId":"ESLint_no-ex-assign","enabled":true},{"patternId":"ESLint_wrap-iife","enabled":true},{"patternId":"ESLint_arrow-parens","enabled":true},{"patternId":"ESLint_no-constant-condition","enabled":true},{"patternId":"ESLint_no-octal","enabled":true},{"patternId":"ESLint_no-dupe-args","enabled":true},{"patternId":"ESLint_quotes","enabled":true},{"patternId":"ESLint_no-fallthrough","enabled":true},{"patternId":"ESLint_no-delete-var","enabled":true},{"patternId":"ESLint_no-caller","enabled":true},{"patternId":"ESLint_no-cond-assign","enabled":true},{"patternId":"ESLint_no-this-before-super","enabled":true},{"patternId":"ESLint_no-negated-in-lhs","enabled":true},{"patternId":"ESLint_no-inner-declarations","enabled":true},{"patternId":"ESLint_eqeqeq","enabled":true},{"patternId":"ESLint_curly","enabled":true},{"patternId":"ESLint_arrow-spacing","enabled":true},{"patternId":"ESLint_no-empty","enabled":true},{"patternId":"ESLint_no-unused-vars","enabled":true},{"patternId":"ESLint_generator-star-spacing","enabled":true},{"patternId":"ESLint_no-duplicate-case","enabled":true},{"patternId":"ESLint_valid-typeof","enabled":true},{"patternId":"ESLint_no-regex-spaces","enabled":true},{"patternId":"ESLint_no-class-assign","enabled":true},{"patternId":"PyLint_W0221","enabled":true},{"patternId":"PyLint_E0117","enabled":true},{"patternId":"PyLint_E0001","enabled":true},{"patternId":"PyLint_E0241","enabled":true},{"patternId":"PyLint_W0404","enabled":true},{"patternId":"PyLint_E0704","enabled":true},{"patternId":"PyLint_E0703","enabled":true},{"patternId":"PyLint_E0302","enabled":true},{"patternId":"PyLint_W1301","enabled":true},{"patternId":"PyLint_R0201","enabled":true},{"patternId":"PyLint_E0113","enabled":true},{"patternId":"PyLint_W0410","enabled":true},{"patternId":"PyLint_C0123","enabled":true},{"patternId":"PyLint_E0115","enabled":true},{"patternId":"PyLint_E0114","enabled":true},{"patternId":"PyLint_E1126","enabled":true},{"patternId":"PyLint_W0702","enabled":true},{"patternId":"PyLint_W1303","enabled":true},{"patternId":"PyLint_W0622","enabled":true},{"patternId":"PyLint_W0222","enabled":true},{"patternId":"PyLint_W0233","enabled":true},{"patternId":"PyLint_W1305","enabled":true},{"patternId":"PyLint_E1127","enabled":true},{"patternId":"PyLint_E0112","enabled":true},{"patternId":"PyLint_W0611","enabled":true},{"patternId":"PyLint_W0601","enabled":true},{"patternId":"PyLint_W1300","enabled":true},{"patternId":"PyLint_W0124","enabled":true},{"patternId":"PyLint_R0203","enabled":true},{"patternId":"PyLint_E0236","enabled":true},{"patternId":"PyLint_W0612","enabled":true},{"patternId":"PyLint_W0604","enabled":true},{"patternId":"PyLint_W0705","enabled":true},{"patternId":"PyLint_E0238","enabled":true},{"patternId":"PyLint_W0602","enabled":true},{"patternId":"PyLint_R0102","enabled":true},{"patternId":"PyLint_R0202","enabled":true},{"patternId":"PyLint_E0240","enabled":true},{"patternId":"PyLint_W0623","enabled":true},{"patternId":"PyLint_W0711","enabled":true},{"patternId":"PyLint_E0116","enabled":true},{"patternId":"PyLint_E0239","enabled":true},{"patternId":"PyLint_E1132","enabled":true},{"patternId":"PyLint_W1307","enabled":true},{"patternId":"PyLint_C0200","enabled":true},{"patternId":"PyLint_E0301","enabled":true},{"patternId":"PyLint_W1306","enabled":true},{"patternId":"PyLint_W1302","enabled":true},{"patternId":"PyLint_E0110","enabled":true},{"patternId":"PyLint_E1125","enabled":true}]} \ No newline at end of file +{"patterns":[{"patternId":"Custom_Javascript_Scopes","enabled":true},{"patternId":"Custom_Javascript_EvalWith","enabled":true},{"patternId":"Custom_Javascript_TryCatch","enabled":true},{"patternId":"Custom_Scala_NonFatal","enabled":true},{"patternId":"bitwise","enabled":true},{"patternId":"maxparams","enabled":true},{"patternId":"CSSLint_universal_selector","enabled":true},{"patternId":"CSSLint_unqualified_attributes","enabled":true},{"patternId":"CSSLint_zero_units","enabled":true},{"patternId":"CSSLint_overqualified_elements","enabled":true},{"patternId":"CSSLint_shorthand","enabled":true},{"patternId":"CSSLint_duplicate_background_images","enabled":true},{"patternId":"CSSLint_box_model","enabled":true},{"patternId":"CSSLint_compatible_vendor_prefixes","enabled":true},{"patternId":"CSSLint_display_property_grouping","enabled":true},{"patternId":"CSSLint_duplicate_properties","enabled":true},{"patternId":"CSSLint_empty_rules","enabled":true},{"patternId":"CSSLint_errors","enabled":true},{"patternId":"CSSLint_gradients","enabled":true},{"patternId":"CSSLint_important","enabled":true},{"patternId":"CSSLint_known_properties","enabled":true},{"patternId":"CSSLint_text_indent","enabled":true},{"patternId":"CSSLint_unique_headings","enabled":true},{"patternId":"PyLint_E0100","enabled":true},{"patternId":"PyLint_E0101","enabled":true},{"patternId":"PyLint_E0102","enabled":true},{"patternId":"PyLint_E0103","enabled":true},{"patternId":"PyLint_E0104","enabled":true},{"patternId":"PyLint_E0105","enabled":true},{"patternId":"PyLint_E0106","enabled":true},{"patternId":"PyLint_E0107","enabled":true},{"patternId":"PyLint_E0108","enabled":true},{"patternId":"PyLint_E0202","enabled":true},{"patternId":"PyLint_E0203","enabled":true},{"patternId":"PyLint_E0211","enabled":true},{"patternId":"PyLint_E0601","enabled":true},{"patternId":"PyLint_E0603","enabled":true},{"patternId":"PyLint_E0604","enabled":true},{"patternId":"PyLint_E0701","enabled":true},{"patternId":"PyLint_E0702","enabled":true},{"patternId":"PyLint_E0710","enabled":true},{"patternId":"PyLint_E0711","enabled":true},{"patternId":"PyLint_E0712","enabled":true},{"patternId":"PyLint_E1003","enabled":true},{"patternId":"PyLint_E1102","enabled":true},{"patternId":"PyLint_E1111","enabled":true},{"patternId":"PyLint_E1120","enabled":true},{"patternId":"PyLint_E1121","enabled":true},{"patternId":"PyLint_E1123","enabled":true},{"patternId":"PyLint_E1124","enabled":true},{"patternId":"PyLint_E1200","enabled":true},{"patternId":"PyLint_E1201","enabled":true},{"patternId":"PyLint_E1205","enabled":true},{"patternId":"PyLint_E1206","enabled":true},{"patternId":"PyLint_E1300","enabled":true},{"patternId":"PyLint_E1301","enabled":true},{"patternId":"PyLint_E1302","enabled":true},{"patternId":"PyLint_E1303","enabled":true},{"patternId":"PyLint_E1304","enabled":true},{"patternId":"PyLint_E1305","enabled":true},{"patternId":"PyLint_E1306","enabled":true},{"patternId":"rulesets-codesize.xml-CyclomaticComplexity","enabled":true},{"patternId":"rulesets-codesize.xml-NPathComplexity","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessiveMethodLength","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessiveClassLength","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessiveParameterList","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessivePublicCount","enabled":true},{"patternId":"rulesets-codesize.xml-TooManyFields","enabled":true},{"patternId":"rulesets-codesize.xml-TooManyMethods","enabled":true},{"patternId":"rulesets-codesize.xml-ExcessiveClassComplexity","enabled":true},{"patternId":"rulesets-controversial.xml-Superglobals","enabled":true},{"patternId":"rulesets-design.xml-ExitExpression","enabled":true},{"patternId":"rulesets-design.xml-EvalExpression","enabled":true},{"patternId":"rulesets-design.xml-GotoStatement","enabled":true},{"patternId":"rulesets-design.xml-NumberOfChildren","enabled":true},{"patternId":"rulesets-design.xml-DepthOfInheritance","enabled":true},{"patternId":"rulesets-unusedcode.xml-UnusedPrivateField","enabled":true},{"patternId":"rulesets-unusedcode.xml-UnusedLocalVariable","enabled":true},{"patternId":"rulesets-unusedcode.xml-UnusedPrivateMethod","enabled":true},{"patternId":"rulesets-unusedcode.xml-UnusedFormalParameter","enabled":true},{"patternId":"PyLint_C0303","enabled":true},{"patternId":"PyLint_C1001","enabled":true},{"patternId":"rulesets-naming.xml-ShortVariable","enabled":true},{"patternId":"rulesets-naming.xml-LongVariable","enabled":true},{"patternId":"rulesets-naming.xml-ShortMethodName","enabled":true},{"patternId":"rulesets-naming.xml-ConstantNamingConventions","enabled":true},{"patternId":"rulesets-naming.xml-BooleanGetMethodName","enabled":true},{"patternId":"PyLint_W0101","enabled":true},{"patternId":"PyLint_W0102","enabled":true},{"patternId":"PyLint_W0104","enabled":true},{"patternId":"PyLint_W0105","enabled":true},{"patternId":"Custom_Scala_GetCalls","enabled":true},{"patternId":"ScalaStyle_EqualsHashCodeChecker","enabled":true},{"patternId":"ScalaStyle_ParameterNumberChecker","enabled":true},{"patternId":"ScalaStyle_ReturnChecker","enabled":true},{"patternId":"ScalaStyle_NullChecker","enabled":true},{"patternId":"ScalaStyle_NoCloneChecker","enabled":true},{"patternId":"ScalaStyle_NoFinalizeChecker","enabled":true},{"patternId":"ScalaStyle_CovariantEqualsChecker","enabled":true},{"patternId":"ScalaStyle_StructuralTypeChecker","enabled":true},{"patternId":"ScalaStyle_MethodLengthChecker","enabled":true},{"patternId":"ScalaStyle_NumberOfMethodsInTypeChecker","enabled":true},{"patternId":"ScalaStyle_WhileChecker","enabled":true},{"patternId":"ScalaStyle_VarFieldChecker","enabled":true},{"patternId":"ScalaStyle_VarLocalChecker","enabled":true},{"patternId":"ScalaStyle_RedundantIfChecker","enabled":true},{"patternId":"ScalaStyle_DeprecatedJavaChecker","enabled":true},{"patternId":"ScalaStyle_EmptyClassChecker","enabled":true},{"patternId":"ScalaStyle_NotImplementedErrorUsage","enabled":true},{"patternId":"Custom_Scala_GroupImports","enabled":true},{"patternId":"Custom_Scala_ReservedKeywords","enabled":true},{"patternId":"Custom_Scala_ElseIf","enabled":true},{"patternId":"Custom_Scala_CallByNameAsLastArguments","enabled":true},{"patternId":"Custom_Scala_WildcardImportOnMany","enabled":true},{"patternId":"Custom_Scala_UtilTryForTryCatch","enabled":true},{"patternId":"Custom_Scala_ProhibitObjectName","enabled":true},{"patternId":"Custom_Scala_ImportsAtBeginningOfPackage","enabled":true},{"patternId":"Custom_Scala_NameResultsAndParameters","enabled":true},{"patternId":"Custom_Scala_IncompletePatternMatching","enabled":true},{"patternId":"Custom_Scala_UsefulTypeAlias","enabled":true},{"patternId":"Custom_Scala_JavaThreads","enabled":true},{"patternId":"Custom_Scala_DirectPromiseCreation","enabled":true},{"patternId":"Custom_Scala_StructuralTypes","enabled":true},{"patternId":"Custom_Scala_CollectionLastHead","enabled":true},{"patternId":"PyLint_W0106","enabled":true},{"patternId":"PyLint_W0107","enabled":true},{"patternId":"PyLint_W0108","enabled":true},{"patternId":"PyLint_W0109","enabled":true},{"patternId":"PyLint_W0110","enabled":true},{"patternId":"PyLint_W0120","enabled":true},{"patternId":"PyLint_W0122","enabled":true},{"patternId":"PyLint_W0150","enabled":true},{"patternId":"PyLint_W0199","enabled":true},{"patternId":"rulesets-cleancode.xml-ElseExpression","enabled":true},{"patternId":"rulesets-cleancode.xml-StaticAccess","enabled":true},{"patternId":"ScalaStyle_NonASCIICharacterChecker","enabled":true},{"patternId":"ScalaStyle_FieldNamesChecker","enabled":true},{"patternId":"Custom_Scala_WithNameCalls","enabled":true},{"patternId":"strictexception_AvoidRethrowingException","enabled":true},{"patternId":"strings_AppendCharacterWithChar","enabled":true},{"patternId":"braces_IfElseStmtsMustUseBraces","enabled":true},{"patternId":"basic_AvoidDecimalLiteralsInBigDecimalConstructor","enabled":true},{"patternId":"basic_CheckSkipResult","enabled":true},{"patternId":"javabeans_MissingSerialVersionUID","enabled":true},{"patternId":"migrating_ShortInstantiation","enabled":true},{"patternId":"design_AvoidInstanceofChecksInCatchClause","enabled":true},{"patternId":"migrating_ReplaceEnumerationWithIterator","enabled":true},{"patternId":"j2ee_DoNotCallSystemExit","enabled":true},{"patternId":"unusedcode_UnusedLocalVariable","enabled":true},{"patternId":"strings_InefficientStringBuffering","enabled":true},{"patternId":"basic_DontUseFloatTypeForLoopIndices","enabled":true},{"patternId":"basic_AvoidBranchingStatementAsLastInLoop","enabled":true},{"patternId":"migrating_JUnit4TestShouldUseTestAnnotation","enabled":true},{"patternId":"optimizations_AddEmptyString","enabled":true},{"patternId":"logging-jakarta-commons_ProperLogger","enabled":true},{"patternId":"optimizations_RedundantFieldInitializer","enabled":true},{"patternId":"logging-java_AvoidPrintStackTrace","enabled":true},{"patternId":"empty_EmptyFinallyBlock","enabled":true},{"patternId":"design_CompareObjectsWithEquals","enabled":true},{"patternId":"basic_ClassCastExceptionWithToArray","enabled":true},{"patternId":"strictexception_DoNotExtendJavaLangError","enabled":true},{"patternId":"junit_UnnecessaryBooleanAssertion","enabled":true},{"patternId":"design_SimplifyBooleanExpressions","enabled":true},{"patternId":"basic_ForLoopShouldBeWhileLoop","enabled":true},{"patternId":"basic_BigIntegerInstantiation","enabled":true},{"patternId":"optimizations_UseArrayListInsteadOfVector","enabled":true},{"patternId":"optimizations_UnnecessaryWrapperObjectCreation","enabled":true},{"patternId":"strings_StringBufferInstantiationWithChar","enabled":true},{"patternId":"basic_JumbledIncrementer","enabled":true},{"patternId":"design_SwitchStmtsShouldHaveDefault","enabled":true},{"patternId":"strictexception_AvoidThrowingRawExceptionTypes","enabled":true},{"patternId":"migrating_LongInstantiation","enabled":true},{"patternId":"design_SimplifyBooleanReturns","enabled":true},{"patternId":"empty_EmptyInitializer","enabled":true},{"patternId":"design_FieldDeclarationsShouldBeAtStartOfClass","enabled":true},{"patternId":"unnecessary_UnnecessaryConversionTemporary","enabled":true},{"patternId":"design_AvoidProtectedFieldInFinalClass","enabled":true},{"patternId":"junit_UseAssertTrueInsteadOfAssertEquals","enabled":true},{"patternId":"naming_PackageCase","enabled":true},{"patternId":"migrating_JUnitUseExpected","enabled":true},{"patternId":"controversial_UnnecessaryConstructor","enabled":true},{"patternId":"naming_MethodNamingConventions","parameters":{"violationSuppressRegex":"\"\"","violationSuppressXPath":"\"//MethodDeclarator[contains(@Image, 'test')]\""},"enabled":true},{"patternId":"design_DefaultLabelNotLastInSwitchStmt","enabled":true},{"patternId":"basic_UnconditionalIfStatement","enabled":true},{"patternId":"design_SingularField","enabled":true},{"patternId":"design_AssignmentToNonFinalStatic","enabled":true},{"patternId":"braces_WhileLoopsMustUseBraces","enabled":true},{"patternId":"logging-java_SystemPrintln","enabled":true},{"patternId":"strings_UseStringBufferLength","enabled":true},{"patternId":"controversial_AvoidUsingNativeCode","enabled":true},{"patternId":"strictexception_AvoidLosingExceptionInformation","enabled":true},{"patternId":"imports_ImportFromSamePackage","enabled":true},{"patternId":"finalizers_AvoidCallingFinalize","enabled":true},{"patternId":"finalizers_FinalizeOverloaded","enabled":true},{"patternId":"naming_ClassNamingConventions","enabled":true},{"patternId":"logging-java_LoggerIsNotStaticFinal","enabled":true},{"patternId":"finalizers_FinalizeOnlyCallsSuperFinalize","enabled":true},{"patternId":"unnecessary_UselessOverridingMethod","enabled":true},{"patternId":"naming_SuspiciousConstantFieldName","enabled":true},{"patternId":"design_OptimizableToArrayCall","enabled":true},{"patternId":"imports_UnnecessaryFullyQualifiedName","enabled":true},{"patternId":"migrating_ReplaceHashtableWithMap","enabled":true},{"patternId":"unusedcode_UnusedPrivateField","enabled":true},{"patternId":"strings_UnnecessaryCaseChange","enabled":true},{"patternId":"migrating_IntegerInstantiation","enabled":true},{"patternId":"design_NonStaticInitializer","enabled":true},{"patternId":"design_MissingBreakInSwitch","enabled":true},{"patternId":"design_AvoidReassigningParameters","enabled":true},{"patternId":"basic_AvoidThreadGroup","enabled":true},{"patternId":"empty_EmptyCatchBlock","parameters":{"allowCommentedBlocks":"true"},"enabled":true},{"patternId":"codesize_ExcessiveParameterList","parameters":{"minimum":"8","violationSuppressRegex":"\"\"","violationSuppressXPath":"\"\""},"enabled":true},{"patternId":"naming_SuspiciousHashcodeMethodName","enabled":true},{"patternId":"migrating_JUnit4TestShouldUseBeforeAnnotation","enabled":true},{"patternId":"design_UncommentedEmptyMethodBody","enabled":true},{"patternId":"basic_BrokenNullCheck","enabled":true},{"patternId":"strings_ConsecutiveLiteralAppends","enabled":true},{"patternId":"strings_StringInstantiation","enabled":true},{"patternId":"design_EqualsNull","enabled":true},{"patternId":"basic_OverrideBothEqualsAndHashcode","enabled":true},{"patternId":"design_InstantiationToGetClass","enabled":true},{"patternId":"basic_BooleanInstantiation","enabled":true},{"patternId":"strings_AvoidStringBufferField","enabled":true},{"patternId":"basic_ReturnFromFinallyBlock","enabled":true},{"patternId":"empty_EmptyTryBlock","enabled":true},{"patternId":"naming_SuspiciousEqualsMethodName","enabled":true},{"patternId":"basic_ExtendsObject","enabled":true},{"patternId":"strings_UselessStringValueOf","enabled":true},{"patternId":"design_UnsynchronizedStaticDateFormatter","enabled":true},{"patternId":"design_UseCollectionIsEmpty","enabled":true},{"patternId":"controversial_AvoidFinalLocalVariable","enabled":true},{"patternId":"strictexception_AvoidThrowingNullPointerException","enabled":true},{"patternId":"design_AvoidProtectedMethodInFinalClassNotExtending","enabled":true},{"patternId":"optimizations_PrematureDeclaration","enabled":true},{"patternId":"empty_EmptySwitchStatements","enabled":true},{"patternId":"basic_MisplacedNullCheck","enabled":true},{"patternId":"optimizations_UseStringBufferForStringAppends","enabled":true},{"patternId":"strings_StringToString","enabled":true},{"patternId":"naming_MethodWithSameNameAsEnclosingClass","enabled":true},{"patternId":"migrating_ReplaceVectorWithList","enabled":true},{"patternId":"imports_UnusedImports","enabled":true},{"patternId":"unnecessary_UnnecessaryFinalModifier","enabled":true},{"patternId":"basic_AvoidMultipleUnaryOperators","enabled":true},{"patternId":"junit_SimplifyBooleanAssertion","enabled":true},{"patternId":"unnecessary_UselessParentheses","enabled":true},{"patternId":"design_IdempotentOperations","enabled":true},{"patternId":"braces_IfStmtsMustUseBraces","enabled":true},{"patternId":"strings_UseIndexOfChar","enabled":true},{"patternId":"naming_NoPackage","enabled":true},{"patternId":"finalizers_FinalizeDoesNotCallSuperFinalize","enabled":true},{"patternId":"design_UseVarargs","enabled":true},{"patternId":"unusedcode_UnusedFormalParameter","enabled":true},{"patternId":"design_ReturnEmptyArrayRatherThanNull","enabled":true},{"patternId":"junit_UseAssertNullInsteadOfAssertTrue","enabled":true},{"patternId":"design_UseUtilityClass","enabled":true},{"patternId":"design_AvoidDeeplyNestedIfStmts","enabled":true},{"patternId":"empty_EmptyStatementNotInLoop","enabled":true},{"patternId":"junit_UseAssertSameInsteadOfAssertTrue","enabled":true},{"patternId":"braces_ForLoopsMustUseBraces","enabled":true},{"patternId":"controversial_DoNotCallGarbageCollectionExplicitly","enabled":true},{"patternId":"naming_GenericsNaming","enabled":true},{"patternId":"strings_UseEqualsToCompareStrings","enabled":true},{"patternId":"optimizations_AvoidArrayLoops","enabled":true},{"patternId":"empty_EmptyStaticInitializer","enabled":true},{"patternId":"design_UncommentedEmptyConstructor","enabled":true},{"patternId":"empty_EmptyStatementBlock","enabled":true},{"patternId":"basic_CollapsibleIfStatements","enabled":true},{"patternId":"design_FinalFieldCouldBeStatic","enabled":true},{"patternId":"logging-java_MoreThanOneLogger","enabled":true},{"patternId":"codesize_ExcessiveClassLength","enabled":true},{"patternId":"design_ImmutableField","enabled":true},{"patternId":"controversial_OneDeclarationPerLine","enabled":true},{"patternId":"empty_EmptyWhileStmt","enabled":true},{"patternId":"unnecessary_UnnecessaryReturn","enabled":true},{"patternId":"strings_InefficientEmptyStringCheck","enabled":true},{"patternId":"design_UseNotifyAllInsteadOfNotify","enabled":true},{"patternId":"strictexception_DoNotThrowExceptionInFinally","enabled":true},{"patternId":"junit_UseAssertEqualsInsteadOfAssertTrue","enabled":true},{"patternId":"typeresolution_CloneMethodMustImplementCloneable","enabled":true},{"patternId":"codesize_NPathComplexity","enabled":true},{"patternId":"imports_DontImportJavaLang","enabled":true},{"patternId":"empty_EmptySynchronizedBlock","enabled":true},{"patternId":"migrating_JUnit4TestShouldUseAfterAnnotation","enabled":true},{"patternId":"design_AvoidConstantsInterface","enabled":true},{"patternId":"unnecessary_UselessOperationOnImmutable","enabled":true},{"patternId":"design_PositionLiteralsFirstInComparisons","enabled":true},{"patternId":"migrating_ByteInstantiation","enabled":true},{"patternId":"junit_JUnitSpelling","enabled":true},{"patternId":"finalizers_EmptyFinalizer","enabled":true},{"patternId":"design_NonCaseLabelInSwitchStatement","enabled":true},{"patternId":"android_DoNotHardCodeSDCard","enabled":true},{"patternId":"design_LogicInversion","enabled":true},{"patternId":"unusedcode_UnusedPrivateMethod","enabled":true},{"patternId":"naming_AvoidDollarSigns","enabled":true},{"patternId":"finalizers_FinalizeShouldBeProtected","enabled":true},{"patternId":"clone_ProperCloneImplementation","enabled":true},{"patternId":"basic_CheckResultSet","enabled":true},{"patternId":"controversial_AvoidPrefixingMethodParameters","enabled":true},{"patternId":"migrating_JUnit4SuitesShouldUseSuiteAnnotation","enabled":true},{"patternId":"empty_EmptyIfStmt","enabled":true},{"patternId":"basic_DontCallThreadRun","enabled":true},{"patternId":"junit_JUnitStaticSuite","enabled":true},{"patternId":"optimizations_UseArraysAsList","enabled":true},{"patternId":"design_MissingStaticMethodInNonInstantiatableClass","enabled":true},{"patternId":"unusedcode_UnusedModifier","enabled":true},{"patternId":"Style_MethodName","enabled":true},{"patternId":"Metrics_CyclomaticComplexity","enabled":true},{"patternId":"Lint_DuplicateMethods","enabled":true},{"patternId":"Style_Lambda","enabled":true},{"patternId":"Lint_UselessSetterCall","enabled":true},{"patternId":"Style_VariableName","enabled":true},{"patternId":"Lint_AmbiguousOperator","enabled":true},{"patternId":"Style_LeadingCommentSpace","enabled":true},{"patternId":"Style_CaseEquality","enabled":true},{"patternId":"Lint_StringConversionInInterpolation","enabled":true},{"patternId":"Performance_ReverseEach","enabled":true},{"patternId":"Lint_LiteralInCondition","enabled":true},{"patternId":"Performance_Sample","enabled":true},{"patternId":"Style_NonNilCheck","enabled":true},{"patternId":"Lint_RescueException","enabled":true},{"patternId":"Lint_UselessElseWithoutRescue","enabled":true},{"patternId":"Style_ConstantName","enabled":true},{"patternId":"Lint_LiteralInInterpolation","enabled":true},{"patternId":"Lint_NestedMethodDefinition","enabled":true},{"patternId":"Style_DoubleNegation","enabled":true},{"patternId":"Lint_SpaceBeforeFirstArg","enabled":true},{"patternId":"Lint_Debugger","enabled":true},{"patternId":"Style_ClassVars","enabled":true},{"patternId":"Lint_EmptyEnsure","enabled":true},{"patternId":"Style_MultilineBlockLayout","enabled":true},{"patternId":"Lint_UnusedBlockArgument","enabled":true},{"patternId":"Lint_UselessAccessModifier","enabled":true},{"patternId":"Performance_Size","enabled":true},{"patternId":"Lint_EachWithObjectArgument","enabled":true},{"patternId":"Style_Alias","enabled":true},{"patternId":"Lint_Loop","enabled":true},{"patternId":"Style_NegatedWhile","enabled":true},{"patternId":"Style_ColonMethodCall","enabled":true},{"patternId":"Lint_AmbiguousRegexpLiteral","enabled":true},{"patternId":"Lint_UnusedMethodArgument","enabled":true},{"patternId":"Style_MultilineIfThen","enabled":true},{"patternId":"Lint_EnsureReturn","enabled":true},{"patternId":"Style_NegatedIf","enabled":true},{"patternId":"Lint_Eval","enabled":true},{"patternId":"Style_NilComparison","enabled":true},{"patternId":"Style_ArrayJoin","enabled":true},{"patternId":"Lint_ConditionPosition","enabled":true},{"patternId":"Lint_UnreachableCode","enabled":true},{"patternId":"Performance_Count","enabled":true},{"patternId":"Lint_EmptyInterpolation","enabled":true},{"patternId":"Style_LambdaCall","enabled":true},{"patternId":"Lint_HandleExceptions","enabled":true},{"patternId":"Lint_ShadowingOuterLocalVariable","enabled":true},{"patternId":"Lint_EndAlignment","enabled":true},{"patternId":"Style_MultilineTernaryOperator","enabled":true},{"patternId":"Style_AutoResourceCleanup","enabled":true},{"patternId":"Lint_ElseLayout","enabled":true},{"patternId":"Style_NestedTernaryOperator","enabled":true},{"patternId":"Style_OneLineConditional","enabled":true},{"patternId":"Style_EmptyElse","enabled":true},{"patternId":"Lint_UselessComparison","enabled":true},{"patternId":"Metrics_PerceivedComplexity","enabled":true},{"patternId":"Style_InfiniteLoop","enabled":true},{"patternId":"Rails_Date","enabled":true},{"patternId":"Style_EvenOdd","enabled":true},{"patternId":"Style_IndentationConsistency","enabled":true},{"patternId":"Style_ModuleFunction","enabled":true},{"patternId":"Lint_UselessAssignment","enabled":true},{"patternId":"Style_EachWithObject","enabled":true},{"patternId":"Performance_Detect","enabled":true},{"patternId":"duplicate_key","enabled":true},{"patternId":"no_interpolation_in_single_quotes","enabled":true},{"patternId":"no_backticks","enabled":true},{"patternId":"no_unnecessary_fat_arrows","enabled":true},{"patternId":"indentation","enabled":true},{"patternId":"ensure_comprehensions","enabled":true},{"patternId":"no_stand_alone_at","enabled":true},{"patternId":"cyclomatic_complexity","enabled":true},{"patternId":"Deserialize","enabled":true},{"patternId":"SymbolDoS","enabled":true},{"patternId":"SkipBeforeFilter","enabled":true},{"patternId":"SanitizeMethods","enabled":true},{"patternId":"SelectTag","enabled":true},{"patternId":"XMLDoS","enabled":true},{"patternId":"SimpleFormat","enabled":true},{"patternId":"Evaluation","enabled":true},{"patternId":"BasicAuth","enabled":true},{"patternId":"JRubyXML","enabled":true},{"patternId":"RenderInline","enabled":true},{"patternId":"YAMLParsing","enabled":true},{"patternId":"Redirect","enabled":true},{"patternId":"UnsafeReflection","enabled":true},{"patternId":"SSLVerify","enabled":true},{"patternId":"HeaderDoS","enabled":true},{"patternId":"TranslateBug","enabled":true},{"patternId":"Execute","enabled":true},{"patternId":"JSONParsing","enabled":true},{"patternId":"LinkTo","enabled":true},{"patternId":"FileDisclosure","enabled":true},{"patternId":"SafeBufferManipulation","enabled":true},{"patternId":"ModelAttributes","enabled":true},{"patternId":"ResponseSplitting","enabled":true},{"patternId":"DigestDoS","enabled":true},{"patternId":"Send","enabled":true},{"patternId":"MailTo","enabled":true},{"patternId":"SymbolDoSCVE","enabled":true},{"patternId":"StripTags","enabled":true},{"patternId":"MassAssignment","enabled":true},{"patternId":"RegexDoS","enabled":true},{"patternId":"SelectVulnerability","enabled":true},{"patternId":"FileAccess","enabled":true},{"patternId":"ContentTag","enabled":true},{"patternId":"SessionSettings","enabled":true},{"patternId":"FilterSkipping","enabled":true},{"patternId":"CreateWith","enabled":true},{"patternId":"JSONEncoding","enabled":true},{"patternId":"SQLCVEs","enabled":true},{"patternId":"ForgerySetting","enabled":true},{"patternId":"QuoteTableName","enabled":true},{"patternId":"I18nXSS","enabled":true},{"patternId":"WithoutProtection","enabled":true},{"patternId":"CrossSiteScripting","enabled":true},{"patternId":"SingleQuotes","enabled":true},{"patternId":"NestedAttributes","enabled":true},{"patternId":"DetailedExceptions","enabled":true},{"patternId":"LinkToHref","enabled":true},{"patternId":"RenderDoS","enabled":true},{"patternId":"ModelSerialize","enabled":true},{"patternId":"SQL","enabled":true},{"patternId":"Render","enabled":true},{"patternId":"UnscopedFind","enabled":true},{"patternId":"ValidationRegex","enabled":true},{"patternId":"EscapeFunction","enabled":true},{"patternId":"Custom_Scala_FieldNamesChecker","enabled":true},{"patternId":"Custom_Scala_ObjDeserialization","enabled":true},{"patternId":"Custom_Scala_RSAPadding","enabled":true},{"patternId":"ESLint_no-extra-boolean-cast","enabled":true},{"patternId":"ESLint_no-iterator","enabled":true},{"patternId":"ESLint_no-invalid-regexp","enabled":true},{"patternId":"ESLint_no-obj-calls","enabled":true},{"patternId":"ESLint_no-sparse-arrays","enabled":true},{"patternId":"ESLint_no-unreachable","enabled":true},{"patternId":"ESLint_no-dupe-keys","enabled":true},{"patternId":"ESLint_no-multi-str","enabled":true},{"patternId":"ESLint_no-extend-native","enabled":true},{"patternId":"ESLint_guard-for-in","enabled":true},{"patternId":"ESLint_no-func-assign","enabled":true},{"patternId":"ESLint_no-extra-semi","enabled":true},{"patternId":"ESLint_camelcase","enabled":true},{"patternId":"ESLint_no-mixed-spaces-and-tabs","enabled":true},{"patternId":"ESLint_no-undef","enabled":true},{"patternId":"ESLint_semi","enabled":true},{"patternId":"ESLint_no-empty-character-class","enabled":true},{"patternId":"ESLint_complexity","enabled":true},{"patternId":"ESLint_no-dupe-class-members","enabled":true},{"patternId":"ESLint_no-debugger","enabled":true},{"patternId":"ESLint_block-scoped-var","enabled":true},{"patternId":"ESLint_no-loop-func","enabled":true},{"patternId":"ESLint_no-use-before-define","enabled":true},{"patternId":"ESLint_no-console","enabled":true},{"patternId":"ESLint_require-yield","enabled":true},{"patternId":"ESLint_no-redeclare","enabled":true},{"patternId":"ESLint_no-undefined","enabled":true},{"patternId":"ESLint_use-isnan","enabled":true},{"patternId":"ESLint_no-control-regex","enabled":true},{"patternId":"ESLint_no-const-assign","enabled":true},{"patternId":"ESLint_no-new","enabled":true},{"patternId":"ESLint_new-cap","enabled":true},{"patternId":"ESLint_no-irregular-whitespace","enabled":true},{"patternId":"ESLint_object-shorthand","enabled":true},{"patternId":"ESLint_no-ex-assign","enabled":true},{"patternId":"ESLint_wrap-iife","enabled":true},{"patternId":"ESLint_arrow-parens","enabled":true},{"patternId":"ESLint_no-constant-condition","enabled":true},{"patternId":"ESLint_no-octal","enabled":true},{"patternId":"ESLint_no-dupe-args","enabled":true},{"patternId":"ESLint_quotes","enabled":true},{"patternId":"ESLint_no-fallthrough","enabled":true},{"patternId":"ESLint_no-delete-var","enabled":true},{"patternId":"ESLint_no-caller","enabled":true},{"patternId":"ESLint_no-cond-assign","enabled":true},{"patternId":"ESLint_no-this-before-super","enabled":true},{"patternId":"ESLint_no-negated-in-lhs","enabled":true},{"patternId":"ESLint_no-inner-declarations","enabled":true},{"patternId":"ESLint_eqeqeq","enabled":true},{"patternId":"ESLint_curly","enabled":true},{"patternId":"ESLint_arrow-spacing","enabled":true},{"patternId":"ESLint_no-empty","enabled":true},{"patternId":"ESLint_no-unused-vars","enabled":true},{"patternId":"ESLint_generator-star-spacing","enabled":true},{"patternId":"ESLint_no-duplicate-case","enabled":true},{"patternId":"ESLint_valid-typeof","enabled":true},{"patternId":"ESLint_no-regex-spaces","enabled":true},{"patternId":"ESLint_no-class-assign","enabled":true},{"patternId":"PyLint_W0221","enabled":true},{"patternId":"PyLint_E0117","enabled":true},{"patternId":"PyLint_E0001","enabled":true},{"patternId":"PyLint_E0241","enabled":true},{"patternId":"PyLint_W0404","enabled":true},{"patternId":"PyLint_E0704","enabled":true},{"patternId":"PyLint_E0703","enabled":true},{"patternId":"PyLint_E0302","enabled":true},{"patternId":"PyLint_W1301","enabled":true},{"patternId":"PyLint_R0201","enabled":true},{"patternId":"PyLint_E0113","enabled":true},{"patternId":"PyLint_W0410","enabled":true},{"patternId":"PyLint_C0123","enabled":true},{"patternId":"PyLint_E0115","enabled":true},{"patternId":"PyLint_E0114","enabled":true},{"patternId":"PyLint_E1126","enabled":true},{"patternId":"PyLint_W0702","enabled":true},{"patternId":"PyLint_W1303","enabled":true},{"patternId":"PyLint_W0622","enabled":true},{"patternId":"PyLint_W0222","enabled":true},{"patternId":"PyLint_W0233","enabled":true},{"patternId":"PyLint_W1305","enabled":true},{"patternId":"PyLint_E1127","enabled":true},{"patternId":"PyLint_E0112","enabled":true},{"patternId":"PyLint_W0611","enabled":true},{"patternId":"PyLint_W0601","enabled":true},{"patternId":"PyLint_W1300","enabled":true},{"patternId":"PyLint_W0124","enabled":true},{"patternId":"PyLint_R0203","enabled":true},{"patternId":"PyLint_E0236","enabled":true},{"patternId":"PyLint_W0612","enabled":true},{"patternId":"PyLint_W0604","enabled":true},{"patternId":"PyLint_W0705","enabled":true},{"patternId":"PyLint_E0238","enabled":true},{"patternId":"PyLint_W0602","enabled":true},{"patternId":"PyLint_R0102","enabled":true},{"patternId":"PyLint_R0202","enabled":true},{"patternId":"PyLint_E0240","enabled":true},{"patternId":"PyLint_W0623","enabled":true},{"patternId":"PyLint_W0711","enabled":true},{"patternId":"PyLint_E0116","enabled":true},{"patternId":"PyLint_E0239","enabled":true},{"patternId":"PyLint_E1132","enabled":true},{"patternId":"PyLint_W1307","enabled":true},{"patternId":"PyLint_C0200","enabled":true},{"patternId":"PyLint_E0301","enabled":true},{"patternId":"PyLint_W1306","enabled":true},{"patternId":"PyLint_W1302","enabled":true},{"patternId":"PyLint_E0110","enabled":true},{"patternId":"PyLint_E1125","enabled":true}]} \ No newline at end of file From 637860c6b7548c5aa8c118b2580a83bc837ef270 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 29 Mar 2016 17:25:05 -0700 Subject: [PATCH 215/375] Update dependencies --- gcloud-java-datastore/pom.xml | 14 ++------------ .../gcloud/datastore/testing/LocalGcdHelper.java | 4 ++-- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index e25144eec8a4..c640ab5a6d86 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -12,16 +12,6 @@ gcloud-java-pom 0.1.7-SNAPSHOT - - - sonatype-snapshots - sonatype-snapshots - https://oss.sonatype.org/content/repositories/snapshots/ - - true - - - gcloud-java-datastore @@ -34,12 +24,12 @@ com.google.cloud.datastore datastore-v1beta3-protos - 0.0.1-SNAPSHOT + 1.0.0-beta com.google.cloud.datastore datastore-v1beta3-proto-client - 0.0.1-SNAPSHOT + 1.0.0-beta ${project.groupId} diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java index d5ce0efe0498..6f1a76b0a482 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java @@ -78,10 +78,10 @@ public class LocalGcdHelper { public static final String DEFAULT_PROJECT_ID = "projectid1"; public static final int DEFAULT_PORT = 8080; private static final String GCD_VERSION = "v1beta3"; - private static final String GCD_BUILD = "0.0.1"; + private static final String GCD_BUILD = "1.0.0"; private static final String GCD_BASENAME = "gcd-" + GCD_VERSION + "-" + GCD_BUILD; private static final String GCD_FILENAME = GCD_BASENAME + ".zip"; - private static final String MD5_CHECKSUM = "496b16f32473d0de0c7a974bd0ee1461"; + private static final String MD5_CHECKSUM = "72156cc993835c57f72789519b85249b"; private static final URL GCD_URL; private static final String GCLOUD = "gcloud"; private static final Path INSTALLED_GCD_PATH; From 8db4b9b6f7b0c56c9b93c5a614a1c945b10336b6 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 30 Mar 2016 22:42:29 +0200 Subject: [PATCH 216/375] Minor refactoring for SelectorHelper - Rename selector method for lists to listSelector - Update selectors to accept List parameters - Add missing unit test for listSelector - Remove redundant extends Serializable from dns' option classes --- .../com/google/gcloud/bigquery/BigQuery.java | 23 ++++++----- .../java/com/google/gcloud/FieldSelector.java | 12 +++--- ...Test.java => FieldSelectorHelperTest.java} | 21 ++++++++-- .../main/java/com/google/gcloud/dns/Dns.java | 38 +++++++++---------- .../resourcemanager/ResourceManager.java | 8 ++-- .../com/google/gcloud/storage/Storage.java | 17 ++++----- 6 files changed, 65 insertions(+), 54 deletions(-) rename gcloud-java-core/src/test/java/com/google/gcloud/{SelectorHelperTest.java => FieldSelectorHelperTest.java} (72%) diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java index c23ee2844762..2d864383e81a 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java @@ -22,7 +22,7 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.gcloud.FieldSelector; -import com.google.gcloud.FieldSelector.SelectorHelper; +import com.google.gcloud.FieldSelector.Helper; import com.google.gcloud.Page; import com.google.gcloud.Service; import com.google.gcloud.bigquery.spi.BigQueryRpc; @@ -55,8 +55,8 @@ enum DatasetField implements FieldSelector { LOCATION("location"), SELF_LINK("selfLink"); - static final List REQUIRED_FIELDS = - ImmutableList.of(DATASET_REFERENCE); + static final List REQUIRED_FIELDS = + ImmutableList.of(DATASET_REFERENCE); private final String selector; @@ -95,8 +95,8 @@ enum TableField implements FieldSelector { TYPE("type"), VIEW("view"); - static final List REQUIRED_FIELDS = - ImmutableList.of(TABLE_REFERENCE, TYPE); + static final List REQUIRED_FIELDS = + ImmutableList.of(TABLE_REFERENCE, TYPE); private final String selector; @@ -126,8 +126,8 @@ enum JobField implements FieldSelector { STATUS("status"), USER_EMAIL("user_email"); - static final List REQUIRED_FIELDS = - ImmutableList.of(JOB_REFERENCE, CONFIGURATION); + static final List REQUIRED_FIELDS = + ImmutableList.of(JOB_REFERENCE, CONFIGURATION); private final String selector; @@ -193,7 +193,7 @@ private DatasetOption(BigQueryRpc.Option option, Object value) { */ public static DatasetOption fields(DatasetField... fields) { return new DatasetOption(BigQueryRpc.Option.FIELDS, - SelectorHelper.selector(DatasetField.REQUIRED_FIELDS, fields)); + Helper.selector(DatasetField.REQUIRED_FIELDS, fields)); } } @@ -263,7 +263,7 @@ private TableOption(BigQueryRpc.Option option, Object value) { */ public static TableOption fields(TableField... fields) { return new TableOption(BigQueryRpc.Option.FIELDS, - SelectorHelper.selector(TableField.REQUIRED_FIELDS, fields)); + Helper.selector(TableField.REQUIRED_FIELDS, fields)); } } @@ -361,8 +361,7 @@ public static JobListOption pageToken(String pageToken) { */ public static JobListOption fields(JobField... fields) { return new JobListOption(BigQueryRpc.Option.FIELDS, - SelectorHelper.selector("jobs", JobField.REQUIRED_FIELDS, fields, "state", - "errorResult")); + Helper.listSelector("jobs", JobField.REQUIRED_FIELDS, fields, "state", "errorResult")); } } @@ -386,7 +385,7 @@ private JobOption(BigQueryRpc.Option option, Object value) { */ public static JobOption fields(JobField... fields) { return new JobOption(BigQueryRpc.Option.FIELDS, - SelectorHelper.selector(JobField.REQUIRED_FIELDS, fields)); + Helper.selector(JobField.REQUIRED_FIELDS, fields)); } } diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java b/gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java index 343f67e3381b..be6ab73d00bf 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java @@ -41,9 +41,9 @@ public interface FieldSelector { * A helper class used to build composite selectors given a number of fields. This class is not * supposed to be used directly by users. */ - class SelectorHelper { + class Helper { - private SelectorHelper() {} + private Helper() {} private static final Function FIELD_TO_STRING_FUNCTION = new Function() { @@ -53,7 +53,7 @@ public String apply(FieldSelector fieldSelector) { } }; - private static String selector(List required, FieldSelector[] others, + private static String selector(List required, FieldSelector[] others, String... extraResourceFields) { Set fieldStrings = Sets.newHashSetWithExpectedSize(required.size() + others.length); fieldStrings.addAll(Lists.transform(required, FIELD_TO_STRING_FUNCTION)); @@ -67,7 +67,7 @@ private static String selector(List required, FieldSelector[] oth * method can be used for field selection in API calls that return a single resource. This * method is not supposed to be used directly by users. */ - public static String selector(List required, FieldSelector... others) { + public static String selector(List required, FieldSelector... others) { return selector(required, others, new String[]{}); } @@ -76,7 +76,7 @@ public static String selector(List required, FieldSelector... oth * selector returned by this method can be used for field selection in API calls that return a * list of resources. This method is not supposed to be used directly by users. */ - public static String selector(String containerName, List required, + public static String listSelector(String containerName, List required, FieldSelector... others) { return "nextPageToken," + containerName + '(' + selector(required, others) + ')'; } @@ -87,7 +87,7 @@ public static String selector(String containerName, List required * string selector returned by this method can be used for field selection in API calls that * return a list of resources. This method is not supposed to be used directly by users. */ - public static String selector(String containerName, List required, + public static String listSelector(String containerName, List required, FieldSelector[] others, String... extraResourceFields) { return "nextPageToken," + containerName + '(' + selector(required, others, extraResourceFields) + ')'; diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/SelectorHelperTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/FieldSelectorHelperTest.java similarity index 72% rename from gcloud-java-core/src/test/java/com/google/gcloud/SelectorHelperTest.java rename to gcloud-java-core/src/test/java/com/google/gcloud/FieldSelectorHelperTest.java index 2279205539cc..9871c942180e 100644 --- a/gcloud-java-core/src/test/java/com/google/gcloud/SelectorHelperTest.java +++ b/gcloud-java-core/src/test/java/com/google/gcloud/FieldSelectorHelperTest.java @@ -20,13 +20,13 @@ import static org.junit.Assert.assertTrue; import com.google.common.collect.ImmutableList; -import com.google.gcloud.FieldSelector.SelectorHelper; +import com.google.gcloud.FieldSelector.Helper; import org.junit.Test; import java.util.List; -public class SelectorHelperTest { +public class FieldSelectorHelperTest { private static final FieldSelector FIELD1 = new FieldSelector() { @Override @@ -51,7 +51,7 @@ public String selector() { @Test public void testSelector() { - String selector = SelectorHelper.selector(REQUIRED_FIELDS, FIELD3); + String selector = Helper.selector(REQUIRED_FIELDS, FIELD3); assertTrue(selector.contains("field1")); assertTrue(selector.contains("field2")); assertTrue(selector.contains("field3")); @@ -60,7 +60,7 @@ public void testSelector() { @Test public void testListSelector() { - String selector = SelectorHelper.selector(CONTAINER, REQUIRED_FIELDS, FIELD3); + String selector = Helper.listSelector(CONTAINER, REQUIRED_FIELDS, FIELD3); assertTrue(selector.startsWith("nextPageToken,container(")); assertTrue(selector.contains("field1")); assertTrue(selector.contains("field2")); @@ -68,4 +68,17 @@ public void testListSelector() { assertTrue(selector.endsWith(")")); assertEquals(45, selector.length()); } + + @Test + public void testListSelectorWithExtraFields() { + String selector = Helper.listSelector(CONTAINER, REQUIRED_FIELDS, + new FieldSelector[]{FIELD3}, "field4"); + assertTrue(selector.startsWith("nextPageToken,container(")); + assertTrue(selector.contains("field1")); + assertTrue(selector.contains("field2")); + assertTrue(selector.contains("field3")); + assertTrue(selector.contains("field4")); + assertTrue(selector.endsWith(")")); + assertEquals(52, selector.length()); + } } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index c4b08e31d533..d95d11a97c19 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -18,7 +18,7 @@ import com.google.common.collect.ImmutableList; import com.google.gcloud.FieldSelector; -import com.google.gcloud.FieldSelector.SelectorHelper; +import com.google.gcloud.FieldSelector.Helper; import com.google.gcloud.Page; import com.google.gcloud.Service; import com.google.gcloud.dns.spi.DnsRpc; @@ -45,7 +45,7 @@ enum ProjectField implements FieldSelector { PROJECT_NUMBER("number"), QUOTA("quota"); - static final List REQUIRED_FIELDS = ImmutableList.of(PROJECT_ID); + static final List REQUIRED_FIELDS = ImmutableList.of(PROJECT_ID); private final String selector; @@ -75,7 +75,7 @@ enum ZoneField implements FieldSelector { NAME_SERVER_SET("nameServerSet"), NAME_SERVERS("nameServers"); - static final List REQUIRED_FIELDS = ImmutableList.of(NAME); + static final List REQUIRED_FIELDS = ImmutableList.of(NAME); private final String selector; @@ -102,7 +102,7 @@ enum RecordSetField implements FieldSelector { TTL("ttl"), TYPE("type"); - static final List REQUIRED_FIELDS = ImmutableList.of(NAME, TYPE); + static final List REQUIRED_FIELDS = ImmutableList.of(NAME, TYPE); private final String selector; @@ -120,8 +120,8 @@ public String selector() { * The fields of a change request. * *

    These values can be used to specify the fields to include in a partial response when calling - * {@link Dns#applyChangeRequest(String, ChangeRequestInfo, ChangeRequestOption...)} The ID is always - * returned even if not selected. + * {@link Dns#applyChangeRequest(String, ChangeRequestInfo, ChangeRequestOption...)} The ID is + * always returned even if not selected. */ enum ChangeRequestField implements FieldSelector { ID("id"), @@ -130,7 +130,7 @@ enum ChangeRequestField implements FieldSelector { ADDITIONS("additions"), DELETIONS("deletions"); - static final List REQUIRED_FIELDS = ImmutableList.of(ID); + static final List REQUIRED_FIELDS = ImmutableList.of(ID); private final String selector; @@ -158,7 +158,7 @@ public String selector() { /** * Class for specifying record set listing options. */ - class RecordSetListOption extends Option implements Serializable { + class RecordSetListOption extends Option { private static final long serialVersionUID = 1009627025381096098L; @@ -176,7 +176,7 @@ class RecordSetListOption extends Option implements Serializable { */ public static RecordSetListOption fields(RecordSetField... fields) { return new RecordSetListOption(DnsRpc.Option.FIELDS, - SelectorHelper.selector("rrsets", RecordSetField.REQUIRED_FIELDS, fields)); + Helper.listSelector("rrsets", RecordSetField.REQUIRED_FIELDS, fields)); } /** @@ -218,7 +218,7 @@ public static RecordSetListOption type(RecordSet.Type type) { /** * Class for specifying zone field options. */ - class ZoneOption extends Option implements Serializable { + class ZoneOption extends Option { private static final long serialVersionUID = -8065564464895945037L; @@ -235,14 +235,14 @@ class ZoneOption extends Option implements Serializable { */ public static ZoneOption fields(ZoneField... fields) { return new ZoneOption(DnsRpc.Option.FIELDS, - SelectorHelper.selector(ZoneField.REQUIRED_FIELDS, fields)); + Helper.selector(ZoneField.REQUIRED_FIELDS, fields)); } } /** * Class for specifying zone listing options. */ - class ZoneListOption extends Option implements Serializable { + class ZoneListOption extends Option { private static final long serialVersionUID = -2830645032124504717L; @@ -259,7 +259,7 @@ class ZoneListOption extends Option implements Serializable { */ public static ZoneListOption fields(ZoneField... fields) { return new ZoneListOption(DnsRpc.Option.FIELDS, - SelectorHelper.selector("managedZones", ZoneField.REQUIRED_FIELDS, fields)); + Helper.listSelector("managedZones", ZoneField.REQUIRED_FIELDS, fields)); } /** @@ -293,7 +293,7 @@ public static ZoneListOption pageSize(int pageSize) { /** * Class for specifying project options. */ - class ProjectOption extends Option implements Serializable { + class ProjectOption extends Option { private static final long serialVersionUID = 6817937338218847748L; @@ -311,14 +311,14 @@ class ProjectOption extends Option implements Serializable { */ public static ProjectOption fields(ProjectField... fields) { return new ProjectOption(DnsRpc.Option.FIELDS, - SelectorHelper.selector(ProjectField.REQUIRED_FIELDS, fields)); + Helper.selector(ProjectField.REQUIRED_FIELDS, fields)); } } /** * Class for specifying change request field options. */ - class ChangeRequestOption extends Option implements Serializable { + class ChangeRequestOption extends Option { private static final long serialVersionUID = 1067273695061077782L; @@ -337,14 +337,14 @@ class ChangeRequestOption extends Option implements Serializable { */ public static ChangeRequestOption fields(ChangeRequestField... fields) { return new ChangeRequestOption(DnsRpc.Option.FIELDS, - SelectorHelper.selector(ChangeRequestField.REQUIRED_FIELDS, fields)); + Helper.selector(ChangeRequestField.REQUIRED_FIELDS, fields)); } } /** * Class for specifying change request listing options. */ - class ChangeRequestListOption extends Option implements Serializable { + class ChangeRequestListOption extends Option { private static final long serialVersionUID = -900209143895376089L; @@ -363,7 +363,7 @@ class ChangeRequestListOption extends Option implements Serializable { */ public static ChangeRequestListOption fields(ChangeRequestField... fields) { return new ChangeRequestListOption(DnsRpc.Option.FIELDS, - SelectorHelper.selector("changes", ChangeRequestField.REQUIRED_FIELDS, fields)); + Helper.listSelector("changes", ChangeRequestField.REQUIRED_FIELDS, fields)); } /** diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java index e000ca69c359..92494a5152fe 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java @@ -18,7 +18,7 @@ import com.google.common.collect.ImmutableList; import com.google.gcloud.FieldSelector; -import com.google.gcloud.FieldSelector.SelectorHelper; +import com.google.gcloud.FieldSelector.Helper; import com.google.gcloud.IamPolicy; import com.google.gcloud.Page; import com.google.gcloud.Service; @@ -50,7 +50,7 @@ enum ProjectField implements FieldSelector { STATE("lifecycleState"), CREATE_TIME("createTime"); - static final List REQUIRED_FIELDS = ImmutableList.of(PROJECT_ID); + static final List REQUIRED_FIELDS = ImmutableList.of(PROJECT_ID); private final String selector; @@ -85,7 +85,7 @@ private ProjectGetOption(ResourceManagerRpc.Option option, Object value) { */ public static ProjectGetOption fields(ProjectField... fields) { return new ProjectGetOption(ResourceManagerRpc.Option.FIELDS, - SelectorHelper.selector(ProjectField.REQUIRED_FIELDS, fields)); + Helper.selector(ProjectField.REQUIRED_FIELDS, fields)); } } @@ -159,7 +159,7 @@ public static ProjectListOption pageSize(int pageSize) { */ public static ProjectListOption fields(ProjectField... fields) { return new ProjectListOption(ResourceManagerRpc.Option.FIELDS, - SelectorHelper.selector("projects", ProjectField.REQUIRED_FIELDS, fields)); + Helper.listSelector("projects", ProjectField.REQUIRED_FIELDS, fields)); } } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index 87d82aad686b..72d89348f5fa 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -25,7 +25,7 @@ import com.google.gcloud.AuthCredentials; import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials; import com.google.gcloud.FieldSelector; -import com.google.gcloud.FieldSelector.SelectorHelper; +import com.google.gcloud.FieldSelector.Helper; import com.google.gcloud.Page; import com.google.gcloud.ReadChannel; import com.google.gcloud.Service; @@ -89,7 +89,7 @@ enum BucketField implements FieldSelector { STORAGE_CLASS("storageClass"), ETAG("etag"); - static final List REQUIRED_FIELDS = ImmutableList.of(NAME); + static final List REQUIRED_FIELDS = ImmutableList.of(NAME); private final String selector; @@ -129,8 +129,7 @@ enum BlobField implements FieldSelector { TIME_DELETED("timeDeleted"), UPDATED("updated"); - static final List REQUIRED_FIELDS = - ImmutableList.of(BUCKET, NAME); + static final List REQUIRED_FIELDS = ImmutableList.of(BUCKET, NAME); private final String selector; @@ -257,7 +256,7 @@ public static BucketGetOption metagenerationNotMatch(long metageneration) { */ public static BucketGetOption fields(BucketField... fields) { return new BucketGetOption(StorageRpc.Option.FIELDS, - SelectorHelper.selector(BucketField.REQUIRED_FIELDS, fields)); + Helper.selector(BucketField.REQUIRED_FIELDS, fields)); } } @@ -598,7 +597,7 @@ public static BlobGetOption metagenerationNotMatch(long metageneration) { */ public static BlobGetOption fields(BlobField... fields) { return new BlobGetOption(StorageRpc.Option.FIELDS, - SelectorHelper.selector(BlobField.REQUIRED_FIELDS, fields)); + Helper.selector(BlobField.REQUIRED_FIELDS, fields)); } } @@ -643,7 +642,7 @@ public static BucketListOption prefix(String prefix) { */ public static BucketListOption fields(BucketField... fields) { return new BucketListOption(StorageRpc.Option.FIELDS, - SelectorHelper.selector("items", BucketField.REQUIRED_FIELDS, fields)); + Helper.listSelector("items", BucketField.REQUIRED_FIELDS, fields)); } } @@ -711,7 +710,7 @@ public static BlobListOption versions(boolean versions) { */ public static BlobListOption fields(BlobField... fields) { return new BlobListOption(StorageRpc.Option.FIELDS, - SelectorHelper.selector("items", BlobField.REQUIRED_FIELDS, fields)); + Helper.listSelector("items", BlobField.REQUIRED_FIELDS, fields)); } } @@ -1529,7 +1528,7 @@ public static Builder builder() { * are merged with metadata in the provided {@code BlobInfo} objects. To replace metadata instead * you first have to unset them. Unsetting metadata can be done by setting the provided * {@code BlobInfo} objects metadata to {@code null}. See - * {@link #update(com.google.gcloud.storage.BlobInfo)} for a code example. + * {@link #update(BlobInfo)} for a code example. * * @param blobInfos blobs to update * @return an immutable list of {@code Blob} objects. If a blob does not exist or access to it From 379a0a89e116413827339169361879480fec703b Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 1 Apr 2016 00:28:12 +0200 Subject: [PATCH 217/375] Get projectId from gcloud active config --- .../java/com/google/gcloud/ServiceOptions.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java index d45069434a26..1c5289bbcda9 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java @@ -27,6 +27,7 @@ import com.google.api.client.http.javanet.NetHttpTransport; import com.google.auth.http.HttpCredentialsAdapter; import com.google.common.collect.Iterables; +import com.google.common.io.Files; import com.google.gcloud.spi.ServiceRpcFactory; import java.io.BufferedReader; @@ -42,6 +43,7 @@ import java.lang.reflect.Method; import java.net.HttpURLConnection; import java.net.URL; +import java.nio.charset.Charset; import java.util.Enumeration; import java.util.Locale; import java.util.Objects; @@ -381,6 +383,18 @@ protected String defaultProject() { return projectId != null ? projectId : googleCloudProjectId(); } + private static String activeGoogleCloudConfig(File configDir) { + String activeGoogleCloudConfig = null; + try { + activeGoogleCloudConfig = + Files.readFirstLine(new File(configDir, "active_config"), Charset.defaultCharset()); + } catch (IOException ex) { + // ignore + } + // if reading active_config failed or the file is empty we try default + return firstNonNull(activeGoogleCloudConfig, "default"); + } + protected static String googleCloudProjectId() { File configDir; if (System.getenv().containsKey("CLOUDSDK_CONFIG")) { @@ -390,9 +404,10 @@ protected static String googleCloudProjectId() { } else { configDir = new File(System.getProperty("user.home"), ".config/gcloud"); } + String activeConfig = activeGoogleCloudConfig(configDir); FileReader fileReader = null; try { - fileReader = new FileReader(new File(configDir, "configurations/config_default")); + fileReader = new FileReader(new File(configDir, "configurations/config_" + activeConfig)); } catch (FileNotFoundException newConfigFileNotFoundEx) { try { fileReader = new FileReader(new File(configDir, "properties")); From 3324808be960ddd0b6dbbe696a7e373fe67cbfa8 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 1 Apr 2016 16:07:20 +0200 Subject: [PATCH 218/375] Rename id to generatedId for BigQuery resources --- .../com/google/gcloud/bigquery/BigQuery.java | 19 ++++++------ .../com/google/gcloud/bigquery/Dataset.java | 4 +-- .../google/gcloud/bigquery/DatasetInfo.java | 29 +++++++++---------- .../java/com/google/gcloud/bigquery/Job.java | 4 +-- .../com/google/gcloud/bigquery/JobInfo.java | 28 +++++++++--------- .../com/google/gcloud/bigquery/Table.java | 4 +-- .../com/google/gcloud/bigquery/TableInfo.java | 28 +++++++++--------- .../gcloud/bigquery/DatasetInfoTest.java | 10 +++---- .../google/gcloud/bigquery/DatasetTest.java | 8 ++--- .../google/gcloud/bigquery/JobInfoTest.java | 20 ++++++------- .../com/google/gcloud/bigquery/JobTest.java | 10 +++---- .../gcloud/bigquery/SerializationTest.java | 10 +++---- .../google/gcloud/bigquery/TableInfoTest.java | 16 +++++----- .../com/google/gcloud/bigquery/TableTest.java | 8 ++--- .../gcloud/bigquery/it/ITBigQueryTest.java | 10 +++---- 15 files changed, 104 insertions(+), 104 deletions(-) diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java index 2d864383e81a..d40cc8145feb 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java @@ -471,9 +471,10 @@ public static QueryResultsOption maxWaitTime(long maxWaitTime) { Dataset getDataset(DatasetId datasetId, DatasetOption... options); /** - * Lists the project's datasets. This method returns partial information on each dataset - * ({@link Dataset#datasetId()}, {@link Dataset#friendlyName()} and {@link Dataset#id()}). To get - * complete information use either {@link #getDataset(String, DatasetOption...)} or + * Lists the project's datasets. This method returns partial information on each dataset: + * ({@link Dataset#datasetId()}, {@link Dataset#friendlyName()} and + * {@link Dataset#generatedId()}). To get complete information use either + * {@link #getDataset(String, DatasetOption...)} or * {@link #getDataset(DatasetId, DatasetOption...)}. * * @throws BigQueryException upon failure @@ -541,9 +542,9 @@ public static QueryResultsOption maxWaitTime(long maxWaitTime) { Table getTable(TableId tableId, TableOption... options); /** - * Lists the tables in the dataset. This method returns partial information on each table - * ({@link Table#tableId()}, {@link Table#friendlyName()}, {@link Table#id()} and type, which - * is part of {@link Table#definition()}). To get complete information use either + * Lists the tables in the dataset. This method returns partial information on each table: + * ({@link Table#tableId()}, {@link Table#friendlyName()}, {@link Table#generatedId()} and type, + * which is part of {@link Table#definition()}). To get complete information use either * {@link #getTable(TableId, TableOption...)} or * {@link #getTable(String, String, TableOption...)}. * @@ -552,9 +553,9 @@ public static QueryResultsOption maxWaitTime(long maxWaitTime) { Page

    listTables(String datasetId, TableListOption... options); /** - * Lists the tables in the dataset. This method returns partial information on each table - * ({@link Table#tableId()}, {@link Table#friendlyName()}, {@link Table#id()} and type, which - * is part of {@link Table#definition()}). To get complete information use either + * Lists the tables in the dataset. This method returns partial information on each table: + * ({@link Table#tableId()}, {@link Table#friendlyName()}, {@link Table#generatedId()} and type, + * which is part of {@link Table#definition()}). To get complete information use either * {@link #getTable(TableId, TableOption...)} or * {@link #getTable(String, String, TableOption...)}. * diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Dataset.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Dataset.java index e17d3e82c4ef..215a0c662c3b 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Dataset.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Dataset.java @@ -103,8 +103,8 @@ public Builder friendlyName(String friendlyName) { } @Override - Builder id(String id) { - infoBuilder.id(id); + Builder generatedId(String generatedId) { + infoBuilder.generatedId(generatedId); return this; } diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/DatasetInfo.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/DatasetInfo.java index aa767b97631b..9f1d25f05925 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/DatasetInfo.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/DatasetInfo.java @@ -55,8 +55,7 @@ public Dataset apply(DatasetInfo datasetInfo) { return datasetInfo.toPb(); } }; - - private static final long serialVersionUID = -6615133444520365839L; + private static final long serialVersionUID = 8469473744160758489L; private final DatasetId datasetId; private final List acl; @@ -65,7 +64,7 @@ public Dataset apply(DatasetInfo datasetInfo) { private final String description; private final String etag; private final String friendlyName; - private final String id; + private final String generatedId; private final Long lastModified; private final String location; private final String selfLink; @@ -114,7 +113,7 @@ public abstract static class Builder { */ public abstract Builder friendlyName(String friendlyName); - abstract Builder id(String id); + abstract Builder generatedId(String generatedId); abstract Builder lastModified(Long lastModified); @@ -144,7 +143,7 @@ static final class BuilderImpl extends Builder { private String description; private String etag; private String friendlyName; - private String id; + private String generatedId; private Long lastModified; private String location; private String selfLink; @@ -159,7 +158,7 @@ static final class BuilderImpl extends Builder { this.description = datasetInfo.description; this.etag = datasetInfo.etag; this.friendlyName = datasetInfo.friendlyName; - this.id = datasetInfo.id; + this.generatedId = datasetInfo.generatedId; this.lastModified = datasetInfo.lastModified; this.location = datasetInfo.location; this.selfLink = datasetInfo.selfLink; @@ -182,7 +181,7 @@ public Acl apply(Dataset.Access accessPb) { this.description = datasetPb.getDescription(); this.etag = datasetPb.getEtag(); this.friendlyName = datasetPb.getFriendlyName(); - this.id = datasetPb.getId(); + this.generatedId = datasetPb.getId(); this.lastModified = datasetPb.getLastModifiedTime(); this.location = datasetPb.getLocation(); this.selfLink = datasetPb.getSelfLink(); @@ -232,8 +231,8 @@ public Builder friendlyName(String friendlyName) { } @Override - Builder id(String id) { - this.id = id; + Builder generatedId(String generatedId) { + this.generatedId = generatedId; return this; } @@ -269,7 +268,7 @@ public DatasetInfo build() { description = builder.description; etag = builder.etag; friendlyName = builder.friendlyName; - id = builder.id; + generatedId = builder.generatedId; lastModified = builder.lastModified; location = builder.location; selfLink = builder.selfLink; @@ -333,10 +332,10 @@ public String friendlyName() { } /** - * Returns an opaque id for the dataset. + * Returns the service-generated id for the dataset. */ - public String id() { - return id; + public String generatedId() { + return generatedId; } /** @@ -381,7 +380,7 @@ public String toString() { .add("description", description) .add("etag", etag) .add("friendlyName", friendlyName) - .add("id", id) + .add("generatedId", generatedId) .add("lastModified", lastModified) .add("location", location) .add("selfLink", selfLink) @@ -431,7 +430,7 @@ Dataset toPb() { datasetPb.setDescription(description); datasetPb.setEtag(etag); datasetPb.setFriendlyName(friendlyName); - datasetPb.setId(id); + datasetPb.setId(generatedId); datasetPb.setLastModifiedTime(lastModified); datasetPb.setLocation(location); datasetPb.setSelfLink(selfLink); diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Job.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Job.java index 1e63344a600d..586395a0f879 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Job.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Job.java @@ -63,8 +63,8 @@ Builder etag(String etag) { } @Override - Builder id(String id) { - infoBuilder.id(id); + Builder generatedId(String generatedId) { + infoBuilder.generatedId(generatedId); return this; } diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/JobInfo.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/JobInfo.java index 1adf7fabafc1..b15ba38f8912 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/JobInfo.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/JobInfo.java @@ -42,10 +42,10 @@ public JobInfo apply(Job pb) { } }; - private static final long serialVersionUID = -3272941007234620265L; + private static final long serialVersionUID = 2740548743267670124L; private final String etag; - private final String id; + private final String generatedId; private final JobId jobId; private final String selfLink; private final JobStatus status; @@ -95,7 +95,7 @@ public abstract static class Builder { abstract Builder etag(String etag); - abstract Builder id(String id); + abstract Builder generatedId(String generatedId); /** * Sets the job identity. @@ -128,7 +128,7 @@ public abstract static class Builder { static final class BuilderImpl extends Builder { private String etag; - private String id; + private String generatedId; private JobId jobId; private String selfLink; private JobStatus status; @@ -140,7 +140,7 @@ static final class BuilderImpl extends Builder { BuilderImpl(JobInfo jobInfo) { this.etag = jobInfo.etag; - this.id = jobInfo.id; + this.generatedId = jobInfo.generatedId; this.jobId = jobInfo.jobId; this.selfLink = jobInfo.selfLink; this.status = jobInfo.status; @@ -151,7 +151,7 @@ static final class BuilderImpl extends Builder { BuilderImpl(Job jobPb) { this.etag = jobPb.getEtag(); - this.id = jobPb.getId(); + this.generatedId = jobPb.getId(); if (jobPb.getJobReference() != null) { this.jobId = JobId.fromPb(jobPb.getJobReference()); } @@ -173,8 +173,8 @@ Builder etag(String etag) { } @Override - Builder id(String id) { - this.id = id; + Builder generatedId(String generatedId) { + this.generatedId = generatedId; return this; } @@ -223,7 +223,7 @@ public JobInfo build() { JobInfo(BuilderImpl builder) { this.jobId = builder.jobId; this.etag = builder.etag; - this.id = builder.id; + this.generatedId = builder.generatedId; this.selfLink = builder.selfLink; this.status = builder.status; this.statistics = builder.statistics; @@ -239,10 +239,10 @@ public String etag() { } /** - * Returns an opaque id for the job. + * Returns the service-generated id for the job. */ - public String id() { - return id; + public String generatedId() { + return generatedId; } /** @@ -306,7 +306,7 @@ public String toString() { .add("statistics", statistics) .add("userEmail", userEmail) .add("etag", etag) - .add("id", id) + .add("generatedId", generatedId) .add("selfLink", selfLink) .add("configuration", configuration) .toString(); @@ -331,7 +331,7 @@ JobInfo setProjectId(String projectId) { Job toPb() { Job jobPb = new Job(); jobPb.setEtag(etag); - jobPb.setId(id); + jobPb.setId(generatedId); jobPb.setSelfLink(selfLink); jobPb.setUserEmail(userEmail); if (jobId != null) { diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Table.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Table.java index 3f902d2ff242..b007771645df 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Table.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Table.java @@ -92,8 +92,8 @@ public Builder friendlyName(String friendlyName) { } @Override - Builder id(String id) { - infoBuilder.id(id); + Builder generatedId(String generatedId) { + infoBuilder.generatedId(generatedId); return this; } diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableInfo.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableInfo.java index de331350e978..938907e245e7 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableInfo.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableInfo.java @@ -52,10 +52,10 @@ public Table apply(TableInfo tableInfo) { } }; - private static final long serialVersionUID = -7679032506430816205L; + private static final long serialVersionUID = 609769795097719407L; private final String etag; - private final String id; + private final String generatedId; private final String selfLink; private final TableId tableId; private final String friendlyName; @@ -90,7 +90,7 @@ public abstract static class Builder { */ public abstract Builder friendlyName(String friendlyName); - abstract Builder id(String id); + abstract Builder generatedId(String generatedId); abstract Builder lastModifiedTime(Long lastModifiedTime); @@ -117,7 +117,7 @@ public abstract static class Builder { static class BuilderImpl extends Builder { private String etag; - private String id; + private String generatedId; private String selfLink; private TableId tableId; private String friendlyName; @@ -131,7 +131,7 @@ static class BuilderImpl extends Builder { BuilderImpl(TableInfo tableInfo) { this.etag = tableInfo.etag; - this.id = tableInfo.id; + this.generatedId = tableInfo.generatedId; this.selfLink = tableInfo.selfLink; this.tableId = tableInfo.tableId; this.friendlyName = tableInfo.friendlyName; @@ -152,7 +152,7 @@ static class BuilderImpl extends Builder { this.friendlyName = tablePb.getFriendlyName(); this.creationTime = tablePb.getCreationTime(); this.etag = tablePb.getEtag(); - this.id = tablePb.getId(); + this.generatedId = tablePb.getId(); this.selfLink = tablePb.getSelfLink(); this.definition = TableDefinition.fromPb(tablePb); } @@ -188,8 +188,8 @@ public Builder friendlyName(String friendlyName) { } @Override - Builder id(String id) { - this.id = id; + Builder generatedId(String generatedId) { + this.generatedId = generatedId; return this; } @@ -226,7 +226,7 @@ public TableInfo build() { TableInfo(BuilderImpl builder) { this.tableId = checkNotNull(builder.tableId); this.etag = builder.etag; - this.id = builder.id; + this.generatedId = builder.generatedId; this.selfLink = builder.selfLink; this.friendlyName = builder.friendlyName; this.description = builder.description; @@ -244,10 +244,10 @@ public String etag() { } /** - * Returns an opaque id for the table. + * Returns the service-generated id for the table. */ - public String id() { - return id; + public String generatedId() { + return generatedId; } /** @@ -321,7 +321,7 @@ public String toString() { return MoreObjects.toStringHelper(this) .add("tableId", tableId) .add("etag", etag) - .add("id", id) + .add("generatedId", generatedId) .add("selfLink", selfLink) .add("friendlyName", friendlyName) .add("description", description) @@ -379,7 +379,7 @@ Table toPb() { tablePb.setEtag(etag); tablePb.setExpirationTime(expirationTime); tablePb.setFriendlyName(friendlyName); - tablePb.setId(id); + tablePb.setId(generatedId); tablePb.setSelfLink(selfLink); return tablePb; } diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetInfoTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetInfoTest.java index 20875c0fc853..474a31d44a20 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetInfoTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetInfoTest.java @@ -38,7 +38,7 @@ public class DatasetInfoTest { private static final String DESCRIPTION = "description"; private static final String ETAG = "0xFF00"; private static final String FRIENDLY_NAME = "friendlyDataset"; - private static final String ID = "P/D:1"; + private static final String GENERATED_ID = "P/D:1"; private static final Long LAST_MODIFIED = CREATION_TIME + 50; private static final String LOCATION = ""; private static final String SELF_LINK = "http://bigquery/p/d"; @@ -51,7 +51,7 @@ public class DatasetInfoTest { .description(DESCRIPTION) .etag(ETAG) .friendlyName(FRIENDLY_NAME) - .id(ID) + .generatedId(GENERATED_ID) .lastModified(LAST_MODIFIED) .location(LOCATION) .selfLink(SELF_LINK) @@ -90,7 +90,7 @@ public void testBuilder() { assertEquals(DESCRIPTION, DATASET_INFO.description()); assertEquals(ETAG, DATASET_INFO.etag()); assertEquals(FRIENDLY_NAME, DATASET_INFO.friendlyName()); - assertEquals(ID, DATASET_INFO.id()); + assertEquals(GENERATED_ID, DATASET_INFO.generatedId()); assertEquals(LAST_MODIFIED, DATASET_INFO.lastModified()); assertEquals(LOCATION, DATASET_INFO.location()); assertEquals(SELF_LINK, DATASET_INFO.selfLink()); @@ -101,7 +101,7 @@ public void testBuilder() { assertEquals(DESCRIPTION, DATASET_INFO_COMPLETE.description()); assertEquals(ETAG, DATASET_INFO_COMPLETE.etag()); assertEquals(FRIENDLY_NAME, DATASET_INFO_COMPLETE.friendlyName()); - assertEquals(ID, DATASET_INFO_COMPLETE.id()); + assertEquals(GENERATED_ID, DATASET_INFO_COMPLETE.generatedId()); assertEquals(LAST_MODIFIED, DATASET_INFO_COMPLETE.lastModified()); assertEquals(LOCATION, DATASET_INFO_COMPLETE.location()); assertEquals(SELF_LINK, DATASET_INFO_COMPLETE.selfLink()); @@ -125,7 +125,7 @@ private void compareDatasets(DatasetInfo expected, DatasetInfo value) { assertEquals(expected.description(), value.description()); assertEquals(expected.etag(), value.etag()); assertEquals(expected.friendlyName(), value.friendlyName()); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.location(), value.location()); assertEquals(expected.selfLink(), value.selfLink()); assertEquals(expected.acl(), value.acl()); diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetTest.java index dd03b7899ebc..43c550c59d11 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetTest.java @@ -51,7 +51,7 @@ public class DatasetTest { private static final String DESCRIPTION = "description"; private static final String ETAG = "0xFF00"; private static final String FRIENDLY_NAME = "friendlyDataset"; - private static final String ID = "P/D:1"; + private static final String GENERATED_ID = "P/D:1"; private static final Long LAST_MODIFIED = CREATION_TIME + 50; private static final String LOCATION = ""; private static final String SELF_LINK = "http://bigquery/p/d"; @@ -102,7 +102,7 @@ public void testBuilder() { .description(DESCRIPTION) .etag(ETAG) .friendlyName(FRIENDLY_NAME) - .id(ID) + .generatedId(GENERATED_ID) .lastModified(LAST_MODIFIED) .location(LOCATION) .selfLink(SELF_LINK) @@ -114,7 +114,7 @@ public void testBuilder() { assertEquals(DESCRIPTION, builtDataset.description()); assertEquals(ETAG, builtDataset.etag()); assertEquals(FRIENDLY_NAME, builtDataset.friendlyName()); - assertEquals(ID, builtDataset.id()); + assertEquals(GENERATED_ID, builtDataset.generatedId()); assertEquals(LAST_MODIFIED, builtDataset.lastModified()); assertEquals(LOCATION, builtDataset.location()); assertEquals(SELF_LINK, builtDataset.selfLink()); @@ -362,7 +362,7 @@ private void compareDatasetInfo(DatasetInfo expected, DatasetInfo value) { assertEquals(expected.description(), value.description()); assertEquals(expected.etag(), value.etag()); assertEquals(expected.friendlyName(), value.friendlyName()); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.location(), value.location()); assertEquals(expected.selfLink(), value.selfLink()); assertEquals(expected.acl(), value.acl()); diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobInfoTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobInfoTest.java index 260088470aff..9c90fbe7b05f 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobInfoTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobInfoTest.java @@ -37,7 +37,7 @@ public class JobInfoTest { private static final String ETAG = "etag"; - private static final String ID = "id"; + private static final String GENERATED_ID = "id"; private static final String SELF_LINK = "selfLink"; private static final String EMAIL = "email"; private static final JobId JOB_ID = JobId.of("job"); @@ -163,7 +163,7 @@ public class JobInfoTest { .statistics(COPY_JOB_STATISTICS) .jobId(JOB_ID) .etag(ETAG) - .id(ID) + .generatedId(GENERATED_ID) .selfLink(SELF_LINK) .userEmail(EMAIL) .status(JOB_STATUS) @@ -173,7 +173,7 @@ public class JobInfoTest { .statistics(EXTRACT_JOB_STATISTICS) .jobId(JOB_ID) .etag(ETAG) - .id(ID) + .generatedId(GENERATED_ID) .selfLink(SELF_LINK) .userEmail(EMAIL) .status(JOB_STATUS) @@ -183,7 +183,7 @@ public class JobInfoTest { .statistics(LOAD_JOB_STATISTICS) .jobId(JOB_ID) .etag(ETAG) - .id(ID) + .generatedId(GENERATED_ID) .selfLink(SELF_LINK) .userEmail(EMAIL) .status(JOB_STATUS) @@ -193,7 +193,7 @@ public class JobInfoTest { .statistics(QUERY_JOB_STATISTICS) .jobId(JOB_ID) .etag(ETAG) - .id(ID) + .generatedId(GENERATED_ID) .selfLink(SELF_LINK) .userEmail(EMAIL) .status(JOB_STATUS) @@ -266,7 +266,7 @@ public void testToBuilderIncomplete() { @Test public void testBuilder() { assertEquals(ETAG, COPY_JOB.etag()); - assertEquals(ID, COPY_JOB.id()); + assertEquals(GENERATED_ID, COPY_JOB.generatedId()); assertEquals(SELF_LINK, COPY_JOB.selfLink()); assertEquals(EMAIL, COPY_JOB.userEmail()); assertEquals(JOB_ID, COPY_JOB.jobId()); @@ -275,7 +275,7 @@ public void testBuilder() { assertEquals(COPY_JOB_STATISTICS, COPY_JOB.statistics()); assertEquals(ETAG, EXTRACT_JOB.etag()); - assertEquals(ID, EXTRACT_JOB.id()); + assertEquals(GENERATED_ID, EXTRACT_JOB.generatedId()); assertEquals(SELF_LINK, EXTRACT_JOB.selfLink()); assertEquals(EMAIL, EXTRACT_JOB.userEmail()); assertEquals(JOB_ID, EXTRACT_JOB.jobId()); @@ -284,7 +284,7 @@ public void testBuilder() { assertEquals(EXTRACT_JOB_STATISTICS, EXTRACT_JOB.statistics()); assertEquals(ETAG, LOAD_JOB.etag()); - assertEquals(ID, LOAD_JOB.id()); + assertEquals(GENERATED_ID, LOAD_JOB.generatedId()); assertEquals(SELF_LINK, LOAD_JOB.selfLink()); assertEquals(EMAIL, LOAD_JOB.userEmail()); assertEquals(JOB_ID, LOAD_JOB.jobId()); @@ -293,7 +293,7 @@ public void testBuilder() { assertEquals(LOAD_JOB_STATISTICS, LOAD_JOB.statistics()); assertEquals(ETAG, QUERY_JOB.etag()); - assertEquals(ID, QUERY_JOB.id()); + assertEquals(GENERATED_ID, QUERY_JOB.generatedId()); assertEquals(SELF_LINK, QUERY_JOB.selfLink()); assertEquals(EMAIL, QUERY_JOB.userEmail()); assertEquals(JOB_ID, QUERY_JOB.jobId()); @@ -359,7 +359,7 @@ private void compareJobInfo(JobInfo expected, JobInfo value) { assertEquals(expected.hashCode(), value.hashCode()); assertEquals(expected.toString(), value.toString()); assertEquals(expected.etag(), value.etag()); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.jobId(), value.jobId()); assertEquals(expected.selfLink(), value.selfLink()); assertEquals(expected.status(), value.status()); diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java index db51706fff5a..e066bbed2fb4 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java @@ -36,7 +36,7 @@ public class JobTest { private static final TableId TABLE_ID1 = TableId.of("dataset", "table1"); private static final TableId TABLE_ID2 = TableId.of("dataset", "table2"); private static final String ETAG = "etag"; - private static final String ID = "id"; + private static final String GENERATED_ID = "id"; private static final String SELF_LINK = "selfLink"; private static final String EMAIL = "email"; private static final JobStatus JOB_STATUS = new JobStatus(JobStatus.State.DONE); @@ -52,7 +52,7 @@ public class JobTest { .statistics(COPY_JOB_STATISTICS) .jobId(JOB_ID) .etag(ETAG) - .id(ID) + .generatedId(GENERATED_ID) .selfLink(SELF_LINK) .userEmail(EMAIL) .status(JOB_STATUS) @@ -89,13 +89,13 @@ public void testBuilder() { .statistics(COPY_JOB_STATISTICS) .jobId(JOB_ID) .etag(ETAG) - .id(ID) + .generatedId(GENERATED_ID) .selfLink(SELF_LINK) .userEmail(EMAIL) .status(JOB_STATUS) .build(); assertEquals(ETAG, builtJob.etag()); - assertEquals(ID, builtJob.id()); + assertEquals(GENERATED_ID, builtJob.generatedId()); assertEquals(SELF_LINK, builtJob.selfLink()); assertEquals(EMAIL, builtJob.userEmail()); assertEquals(JOB_ID, builtJob.jobId()); @@ -247,7 +247,7 @@ private void compareJobInfo(JobInfo expected, JobInfo value) { assertEquals(expected.hashCode(), value.hashCode()); assertEquals(expected.toString(), value.toString()); assertEquals(expected.etag(), value.etag()); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.jobId(), value.jobId()); assertEquals(expected.selfLink(), value.selfLink()); assertEquals(expected.status(), value.status()); diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java index 111df074ffa2..61e763f9a539 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java @@ -44,7 +44,7 @@ public class SerializationTest extends BaseSerializationTest { private static final String DESCRIPTION = "Description"; private static final String ETAG = "0xFF00"; private static final String FRIENDLY_NAME = "friendlyDataset"; - private static final String ID = "P/D:1"; + private static final String GENERATED_ID = "P/D:1"; private static final Long LAST_MODIFIED = CREATION_TIME + 50; private static final String LOCATION = ""; private static final String SELF_LINK = "http://bigquery/p/d"; @@ -56,7 +56,7 @@ public class SerializationTest extends BaseSerializationTest { .description(DESCRIPTION) .etag(ETAG) .friendlyName(FRIENDLY_NAME) - .id(ID) + .generatedId(GENERATED_ID) .lastModified(LAST_MODIFIED) .location(LOCATION) .selfLink(SELF_LINK) @@ -106,21 +106,21 @@ public class SerializationTest extends BaseSerializationTest { .creationTime(CREATION_TIME) .description(DESCRIPTION) .etag(ETAG) - .id(ID) + .generatedId(GENERATED_ID) .build(); private static final TableDefinition VIEW_DEFINITION = ViewDefinition.of("QUERY"); private static final TableInfo VIEW_INFO = TableInfo.builder(TABLE_ID, VIEW_DEFINITION) .creationTime(CREATION_TIME) .description(DESCRIPTION) .etag(ETAG) - .id(ID) + .generatedId(GENERATED_ID) .build(); private static final TableInfo EXTERNAL_TABLE_INFO = TableInfo.builder(TABLE_ID, EXTERNAL_TABLE_DEFINITION) .creationTime(CREATION_TIME) .description(DESCRIPTION) .etag(ETAG) - .id(ID) + .generatedId(GENERATED_ID) .build(); private static final JobStatistics JOB_STATISTICS = JobStatistics.builder() .creationTime(1L) diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableInfoTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableInfoTest.java index 18b8be10d71e..84d224f220cb 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableInfoTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableInfoTest.java @@ -27,7 +27,7 @@ public class TableInfoTest { private static final String ETAG = "etag"; - private static final String ID = "project:dataset:table"; + private static final String GENERATED_ID = "project:dataset:table"; private static final String SELF_LINK = "selfLink"; private static final TableId TABLE_ID = TableId.of("dataset", "table"); private static final String FRIENDLY_NAME = "friendlyName"; @@ -89,7 +89,7 @@ public class TableInfoTest { .etag(ETAG) .expirationTime(EXPIRATION_TIME) .friendlyName(FRIENDLY_NAME) - .id(ID) + .generatedId(GENERATED_ID) .lastModifiedTime(LAST_MODIFIED_TIME) .selfLink(SELF_LINK) .build(); @@ -99,7 +99,7 @@ public class TableInfoTest { .etag(ETAG) .expirationTime(EXPIRATION_TIME) .friendlyName(FRIENDLY_NAME) - .id(ID) + .generatedId(GENERATED_ID) .lastModifiedTime(LAST_MODIFIED_TIME) .selfLink(SELF_LINK) .build(); @@ -110,7 +110,7 @@ public class TableInfoTest { .etag(ETAG) .expirationTime(EXPIRATION_TIME) .friendlyName(FRIENDLY_NAME) - .id(ID) + .generatedId(GENERATED_ID) .lastModifiedTime(LAST_MODIFIED_TIME) .selfLink(SELF_LINK) .build(); @@ -148,7 +148,7 @@ public void testBuilder() { assertEquals(ETAG, TABLE_INFO.etag()); assertEquals(EXPIRATION_TIME, TABLE_INFO.expirationTime()); assertEquals(FRIENDLY_NAME, TABLE_INFO.friendlyName()); - assertEquals(ID, TABLE_INFO.id()); + assertEquals(GENERATED_ID, TABLE_INFO.generatedId()); assertEquals(LAST_MODIFIED_TIME, TABLE_INFO.lastModifiedTime()); assertEquals(TABLE_DEFINITION, TABLE_INFO.definition()); assertEquals(SELF_LINK, TABLE_INFO.selfLink()); @@ -159,7 +159,7 @@ public void testBuilder() { assertEquals(ETAG, VIEW_INFO.etag()); assertEquals(EXPIRATION_TIME, VIEW_INFO.expirationTime()); assertEquals(FRIENDLY_NAME, VIEW_INFO.friendlyName()); - assertEquals(ID, VIEW_INFO.id()); + assertEquals(GENERATED_ID, VIEW_INFO.generatedId()); assertEquals(LAST_MODIFIED_TIME, VIEW_INFO.lastModifiedTime()); assertEquals(VIEW_TYPE, VIEW_INFO.definition()); assertEquals(SELF_LINK, VIEW_INFO.selfLink()); @@ -169,7 +169,7 @@ public void testBuilder() { assertEquals(ETAG, EXTERNAL_TABLE_INFO.etag()); assertEquals(EXPIRATION_TIME, EXTERNAL_TABLE_INFO.expirationTime()); assertEquals(FRIENDLY_NAME, EXTERNAL_TABLE_INFO.friendlyName()); - assertEquals(ID, EXTERNAL_TABLE_INFO.id()); + assertEquals(GENERATED_ID, EXTERNAL_TABLE_INFO.generatedId()); assertEquals(LAST_MODIFIED_TIME, EXTERNAL_TABLE_INFO.lastModifiedTime()); assertEquals(EXTERNAL_TABLE_DEFINITION, EXTERNAL_TABLE_INFO.definition()); assertEquals(SELF_LINK, EXTERNAL_TABLE_INFO.selfLink()); @@ -198,7 +198,7 @@ private void compareTableInfo(TableInfo expected, TableInfo value) { assertEquals(expected.etag(), value.etag()); assertEquals(expected.expirationTime(), value.expirationTime()); assertEquals(expected.friendlyName(), value.friendlyName()); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.lastModifiedTime(), value.lastModifiedTime()); assertEquals(expected.selfLink(), value.selfLink()); assertEquals(expected.definition(), value.definition()); diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableTest.java index c7828ebeadf4..cab71d4705d5 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableTest.java @@ -44,7 +44,7 @@ public class TableTest { private static final String ETAG = "etag"; - private static final String ID = "project:dataset:table1"; + private static final String GENERATED_ID = "project:dataset:table1"; private static final String SELF_LINK = "selfLink"; private static final String FRIENDLY_NAME = "friendlyName"; private static final String DESCRIPTION = "description"; @@ -115,7 +115,7 @@ public void testBuilder() { .etag(ETAG) .expirationTime(EXPIRATION_TIME) .friendlyName(FRIENDLY_NAME) - .id(ID) + .generatedId(GENERATED_ID) .lastModifiedTime(LAST_MODIFIED_TIME) .selfLink(SELF_LINK) .build(); @@ -125,7 +125,7 @@ public void testBuilder() { assertEquals(ETAG, builtTable.etag()); assertEquals(EXPIRATION_TIME, builtTable.expirationTime()); assertEquals(FRIENDLY_NAME, builtTable.friendlyName()); - assertEquals(ID, builtTable.id()); + assertEquals(GENERATED_ID, builtTable.generatedId()); assertEquals(LAST_MODIFIED_TIME, builtTable.lastModifiedTime()); assertEquals(TABLE_DEFINITION, builtTable.definition()); assertEquals(SELF_LINK, builtTable.selfLink()); @@ -398,7 +398,7 @@ private void compareTableInfo(TableInfo expected, TableInfo value) { assertEquals(expected.etag(), value.etag()); assertEquals(expected.expirationTime(), value.expirationTime()); assertEquals(expected.friendlyName(), value.friendlyName()); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.lastModifiedTime(), value.lastModifiedTime()); assertEquals(expected.selfLink(), value.selfLink()); assertEquals(expected.definition(), value.definition()); diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java index 50780b4fc9a9..e712eeeb23fd 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java @@ -214,7 +214,7 @@ public void testGetDataset() { assertEquals(DESCRIPTION, dataset.description()); assertNotNull(dataset.acl()); assertNotNull(dataset.etag()); - assertNotNull(dataset.id()); + assertNotNull(dataset.generatedId()); assertNotNull(dataset.lastModified()); assertNotNull(dataset.selfLink()); } @@ -231,7 +231,7 @@ public void testGetDatasetWithSelectedFields() { assertNull(dataset.acl()); assertNull(dataset.etag()); assertNull(dataset.friendlyName()); - assertNull(dataset.id()); + assertNull(dataset.generatedId()); assertNull(dataset.lastModified()); assertNull(dataset.location()); assertNull(dataset.selfLink()); @@ -270,7 +270,7 @@ public void testUpdateDatasetWithSelectedFields() { assertNull(updatedDataset.acl()); assertNull(updatedDataset.etag()); assertNull(updatedDataset.friendlyName()); - assertNull(updatedDataset.id()); + assertNull(updatedDataset.generatedId()); assertNull(updatedDataset.lastModified()); assertNull(updatedDataset.location()); assertNull(updatedDataset.selfLink()); @@ -697,7 +697,7 @@ public void testListJobs() { assertNotNull(job.statistics()); assertNotNull(job.status()); assertNotNull(job.userEmail()); - assertNotNull(job.id()); + assertNotNull(job.generatedId()); } } @@ -709,7 +709,7 @@ public void testListJobsWithSelectedFields() { assertNotNull(job.status()); assertNotNull(job.userEmail()); assertNull(job.statistics()); - assertNull(job.id()); + assertNull(job.generatedId()); } } From d4faad32326b9f9043bfc9f405fc00ef4e77690e Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 1 Apr 2016 16:14:08 +0200 Subject: [PATCH 219/375] Rename id to generatedId for Storage resources --- .../java/com/google/gcloud/storage/Blob.java | 4 +-- .../com/google/gcloud/storage/BlobInfo.java | 26 +++++++++---------- .../com/google/gcloud/storage/Bucket.java | 4 +-- .../com/google/gcloud/storage/BucketInfo.java | 26 +++++++++---------- .../google/gcloud/storage/BlobInfoTest.java | 12 ++++----- .../com/google/gcloud/storage/BlobTest.java | 10 +++---- .../google/gcloud/storage/BucketInfoTest.java | 14 +++++----- .../com/google/gcloud/storage/BucketTest.java | 8 +++--- .../gcloud/storage/it/ITStorageTest.java | 4 +-- 9 files changed, 54 insertions(+), 54 deletions(-) diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java index b6f668dada82..9bd9902fee56 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java @@ -178,8 +178,8 @@ public Builder blobId(BlobId blobId) { } @Override - Builder id(String id) { - infoBuilder.id(id); + Builder generatedId(String generatedId) { + infoBuilder.generatedId(generatedId); return this; } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobInfo.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobInfo.java index cf509c8f0961..42a2e282b002 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobInfo.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobInfo.java @@ -57,9 +57,9 @@ public StorageObject apply(BlobInfo blobInfo) { } }; - private static final long serialVersionUID = 2228487739943277159L; + private static final long serialVersionUID = -5625857076205028976L; private final BlobId blobId; - private final String id; + private final String generatedId; private final String selfLink; private final String cacheControl; private final List acl; @@ -101,7 +101,7 @@ public abstract static class Builder { */ public abstract Builder blobId(BlobId blobId); - abstract Builder id(String id); + abstract Builder generatedId(String generatedId); /** * Sets the blob's data content type. @@ -199,7 +199,7 @@ public abstract static class Builder { static final class BuilderImpl extends Builder { private BlobId blobId; - private String id; + private String generatedId; private String contentType; private String contentEncoding; private String contentDisposition; @@ -226,7 +226,7 @@ static final class BuilderImpl extends Builder { BuilderImpl(BlobInfo blobInfo) { blobId = blobInfo.blobId; - id = blobInfo.id; + generatedId = blobInfo.generatedId; cacheControl = blobInfo.cacheControl; contentEncoding = blobInfo.contentEncoding; contentType = blobInfo.contentType; @@ -255,8 +255,8 @@ public Builder blobId(BlobId blobId) { } @Override - Builder id(String id) { - this.id = id; + Builder generatedId(String generatedId) { + this.generatedId = generatedId; return this; } @@ -384,7 +384,7 @@ public BlobInfo build() { BlobInfo(BuilderImpl builder) { blobId = builder.blobId; - id = builder.id; + generatedId = builder.generatedId; cacheControl = builder.cacheControl; contentEncoding = builder.contentEncoding; contentType = builder.contentType; @@ -421,10 +421,10 @@ public String bucket() { } /** - * Returns the blob's id. + * Returns the service-generated for the blob. */ - public String id() { - return id; + public String generatedId() { + return generatedId; } /** @@ -684,7 +684,7 @@ public ObjectAccessControl apply(Acl acl) { storageObject.setComponentCount(componentCount); storageObject.setContentLanguage(contentLanguage); storageObject.setEtag(etag); - storageObject.setId(id); + storageObject.setId(generatedId); storageObject.setSelfLink(selfLink); return storageObject; } @@ -757,7 +757,7 @@ static BlobInfo fromPb(StorageObject storageObject) { builder.etag(storageObject.getEtag()); } if (storageObject.getId() != null) { - builder.id(storageObject.getId()); + builder.generatedId(storageObject.getId()); } if (storageObject.getSelfLink() != null) { builder.selfLink(storageObject.getSelfLink()); diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java index e44bd60d785c..cb2058a9e7ab 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java @@ -427,8 +427,8 @@ public Builder name(String name) { } @Override - Builder id(String id) { - infoBuilder.id(id); + Builder generatedId(String generatedId) { + infoBuilder.generatedId(generatedId); return this; } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BucketInfo.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BucketInfo.java index a1de1a07e03e..a893e45c5c86 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BucketInfo.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BucketInfo.java @@ -64,8 +64,8 @@ public com.google.api.services.storage.model.Bucket apply(BucketInfo bucketInfo) return bucketInfo.toPb(); } }; - private static final long serialVersionUID = -3946094202176916586L; - private final String id; + private static final long serialVersionUID = -4712013629621638459L; + private final String generatedId; private final String name; private final Acl.Entity owner; private final String selfLink; @@ -326,7 +326,7 @@ public abstract static class Builder { */ public abstract Builder name(String name); - abstract Builder id(String id); + abstract Builder generatedId(String generatedId); abstract Builder owner(Acl.Entity owner); @@ -411,7 +411,7 @@ public abstract static class Builder { static final class BuilderImpl extends Builder { - private String id; + private String generatedId; private String name; private Acl.Entity owner; private String selfLink; @@ -433,7 +433,7 @@ static final class BuilderImpl extends Builder { } BuilderImpl(BucketInfo bucketInfo) { - id = bucketInfo.id; + generatedId = bucketInfo.generatedId; name = bucketInfo.name; etag = bucketInfo.etag; createTime = bucketInfo.createTime; @@ -458,8 +458,8 @@ public Builder name(String name) { } @Override - Builder id(String id) { - this.id = id; + Builder generatedId(String generatedId) { + this.generatedId = generatedId; return this; } @@ -555,7 +555,7 @@ public BucketInfo build() { } BucketInfo(BuilderImpl builder) { - id = builder.id; + generatedId = builder.generatedId; name = builder.name; etag = builder.etag; createTime = builder.createTime; @@ -574,10 +574,10 @@ public BucketInfo build() { } /** - * Returns the bucket's id. + * Returns the service-generated id for the bucket. */ - public String id() { - return id; + public String generatedId() { + return generatedId; } /** @@ -733,7 +733,7 @@ public String toString() { com.google.api.services.storage.model.Bucket toPb() { com.google.api.services.storage.model.Bucket bucketPb = new com.google.api.services.storage.model.Bucket(); - bucketPb.setId(id); + bucketPb.setId(generatedId); bucketPb.setName(name); bucketPb.setEtag(etag); if (createTime != null) { @@ -810,7 +810,7 @@ public static Builder builder(String name) { static BucketInfo fromPb(com.google.api.services.storage.model.Bucket bucketPb) { Builder builder = new BuilderImpl(bucketPb.getName()); if (bucketPb.getId() != null) { - builder.id(bucketPb.getId()); + builder.generatedId(bucketPb.getId()); } if (bucketPb.getEtag() != null) { builder.etag(bucketPb.getEtag()); diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobInfoTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobInfoTest.java index 029181c6c07b..db9dddaa864e 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobInfoTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobInfoTest.java @@ -51,7 +51,7 @@ public class BlobInfoTest { private static final Long DELETE_TIME = System.currentTimeMillis(); private static final String ETAG = "0xFF00"; private static final Long GENERATION = 1L; - private static final String ID = "B/N:1"; + private static final String GENERATED_ID = "B/N:1"; private static final String MD5 = "0xFF00"; private static final String MEDIA_LINK = "http://media/b/n"; private static final Map METADATA = ImmutableMap.of("n1", "v1", "n2", "v2"); @@ -71,7 +71,7 @@ public class BlobInfoTest { .crc32c(CRC32) .deleteTime(DELETE_TIME) .etag(ETAG) - .id(ID) + .generatedId(GENERATED_ID) .md5(MD5) .mediaLink(MEDIA_LINK) .metadata(METADATA) @@ -118,7 +118,7 @@ public void testBuilder() { assertEquals(DELETE_TIME, BLOB_INFO.deleteTime()); assertEquals(ETAG, BLOB_INFO.etag()); assertEquals(GENERATION, BLOB_INFO.generation()); - assertEquals(ID, BLOB_INFO.id()); + assertEquals(GENERATED_ID, BLOB_INFO.generatedId()); assertEquals(MD5, BLOB_INFO.md5()); assertEquals(MEDIA_LINK, BLOB_INFO.mediaLink()); assertEquals(METADATA, BLOB_INFO.metadata()); @@ -141,7 +141,7 @@ public void testBuilder() { assertNull(DIRECTORY_INFO.deleteTime()); assertNull(DIRECTORY_INFO.etag()); assertNull(DIRECTORY_INFO.generation()); - assertNull(DIRECTORY_INFO.id()); + assertNull(DIRECTORY_INFO.generatedId()); assertNull(DIRECTORY_INFO.md5()); assertNull(DIRECTORY_INFO.mediaLink()); assertNull(DIRECTORY_INFO.metadata()); @@ -168,7 +168,7 @@ private void compareBlobs(BlobInfo expected, BlobInfo value) { assertEquals(expected.deleteTime(), value.deleteTime()); assertEquals(expected.etag(), value.etag()); assertEquals(expected.generation(), value.generation()); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.md5(), value.md5()); assertEquals(expected.mediaLink(), value.mediaLink()); assertEquals(expected.metadata(), value.metadata()); @@ -203,7 +203,7 @@ public void testToPbAndFromPb() { assertNull(blobInfo.deleteTime()); assertNull(blobInfo.etag()); assertNull(blobInfo.generation()); - assertNull(blobInfo.id()); + assertNull(blobInfo.generatedId()); assertNull(blobInfo.md5()); assertNull(blobInfo.mediaLink()); assertNull(blobInfo.metadata()); diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java index d6c97ca9ca03..c8c5fb5d763c 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java @@ -64,7 +64,7 @@ public class BlobTest { private static final Long DELETE_TIME = System.currentTimeMillis(); private static final String ETAG = "0xFF00"; private static final Long GENERATION = 1L; - private static final String ID = "B/N:1"; + private static final String GENERATED_ID = "B/N:1"; private static final String MD5 = "0xFF00"; private static final String MEDIA_LINK = "http://media/b/n"; private static final Map METADATA = ImmutableMap.of("n1", "v1", "n2", "v2"); @@ -84,7 +84,7 @@ public class BlobTest { .crc32c(CRC32) .deleteTime(DELETE_TIME) .etag(ETAG) - .id(ID) + .generatedId(GENERATED_ID) .md5(MD5) .mediaLink(MEDIA_LINK) .metadata(METADATA) @@ -338,7 +338,7 @@ public void testBuilder() { .crc32c(CRC32) .deleteTime(DELETE_TIME) .etag(ETAG) - .id(ID) + .generatedId(GENERATED_ID) .md5(MD5) .mediaLink(MEDIA_LINK) .metadata(METADATA) @@ -360,7 +360,7 @@ public void testBuilder() { assertEquals(CRC32, blob.crc32c()); assertEquals(DELETE_TIME, blob.deleteTime()); assertEquals(ETAG, blob.etag()); - assertEquals(ID, blob.id()); + assertEquals(GENERATED_ID, blob.generatedId()); assertEquals(MD5, blob.md5()); assertEquals(MEDIA_LINK, blob.mediaLink()); assertEquals(METADATA, blob.metadata()); @@ -387,7 +387,7 @@ public void testBuilder() { assertNull(blob.crc32c()); assertNull(blob.deleteTime()); assertNull(blob.etag()); - assertNull(blob.id()); + assertNull(blob.generatedId()); assertNull(blob.md5()); assertNull(blob.mediaLink()); assertNull(blob.metadata()); diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketInfoTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketInfoTest.java index bd6bcdbbcff2..6f9fadfdf7cd 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketInfoTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketInfoTest.java @@ -44,7 +44,7 @@ public class BucketInfoTest { Acl.of(User.ofAllAuthenticatedUsers(), Role.READER), Acl.of(new Project(VIEWERS, "p1"), Role.WRITER)); private static final String ETAG = "0xFF00"; - private static final String ID = "B/N:1"; + private static final String GENERATED_ID = "B/N:1"; private static final Long META_GENERATION = 10L; private static final User OWNER = new User("user@gmail.com"); private static final String SELF_LINK = "http://storage/b/n"; @@ -62,7 +62,7 @@ public class BucketInfoTest { private static final BucketInfo BUCKET_INFO = BucketInfo.builder("b") .acl(ACL) .etag(ETAG) - .id(ID) + .generatedId(GENERATED_ID) .metageneration(META_GENERATION) .owner(OWNER) .selfLink(SELF_LINK) @@ -80,10 +80,10 @@ public class BucketInfoTest { @Test public void testToBuilder() { compareBuckets(BUCKET_INFO, BUCKET_INFO.toBuilder().build()); - BucketInfo bucketInfo = BUCKET_INFO.toBuilder().name("B").id("id").build(); + BucketInfo bucketInfo = BUCKET_INFO.toBuilder().name("B").generatedId("id").build(); assertEquals("B", bucketInfo.name()); - assertEquals("id", bucketInfo.id()); - bucketInfo = bucketInfo.toBuilder().name("b").id(ID).build(); + assertEquals("id", bucketInfo.generatedId()); + bucketInfo = bucketInfo.toBuilder().name("b").generatedId(GENERATED_ID).build(); compareBuckets(BUCKET_INFO, bucketInfo); } @@ -104,7 +104,7 @@ public void testBuilder() { assertEquals("b", BUCKET_INFO.name()); assertEquals(ACL, BUCKET_INFO.acl()); assertEquals(ETAG, BUCKET_INFO.etag()); - assertEquals(ID, BUCKET_INFO.id()); + assertEquals(GENERATED_ID, BUCKET_INFO.generatedId()); assertEquals(META_GENERATION, BUCKET_INFO.metageneration()); assertEquals(OWNER, BUCKET_INFO.owner()); assertEquals(SELF_LINK, BUCKET_INFO.selfLink()); @@ -131,7 +131,7 @@ private void compareBuckets(BucketInfo expected, BucketInfo value) { assertEquals(expected.name(), value.name()); assertEquals(expected.acl(), value.acl()); assertEquals(expected.etag(), value.etag()); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.metageneration(), value.metageneration()); assertEquals(expected.owner(), value.owner()); assertEquals(expected.selfLink(), value.selfLink()); diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java index 53056c39c0dc..30b7416531f3 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java @@ -59,7 +59,7 @@ public class BucketTest { private static final List ACL = ImmutableList.of( Acl.of(User.ofAllAuthenticatedUsers(), READER), Acl.of(new Project(VIEWERS, "p1"), WRITER)); private static final String ETAG = "0xFF00"; - private static final String ID = "B/N:1"; + private static final String GENERATED_ID = "B/N:1"; private static final Long META_GENERATION = 10L; private static final User OWNER = new User("user@gmail.com"); private static final String SELF_LINK = "http://storage/b/n"; @@ -77,7 +77,7 @@ public class BucketTest { private static final BucketInfo FULL_BUCKET_INFO = BucketInfo.builder("b") .acl(ACL) .etag(ETAG) - .id(ID) + .generatedId(GENERATED_ID) .metageneration(META_GENERATION) .owner(OWNER) .selfLink(SELF_LINK) @@ -495,7 +495,7 @@ public void testBuilder() { new Bucket.Builder(new Bucket(storage, new BucketInfo.BuilderImpl(BUCKET_INFO))); Bucket bucket = builder.acl(ACL) .etag(ETAG) - .id(ID) + .generatedId(GENERATED_ID) .metageneration(META_GENERATION) .owner(OWNER) .selfLink(SELF_LINK) @@ -512,7 +512,7 @@ public void testBuilder() { assertEquals("b", bucket.name()); assertEquals(ACL, bucket.acl()); assertEquals(ETAG, bucket.etag()); - assertEquals(ID, bucket.id()); + assertEquals(GENERATED_ID, bucket.generatedId()); assertEquals(META_GENERATION, bucket.metageneration()); assertEquals(OWNER, bucket.owner()); assertEquals(SELF_LINK, bucket.selfLink()); diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java index 13d768442c34..542cf966d269 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java @@ -122,7 +122,7 @@ public void testGetBucketSelectedFields() { Bucket remoteBucket = storage.get(BUCKET, Storage.BucketGetOption.fields(BucketField.ID)); assertEquals(BUCKET, remoteBucket.name()); assertNull(remoteBucket.createTime()); - assertNotNull(remoteBucket.id()); + assertNotNull(remoteBucket.generatedId()); } @Test @@ -256,7 +256,7 @@ public void testGetBlobAllSelectedFields() { assertEquals(blob.bucket(), remoteBlob.bucket()); assertEquals(blob.name(), remoteBlob.name()); assertEquals(ImmutableMap.of("k", "v"), remoteBlob.metadata()); - assertNotNull(remoteBlob.id()); + assertNotNull(remoteBlob.generatedId()); assertNotNull(remoteBlob.selfLink()); assertTrue(remoteBlob.delete()); } From 8df138b0aba5dbfa0a5b8dc07a1dc6541b4d2bac Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 1 Apr 2016 19:29:28 +0200 Subject: [PATCH 220/375] Rename id to generatedId for Dns resources --- gcloud-java-dns/README.md | 6 +- .../com/google/gcloud/dns/ChangeRequest.java | 4 +- .../google/gcloud/dns/ChangeRequestInfo.java | 40 +++--- .../main/java/com/google/gcloud/dns/Zone.java | 4 +- .../java/com/google/gcloud/dns/ZoneInfo.java | 36 +++--- .../gcloud/dns/ChangeRequestInfoTest.java | 12 +- .../google/gcloud/dns/ChangeRequestTest.java | 6 +- .../com/google/gcloud/dns/DnsImplTest.java | 13 +- .../google/gcloud/dns/SerializationTest.java | 4 +- .../com/google/gcloud/dns/ZoneInfoTest.java | 18 +-- .../java/com/google/gcloud/dns/ZoneTest.java | 60 ++++----- .../com/google/gcloud/dns/it/ITDnsTest.java | 118 +++++++++--------- .../gcloud/examples/dns/DnsExample.java | 12 +- .../examples/dns/snippets/CreateZone.java | 2 +- .../examples/dns/snippets/DeleteZone.java | 2 +- .../ManipulateZonesAndRecordSets.java | 6 +- 16 files changed, 175 insertions(+), 168 deletions(-) diff --git a/gcloud-java-dns/README.md b/gcloud-java-dns/README.md index a01282f16c5d..703bcb190807 100644 --- a/gcloud-java-dns/README.md +++ b/gcloud-java-dns/README.md @@ -125,7 +125,7 @@ ZoneInfo zoneInfo = ZoneInfo.of(zoneName, domainName, description); // Create zone in Google Cloud DNS Zone zone = dns.create(zoneInfo); -System.out.printf("Zone was created and assigned ID %s.%n", zone.id()); +System.out.printf("Zone was created and assigned ID %s.%n", zone.generatedId()); ``` You now have an empty zone hosted in Google Cloud DNS which is ready to be populated with @@ -226,7 +226,7 @@ while (ChangeRequestInfo.Status.PENDING.equals(changeRequest.status())) { } catch (InterruptedException e) { System.err.println("The thread was interrupted while waiting..."); } - changeRequest = dns.getChangeRequest(zone.name(), changeRequest.id()); + changeRequest = dns.getChangeRequest(zone.name(), changeRequest.generatedId()); } System.out.println("The change request has been applied."); ``` @@ -315,7 +315,7 @@ if (!changeRequest.deletions().isEmpty()) { } // Update the change, but fetch only change ID and status - changeRequest = dns.getChangeRequest(zoneName, changeRequest.id(), option); + changeRequest = dns.getChangeRequest(zoneName, changeRequest.generatedId(), option); } } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java index 4b6369976ca6..60b053faab6d 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java @@ -103,8 +103,8 @@ public Builder removeDeletion(RecordSet recordSet) { } @Override - Builder id(String id) { - infoBuilder.id(id); + Builder generatedId(String generatedId) { + infoBuilder.generatedId(generatedId); return this; } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequestInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequestInfo.java index b63b4f4a0788..4a92512996dd 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequestInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequestInfo.java @@ -47,10 +47,10 @@ public ChangeRequestInfo apply(Change pb) { return ChangeRequestInfo.fromPb(pb); } }; - private static final long serialVersionUID = -9027378042756366333L; + private static final long serialVersionUID = -6029143477639439169L; private final List additions; private final List deletions; - private final String id; + private final String generatedId; private final Long startTimeMillis; private final ChangeRequestInfo.Status status; @@ -119,9 +119,9 @@ public abstract static class Builder { public abstract Builder removeDeletion(RecordSet recordSet); /** - * Associates a server-assigned id to this {@code ChangeRequestInfo}. + * Associates a service-generated id to this {@code ChangeRequestInfo}. */ - abstract Builder id(String id); + abstract Builder generatedId(String generatedId); /** * Sets the time when this change request was started by a server. @@ -143,7 +143,7 @@ public abstract static class Builder { static class BuilderImpl extends Builder { private List additions; private List deletions; - private String id; + private String generatedId; private Long startTimeMillis; private ChangeRequestInfo.Status status; @@ -155,7 +155,7 @@ static class BuilderImpl extends Builder { BuilderImpl(ChangeRequestInfo info) { this.additions = Lists.newLinkedList(info.additions()); this.deletions = Lists.newLinkedList(info.deletions()); - this.id = info.id(); + this.generatedId = info.generatedId; this.startTimeMillis = info.startTimeMillis; this.status = info.status; } @@ -214,8 +214,8 @@ public ChangeRequestInfo build() { } @Override - Builder id(String id) { - this.id = checkNotNull(id); + Builder generatedId(String generatedId) { + this.generatedId = checkNotNull(generatedId); return this; } @@ -235,7 +235,7 @@ Builder status(ChangeRequestInfo.Status status) { ChangeRequestInfo(BuilderImpl builder) { this.additions = ImmutableList.copyOf(builder.additions); this.deletions = ImmutableList.copyOf(builder.deletions); - this.id = builder.id; + this.generatedId = builder.generatedId; this.startTimeMillis = builder.startTimeMillis; this.status = builder.status; } @@ -271,22 +271,22 @@ public List deletions() { } /** - * Returns the id assigned to this {@code ChangeRequest} by the server. + * Returns the service-generated id for this change request. */ - public String id() { - return id; + public String generatedId() { + return generatedId; } /** - * Returns the time when this {@code ChangeRequest} was started by the server. + * Returns the time when this change request was started by the server. */ public Long startTimeMillis() { return startTimeMillis; } /** - * Returns the status of this {@code ChangeRequest}. If the change request has not been applied - * yet, the status is {@code PENDING}. + * Returns the status of this change request. If the change request has not been applied yet, the + * status is {@code PENDING}. */ public ChangeRequestInfo.Status status() { return status; @@ -295,8 +295,8 @@ public ChangeRequestInfo.Status status() { Change toPb() { Change pb = new Change(); // set id - if (id() != null) { - pb.setId(id()); + if (generatedId() != null) { + pb.setId(generatedId()); } // set timestamp if (startTimeMillis() != null) { @@ -316,7 +316,7 @@ Change toPb() { static ChangeRequestInfo fromPb(Change pb) { Builder builder = builder(); if (pb.getId() != null) { - builder.id(pb.getId()); + builder.generatedId(pb.getId()); } if (pb.getStartTime() != null) { builder.startTimeMillis(DateTime.parse(pb.getStartTime()).getMillis()); @@ -342,7 +342,7 @@ public boolean equals(Object other) { @Override public int hashCode() { - return Objects.hash(additions, deletions, id, startTimeMillis, status); + return Objects.hash(additions, deletions, generatedId, startTimeMillis, status); } @Override @@ -350,7 +350,7 @@ public String toString() { return MoreObjects.toStringHelper(this) .add("additions", additions) .add("deletions", deletions) - .add("id", id) + .add("generatedId", generatedId) .add("startTimeMillis", startTimeMillis) .add("status", status) .toString(); diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java index 9930bfdbad67..6e22bfc6785a 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java @@ -61,8 +61,8 @@ public Builder name(String name) { } @Override - Builder id(String id) { - infoBuilder.id(id); + Builder generatedId(String generatedId) { + infoBuilder.generatedId(generatedId); return this; } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java index 38a88b67777e..a0ee24bc5948 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java @@ -38,9 +38,9 @@ */ public class ZoneInfo implements Serializable { - private static final long serialVersionUID = 201601191647L; + private static final long serialVersionUID = -5313169712036079818L; private final String name; - private final String id; + private final String generatedId; private final Long creationTimeMillis; private final String dnsName; private final String description; @@ -57,9 +57,9 @@ public abstract static class Builder { public abstract Builder name(String name); /** - * Sets an id for the zone which is assigned to the zone by the server. + * Sets service-generated id for the zone. */ - abstract Builder id(String id); + abstract Builder generatedId(String generatedId); /** * Sets the time when this zone was created. @@ -98,7 +98,7 @@ public abstract static class Builder { static class BuilderImpl extends Builder { private String name; - private String id; + private String generatedId; private Long creationTimeMillis; private String dnsName; private String description; @@ -114,7 +114,7 @@ private BuilderImpl(String name) { */ BuilderImpl(ZoneInfo info) { this.name = info.name; - this.id = info.id; + this.generatedId = info.generatedId; this.creationTimeMillis = info.creationTimeMillis; this.dnsName = info.dnsName; this.description = info.description; @@ -131,8 +131,8 @@ public Builder name(String name) { } @Override - Builder id(String id) { - this.id = id; + Builder generatedId(String generatedId) { + this.generatedId = generatedId; return this; } @@ -175,7 +175,7 @@ public ZoneInfo build() { ZoneInfo(BuilderImpl builder) { this.name = builder.name; - this.id = builder.id; + this.generatedId = builder.generatedId; this.creationTimeMillis = builder.creationTimeMillis; this.dnsName = builder.dnsName; this.description = builder.description; @@ -199,10 +199,10 @@ public String name() { } /** - * Returns the read-only zone id assigned by the server. + * Returns the service-generated id for this zone. */ - public String id() { - return id; + public String generatedId() { + return generatedId; } /** @@ -253,8 +253,8 @@ com.google.api.services.dns.model.ManagedZone toPb() { new com.google.api.services.dns.model.ManagedZone(); pb.setDescription(this.description()); pb.setDnsName(this.dnsName()); - if (this.id() != null) { - pb.setId(new BigInteger(this.id())); + if (this.generatedId() != null) { + pb.setId(new BigInteger(this.generatedId())); } pb.setName(this.name()); pb.setNameServers(this.nameServers); // do use real attribute value which may be null @@ -276,7 +276,7 @@ static ZoneInfo fromPb(com.google.api.services.dns.model.ManagedZone pb) { builder.dnsName(pb.getDnsName()); } if (pb.getId() != null) { - builder.id(pb.getId().toString()); + builder.generatedId(pb.getId().toString()); } if (pb.getNameServers() != null) { builder.nameServers(pb.getNameServers()); @@ -298,15 +298,15 @@ public boolean equals(Object obj) { @Override public int hashCode() { - return Objects.hash(name, id, creationTimeMillis, dnsName, - description, nameServerSet, nameServers); + return Objects.hash(name, generatedId, creationTimeMillis, dnsName, description, nameServerSet, + nameServers); } @Override public String toString() { return MoreObjects.toStringHelper(this) .add("name", name()) - .add("id", id()) + .add("generatedId", generatedId()) .add("description", description()) .add("dnsName", dnsName()) .add("nameServerSet", nameServerSet()) diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestInfoTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestInfoTest.java index 55f2af0824ec..f3ae7a586391 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestInfoTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestInfoTest.java @@ -31,7 +31,7 @@ public class ChangeRequestInfoTest { - private static final String ID = "cr-id-1"; + private static final String GENERATED_ID = "cr-id-1"; private static final Long START_TIME_MILLIS = 12334567890L; private static final ChangeRequest.Status STATUS = ChangeRequest.Status.PENDING; private static final String NAME1 = "dns1"; @@ -51,7 +51,7 @@ public class ChangeRequestInfoTest { .delete(RECORD3) .startTimeMillis(START_TIME_MILLIS) .status(STATUS) - .id(ID) + .generatedId(GENERATED_ID) .build(); @Test @@ -65,7 +65,7 @@ public void testEmptyBuilder() { @Test public void testBuilder() { - assertEquals(ID, CHANGE.id()); + assertEquals(GENERATED_ID, CHANGE.generatedId()); assertEquals(STATUS, CHANGE.status()); assertEquals(START_TIME_MILLIS, CHANGE.startTimeMillis()); assertEquals(ADDITIONS, CHANGE.additions()); @@ -85,7 +85,7 @@ public void testEqualsAndNotEquals() { assertEquals(CHANGE, clone); clone = ChangeRequest.fromPb(CHANGE.toPb()); assertEquals(CHANGE, clone); - clone = CHANGE.toBuilder().id("some-other-id").build(); + clone = CHANGE.toBuilder().generatedId("some-other-id").build(); assertNotEquals(CHANGE, clone); clone = CHANGE.toBuilder().startTimeMillis(CHANGE.startTimeMillis() + 1).build(); assertNotEquals(CHANGE, clone); @@ -112,7 +112,7 @@ public void testToAndFromPb() { assertEquals(CHANGE, ChangeRequest.fromPb(CHANGE.toPb())); ChangeRequestInfo partial = ChangeRequest.builder().build(); assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); - partial = ChangeRequest.builder().id(ID).build(); + partial = ChangeRequest.builder().generatedId(GENERATED_ID).build(); assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); partial = ChangeRequest.builder().add(RECORD1).build(); assertEquals(partial, ChangeRequest.fromPb(partial.toPb())); @@ -133,7 +133,7 @@ public void testToBuilder() { assertEquals(CHANGE, CHANGE.toBuilder().build()); ChangeRequestInfo partial = ChangeRequest.builder().build(); assertEquals(partial, partial.toBuilder().build()); - partial = ChangeRequest.builder().id(ID).build(); + partial = ChangeRequest.builder().generatedId(GENERATED_ID).build(); assertEquals(partial, partial.toBuilder().build()); partial = ChangeRequest.builder().add(RECORD1).build(); assertEquals(partial, partial.toBuilder().build()); diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java index bfd1d0f512f4..4d4b2c01823c 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java @@ -53,7 +53,7 @@ public void setUp() throws Exception { changeRequest = new ChangeRequest(dns, ZONE_NAME, new ChangeRequestInfo.BuilderImpl( CHANGE_REQUEST_INFO.toBuilder() .startTimeMillis(132L) - .id("12") + .generatedId("12") .status(ChangeRequest.Status.DONE) .build())); changeRequestPartial = new ChangeRequest(dns, ZONE_NAME, @@ -104,8 +104,8 @@ public void testBuilder() { // one for each build() call because it invokes a constructor expect(dns.options()).andReturn(OPTIONS).times(9); replay(dns); - String id = changeRequest.id() + "aaa"; - assertEquals(id, changeRequest.toBuilder().id(id).build().id()); + String id = changeRequest.generatedId() + "aaa"; + assertEquals(id, changeRequest.toBuilder().generatedId(id).build().generatedId()); ChangeRequest modified = changeRequest.toBuilder().status(ChangeRequest.Status.PENDING).build(); assertEquals(ChangeRequest.Status.PENDING, modified.status()); diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java index 94ed4a3da3f7..d9d657ee03e7 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java @@ -60,7 +60,7 @@ public class DnsImplTest { .add(DNS_RECORD1) .startTimeMillis(123L) .status(ChangeRequest.Status.PENDING) - .id(CHANGE_ID) + .generatedId(CHANGE_ID) .build(); // Result lists @@ -215,12 +215,13 @@ public void testProjectGetWithOptions() { @Test public void testGetChangeRequest() { - EasyMock.expect(dnsRpcMock.getChangeRequest(ZONE_INFO.name(), CHANGE_REQUEST_COMPLETE.id(), - EMPTY_RPC_OPTIONS)).andReturn(CHANGE_REQUEST_COMPLETE.toPb()); + EasyMock.expect(dnsRpcMock.getChangeRequest(ZONE_INFO.name(), + CHANGE_REQUEST_COMPLETE.generatedId(), EMPTY_RPC_OPTIONS)) + .andReturn(CHANGE_REQUEST_COMPLETE.toPb()); EasyMock.replay(dnsRpcMock); dns = options.service(); // creates DnsImpl ChangeRequest changeRequest = dns.getChangeRequest(ZONE_INFO.name(), - CHANGE_REQUEST_COMPLETE.id()); + CHANGE_REQUEST_COMPLETE.generatedId()); assertEquals(new ChangeRequest(dns, ZONE_INFO.name(), new ChangeRequestInfo.BuilderImpl(CHANGE_REQUEST_COMPLETE)), changeRequest); } @@ -229,12 +230,12 @@ public void testGetChangeRequest() { public void testGetChangeRequestWithOptions() { Capture> capturedOptions = Capture.newInstance(); EasyMock.expect(dnsRpcMock.getChangeRequest(EasyMock.eq(ZONE_INFO.name()), - EasyMock.eq(CHANGE_REQUEST_COMPLETE.id()), EasyMock.capture(capturedOptions))) + EasyMock.eq(CHANGE_REQUEST_COMPLETE.generatedId()), EasyMock.capture(capturedOptions))) .andReturn(CHANGE_REQUEST_COMPLETE.toPb()); EasyMock.replay(dnsRpcMock); dns = options.service(); // creates DnsImpl ChangeRequest changeRequest = dns.getChangeRequest(ZONE_INFO.name(), - CHANGE_REQUEST_COMPLETE.id(), CHANGE_GET_FIELDS); + CHANGE_REQUEST_COMPLETE.generatedId(), CHANGE_GET_FIELDS); String selector = (String) capturedOptions.getValue().get(CHANGE_GET_FIELDS.rpcOption()); assertEquals(new ChangeRequest(dns, ZONE_INFO.name(), new ChangeRequestInfo.BuilderImpl(CHANGE_REQUEST_COMPLETE)), changeRequest); diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java index ad25b31068dd..7742d4c59a48 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java @@ -31,7 +31,7 @@ public class SerializationTest extends BaseSerializationTest { private static final ZoneInfo FULL_ZONE_INFO = Zone.of("some zone name", "www.example.com", "some descriptions").toBuilder() .creationTimeMillis(132L) - .id("123333") + .generatedId("123333") .nameServers(ImmutableList.of("server 1", "server 2")) .nameServerSet("specificationstring") .build(); @@ -78,7 +78,7 @@ public class SerializationTest extends BaseSerializationTest { .add(RECORD_SET_COMPLETE) .delete(RECORD_SET_PARTIAL) .status(ChangeRequest.Status.PENDING) - .id("some id") + .generatedId("some id") .startTimeMillis(132L) .build(); private static final ChangeRequest CHANGE_REQUEST_COMPLETE = new ChangeRequest(DNS, "name", diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java index 923672bb85a7..d0a64a61b816 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java @@ -32,7 +32,7 @@ public class ZoneInfoTest { private static final String NAME = "mz-example.com"; - private static final String ID = "123456"; + private static final String GENERATED_ID = "123456"; private static final Long CREATION_TIME_MILLIS = 1123468321321L; private static final String DNS_NAME = "example.com."; private static final String DESCRIPTION = "description for the zone"; @@ -43,7 +43,7 @@ public class ZoneInfoTest { private static final List NAME_SERVERS = ImmutableList.of(NS1, NS2, NS3); private static final ZoneInfo INFO = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION).toBuilder() .creationTimeMillis(CREATION_TIME_MILLIS) - .id(ID) + .generatedId(GENERATED_ID) .nameServerSet(NAME_SERVER_SET) .nameServers(NAME_SERVERS) .build(); @@ -53,7 +53,7 @@ public void testOf() { ZoneInfo partial = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION); assertTrue(partial.nameServers().isEmpty()); assertEquals(NAME, partial.name()); - assertNull(partial.id()); + assertNull(partial.generatedId()); assertNull(partial.creationTimeMillis()); assertNull(partial.nameServerSet()); assertEquals(DESCRIPTION, partial.description()); @@ -67,7 +67,7 @@ public void testBuilder() { assertEquals(NS2, INFO.nameServers().get(1)); assertEquals(NS3, INFO.nameServers().get(2)); assertEquals(NAME, INFO.name()); - assertEquals(ID, INFO.id()); + assertEquals(GENERATED_ID, INFO.generatedId()); assertEquals(CREATION_TIME_MILLIS, INFO.creationTimeMillis()); assertEquals(NAME_SERVER_SET, INFO.nameServerSet()); assertEquals(DESCRIPTION, INFO.description()); @@ -91,7 +91,7 @@ public void testEqualsAndNotEquals() { assertNotEquals(INFO, clone); clone = INFO.toBuilder().dnsName(differentName).build(); assertNotEquals(INFO, clone); - clone = INFO.toBuilder().id(INFO.id() + "1111").build(); + clone = INFO.toBuilder().generatedId(INFO.generatedId() + "1111").build(); assertNotEquals(INFO, clone); clone = INFO.toBuilder().nameServerSet(INFO.nameServerSet() + "salt").build(); assertNotEquals(INFO, clone); @@ -109,7 +109,9 @@ public void testToBuilder() { assertEquals(INFO, INFO.toBuilder().build()); ZoneInfo partial = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION); assertEquals(partial, partial.toBuilder().build()); - partial = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION).toBuilder().id(ID).build(); + partial = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION).toBuilder() + .generatedId(GENERATED_ID) + .build(); assertEquals(partial, partial.toBuilder().build()); partial = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION).toBuilder() .creationTimeMillis(CREATION_TIME_MILLIS).build(); @@ -128,7 +130,9 @@ public void testToAndFromPb() { assertEquals(INFO, ZoneInfo.fromPb(INFO.toPb())); ZoneInfo partial = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION); assertEquals(partial, ZoneInfo.fromPb(partial.toPb())); - partial = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION).toBuilder().id(ID).build(); + partial = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION).toBuilder() + .generatedId(GENERATED_ID) + .build(); assertEquals(partial, ZoneInfo.fromPb(partial.toPb())); partial = ZoneInfo.of(NAME, DNS_NAME, DESCRIPTION).toBuilder() .creationTimeMillis(CREATION_TIME_MILLIS).build(); diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java index ba4493abfca8..f14addfc44b6 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java @@ -45,7 +45,7 @@ public class ZoneTest { private static final String ZONE_ID = "123"; private static final ZoneInfo ZONE_INFO = Zone.of(ZONE_NAME, "example.com", "description") .toBuilder() - .id(ZONE_ID) + .generatedId(ZONE_ID) .creationTimeMillis(123478946464L) .build(); private static final ZoneInfo NO_ID_INFO = @@ -61,7 +61,7 @@ public class ZoneTest { private static final Dns.ChangeRequestListOption CHANGE_REQUEST_LIST_OPTIONS = Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.START_TIME); private static final ChangeRequestInfo CHANGE_REQUEST = - ChangeRequestInfo.builder().id("someid").build(); + ChangeRequestInfo.builder().generatedId("someid").build(); private static final ChangeRequestInfo CHANGE_REQUEST_NO_ID = ChangeRequestInfo.builder().build(); private static final DnsException EXCEPTION = createStrictMock(DnsException.class); @@ -287,51 +287,52 @@ public void applyNullChangeRequest() { @Test public void getChangeAndZoneFoundByName() { - expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())) + expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.generatedId())) .andReturn(changeRequestAfter).times(2); // again for options - expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) - .andReturn(changeRequestAfter).times(2); + expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.generatedId(), + CHANGE_REQUEST_FIELD_OPTIONS)).andReturn(changeRequestAfter).times(2); replay(dns); - ChangeRequest result = zoneNoId.getChangeRequest(CHANGE_REQUEST.id()); + ChangeRequest result = zoneNoId.getChangeRequest(CHANGE_REQUEST.generatedId()); assertEquals(changeRequestAfter, result); - result = zone.getChangeRequest(CHANGE_REQUEST.id()); + result = zone.getChangeRequest(CHANGE_REQUEST.generatedId()); assertEquals(changeRequestAfter, result); // check options - result = zoneNoId.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS); + result = zoneNoId.getChangeRequest(CHANGE_REQUEST.generatedId(), CHANGE_REQUEST_FIELD_OPTIONS); assertEquals(changeRequestAfter, result); - result = zone.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS); + result = zone.getChangeRequest(CHANGE_REQUEST.generatedId(), CHANGE_REQUEST_FIELD_OPTIONS); assertEquals(changeRequestAfter, result); } @Test public void getChangeAndZoneNotFoundByName() { - expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())).andThrow(EXCEPTION).times(2); + expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.generatedId())).andThrow(EXCEPTION) + .times(2); // again for options - expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) - .andThrow(EXCEPTION).times(2); + expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.generatedId(), + CHANGE_REQUEST_FIELD_OPTIONS)).andThrow(EXCEPTION).times(2); replay(dns); try { - zoneNoId.getChangeRequest(CHANGE_REQUEST.id()); + zoneNoId.getChangeRequest(CHANGE_REQUEST.generatedId()); fail("Parent container not found, should throw an exception."); } catch (DnsException e) { // expected } try { - zone.getChangeRequest(CHANGE_REQUEST.id()); + zone.getChangeRequest(CHANGE_REQUEST.generatedId()); fail("Parent container not found, should throw an exception."); } catch (DnsException e) { // expected } // check options try { - zoneNoId.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS); + zoneNoId.getChangeRequest(CHANGE_REQUEST.generatedId(), CHANGE_REQUEST_FIELD_OPTIONS); fail("Parent container not found, should throw an exception."); } catch (DnsException e) { // expected } try { - zone.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS); + zone.getChangeRequest(CHANGE_REQUEST.generatedId(), CHANGE_REQUEST_FIELD_OPTIONS); fail("Parent container not found, should throw an exception."); } catch (DnsException e) { // expected @@ -340,15 +341,16 @@ public void getChangeAndZoneNotFoundByName() { @Test public void getChangedWhichDoesNotExistZoneFound() { - expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id())).andReturn(null).times(2); + expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.generatedId())).andReturn(null).times(2); // again for options - expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)) - .andReturn(null).times(2); + expect(dns.getChangeRequest(ZONE_NAME, CHANGE_REQUEST.generatedId(), + CHANGE_REQUEST_FIELD_OPTIONS)).andReturn(null).times(2); replay(dns); - assertNull(zoneNoId.getChangeRequest(CHANGE_REQUEST.id())); - assertNull(zone.getChangeRequest(CHANGE_REQUEST.id())); - assertNull(zoneNoId.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)); - assertNull(zone.getChangeRequest(CHANGE_REQUEST.id(), CHANGE_REQUEST_FIELD_OPTIONS)); + assertNull(zoneNoId.getChangeRequest(CHANGE_REQUEST.generatedId())); + assertNull(zone.getChangeRequest(CHANGE_REQUEST.generatedId())); + assertNull( + zoneNoId.getChangeRequest(CHANGE_REQUEST.generatedId(),CHANGE_REQUEST_FIELD_OPTIONS)); + assertNull(zone.getChangeRequest(CHANGE_REQUEST.generatedId(), CHANGE_REQUEST_FIELD_OPTIONS)); } @Test @@ -384,25 +386,25 @@ public void getNullChangeRequest() { public void getChangeRequestWithNoId() { replay(dns); // no calls expected try { - zone.getChangeRequest(CHANGE_REQUEST_NO_ID.id()); + zone.getChangeRequest(CHANGE_REQUEST_NO_ID.generatedId()); fail("Cannot get ChangeRequest by null id."); } catch (NullPointerException e) { // expected } try { - zone.getChangeRequest(CHANGE_REQUEST_NO_ID.id(), CHANGE_REQUEST_FIELD_OPTIONS); + zone.getChangeRequest(CHANGE_REQUEST_NO_ID.generatedId(), CHANGE_REQUEST_FIELD_OPTIONS); fail("Cannot get ChangeRequest by null id."); } catch (NullPointerException e) { // expected } try { - zoneNoId.getChangeRequest(CHANGE_REQUEST_NO_ID.id()); + zoneNoId.getChangeRequest(CHANGE_REQUEST_NO_ID.generatedId()); fail("Cannot get ChangeRequest by null id."); } catch (NullPointerException e) { // expected } try { - zoneNoId.getChangeRequest(CHANGE_REQUEST_NO_ID.id(), CHANGE_REQUEST_FIELD_OPTIONS); + zoneNoId.getChangeRequest(CHANGE_REQUEST_NO_ID.generatedId(), CHANGE_REQUEST_FIELD_OPTIONS); fail("Cannot get ChangeRequest by null id."); } catch (NullPointerException e) { // expected @@ -482,7 +484,7 @@ public void testBuilder() { expect(dns.options()).andReturn(OPTIONS).times(8); replay(dns); assertNotEquals(zone, zone.toBuilder() - .id((new BigInteger(zone.id())).add(BigInteger.ONE).toString()) + .generatedId(new BigInteger(zone.generatedId()).add(BigInteger.ONE).toString()) .build()); assertNotEquals(zone, zone.toBuilder().dnsName(zone.name() + "aaaa").build()); assertNotEquals(zone, zone.toBuilder().nameServerSet(zone.nameServerSet() + "aaaa").build()); @@ -491,7 +493,7 @@ public void testBuilder() { assertNotEquals(zone, zone.toBuilder().creationTimeMillis(zone.creationTimeMillis() + 1) .build()); Zone.Builder builder = zone.toBuilder(); - builder.id(ZONE_ID) + builder.generatedId(ZONE_ID) .dnsName("example.com") .creationTimeMillis(123478946464L) .build(); diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java index c9070f2eddde..aa6c78461b8b 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java @@ -97,7 +97,7 @@ private static void clear() { when the list has been retrieved and executing the subsequent delete operation. */ Iterator iterator = zone.listChangeRequests().iterateAll(); while (iterator.hasNext()) { - waitForChangeToComplete(zoneName, iterator.next().id()); + waitForChangeToComplete(zoneName, iterator.next().generatedId()); } Iterator recordSetIterator = zone.listRecordSets().iterateAll(); List toDelete = new LinkedList<>(); @@ -111,7 +111,7 @@ private static void clear() { if (!toDelete.isEmpty()) { ChangeRequest deletion = zone.applyChangeRequest(ChangeRequest.builder().deletions(toDelete).build()); - waitForChangeToComplete(zone.name(), deletion.id()); + waitForChangeToComplete(zone.name(), deletion.generatedId()); } zone.delete(); } @@ -142,7 +142,7 @@ public static void after() { private static void assertEqChangesIgnoreStatus(ChangeRequest expected, ChangeRequest actual) { assertEquals(expected.additions(), actual.additions()); assertEquals(expected.deletions(), actual.deletions()); - assertEquals(expected.id(), actual.id()); + assertEquals(expected.generatedId(), actual.generatedId()); assertEquals(expected.startTimeMillis(), actual.startTimeMillis()); } @@ -174,7 +174,7 @@ public void testCreateValidZone() { assertNotNull(created.creationTimeMillis()); assertNotNull(created.nameServers()); assertNull(created.nameServerSet()); - assertNotNull(created.id()); + assertNotNull(created.generatedId()); Zone retrieved = DNS.getZone(ZONE1.name()); assertEquals(created, retrieved); created = DNS.create(ZONE_EMPTY_DESCRIPTION); @@ -184,7 +184,7 @@ public void testCreateValidZone() { assertNotNull(created.creationTimeMillis()); assertNotNull(created.nameServers()); assertNull(created.nameServerSet()); - assertNotNull(created.id()); + assertNotNull(created.generatedId()); retrieved = DNS.getZone(ZONE_EMPTY_DESCRIPTION.name()); assertEquals(created, retrieved); } finally { @@ -226,7 +226,7 @@ public void testCreateZoneWithOptions() { assertNull(created.dnsName()); assertTrue(created.nameServers().isEmpty()); // never returns null assertNull(created.nameServerSet()); - assertNull(created.id()); + assertNull(created.generatedId()); created.delete(); created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.DESCRIPTION)); assertEquals(ZONE1.name(), created.name()); // always returned @@ -235,7 +235,7 @@ public void testCreateZoneWithOptions() { assertNull(created.dnsName()); assertTrue(created.nameServers().isEmpty()); // never returns null assertNull(created.nameServerSet()); - assertNull(created.id()); + assertNull(created.generatedId()); created.delete(); created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.DNS_NAME)); assertEquals(ZONE1.name(), created.name()); // always returned @@ -244,7 +244,7 @@ public void testCreateZoneWithOptions() { assertNull(created.description()); assertTrue(created.nameServers().isEmpty()); // never returns null assertNull(created.nameServerSet()); - assertNull(created.id()); + assertNull(created.generatedId()); created.delete(); created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); assertEquals(ZONE1.name(), created.name()); // always returned @@ -253,7 +253,7 @@ public void testCreateZoneWithOptions() { assertNull(created.description()); assertTrue(created.nameServers().isEmpty()); // never returns null assertNull(created.nameServerSet()); - assertNull(created.id()); + assertNull(created.generatedId()); created.delete(); created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVER_SET)); assertEquals(ZONE1.name(), created.name()); // always returned @@ -262,7 +262,7 @@ public void testCreateZoneWithOptions() { assertNull(created.description()); assertTrue(created.nameServers().isEmpty()); // never returns null assertNull(created.nameServerSet()); // we did not set it - assertNull(created.id()); + assertNull(created.generatedId()); created.delete(); created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVERS)); assertEquals(ZONE1.name(), created.name()); // always returned @@ -271,7 +271,7 @@ public void testCreateZoneWithOptions() { assertNull(created.description()); assertFalse(created.nameServers().isEmpty()); assertNull(created.nameServerSet()); - assertNull(created.id()); + assertNull(created.generatedId()); created.delete(); created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID)); assertEquals(ZONE1.name(), created.name()); // always returned @@ -280,7 +280,7 @@ public void testCreateZoneWithOptions() { assertNull(created.description()); assertNotNull(created.nameServers()); assertTrue(created.nameServers().isEmpty()); // never returns null - assertNotNull(created.id()); + assertNotNull(created.generatedId()); created.delete(); // combination of multiple things created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID, @@ -291,7 +291,7 @@ public void testCreateZoneWithOptions() { assertEquals(ZONE1.description(), created.description()); assertFalse(created.nameServers().isEmpty()); assertNull(created.nameServerSet()); // we did not set it - assertNotNull(created.id()); + assertNotNull(created.generatedId()); } finally { DNS.delete(ZONE1.name()); } @@ -308,7 +308,7 @@ public void testGetZone() { assertNull(created.dnsName()); assertTrue(created.nameServers().isEmpty()); // never returns null assertNull(created.nameServerSet()); - assertNull(created.id()); + assertNull(created.generatedId()); created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.DESCRIPTION)); assertEquals(ZONE1.name(), created.name()); // always returned assertNull(created.creationTimeMillis()); @@ -316,7 +316,7 @@ public void testGetZone() { assertNull(created.dnsName()); assertTrue(created.nameServers().isEmpty()); // never returns null assertNull(created.nameServerSet()); - assertNull(created.id()); + assertNull(created.generatedId()); created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.DNS_NAME)); assertEquals(ZONE1.name(), created.name()); // always returned assertNull(created.creationTimeMillis()); @@ -324,7 +324,7 @@ public void testGetZone() { assertNull(created.description()); assertTrue(created.nameServers().isEmpty()); // never returns null assertNull(created.nameServerSet()); - assertNull(created.id()); + assertNull(created.generatedId()); created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.NAME)); assertEquals(ZONE1.name(), created.name()); // always returned assertNull(created.creationTimeMillis()); @@ -332,7 +332,7 @@ public void testGetZone() { assertNull(created.description()); assertTrue(created.nameServers().isEmpty()); // never returns null assertNull(created.nameServerSet()); - assertNull(created.id()); + assertNull(created.generatedId()); created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVER_SET)); assertEquals(ZONE1.name(), created.name()); // always returned assertNull(created.creationTimeMillis()); @@ -340,7 +340,7 @@ public void testGetZone() { assertNull(created.description()); assertTrue(created.nameServers().isEmpty()); // never returns null assertNull(created.nameServerSet()); // we did not set it - assertNull(created.id()); + assertNull(created.generatedId()); created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVERS)); assertEquals(ZONE1.name(), created.name()); // always returned assertNull(created.creationTimeMillis()); @@ -348,7 +348,7 @@ public void testGetZone() { assertNull(created.description()); assertFalse(created.nameServers().isEmpty()); assertNull(created.nameServerSet()); - assertNull(created.id()); + assertNull(created.generatedId()); created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID)); assertEquals(ZONE1.name(), created.name()); // always returned assertNull(created.creationTimeMillis()); @@ -356,7 +356,7 @@ public void testGetZone() { assertNull(created.description()); assertNotNull(created.nameServers()); assertTrue(created.nameServers().isEmpty()); // never returns null - assertNotNull(created.id()); + assertNotNull(created.generatedId()); // combination of multiple things created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID, Dns.ZoneField.NAME_SERVERS, Dns.ZoneField.NAME_SERVER_SET, Dns.ZoneField.DESCRIPTION)); @@ -366,7 +366,7 @@ public void testGetZone() { assertEquals(ZONE1.description(), created.description()); assertFalse(created.nameServers().isEmpty()); assertNull(created.nameServerSet()); // we did not set it - assertNotNull(created.id()); + assertNotNull(created.generatedId()); } finally { DNS.delete(ZONE1.name()); } @@ -428,7 +428,7 @@ public void testListZones() { assertNull(zone.description()); assertNull(zone.nameServerSet()); assertTrue(zone.nameServers().isEmpty()); - assertNotNull(zone.id()); + assertNotNull(zone.generatedId()); assertFalse(zoneIterator.hasNext()); zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), Dns.ZoneListOption.fields(Dns.ZoneField.CREATION_TIME)).iterateAll(); @@ -439,7 +439,7 @@ public void testListZones() { assertNull(zone.description()); assertNull(zone.nameServerSet()); assertTrue(zone.nameServers().isEmpty()); - assertNull(zone.id()); + assertNull(zone.generatedId()); assertFalse(zoneIterator.hasNext()); zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), Dns.ZoneListOption.fields(Dns.ZoneField.DNS_NAME)).iterateAll(); @@ -450,7 +450,7 @@ public void testListZones() { assertNull(zone.description()); assertNull(zone.nameServerSet()); assertTrue(zone.nameServers().isEmpty()); - assertNull(zone.id()); + assertNull(zone.generatedId()); assertFalse(zoneIterator.hasNext()); zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), Dns.ZoneListOption.fields(Dns.ZoneField.DESCRIPTION)).iterateAll(); @@ -461,7 +461,7 @@ public void testListZones() { assertNotNull(zone.description()); assertNull(zone.nameServerSet()); assertTrue(zone.nameServers().isEmpty()); - assertNull(zone.id()); + assertNull(zone.generatedId()); assertFalse(zoneIterator.hasNext()); zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), Dns.ZoneListOption.fields(Dns.ZoneField.NAME_SERVERS)).iterateAll(); @@ -472,7 +472,7 @@ public void testListZones() { assertNull(zone.description()); assertNull(zone.nameServerSet()); assertTrue(!zone.nameServers().isEmpty()); - assertNull(zone.id()); + assertNull(zone.generatedId()); assertFalse(zoneIterator.hasNext()); zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), Dns.ZoneListOption.fields(Dns.ZoneField.NAME_SERVER_SET)).iterateAll(); @@ -483,7 +483,7 @@ public void testListZones() { assertNull(zone.description()); assertNull(zone.nameServerSet()); // we cannot set it using gcloud java assertTrue(zone.nameServers().isEmpty()); - assertNull(zone.id()); + assertNull(zone.generatedId()); assertFalse(zoneIterator.hasNext()); // several combined zones = filter(DNS.listZones(Dns.ZoneListOption.fields(Dns.ZoneField.ZONE_ID, @@ -497,7 +497,7 @@ public void testListZones() { assertNotNull(current.description()); assertNull(current.nameServerSet()); assertTrue(zone.nameServers().isEmpty()); - assertNotNull(current.id()); + assertNotNull(current.generatedId()); } } finally { DNS.delete(ZONE1.name()); @@ -525,7 +525,7 @@ public void testCreateChange() { assertEquals(CHANGE_ADD_ZONE1.additions(), created.additions()); assertNotNull(created.startTimeMillis()); assertTrue(created.deletions().isEmpty()); - assertEquals("1", created.id()); + assertEquals("1", created.generatedId()); assertTrue(ImmutableList.of(ChangeRequest.Status.PENDING, ChangeRequest.Status.DONE) .contains(created.status())); assertEqChangesIgnoreStatus(created, DNS.getChangeRequest(ZONE1.name(), "1")); @@ -538,7 +538,7 @@ public void testCreateChange() { assertTrue(created.additions().isEmpty()); assertNull(created.startTimeMillis()); assertTrue(created.deletions().isEmpty()); - assertEquals("3", created.id()); + assertEquals("3", created.generatedId()); assertNull(created.status()); waitForChangeToComplete(ZONE1.name(), "3"); DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); @@ -548,7 +548,7 @@ public void testCreateChange() { assertTrue(created.additions().isEmpty()); assertNull(created.startTimeMillis()); assertTrue(created.deletions().isEmpty()); - assertEquals("5", created.id()); + assertEquals("5", created.generatedId()); assertNotNull(created.status()); waitForChangeToComplete(ZONE1.name(), "5"); DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); @@ -558,7 +558,7 @@ public void testCreateChange() { assertTrue(created.additions().isEmpty()); assertNotNull(created.startTimeMillis()); assertTrue(created.deletions().isEmpty()); - assertEquals("7", created.id()); + assertEquals("7", created.generatedId()); assertNull(created.status()); waitForChangeToComplete(ZONE1.name(), "7"); DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); @@ -568,7 +568,7 @@ public void testCreateChange() { assertEquals(CHANGE_ADD_ZONE1.additions(), created.additions()); assertNull(created.startTimeMillis()); assertTrue(created.deletions().isEmpty()); - assertEquals("9", created.id()); + assertEquals("9", created.generatedId()); assertNull(created.status()); // finishes with delete otherwise we cannot delete the zone waitForChangeToComplete(ZONE1.name(), "9"); @@ -578,7 +578,7 @@ public void testCreateChange() { assertEquals(CHANGE_DELETE_ZONE1.deletions(), created.deletions()); assertNull(created.startTimeMillis()); assertTrue(created.additions().isEmpty()); - assertEquals("10", created.id()); + assertEquals("10", created.generatedId()); assertNull(created.status()); waitForChangeToComplete(ZONE1.name(), "10"); } finally { @@ -653,7 +653,7 @@ public void testInvalidChangeRequest() { if (recordAdded) { ChangeRequestInfo deletion = ChangeRequest.builder().delete(validA).build(); ChangeRequest request = zone.applyChangeRequest(deletion); - waitForChangeToComplete(zone.name(), request.id()); + waitForChangeToComplete(zone.name(), request.generatedId()); } zone.delete(); } @@ -678,13 +678,13 @@ public void testListChanges() { assertEquals(1, changes.size()); // default change creating SOA and NS // zone has changes ChangeRequest change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); - waitForChangeToComplete(ZONE1.name(), change.id()); + waitForChangeToComplete(ZONE1.name(), change.generatedId()); change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - waitForChangeToComplete(ZONE1.name(), change.id()); + waitForChangeToComplete(ZONE1.name(), change.generatedId()); change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); - waitForChangeToComplete(ZONE1.name(), change.id()); + waitForChangeToComplete(ZONE1.name(), change.generatedId()); change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - waitForChangeToComplete(ZONE1.name(), change.id()); + waitForChangeToComplete(ZONE1.name(), change.generatedId()); changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name()).iterateAll()); assertEquals(5, changes.size()); // error in options @@ -724,7 +724,7 @@ public void testListChanges() { change = changes.get(1); assertEquals(CHANGE_ADD_ZONE1.additions(), change.additions()); assertTrue(change.deletions().isEmpty()); - assertEquals("1", change.id()); + assertEquals("1", change.generatedId()); assertNull(change.startTimeMillis()); assertNull(change.status()); changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), @@ -733,7 +733,7 @@ public void testListChanges() { change = changes.get(2); assertTrue(change.additions().isEmpty()); assertNotNull(change.deletions()); - assertEquals("2", change.id()); + assertEquals("2", change.generatedId()); assertNull(change.startTimeMillis()); assertNull(change.status()); changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), @@ -742,7 +742,7 @@ public void testListChanges() { change = changes.get(1); assertTrue(change.additions().isEmpty()); assertTrue(change.deletions().isEmpty()); - assertEquals("1", change.id()); + assertEquals("1", change.generatedId()); assertNull(change.startTimeMillis()); assertNull(change.status()); changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), @@ -751,7 +751,7 @@ public void testListChanges() { change = changes.get(1); assertTrue(change.additions().isEmpty()); assertTrue(change.deletions().isEmpty()); - assertEquals("1", change.id()); + assertEquals("1", change.generatedId()); assertNotNull(change.startTimeMillis()); assertNull(change.status()); changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), @@ -760,7 +760,7 @@ public void testListChanges() { change = changes.get(1); assertTrue(change.additions().isEmpty()); assertTrue(change.deletions().isEmpty()); - assertEquals("1", change.id()); + assertEquals("1", change.generatedId()); assertNull(change.startTimeMillis()); assertEquals(ChangeRequest.Status.DONE, change.status()); } finally { @@ -773,45 +773,45 @@ public void testGetChange() { try { Zone zone = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); ChangeRequest created = zone.applyChangeRequest(CHANGE_ADD_ZONE1); - ChangeRequest retrieved = DNS.getChangeRequest(zone.name(), created.id()); + ChangeRequest retrieved = DNS.getChangeRequest(zone.name(), created.generatedId()); assertEqChangesIgnoreStatus(created, retrieved); - waitForChangeToComplete(zone.name(), created.id()); + waitForChangeToComplete(zone.name(), created.generatedId()); zone.applyChangeRequest(CHANGE_DELETE_ZONE1); // with options created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); - retrieved = DNS.getChangeRequest(zone.name(), created.id(), + retrieved = DNS.getChangeRequest(zone.name(), created.generatedId(), Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); assertEqChangesIgnoreStatus(created, retrieved); - waitForChangeToComplete(zone.name(), created.id()); + waitForChangeToComplete(zone.name(), created.generatedId()); zone.applyChangeRequest(CHANGE_DELETE_ZONE1); created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); - retrieved = DNS.getChangeRequest(zone.name(), created.id(), + retrieved = DNS.getChangeRequest(zone.name(), created.generatedId(), Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); assertEqChangesIgnoreStatus(created, retrieved); - waitForChangeToComplete(zone.name(), created.id()); + waitForChangeToComplete(zone.name(), created.generatedId()); zone.applyChangeRequest(CHANGE_DELETE_ZONE1); created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); - retrieved = DNS.getChangeRequest(zone.name(), created.id(), + retrieved = DNS.getChangeRequest(zone.name(), created.generatedId(), Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); assertEqChangesIgnoreStatus(created, retrieved); - waitForChangeToComplete(zone.name(), created.id()); + waitForChangeToComplete(zone.name(), created.generatedId()); zone.applyChangeRequest(CHANGE_DELETE_ZONE1); created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); - retrieved = DNS.getChangeRequest(zone.name(), created.id(), + retrieved = DNS.getChangeRequest(zone.name(), created.generatedId(), Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); assertEqChangesIgnoreStatus(created, retrieved); - waitForChangeToComplete(zone.name(), created.id()); + waitForChangeToComplete(zone.name(), created.generatedId()); // finishes with delete otherwise we cannot delete the zone created = zone.applyChangeRequest(CHANGE_DELETE_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); - retrieved = DNS.getChangeRequest(zone.name(), created.id(), + retrieved = DNS.getChangeRequest(zone.name(), created.generatedId(), Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); assertEqChangesIgnoreStatus(created, retrieved); - waitForChangeToComplete(zone.name(), created.id()); + waitForChangeToComplete(zone.name(), created.generatedId()); } finally { clear(); } @@ -904,7 +904,7 @@ public void testListDnsRecords() { assertEquals(1, ImmutableList.copyOf(recordSetPage.values().iterator()).size()); // test name filter ChangeRequest change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); - waitForChangeToComplete(ZONE1.name(), change.id()); + waitForChangeToComplete(ZONE1.name(), change.generatedId()); recordSetIterator = DNS.listRecordSets(ZONE1.name(), Dns.RecordSetListOption.dnsName(A_RECORD_ZONE1.name())).iterateAll(); counter = 0; @@ -916,7 +916,7 @@ public void testListDnsRecords() { } assertEquals(2, counter); // test type filter - waitForChangeToComplete(ZONE1.name(), change.id()); + waitForChangeToComplete(ZONE1.name(), change.generatedId()); recordSetIterator = DNS.listRecordSets(ZONE1.name(), Dns.RecordSetListOption.dnsName(A_RECORD_ZONE1.name()), Dns.RecordSetListOption.type(A_RECORD_ZONE1.type())) @@ -956,7 +956,7 @@ public void testListDnsRecords() { assertEquals(400, ex.code()); assertFalse(ex.retryable()); } - waitForChangeToComplete(ZONE1.name(), change.id()); + waitForChangeToComplete(ZONE1.name(), change.generatedId()); } finally { clear(); } diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java index a9e5c5d25377..e5f0cf01a6c9 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java @@ -90,7 +90,7 @@ public void run(Dns dns, String... args) { ZoneInfo zoneInfo = ZoneInfo.of(zoneName, dnsName, description); Zone zone = dns.create(zoneInfo); System.out.printf("Successfully created zone with name %s which was assigned ID %s.%n", - zone.name(), zone.id()); + zone.name(), zone.generatedId()); } @Override @@ -213,7 +213,7 @@ public void run(Dns dns, String... args) { .build(); changeRequest = dns.applyChangeRequest(zoneName, changeRequest); System.out.printf("The request for deleting A record %s for zone %s was successfully " - + "submitted and assigned ID %s.%n", recordName, zoneName, changeRequest.id()); + + "submitted and assigned ID %s.%n", recordName, zoneName, changeRequest.generatedId()); System.out.print("Waiting for deletion to happen..."); waitForChangeToFinish(dns, zoneName, changeRequest); System.out.printf("%nThe deletion has been completed.%n"); @@ -258,7 +258,7 @@ public void run(Dns dns, String... args) { ChangeRequestInfo changeRequest = ChangeRequest.builder().add(recordSet).build(); changeRequest = dns.applyChangeRequest(zoneName, changeRequest); System.out.printf("The request for adding A record %s for zone %s was successfully " - + "submitted and assigned ID %s.%n", recordName, zoneName, changeRequest.id()); + + "submitted and assigned ID %s.%n", recordName, zoneName, changeRequest.generatedId()); System.out.print("Waiting for addition to happen..."); waitForChangeToFinish(dns, zoneName, changeRequest); System.out.printf("The addition has been completed.%n"); @@ -334,7 +334,7 @@ public void run(Dns dns, String... args) { System.out.printf("Change requests for zone %s:%n", zoneName); while (iterator.hasNext()) { ChangeRequest change = iterator.next(); - System.out.printf("%nID: %s%n", change.id()); + System.out.printf("%nID: %s%n", change.generatedId()); System.out.printf("Status: %s%n", change.status()); System.out.printf("Started: %s%n", FORMATTER.format(change.startTimeMillis())); System.out.printf("Deletions: %s%n", Joiner.on(", ").join(change.deletions())); @@ -439,7 +439,7 @@ public boolean check(String... args) { private static void printZone(Zone zone) { System.out.printf("%nName: %s%n", zone.name()); - System.out.printf("ID: %s%n", zone.id()); + System.out.printf("ID: %s%n", zone.generatedId()); System.out.printf("Description: %s%n", zone.description()); System.out.printf("Created: %s%n", FORMATTER.format(new Date(zone.creationTimeMillis()))); System.out.printf("Name servers: %s%n", Joiner.on(", ").join(zone.nameServers())); @@ -455,7 +455,7 @@ private static ChangeRequestInfo waitForChangeToFinish(Dns dns, String zoneName, } catch (InterruptedException e) { System.err.println("Thread was interrupted while waiting."); } - current = dns.getChangeRequest(zoneName, current.id()); + current = dns.getChangeRequest(zoneName, current.generatedId()); } return current; } diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateZone.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateZone.java index 2c2ba211bd86..dcf8019319c3 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateZone.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateZone.java @@ -46,6 +46,6 @@ public static void main(String... args) { // Create zone in Google Cloud DNS Zone zone = dns.create(zoneInfo); - System.out.printf("Zone was created and assigned ID %s.%n", zone.id()); + System.out.printf("Zone was created and assigned ID %s.%n", zone.generatedId()); } } diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java index 63f26eeebb2a..aaf663920173 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java @@ -73,7 +73,7 @@ public static void main(String... args) { + "processed."); } // Update the change, but fetch only change ID and status - changeRequest = dns.getChangeRequest(zoneName, changeRequest.id(), option); + changeRequest = dns.getChangeRequest(zoneName, changeRequest.generatedId(), option); } } diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java index 9c9a9e77289c..50f3a1a5c951 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java @@ -51,7 +51,7 @@ public static void main(String... args) { // Create zone in Google Cloud DNS Zone zone = dns.create(zoneInfo); - System.out.printf("Zone was created and assigned ID %s.%n", zone.id()); + System.out.printf("Zone was created and assigned ID %s.%n", zone.generatedId()); // Print assigned name servers List nameServers = zone.nameServers(); @@ -89,7 +89,7 @@ public static void main(String... args) { } catch (InterruptedException e) { System.err.println("The thread was interrupted while waiting..."); } - changeRequest = dns.getChangeRequest(zone.name(), changeRequest.id()); + changeRequest = dns.getChangeRequest(zone.name(), changeRequest.generatedId()); } System.out.println("The change request has been applied."); @@ -143,7 +143,7 @@ public static void main(String... args) { } // Update the change, but fetch only change ID and status - changeRequest = dns.getChangeRequest(zoneName, changeRequest.id(), option); + changeRequest = dns.getChangeRequest(zoneName, changeRequest.generatedId(), option); } } From 883c60eff3f38413ca4187722233c599378e6de2 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 1 Apr 2016 13:43:05 -0700 Subject: [PATCH 221/375] rename QueryStage id to generatedId --- .../google/gcloud/bigquery/QueryStage.java | 26 +++++++++---------- .../gcloud/bigquery/JobStatisticsTest.java | 2 +- .../gcloud/bigquery/QueryStageTest.java | 6 ++--- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryStage.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryStage.java index 8c9f91fd39f3..9404fbf5d9ad 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryStage.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryStage.java @@ -137,7 +137,7 @@ static QueryStep fromPb(com.google.api.services.bigquery.model.ExplainQueryStep private final double computeRatioAvg; private final double computeRatioMax; - private final long id; + private final long generatedId; private final String name; private final double readRatioAvg; private final double readRatioMax; @@ -153,7 +153,7 @@ static final class Builder { private double computeRatioAvg; private double computeRatioMax; - private long id; + private long generatedId; private String name; private double readRatioAvg; private double readRatioMax; @@ -177,8 +177,8 @@ Builder computeRatioMax(double computeRatioMax) { return this; } - Builder id(long id) { - this.id = id; + Builder generatedId(long generatedId) { + this.generatedId = generatedId; return this; } @@ -240,7 +240,7 @@ QueryStage build() { QueryStage(Builder builder) { computeRatioAvg = builder.computeRatioAvg; computeRatioMax = builder.computeRatioMax; - id = builder.id; + generatedId = builder.generatedId; name = builder.name; readRatioAvg = builder.readRatioAvg; readRatioMax = builder.readRatioMax; @@ -270,10 +270,10 @@ public double computeRatioMax() { } /** - * Returns a unique ID for the stage within its plan. + * Returns a unique, server-generated ID for the stage within its plan. */ - public long id() { - return id; + public long generatedId() { + return generatedId; } /** @@ -357,7 +357,7 @@ public String toString() { return MoreObjects.toStringHelper(this) .add("computeRatioAvg", computeRatioAvg) .add("computeRatioMax", computeRatioMax) - .add("id", id) + .add("generatedId", generatedId) .add("name", name) .add("readRatioAvg", readRatioAvg) .add("readRatioMax", readRatioMax) @@ -373,7 +373,7 @@ public String toString() { @Override public int hashCode() { - return Objects.hash(computeRatioAvg, computeRatioMax, id, name, readRatioAvg, readRatioMax, + return Objects.hash(computeRatioAvg, computeRatioMax, generatedId, name, readRatioAvg, readRatioMax, recordsRead, recordsWritten, steps, waitRatioAvg, waitRatioMax, writeRatioAvg); } @@ -383,7 +383,7 @@ public boolean equals(Object obj) { return false; } QueryStage other = (QueryStage) obj; - return id == other.id + return generatedId == other.generatedId && computeRatioAvg == other.computeRatioAvg && computeRatioMax == other.computeRatioMax && readRatioAvg == other.readRatioAvg @@ -406,7 +406,7 @@ ExplainQueryStage toPb() { ExplainQueryStage stagePb = new ExplainQueryStage() .setComputeRatioAvg(computeRatioAvg) .setComputeRatioMax(computeRatioMax) - .setId(id) + .setId(generatedId) .setName(name) .setReadRatioAvg(readRatioAvg) .setReadRatioMax(readRatioMax) @@ -426,7 +426,7 @@ static QueryStage fromPb(com.google.api.services.bigquery.model.ExplainQueryStag Builder builder = new QueryStage.Builder(); builder.computeRatioAvg(stagePb.getComputeRatioAvg()); builder.computeRatioMax(stagePb.getComputeRatioMax()); - builder.id(stagePb.getId()); + builder.generatedId(stagePb.getId()); builder.name(stagePb.getName()); builder.readRatioAvg(stagePb.getReadRatioAvg()); builder.readRatioMax(stagePb.getReadRatioMax()); diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobStatisticsTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobStatisticsTest.java index 1ec67d034754..4a3940ba4543 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobStatisticsTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobStatisticsTest.java @@ -71,7 +71,7 @@ public class JobStatisticsTest { private static final QueryStage QUERY_STAGE = QueryStage.builder() .computeRatioAvg(1.1) .computeRatioMax(2.2) - .id(42L) + .generatedId(42L) .name("stage") .readRatioAvg(3.3) .readRatioMax(4.4) diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryStageTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryStageTest.java index 99a7c8096454..ac60967a8bee 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryStageTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryStageTest.java @@ -48,7 +48,7 @@ public class QueryStageTest { private static final QueryStage QUERY_STAGE = QueryStage.builder() .computeRatioAvg(COMPUTE_RATIO_AVG) .computeRatioMax(COMPUTE_RATIO_MAX) - .id(ID) + .generatedId(ID) .name(NAME) .readRatioAvg(READ_RATIO_AVG) .readRatioMax(READ_RATIO_MAX) @@ -73,7 +73,7 @@ public void testQueryStepConstructor() { public void testBuilder() { assertEquals(COMPUTE_RATIO_AVG, QUERY_STAGE.computeRatioAvg(), 0); assertEquals(COMPUTE_RATIO_MAX, QUERY_STAGE.computeRatioMax(), 0); - assertEquals(ID, QUERY_STAGE.id()); + assertEquals(ID, QUERY_STAGE.generatedId()); assertEquals(NAME, QUERY_STAGE.name()); assertEquals(READ_RATIO_AVG, QUERY_STAGE.readRatioAvg(), 0); assertEquals(READ_RATIO_MAX, QUERY_STAGE.readRatioMax(), 0); @@ -108,7 +108,7 @@ private void compareQueryStage(QueryStage expected, QueryStage value) { assertEquals(expected, value); assertEquals(expected.computeRatioAvg(), value.computeRatioAvg(), 0); assertEquals(expected.computeRatioMax(), value.computeRatioMax(), 0); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.name(), value.name()); assertEquals(expected.readRatioAvg(), value.readRatioAvg(), 0); assertEquals(expected.readRatioMax(), value.readRatioMax(), 0); From 43b2ef990fd27944823722aaf6caee902f9d429c Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 1 Apr 2016 13:46:59 -0700 Subject: [PATCH 222/375] Release 0.1.7 --- gcloud-java-bigquery/pom.xml | 2 +- gcloud-java-contrib/pom.xml | 2 +- gcloud-java-core/pom.xml | 2 +- gcloud-java-datastore/pom.xml | 2 +- gcloud-java-dns/pom.xml | 2 +- gcloud-java-examples/pom.xml | 2 +- gcloud-java-resourcemanager/pom.xml | 2 +- gcloud-java-storage/pom.xml | 2 +- gcloud-java/pom.xml | 2 +- pom.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/gcloud-java-bigquery/pom.xml b/gcloud-java-bigquery/pom.xml index 952e75899de7..867318ee6c3f 100644 --- a/gcloud-java-bigquery/pom.xml +++ b/gcloud-java-bigquery/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.7-SNAPSHOT + 0.1.7 gcloud-java-bigquery diff --git a/gcloud-java-contrib/pom.xml b/gcloud-java-contrib/pom.xml index c1a0eaad9008..aef99d78306e 100644 --- a/gcloud-java-contrib/pom.xml +++ b/gcloud-java-contrib/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.7-SNAPSHOT + 0.1.7 gcloud-java-contrib diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml index 13e170e061ee..7d6b9c888788 100644 --- a/gcloud-java-core/pom.xml +++ b/gcloud-java-core/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.7-SNAPSHOT + 0.1.7 gcloud-java-core diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index 7110d8de3947..2f23e1fbb919 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.7-SNAPSHOT + 0.1.7 gcloud-java-datastore diff --git a/gcloud-java-dns/pom.xml b/gcloud-java-dns/pom.xml index 66dc1e54752e..c36a0ffe39a6 100644 --- a/gcloud-java-dns/pom.xml +++ b/gcloud-java-dns/pom.xml @@ -13,7 +13,7 @@ com.google.gcloud gcloud-java-pom - 0.1.7-SNAPSHOT + 0.1.7 gcloud-java-dns diff --git a/gcloud-java-examples/pom.xml b/gcloud-java-examples/pom.xml index 15bb536916f4..948ee5c53005 100644 --- a/gcloud-java-examples/pom.xml +++ b/gcloud-java-examples/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.7-SNAPSHOT + 0.1.7 gcloud-java-examples diff --git a/gcloud-java-resourcemanager/pom.xml b/gcloud-java-resourcemanager/pom.xml index f8a2697c23b5..a50067519613 100644 --- a/gcloud-java-resourcemanager/pom.xml +++ b/gcloud-java-resourcemanager/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.7-SNAPSHOT + 0.1.7 gcloud-java-resourcemanager diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml index 37f4d00991a3..80ad0e3ca4e7 100644 --- a/gcloud-java-storage/pom.xml +++ b/gcloud-java-storage/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.7-SNAPSHOT + 0.1.7 gcloud-java-storage diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml index 2a1720fcd300..01aab1ff7121 100644 --- a/gcloud-java/pom.xml +++ b/gcloud-java/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.7-SNAPSHOT + 0.1.7 diff --git a/pom.xml b/pom.xml index 4c53e54560c2..67e71716cc0f 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.gcloud gcloud-java-pom pom - 0.1.7-SNAPSHOT + 0.1.7 GCloud Java https://github.com/GoogleCloudPlatform/gcloud-java From 9a8d15605d156f02030ee3e9950a452a19664a9c Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 1 Apr 2016 14:30:58 -0700 Subject: [PATCH 223/375] Remove flaky tests --- .../java/com/google/gcloud/bigquery/it/ITBigQueryTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java index e712eeeb23fd..cc7f06a251db 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java @@ -71,6 +71,7 @@ import org.junit.AfterClass; import org.junit.BeforeClass; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.Timeout; @@ -623,6 +624,7 @@ public void testInsertAllWithErrors() { assertTrue(bigquery.delete(TableId.of(DATASET, tableName))); } + @Ignore("Flaky test; see issue #836") @Test public void testListAllTableData() { Page> rows = bigquery.listTableData(TABLE_ID); @@ -906,6 +908,7 @@ public void testCancelNonExistingJob() { assertFalse(bigquery.cancel("test_cancel_non_existing_job")); } + @Ignore("Flaky test; see #836") @Test public void testInsertFromFile() throws InterruptedException { String destinationTableName = "test_insert_from_file_table"; From df86a444de86aefbd5b9cbb198976badc8438052 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 1 Apr 2016 15:37:22 -0700 Subject: [PATCH 224/375] Fix endpoint --- .../java/com/google/gcloud/datastore/DatastoreOptions.java | 2 +- .../com/google/gcloud/datastore/spi/DefaultDatastoreRpc.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java index 81e4a36a3584..bc0efd837755 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java @@ -130,7 +130,7 @@ protected String defaultHost() { String host = System.getProperty( com.google.datastore.v1beta3.client.DatastoreHelper.LOCAL_HOST_ENV_VAR, System.getenv(com.google.datastore.v1beta3.client.DatastoreHelper.LOCAL_HOST_ENV_VAR)); - return host != null ? host : super.defaultHost(); + return host != null ? host : com.google.datastore.v1beta3.client.DatastoreFactory.DEFAULT_HOST; } @Override diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/spi/DefaultDatastoreRpc.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/spi/DefaultDatastoreRpc.java index 421ba95161f2..1fb0fa3a26c6 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/spi/DefaultDatastoreRpc.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/spi/DefaultDatastoreRpc.java @@ -54,8 +54,9 @@ public DefaultDatastoreRpc(DatastoreOptions options) { if (fullURL.charAt(fullURL.length() - 1) != '/') { fullURL = fullURL + '/'; } - fullURL = fullURL + "datastore/" - + com.google.datastore.v1beta3.client.DatastoreFactory.VERSION + "/projects/" + fullURL = fullURL + + com.google.datastore.v1beta3.client.DatastoreFactory.VERSION + + "/projects/" + options.projectId(); clientBuilder = clientBuilder.projectId(null).projectEndpoint(fullURL); } From 6f54be2ea7bfe9b7f715e5bc834aab00dcc1f30d Mon Sep 17 00:00:00 2001 From: travis-ci Date: Fri, 1 Apr 2016 23:24:02 +0000 Subject: [PATCH 225/375] Updating version in README files. [ci skip] --- README.md | 6 +++--- gcloud-java-bigquery/README.md | 6 +++--- gcloud-java-contrib/README.md | 6 +++--- gcloud-java-core/README.md | 6 +++--- gcloud-java-datastore/README.md | 6 +++--- gcloud-java-dns/README.md | 6 +++--- gcloud-java-examples/README.md | 6 +++--- gcloud-java-resourcemanager/README.md | 6 +++--- gcloud-java-storage/README.md | 6 +++--- gcloud-java/README.md | 6 +++--- 10 files changed, 30 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index d5604dddbbff..6708ba3d358d 100644 --- a/README.md +++ b/README.md @@ -30,16 +30,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java - 0.1.6 + 0.1.7 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java:0.1.6' +compile 'com.google.gcloud:gcloud-java:0.1.7' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java" % "0.1.6" +libraryDependencies += "com.google.gcloud" % "gcloud-java" % "0.1.7" ``` Example Applications diff --git a/gcloud-java-bigquery/README.md b/gcloud-java-bigquery/README.md index f81cccd5ad44..d300d3969c40 100644 --- a/gcloud-java-bigquery/README.md +++ b/gcloud-java-bigquery/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-bigquery - 0.1.6 + 0.1.7 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-bigquery:0.1.6' +compile 'com.google.gcloud:gcloud-java-bigquery:0.1.7' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-bigquery" % "0.1.6" +libraryDependencies += "com.google.gcloud" % "gcloud-java-bigquery" % "0.1.7" ``` Example Application diff --git a/gcloud-java-contrib/README.md b/gcloud-java-contrib/README.md index b41467934690..f0ead8c79dea 100644 --- a/gcloud-java-contrib/README.md +++ b/gcloud-java-contrib/README.md @@ -16,16 +16,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-contrib - 0.1.6 + 0.1.7 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-contrib:0.1.6' +compile 'com.google.gcloud:gcloud-java-contrib:0.1.7' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-contrib" % "0.1.6" +libraryDependencies += "com.google.gcloud" % "gcloud-java-contrib" % "0.1.7" ``` Java Versions diff --git a/gcloud-java-core/README.md b/gcloud-java-core/README.md index 1ee96b950471..067505179bc9 100644 --- a/gcloud-java-core/README.md +++ b/gcloud-java-core/README.md @@ -19,16 +19,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-core - 0.1.6 + 0.1.7 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-core:0.1.6' +compile 'com.google.gcloud:gcloud-java-core:0.1.7' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-core" % "0.1.6" +libraryDependencies += "com.google.gcloud" % "gcloud-java-core" % "0.1.7" ``` Troubleshooting diff --git a/gcloud-java-datastore/README.md b/gcloud-java-datastore/README.md index 1025de79f63d..69cf039472a3 100644 --- a/gcloud-java-datastore/README.md +++ b/gcloud-java-datastore/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-datastore - 0.1.6 + 0.1.7 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-datastore:0.1.6' +compile 'com.google.gcloud:gcloud-java-datastore:0.1.7' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-datastore" % "0.1.6" +libraryDependencies += "com.google.gcloud" % "gcloud-java-datastore" % "0.1.7" ``` Example Application diff --git a/gcloud-java-dns/README.md b/gcloud-java-dns/README.md index 703bcb190807..ae5e52e9291f 100644 --- a/gcloud-java-dns/README.md +++ b/gcloud-java-dns/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-dns - 0.1.6 + 0.1.7 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-dns:0.1.6' +compile 'com.google.gcloud:gcloud-java-dns:0.1.7' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-dns" % "0.1.6" +libraryDependencies += "com.google.gcloud" % "gcloud-java-dns" % "0.1.7" ``` Example Application diff --git a/gcloud-java-examples/README.md b/gcloud-java-examples/README.md index 45658e37323e..12f25bbe480c 100644 --- a/gcloud-java-examples/README.md +++ b/gcloud-java-examples/README.md @@ -19,16 +19,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-examples - 0.1.6 + 0.1.7 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-examples:0.1.6' +compile 'com.google.gcloud:gcloud-java-examples:0.1.7' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-examples" % "0.1.6" +libraryDependencies += "com.google.gcloud" % "gcloud-java-examples" % "0.1.7" ``` To run examples from your command line: diff --git a/gcloud-java-resourcemanager/README.md b/gcloud-java-resourcemanager/README.md index 9d142fc558ea..667e9222a402 100644 --- a/gcloud-java-resourcemanager/README.md +++ b/gcloud-java-resourcemanager/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-resourcemanager - 0.1.6 + 0.1.7 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-resourcemanager:0.1.6' +compile 'com.google.gcloud:gcloud-java-resourcemanager:0.1.7' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-resourcemanager" % "0.1.6" +libraryDependencies += "com.google.gcloud" % "gcloud-java-resourcemanager" % "0.1.7" ``` Example Application diff --git a/gcloud-java-storage/README.md b/gcloud-java-storage/README.md index 962b90c82b34..1bd12d7846bb 100644 --- a/gcloud-java-storage/README.md +++ b/gcloud-java-storage/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java-storage - 0.1.6 + 0.1.7 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-storage:0.1.6' +compile 'com.google.gcloud:gcloud-java-storage:0.1.7' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-storage" % "0.1.6" +libraryDependencies += "com.google.gcloud" % "gcloud-java-storage" % "0.1.7" ``` Example Application diff --git a/gcloud-java/README.md b/gcloud-java/README.md index c898da5d5f72..36e82fb23a74 100644 --- a/gcloud-java/README.md +++ b/gcloud-java/README.md @@ -27,16 +27,16 @@ If you are using Maven, add this to your pom.xml file com.google.gcloud gcloud-java - 0.1.6 + 0.1.7 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java:0.1.6' +compile 'com.google.gcloud:gcloud-java:0.1.7' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java" % "0.1.6" +libraryDependencies += "com.google.gcloud" % "gcloud-java" % "0.1.7" ``` Troubleshooting From 85d0188e1444252b62b507b67c63b8a130201cba Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 1 Apr 2016 17:05:26 -0700 Subject: [PATCH 226/375] Update to version 0.1.8-SNAPSHOT --- gcloud-java-bigquery/pom.xml | 2 +- gcloud-java-contrib/pom.xml | 2 +- gcloud-java-core/pom.xml | 2 +- gcloud-java-datastore/pom.xml | 2 +- gcloud-java-dns/pom.xml | 2 +- gcloud-java-examples/pom.xml | 2 +- gcloud-java-resourcemanager/pom.xml | 2 +- gcloud-java-storage/pom.xml | 2 +- gcloud-java/pom.xml | 2 +- pom.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/gcloud-java-bigquery/pom.xml b/gcloud-java-bigquery/pom.xml index 867318ee6c3f..39b0d6fc4e37 100644 --- a/gcloud-java-bigquery/pom.xml +++ b/gcloud-java-bigquery/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.7 + 0.1.8-SNAPSHOT gcloud-java-bigquery diff --git a/gcloud-java-contrib/pom.xml b/gcloud-java-contrib/pom.xml index aef99d78306e..1ef855a1ae5d 100644 --- a/gcloud-java-contrib/pom.xml +++ b/gcloud-java-contrib/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.7 + 0.1.8-SNAPSHOT gcloud-java-contrib diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml index 7d6b9c888788..df116b0b1be4 100644 --- a/gcloud-java-core/pom.xml +++ b/gcloud-java-core/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.7 + 0.1.8-SNAPSHOT gcloud-java-core diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index bbdc122a3772..22498ab505f4 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.7 + 0.1.8-SNAPSHOT gcloud-java-datastore diff --git a/gcloud-java-dns/pom.xml b/gcloud-java-dns/pom.xml index c36a0ffe39a6..e7a02452d92f 100644 --- a/gcloud-java-dns/pom.xml +++ b/gcloud-java-dns/pom.xml @@ -13,7 +13,7 @@ com.google.gcloud gcloud-java-pom - 0.1.7 + 0.1.8-SNAPSHOT gcloud-java-dns diff --git a/gcloud-java-examples/pom.xml b/gcloud-java-examples/pom.xml index 948ee5c53005..f5d4cb290118 100644 --- a/gcloud-java-examples/pom.xml +++ b/gcloud-java-examples/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.7 + 0.1.8-SNAPSHOT gcloud-java-examples diff --git a/gcloud-java-resourcemanager/pom.xml b/gcloud-java-resourcemanager/pom.xml index a50067519613..d970bdf883da 100644 --- a/gcloud-java-resourcemanager/pom.xml +++ b/gcloud-java-resourcemanager/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.7 + 0.1.8-SNAPSHOT gcloud-java-resourcemanager diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml index 80ad0e3ca4e7..2316706850d3 100644 --- a/gcloud-java-storage/pom.xml +++ b/gcloud-java-storage/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.7 + 0.1.8-SNAPSHOT gcloud-java-storage diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml index 01aab1ff7121..9b765db419d7 100644 --- a/gcloud-java/pom.xml +++ b/gcloud-java/pom.xml @@ -10,7 +10,7 @@ com.google.gcloud gcloud-java-pom - 0.1.7 + 0.1.8-SNAPSHOT diff --git a/pom.xml b/pom.xml index 67e71716cc0f..42f9bd73cdfb 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.gcloud gcloud-java-pom pom - 0.1.7 + 0.1.8-SNAPSHOT GCloud Java https://github.com/GoogleCloudPlatform/gcloud-java From 59cdf37fed705df06669611a79487faf8d1af8f7 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 4 Apr 2016 17:41:05 +0200 Subject: [PATCH 227/375] Update ruby logo --- src/site/resources/img/icon-lang-ruby.svg | 38 +++++++++-------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/src/site/resources/img/icon-lang-ruby.svg b/src/site/resources/img/icon-lang-ruby.svg index acfaab8d6ea5..5f4e5a25d893 100644 --- a/src/site/resources/img/icon-lang-ruby.svg +++ b/src/site/resources/img/icon-lang-ruby.svg @@ -1,23 +1,15 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + From d17e3253afaafaa9441df140d95fbca86a4051ef Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 4 Apr 2016 18:29:44 +0200 Subject: [PATCH 228/375] Extract projectId from GOOGLE_APPLICATION_CREDENTIALS if set * Extract projectId from GOOGLE_APPLICATION_CREDENTIALS if set * First look for AE's project id, then GOOGLE_APPLICATION_CREDENTIALS' --- README.md | 5 ++-- .../com/google/gcloud/ServiceOptions.java | 26 +++++++++++++++++-- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6708ba3d358d..6bd1e7211f2c 100644 --- a/README.md +++ b/README.md @@ -84,8 +84,9 @@ Most `gcloud-java` libraries require a project ID. There are multiple ways to s 1. Project ID supplied when building the service options 2. Project ID specified by the environment variable `GCLOUD_PROJECT` 3. App Engine project ID -4. Google Cloud SDK project ID -5. Compute Engine project ID +4. Project ID specified in the JSON credentials file pointed by the `GOOGLE_APPLICATION_CREDENTIALS` environment variable +5. Google Cloud SDK project ID +6. Compute Engine project ID Authentication -------------- diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java index 1c5289bbcda9..d53cfcdafe24 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java @@ -30,8 +30,13 @@ import com.google.common.io.Files; import com.google.gcloud.spi.ServiceRpcFactory; +import org.json.JSONException; +import org.json.JSONObject; +import org.json.JSONTokener; + import java.io.BufferedReader; import java.io.File; +import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; @@ -378,7 +383,10 @@ protected String defaultHost() { protected String defaultProject() { String projectId = System.getProperty(PROJECT_ENV_NAME, System.getenv(PROJECT_ENV_NAME)); if (projectId == null) { - projectId = getAppEngineProjectId(); + projectId = appEngineProjectId(); + } + if (projectId == null) { + projectId = serviceAccountProjectId(); } return projectId != null ? projectId : googleCloudProjectId(); } @@ -461,7 +469,7 @@ private static boolean isWindows() { return System.getProperty("os.name").toLowerCase(Locale.ENGLISH).contains("windows"); } - protected static String getAppEngineProjectId() { + protected static String appEngineProjectId() { try { Class factoryClass = Class.forName("com.google.appengine.api.appidentity.AppIdentityServiceFactory"); @@ -479,6 +487,20 @@ protected static String getAppEngineProjectId() { } } + protected static String serviceAccountProjectId() { + String project = null; + String credentialsPath = System.getenv("GOOGLE_APPLICATION_CREDENTIALS"); + if(credentialsPath != null) { + try (InputStream credentialsStream = new FileInputStream(credentialsPath)) { + JSONObject json = new JSONObject(new JSONTokener(credentialsStream)); + project = json.getString("project_id"); + } catch (IOException | JSONException ex) { + // ignore + } + } + return project; + } + @SuppressWarnings("unchecked") public ServiceT service() { if (service == null) { From 560d0b6b5df5f1d71731ddd2eb121750c1fa39b3 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Mon, 4 Apr 2016 16:23:42 -0400 Subject: [PATCH 229/375] Modified methods in ChangeRequest. * Modified methods in ChangeRequest. Added reload() and isDone() to change request. Also changed signature of applyTo(). --- gcloud-java-dns/README.md | 16 +++---- .../com/google/gcloud/dns/ChangeRequest.java | 38 ++++++++++++++-- .../main/java/com/google/gcloud/dns/Dns.java | 2 +- .../google/gcloud/dns/ChangeRequestTest.java | 41 ++++++++++++++++-- .../com/google/gcloud/dns/it/ITDnsTest.java | 43 ++++++++++--------- .../examples/dns/snippets/DeleteZone.java | 11 ++--- .../ManipulateZonesAndRecordSets.java | 11 ++--- 7 files changed, 107 insertions(+), 55 deletions(-) diff --git a/gcloud-java-dns/README.md b/gcloud-java-dns/README.md index ae5e52e9291f..0bb9a47635a2 100644 --- a/gcloud-java-dns/README.md +++ b/gcloud-java-dns/README.md @@ -212,7 +212,7 @@ while (recordSetIterator.hasNext()) { // Build and apply the change request to our zone ChangeRequestInfo changeRequest = changeBuilder.build(); -zone.applyChangeRequest(changeRequest); +ChangeRequest pendingRequest = zone.applyChangeRequest(changeRequest); ``` You can find more information about changes in the [Cloud DNS documentation] (https://cloud.google.com/dns/what-is-cloud-dns#cloud_dns_api_concepts). @@ -220,13 +220,12 @@ When the change request is applied, it is registered with the Cloud DNS service can wait for its completion as follows: ```java -while (ChangeRequestInfo.Status.PENDING.equals(changeRequest.status())) { +while (!pendingRequest.isDone()) { try { Thread.sleep(500L); } catch (InterruptedException e) { System.err.println("The thread was interrupted while waiting..."); } - changeRequest = dns.getChangeRequest(zone.name(), changeRequest.generatedId()); } System.out.println("The change request has been applied."); ``` @@ -300,12 +299,10 @@ while (recordIterator.hasNext()) { // Build and apply the change request to our zone if it contains records to delete ChangeRequestInfo changeRequest = changeBuilder.build(); if (!changeRequest.deletions().isEmpty()) { - changeRequest = dns.applyChangeRequest(zoneName, changeRequest); + ChangeRequest pendingRequest = dns.applyChangeRequest(zoneName, changeRequest); - // Wait for change to finish, but save data traffic by transferring only ID and status - Dns.ChangeRequestOption option = - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS); - while (ChangeRequestInfo.Status.PENDING.equals(changeRequest.status())) { + // Wait for the change request to complete + while (!pendingRequest.isDone()) { System.out.println("Waiting for change to complete. Going to sleep for 500ms..."); try { Thread.sleep(500); @@ -313,9 +310,6 @@ if (!changeRequest.deletions().isEmpty()) { System.err.println("The thread was interrupted while waiting for change request to be " + "processed."); } - - // Update the change, but fetch only change ID and status - changeRequest = dns.getChangeRequest(zoneName, changeRequest.generatedId(), option); } } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java index 60b053faab6d..66e841c20a15 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java @@ -148,10 +148,42 @@ public Dns dns() { } /** - * Applies this change request to the associated zone. + * Applies this change request to the zone identified by {@code zoneName}. + * + * @throws DnsException upon failure or if zone is not found */ - public ChangeRequest applyTo(Dns.ChangeRequestOption... options) { - return dns.applyChangeRequest(zone, this, options); + public ChangeRequest applyTo(String zoneName, Dns.ChangeRequestOption... options) { + return dns.applyChangeRequest(zoneName, this, options); + } + + /** + * Retrieves the up-to-date information about the change request from Google Cloud DNS. Parameter + * {@code options} can be used to restrict the fields to be included in the updated object the + * same way as in {@link Dns#getChangeRequest(String, String, Dns.ChangeRequestOption...)}. If + * {@code options} are provided, any field other than generatedId which is not included in the + * {@code options} will be {@code null} regardless of whether they are initialized or not in + * {@code this} instance. + * + * @return an object with the updated information or {@code null} if it does not exist + * @throws DnsException upon failure of the API call or if the associated zone was not found + */ + public ChangeRequest reload(Dns.ChangeRequestOption... options) { + return dns.getChangeRequest(zone, generatedId(), options); + } + + /** + * Returns {@code true} if the change request has been completed. If the status is not {@link + * Status#DONE} already, the method makes an API call to Google Cloud DNS to update the change + * request first. + * + * @throws DnsException upon failure of the API call or if the associated zone was not found + */ + public boolean isDone() { + if (status() == Status.DONE) { + return true; + } + ChangeRequest updated = reload(Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); + return updated == null || updated.status() == Status.DONE; } @Override diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index d95d11a97c19..a78eaef7c4e7 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -475,7 +475,7 @@ public static ChangeRequestListOption sortOrder(SortingOrder order) { * servers. The fields to be returned can be selected by {@link ChangeRequestOption}s. * * @return the new {@link ChangeRequest} - * @throws DnsException upon failure if zone is not found + * @throws DnsException upon failure or if zone is not found * @see Cloud DNS Changes: create */ ChangeRequest applyChangeRequest(String zoneName, ChangeRequestInfo changeRequest, diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java index 4d4b2c01823c..2c3be337f033 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java @@ -43,12 +43,13 @@ public class ChangeRequestTest { private Dns dns; private ChangeRequest changeRequest; + private ChangeRequest changeRequestPending; private ChangeRequest changeRequestPartial; @Before public void setUp() throws Exception { dns = createStrictMock(Dns.class); - expect(dns.options()).andReturn(OPTIONS).times(2); + expect(dns.options()).andReturn(OPTIONS).times(3); replay(dns); changeRequest = new ChangeRequest(dns, ZONE_NAME, new ChangeRequestInfo.BuilderImpl( CHANGE_REQUEST_INFO.toBuilder() @@ -56,6 +57,12 @@ public void setUp() throws Exception { .generatedId("12") .status(ChangeRequest.Status.DONE) .build())); + changeRequestPending = new ChangeRequest(dns, ZONE_NAME, new ChangeRequestInfo.BuilderImpl( + CHANGE_REQUEST_INFO.toBuilder() + .startTimeMillis(132L) + .generatedId("12") + .status(ChangeRequest.Status.PENDING) + .build())); changeRequestPartial = new ChangeRequest(dns, ZONE_NAME, new ChangeRequest.BuilderImpl(CHANGE_REQUEST_INFO)); reset(dns); @@ -133,8 +140,34 @@ public void testApplyTo() { Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME))) .andReturn(changeRequest); replay(dns); - assertSame(changeRequest, changeRequest.applyTo()); - assertSame(changeRequest, - changeRequest.applyTo(Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME))); + assertSame(changeRequest, changeRequest.applyTo(ZONE_NAME)); + assertSame(changeRequest, changeRequest.applyTo(ZONE_NAME, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME))); + } + + @Test + public void testReload() { + expect(dns.getChangeRequest(ZONE_NAME, changeRequest.generatedId())).andReturn(changeRequest); + expect(dns.getChangeRequest(ZONE_NAME, changeRequest.generatedId(), + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME))) + .andReturn(changeRequest); + replay(dns); + assertSame(changeRequest, changeRequest.reload()); + assertSame(changeRequest, changeRequest.reload( + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME))); + } + + @Test + public void testIsDone() { + replay(dns); + assertTrue(changeRequest.isDone()); + verify(dns); + reset(dns); + expect(dns.getChangeRequest(ZONE_NAME, changeRequest.generatedId(), + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS))) + .andReturn(changeRequest); + replay(dns); + assertTrue(changeRequestPending.isDone()); + verify(dns); } } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java index aa6c78461b8b..f25bd537cd72 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java @@ -147,12 +147,13 @@ private static void assertEqChangesIgnoreStatus(ChangeRequest expected, ChangeRe } private static void waitForChangeToComplete(String zoneName, String changeId) { - while (true) { - ChangeRequest changeRequest = DNS.getChangeRequest(zoneName, changeId, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); - if (ChangeRequest.Status.DONE.equals(changeRequest.status())) { - return; - } + ChangeRequest changeRequest = DNS.getChangeRequest(zoneName, changeId, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); + waitForChangeToComplete(changeRequest); + } + + private static void waitForChangeToComplete(ChangeRequest changeRequest) { + while (!changeRequest.isDone()) { try { Thread.sleep(500); } catch (InterruptedException e) { @@ -529,9 +530,9 @@ public void testCreateChange() { assertTrue(ImmutableList.of(ChangeRequest.Status.PENDING, ChangeRequest.Status.DONE) .contains(created.status())); assertEqChangesIgnoreStatus(created, DNS.getChangeRequest(ZONE1.name(), "1")); - waitForChangeToComplete(ZONE1.name(), "1"); - DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - waitForChangeToComplete(ZONE1.name(), "2"); + waitForChangeToComplete(created); + created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + waitForChangeToComplete(created); // with options created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); @@ -540,9 +541,9 @@ public void testCreateChange() { assertTrue(created.deletions().isEmpty()); assertEquals("3", created.generatedId()); assertNull(created.status()); - waitForChangeToComplete(ZONE1.name(), "3"); - DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - waitForChangeToComplete(ZONE1.name(), "4"); + waitForChangeToComplete(created); + created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + waitForChangeToComplete(created); created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); assertTrue(created.additions().isEmpty()); @@ -550,9 +551,9 @@ public void testCreateChange() { assertTrue(created.deletions().isEmpty()); assertEquals("5", created.generatedId()); assertNotNull(created.status()); - waitForChangeToComplete(ZONE1.name(), "5"); - DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - waitForChangeToComplete(ZONE1.name(), "6"); + waitForChangeToComplete(created); + created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + waitForChangeToComplete(created); created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); assertTrue(created.additions().isEmpty()); @@ -560,9 +561,9 @@ public void testCreateChange() { assertTrue(created.deletions().isEmpty()); assertEquals("7", created.generatedId()); assertNull(created.status()); - waitForChangeToComplete(ZONE1.name(), "7"); - DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); - waitForChangeToComplete(ZONE1.name(), "8"); + waitForChangeToComplete(created); + created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + waitForChangeToComplete(created); created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); assertEquals(CHANGE_ADD_ZONE1.additions(), created.additions()); @@ -571,16 +572,16 @@ public void testCreateChange() { assertEquals("9", created.generatedId()); assertNull(created.status()); // finishes with delete otherwise we cannot delete the zone - waitForChangeToComplete(ZONE1.name(), "9"); + waitForChangeToComplete(created); created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1, Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); - waitForChangeToComplete(ZONE1.name(), "10"); + waitForChangeToComplete(created); assertEquals(CHANGE_DELETE_ZONE1.deletions(), created.deletions()); assertNull(created.startTimeMillis()); assertTrue(created.additions().isEmpty()); assertEquals("10", created.generatedId()); assertNull(created.status()); - waitForChangeToComplete(ZONE1.name(), "10"); + waitForChangeToComplete(created); } finally { clear(); } diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java index aaf663920173..c791ea8c0992 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java @@ -22,6 +22,7 @@ package com.google.gcloud.examples.dns.snippets; +import com.google.gcloud.dns.ChangeRequest; import com.google.gcloud.dns.ChangeRequestInfo; import com.google.gcloud.dns.Dns; import com.google.gcloud.dns.DnsOptions; @@ -59,12 +60,10 @@ public static void main(String... args) { // Build and apply the change request to our zone if it contains records to delete ChangeRequestInfo changeRequest = changeBuilder.build(); if (!changeRequest.deletions().isEmpty()) { - changeRequest = dns.applyChangeRequest(zoneName, changeRequest); + ChangeRequest pendingRequest = dns.applyChangeRequest(zoneName, changeRequest); - // Wait for change to finish, but save data traffic by transferring only ID and status - Dns.ChangeRequestOption option = - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS); - while (ChangeRequestInfo.Status.PENDING.equals(changeRequest.status())) { + // Wait for the change request to complete + while (!pendingRequest.isDone()) { System.out.println("Waiting for change to complete. Going to sleep for 500ms..."); try { Thread.sleep(500); @@ -72,8 +71,6 @@ public static void main(String... args) { System.err.println("The thread was interrupted while waiting for change request to be " + "processed."); } - // Update the change, but fetch only change ID and status - changeRequest = dns.getChangeRequest(zoneName, changeRequest.generatedId(), option); } } diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java index 50f3a1a5c951..c96c93191c10 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java @@ -128,12 +128,10 @@ public static void main(String... args) { // Build and apply the change request to our zone if it contains records to delete changeRequest = changeBuilder.build(); if (!changeRequest.deletions().isEmpty()) { - changeRequest = dns.applyChangeRequest(zoneName, changeRequest); + ChangeRequest pendingRequest = dns.applyChangeRequest(zoneName, changeRequest); - // Wait for change to finish, but save data traffic by transferring only ID and status - Dns.ChangeRequestOption option = - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS); - while (ChangeRequest.Status.PENDING.equals(changeRequest.status())) { + // Wait for the change request to complete + while (!pendingRequest.isDone()) { System.out.println("Waiting for change to complete. Going to sleep for 500ms..."); try { Thread.sleep(500); @@ -141,9 +139,6 @@ public static void main(String... args) { System.err.println("The thread was interrupted while waiting for change request to be " + "processed."); } - - // Update the change, but fetch only change ID and status - changeRequest = dns.getChangeRequest(zoneName, changeRequest.generatedId(), option); } } From 25ccf0868ed807f7159de8ba0e401620d332cc19 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 4 Apr 2016 20:28:33 -0700 Subject: [PATCH 230/375] Fix Storage API activation instructions --- gcloud-java-examples/README.md | 2 +- gcloud-java-storage/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gcloud-java-examples/README.md b/gcloud-java-examples/README.md index 12f25bbe480c..fc6b7c28f636 100644 --- a/gcloud-java-examples/README.md +++ b/gcloud-java-examples/README.md @@ -98,7 +98,7 @@ To run examples from your command line: * Here's an example run of `StorageExample`. - Before running the example, go to the [Google Developers Console][developers-console] to ensure that Google Cloud Storage API is enabled and that you have a bucket. Also ensure that you have a test file (`test.txt` is chosen here) to upload to Cloud Storage stored locally on your machine. + Before running the example, go to the [Google Developers Console][developers-console] to ensure that "Google Cloud Storage" and "Google Cloud Storage JSON API" are enabled and that you have a bucket. Also ensure that you have a test file (`test.txt` is chosen here) to upload to Cloud Storage stored locally on your machine. ``` mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.storage.StorageExample" -Dexec.args="upload /path/to/test.txt " mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.storage.StorageExample" -Dexec.args="list " diff --git a/gcloud-java-storage/README.md b/gcloud-java-storage/README.md index 1bd12d7846bb..5a8897356db8 100644 --- a/gcloud-java-storage/README.md +++ b/gcloud-java-storage/README.md @@ -61,7 +61,7 @@ with the Cloud Storage using this Client Library. Getting Started --------------- #### Prerequisites -For this tutorial, you will need a [Google Developers Console](https://console.developers.google.com/) project with the Storage JSON API enabled. You will need to [enable billing](https://support.google.com/cloud/answer/6158867?hl=en) to use Google Cloud Storage. [Follow these instructions](https://cloud.google.com/docs/authentication#preparation) to get your project set up. You will also need to set up the local development environment by [installing the Google Cloud SDK](https://cloud.google.com/sdk/) and running the following commands in command line: `gcloud auth login` and `gcloud config set project [YOUR PROJECT ID]`. +For this tutorial, you will need a [Google Developers Console](https://console.developers.google.com/) project with "Google Cloud Storage" and "Google Cloud Storage JSON API" enabled via the console's API Manager. You will need to [enable billing](https://support.google.com/cloud/answer/6158867?hl=en) to use Google Cloud Storage. [Follow these instructions](https://cloud.google.com/docs/authentication#preparation) to get your project set up. You will also need to set up the local development environment by [installing the Google Cloud SDK](https://cloud.google.com/sdk/) and running the following commands in command line: `gcloud auth login` and `gcloud config set project [YOUR PROJECT ID]`. #### Installation and setup You'll need to obtain the `gcloud-java-storage` library. See the [Quickstart](#quickstart) section to add `gcloud-java-storage` as a dependency in your code. From 3e7069a1e4af6f7c7efbc7a71e5ccbb148387863 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Tue, 5 Apr 2016 11:29:50 -0400 Subject: [PATCH 231/375] Addressed codacy issues in DNS. * Addressed codacy issues in DNS. This includes - removing static formatter from example - removing and unifying imports and full qualification - removing unused serializable import from Dns - replacing assert not true with assertFalse in ITDnsTest - removing unused method from LocalDnsHelperTest. * Fixed some other minor issues: - added joda formatter to example - style in ZoneTest - visibility in LocalDnsHelper - added private constructor to OptionParsers - adjusted pom.xml * Unified imports of model objects. --- gcloud-java-dns/pom.xml | 1 - .../com/google/gcloud/dns/ChangeRequest.java | 2 +- .../main/java/com/google/gcloud/dns/Dns.java | 1 - .../java/com/google/gcloud/dns/DnsImpl.java | 61 +++++++++---------- .../com/google/gcloud/dns/ProjectInfo.java | 10 +-- .../java/com/google/gcloud/dns/RecordSet.java | 7 +-- .../main/java/com/google/gcloud/dns/Zone.java | 7 ++- .../java/com/google/gcloud/dns/ZoneInfo.java | 9 +-- .../gcloud/dns/testing/LocalDnsHelper.java | 8 +-- .../gcloud/dns/testing/OptionParsers.java | 3 + .../gcloud/dns/ChangeRequestInfoTest.java | 3 +- .../com/google/gcloud/dns/DnsImplTest.java | 4 +- .../com/google/gcloud/dns/RecordSetTest.java | 25 ++++---- .../com/google/gcloud/dns/ZoneInfoTest.java | 5 +- .../java/com/google/gcloud/dns/ZoneTest.java | 2 +- .../com/google/gcloud/dns/it/ITDnsTest.java | 8 +-- .../dns/testing/LocalDnsHelperTest.java | 7 --- .../gcloud/examples/dns/DnsExample.java | 13 ++-- 18 files changed, 85 insertions(+), 91 deletions(-) diff --git a/gcloud-java-dns/pom.xml b/gcloud-java-dns/pom.xml index e7a02452d92f..a4928ccf0397 100644 --- a/gcloud-java-dns/pom.xml +++ b/gcloud-java-dns/pom.xml @@ -3,7 +3,6 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.google.gcloud gcloud-java-dns jar GCloud Java DNS diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java index 66e841c20a15..b3a2a2170d8b 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java @@ -221,7 +221,7 @@ static ChangeRequest fromPb(Dns dns, String zoneName, Change pb) { static Function fromPbFunction(final Dns dns, final String zoneName) { return new Function() { @Override - public ChangeRequest apply(com.google.api.services.dns.model.Change pb) { + public ChangeRequest apply(Change pb) { return ChangeRequest.fromPb(dns, zoneName, pb); } }; diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index a78eaef7c4e7..2216733ca779 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -23,7 +23,6 @@ import com.google.gcloud.Service; import com.google.gcloud.dns.spi.DnsRpc; -import java.io.Serializable; import java.util.List; /** diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java index 9f4fa2a9d9d1..3218daa543b2 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java @@ -17,11 +17,11 @@ package com.google.gcloud.dns; import static com.google.common.base.Preconditions.checkArgument; -import static com.google.gcloud.RetryHelper.RetryHelperException; import static com.google.gcloud.RetryHelper.runWithRetries; import com.google.api.services.dns.model.Change; import com.google.api.services.dns.model.ManagedZone; +import com.google.api.services.dns.model.Project; import com.google.api.services.dns.model.ResourceRecordSet; import com.google.common.base.Function; import com.google.common.collect.ImmutableList; @@ -121,8 +121,7 @@ private static Page listZones(final DnsOptions serviceOptions, // this differs from the other list operations since zone is functional and requires dns service Function pbToZoneFunction = new Function() { @Override - public Zone apply( - com.google.api.services.dns.model.ManagedZone zonePb) { + public Zone apply(ManagedZone zonePb) { return Zone.fromPb(serviceOptions.service(), zonePb); } }; @@ -142,7 +141,7 @@ public DnsRpc.ListResult call() { ? ImmutableList.of() : Iterables.transform(result.results(), pbToZoneFunction); return new PageImpl<>(new ZonePageFetcher(serviceOptions, cursor, optionsMap), cursor, zones); - } catch (RetryHelperException e) { + } catch (RetryHelper.RetryHelperException e) { throw DnsException.translateAndThrow(e); } } @@ -169,10 +168,10 @@ public DnsRpc.ListResult call() { Iterable changes = result.results() == null ? ImmutableList.of() : Iterables.transform(result.results(), - ChangeRequest.fromPbFunction(serviceOptions.service(), zoneName)); + ChangeRequest.fromPbFunction(serviceOptions.service(), zoneName)); return new PageImpl<>(new ChangeRequestPageFetcher(zoneName, serviceOptions, cursor, optionsMap), cursor, changes); - } catch (RetryHelperException e) { + } catch (RetryHelper.RetryHelperException e) { throw DnsException.translateAndThrow(e); } } @@ -201,7 +200,7 @@ public DnsRpc.ListResult call() { : Iterables.transform(result.results(), RecordSet.FROM_PB_FUNCTION); return new PageImpl<>(new DnsRecordPageFetcher(zoneName, serviceOptions, cursor, optionsMap), cursor, recordSets); - } catch (RetryHelperException e) { + } catch (RetryHelper.RetryHelperException e) { throw DnsException.translateAndThrow(e); } } @@ -210,10 +209,10 @@ public DnsRpc.ListResult call() { public Zone create(final ZoneInfo zoneInfo, Dns.ZoneOption... options) { final Map optionsMap = optionMap(options); try { - com.google.api.services.dns.model.ManagedZone answer = runWithRetries( - new Callable() { + ManagedZone answer = runWithRetries( + new Callable() { @Override - public com.google.api.services.dns.model.ManagedZone call() { + public ManagedZone call() { return dnsRpc.create(zoneInfo.toPb(), optionsMap); } }, options().retryParams(), EXCEPTION_HANDLER); @@ -227,10 +226,10 @@ public com.google.api.services.dns.model.ManagedZone call() { public Zone getZone(final String zoneName, Dns.ZoneOption... options) { final Map optionsMap = optionMap(options); try { - com.google.api.services.dns.model.ManagedZone answer = runWithRetries( - new Callable() { + ManagedZone answer = runWithRetries( + new Callable() { @Override - public com.google.api.services.dns.model.ManagedZone call() { + public ManagedZone call() { return dnsRpc.getZone(zoneName, optionsMap); } }, options().retryParams(), EXCEPTION_HANDLER); @@ -258,10 +257,10 @@ public Boolean call() { public ProjectInfo getProject(Dns.ProjectOption... fields) { final Map optionsMap = optionMap(fields); try { - com.google.api.services.dns.model.Project answer = runWithRetries( - new Callable() { + Project answer = runWithRetries( + new Callable() { @Override - public com.google.api.services.dns.model.Project call() { + public Project call() { return dnsRpc.getProject(optionsMap); } }, options().retryParams(), EXCEPTION_HANDLER); @@ -276,14 +275,13 @@ public ChangeRequest applyChangeRequest(final String zoneName, final ChangeRequestInfo changeRequest, ChangeRequestOption... options) { final Map optionsMap = optionMap(options); try { - com.google.api.services.dns.model.Change answer = - runWithRetries( - new Callable() { - @Override - public com.google.api.services.dns.model.Change call() { - return dnsRpc.applyChangeRequest(zoneName, changeRequest.toPb(), optionsMap); - } - }, options().retryParams(), EXCEPTION_HANDLER); + Change answer = runWithRetries( + new Callable() { + @Override + public Change call() { + return dnsRpc.applyChangeRequest(zoneName, changeRequest.toPb(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); return answer == null ? null : ChangeRequest.fromPb(this, zoneName, answer); // not null } catch (RetryHelper.RetryHelperException ex) { throw DnsException.translateAndThrow(ex); @@ -295,14 +293,13 @@ public ChangeRequest getChangeRequest(final String zoneName, final String change Dns.ChangeRequestOption... options) { final Map optionsMap = optionMap(options); try { - com.google.api.services.dns.model.Change answer = - runWithRetries( - new Callable() { - @Override - public com.google.api.services.dns.model.Change call() { - return dnsRpc.getChangeRequest(zoneName, changeRequestId, optionsMap); - } - }, options().retryParams(), EXCEPTION_HANDLER); + Change answer = runWithRetries( + new Callable() { + @Override + public Change call() { + return dnsRpc.getChangeRequest(zoneName, changeRequestId, optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); return answer == null ? null : ChangeRequest.fromPb(this, zoneName, answer); } catch (RetryHelper.RetryHelperException ex) { throw DnsException.translateAndThrow(ex); diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java index 319f06ad2444..52edb25ec902 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java @@ -18,6 +18,7 @@ import static com.google.api.client.repackaged.com.google.common.base.Preconditions.checkNotNull; +import com.google.api.services.dns.model.Project; import com.google.common.base.MoreObjects; import java.io.Serializable; @@ -143,14 +144,13 @@ com.google.api.services.dns.model.Quota toPb() { } static Quota fromPb(com.google.api.services.dns.model.Quota pb) { - Quota quota = new Quota(pb.getManagedZones(), + return new Quota(pb.getManagedZones(), pb.getResourceRecordsPerRrset(), pb.getRrsetAdditionsPerChange(), pb.getRrsetDeletionsPerChange(), pb.getRrsetsPerManagedZone(), pb.getTotalRrdataSizePerChange() ); - return quota; } @Override @@ -243,8 +243,8 @@ String id() { return id; } - com.google.api.services.dns.model.Project toPb() { - com.google.api.services.dns.model.Project pb = new com.google.api.services.dns.model.Project(); + Project toPb() { + Project pb = new Project(); pb.setId(id); pb.setNumber(number); if (this.quota != null) { @@ -253,7 +253,7 @@ com.google.api.services.dns.model.Project toPb() { return pb; } - static ProjectInfo fromPb(com.google.api.services.dns.model.Project pb) { + static ProjectInfo fromPb(Project pb) { Builder builder = builder(); if (pb.getId() != null) { builder.id(pb.getId()); diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/RecordSet.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/RecordSet.java index dc6d956406c3..90beedba1d89 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/RecordSet.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/RecordSet.java @@ -285,9 +285,8 @@ public boolean equals(Object obj) { return obj instanceof RecordSet && Objects.equals(this.toPb(), ((RecordSet) obj).toPb()); } - com.google.api.services.dns.model.ResourceRecordSet toPb() { - com.google.api.services.dns.model.ResourceRecordSet pb = - new com.google.api.services.dns.model.ResourceRecordSet(); + ResourceRecordSet toPb() { + ResourceRecordSet pb = new ResourceRecordSet(); pb.setName(this.name()); pb.setRrdatas(this.records()); pb.setTtl(this.ttl()); @@ -295,7 +294,7 @@ com.google.api.services.dns.model.ResourceRecordSet toPb() { return pb; } - static RecordSet fromPb(com.google.api.services.dns.model.ResourceRecordSet pb) { + static RecordSet fromPb(ResourceRecordSet pb) { Builder builder = builder(pb.getName(), Type.valueOf(pb.getType())); if (pb.getRrdatas() != null) { builder.records(pb.getRrdatas()); diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java index 6e22bfc6785a..c4250bd206eb 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java @@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkNotNull; +import com.google.api.services.dns.model.ManagedZone; import com.google.gcloud.Page; import java.io.IOException; @@ -205,12 +206,12 @@ public int hashCode() { return Objects.hash(super.hashCode(), options); } - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - in.defaultReadObject(); + private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { + stream.defaultReadObject(); this.dns = options.service(); } - static Zone fromPb(Dns dns, com.google.api.services.dns.model.ManagedZone zone) { + static Zone fromPb(Dns dns, ManagedZone zone) { ZoneInfo info = ZoneInfo.fromPb(zone); return new Zone(dns, new ZoneInfo.BuilderImpl(info)); } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java index a0ee24bc5948..03c23a6ce3d3 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java @@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkNotNull; +import com.google.api.services.dns.model.ManagedZone; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; @@ -248,9 +249,9 @@ public Builder toBuilder() { return new BuilderImpl(this); } - com.google.api.services.dns.model.ManagedZone toPb() { - com.google.api.services.dns.model.ManagedZone pb = - new com.google.api.services.dns.model.ManagedZone(); + ManagedZone toPb() { + ManagedZone pb = + new ManagedZone(); pb.setDescription(this.description()); pb.setDnsName(this.dnsName()); if (this.generatedId() != null) { @@ -267,7 +268,7 @@ com.google.api.services.dns.model.ManagedZone toPb() { return pb; } - static ZoneInfo fromPb(com.google.api.services.dns.model.ManagedZone pb) { + static ZoneInfo fromPb(ManagedZone pb) { Builder builder = new BuilderImpl(pb.getName()); if (pb.getDescription() != null) { builder.description(pb.getDescription()); diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/LocalDnsHelper.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/LocalDnsHelper.java index 0ae2c37b9b4d..54edcddb5ade 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/LocalDnsHelper.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/LocalDnsHelper.java @@ -122,7 +122,7 @@ public class LocalDnsHelper { } } - private long delayChange; + private final long delayChange; private final HttpServer server; private final int port; @@ -140,8 +140,8 @@ private enum CallRegex { PROJECT_GET("GET", CONTEXT + "/[^/]+"), RECORD_LIST("GET", CONTEXT + "/[^/]+/managedZones/[^/]+/rrsets"); - private String method; - private String pathRegex; + private final String method; + private final String pathRegex; CallRegex(String method, String pathRegex) { this.pathRegex = pathRegex; @@ -382,7 +382,7 @@ ConcurrentSkipListMap projects() { } /** - * Creates new {@link LocalDnsHelper} instance that listens to requests on the local machine. This + * Creates new {@code LocalDnsHelper} instance that listens to requests on the local machine. This * instance processes changes in separate thread. The parameter determines how long a thread * should wait before processing a change. If it is set to 0, the threading is turned off and the * mock will behave synchronously. diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/OptionParsers.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/OptionParsers.java index 578a0b52db3d..bd773a931ef2 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/OptionParsers.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/OptionParsers.java @@ -29,6 +29,9 @@ */ class OptionParsers { + private OptionParsers() { + } + static Map parseListZonesOptions(String query) { Map options = new HashMap<>(); if (query != null) { diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestInfoTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestInfoTest.java index f3ae7a586391..136a6e0d56ec 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestInfoTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestInfoTest.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.google.api.services.dns.model.Change; import com.google.common.collect.ImmutableList; import org.junit.Test; @@ -209,7 +210,7 @@ public void testRemoveDeletion() { @Test public void testDateParsing() { String startTime = "2016-01-26T18:33:43.512Z"; // obtained from service - com.google.api.services.dns.model.Change change = CHANGE.toPb().setStartTime(startTime); + Change change = CHANGE.toPb().setStartTime(startTime); ChangeRequestInfo converted = ChangeRequest.fromPb(change); assertNotNull(converted.startTimeMillis()); assertEquals(change, converted.toPb()); diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java index d9d657ee03e7..c359871b998c 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java @@ -21,6 +21,7 @@ import com.google.api.services.dns.model.Change; import com.google.api.services.dns.model.ManagedZone; +import com.google.api.services.dns.model.ResourceRecordSet; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; @@ -69,8 +70,7 @@ public class DnsImplTest { CHANGE_REQUEST_PARTIAL.toPb())); private static final DnsRpc.ListResult LIST_RESULT_OF_PB_ZONES = DnsRpc.ListResult.of("cursor", ImmutableList.of(ZONE_INFO.toPb())); - private static final DnsRpc.ListResult - LIST_OF_PB_DNS_RECORDS = + private static final DnsRpc.ListResult LIST_OF_PB_DNS_RECORDS = DnsRpc.ListResult.of("cursor", ImmutableList.of(DNS_RECORD1.toPb(), DNS_RECORD2.toPb())); // Field options diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/RecordSetTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/RecordSetTest.java index 369e078a48c7..fc888bf8a697 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/RecordSetTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/RecordSetTest.java @@ -16,7 +16,6 @@ package com.google.gcloud.dns; -import static com.google.gcloud.dns.RecordSet.builder; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; @@ -33,13 +32,13 @@ public class RecordSetTest { private static final TimeUnit UNIT = TimeUnit.HOURS; private static final Integer UNIT_TTL = 1; private static final RecordSet.Type TYPE = RecordSet.Type.AAAA; - private static final RecordSet recordSet = builder(NAME, TYPE) + private static final RecordSet recordSet = RecordSet.builder(NAME, TYPE) .ttl(UNIT_TTL, UNIT) .build(); @Test public void testDefaultDnsRecord() { - RecordSet recordSet = builder(NAME, TYPE).build(); + RecordSet recordSet = RecordSet.builder(NAME, TYPE).build(); assertEquals(0, recordSet.records().size()); assertEquals(TYPE, recordSet.type()); assertEquals(NAME, recordSet.name()); @@ -66,15 +65,15 @@ public void testBuilder() { @Test public void testValidTtl() { try { - builder(NAME, TYPE).ttl(-1, TimeUnit.SECONDS); + RecordSet.builder(NAME, TYPE).ttl(-1, TimeUnit.SECONDS); fail("A negative value is not acceptable for ttl."); } catch (IllegalArgumentException e) { // expected } - builder(NAME, TYPE).ttl(0, TimeUnit.SECONDS); - builder(NAME, TYPE).ttl(Integer.MAX_VALUE, TimeUnit.SECONDS); + RecordSet.builder(NAME, TYPE).ttl(0, TimeUnit.SECONDS); + RecordSet.builder(NAME, TYPE).ttl(Integer.MAX_VALUE, TimeUnit.SECONDS); try { - builder(NAME, TYPE).ttl(Integer.MAX_VALUE, TimeUnit.HOURS); + RecordSet.builder(NAME, TYPE).ttl(Integer.MAX_VALUE, TimeUnit.HOURS); fail("This value is too large for int."); } catch (IllegalArgumentException e) { // expected @@ -108,22 +107,22 @@ public void testSameHashCodeOnEquals() { @Test public void testToAndFromPb() { assertEquals(recordSet, RecordSet.fromPb(recordSet.toPb())); - RecordSet partial = builder(NAME, TYPE).build(); + RecordSet partial = RecordSet.builder(NAME, TYPE).build(); assertEquals(partial, RecordSet.fromPb(partial.toPb())); - partial = builder(NAME, TYPE).addRecord("test").build(); + partial = RecordSet.builder(NAME, TYPE).addRecord("test").build(); assertEquals(partial, RecordSet.fromPb(partial.toPb())); - partial = builder(NAME, TYPE).ttl(15, TimeUnit.SECONDS).build(); + partial = RecordSet.builder(NAME, TYPE).ttl(15, TimeUnit.SECONDS).build(); assertEquals(partial, RecordSet.fromPb(partial.toPb())); } @Test public void testToBuilder() { assertEquals(recordSet, recordSet.toBuilder().build()); - RecordSet partial = builder(NAME, TYPE).build(); + RecordSet partial = RecordSet.builder(NAME, TYPE).build(); assertEquals(partial, partial.toBuilder().build()); - partial = builder(NAME, TYPE).addRecord("test").build(); + partial = RecordSet.builder(NAME, TYPE).addRecord("test").build(); assertEquals(partial, partial.toBuilder().build()); - partial = builder(NAME, TYPE).ttl(15, TimeUnit.SECONDS).build(); + partial = RecordSet.builder(NAME, TYPE).ttl(15, TimeUnit.SECONDS).build(); assertEquals(partial, partial.toBuilder().build()); } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java index d0a64a61b816..b537735c3c4e 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java @@ -21,6 +21,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import com.google.api.services.dns.model.ManagedZone; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; @@ -155,10 +156,10 @@ public void testEmptyNameServers() { @Test public void testDateParsing() { - com.google.api.services.dns.model.ManagedZone pb = INFO.toPb(); + ManagedZone pb = INFO.toPb(); pb.setCreationTime("2016-01-19T18:00:12.854Z"); // a real value obtained from Google Cloud DNS ZoneInfo mz = ZoneInfo.fromPb(pb); // parses the string timestamp to millis - com.google.api.services.dns.model.ManagedZone pbClone = mz.toPb(); // converts it back to string + ManagedZone pbClone = mz.toPb(); // converts it back to string assertEquals(pb, pbClone); assertEquals(pb.getCreationTime(), pbClone.getCreationTime()); } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java index f14addfc44b6..5407d4f248b7 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java @@ -349,7 +349,7 @@ public void getChangedWhichDoesNotExistZoneFound() { assertNull(zoneNoId.getChangeRequest(CHANGE_REQUEST.generatedId())); assertNull(zone.getChangeRequest(CHANGE_REQUEST.generatedId())); assertNull( - zoneNoId.getChangeRequest(CHANGE_REQUEST.generatedId(),CHANGE_REQUEST_FIELD_OPTIONS)); + zoneNoId.getChangeRequest(CHANGE_REQUEST.generatedId(), CHANGE_REQUEST_FIELD_OPTIONS)); assertNull(zone.getChangeRequest(CHANGE_REQUEST.generatedId(), CHANGE_REQUEST_FIELD_OPTIONS)); } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java index f25bd537cd72..e6513451e7f6 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java @@ -87,6 +87,9 @@ public class ITDnsTest { .build(); private static final List ZONE_NAMES = ImmutableList.of(ZONE_NAME1, ZONE_NAME_EMPTY_DESCRIPTION); + + @Rule + public Timeout globalTimeout = Timeout.seconds(300); private static void clear() { for (String zoneName : ZONE_NAMES) { @@ -162,9 +165,6 @@ private static void waitForChangeToComplete(ChangeRequest changeRequest) { } } - @Rule - public Timeout globalTimeout = Timeout.seconds(300); - @Test public void testCreateValidZone() { try { @@ -472,7 +472,7 @@ public void testListZones() { assertNull(zone.dnsName()); assertNull(zone.description()); assertNull(zone.nameServerSet()); - assertTrue(!zone.nameServers().isEmpty()); + assertFalse(zone.nameServers().isEmpty()); assertNull(zone.generatedId()); assertFalse(zoneIterator.hasNext()); zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/testing/LocalDnsHelperTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/testing/LocalDnsHelperTest.java index 44516f47c657..315a47c5bb7c 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/testing/LocalDnsHelperTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/testing/LocalDnsHelperTest.java @@ -119,13 +119,6 @@ private static void resetProjects() { } } - private static void assertEqChangesIgnoreStatus(Change expected, Change actual) { - assertEquals(expected.getAdditions(), actual.getAdditions()); - assertEquals(expected.getDeletions(), actual.getDeletions()); - assertEquals(expected.getId(), actual.getId()); - assertEquals(expected.getStartTime(), actual.getStartTime()); - } - @Test public void testCreateZone() { ManagedZone created = RPC.create(ZONE1, EMPTY_RPC_OPTIONS); diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java index e5f0cf01a6c9..d0cda485e9f5 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java @@ -27,10 +27,10 @@ import com.google.gcloud.dns.Zone; import com.google.gcloud.dns.ZoneInfo; -import java.text.DateFormat; -import java.text.SimpleDateFormat; +import org.joda.time.format.DateTimeFormat; +import org.joda.time.format.DateTimeFormatter; + import java.util.Arrays; -import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -67,7 +67,8 @@ public class DnsExample { private static final Map ACTIONS = new HashMap<>(); - private static final DateFormat FORMATTER = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss"); + private static final DateTimeFormatter FORMATTER = + DateTimeFormat.forPattern("YYYY-MM-dd HH:mm:ss"); private interface DnsAction { void run(Dns dns, String... args); @@ -336,7 +337,7 @@ public void run(Dns dns, String... args) { ChangeRequest change = iterator.next(); System.out.printf("%nID: %s%n", change.generatedId()); System.out.printf("Status: %s%n", change.status()); - System.out.printf("Started: %s%n", FORMATTER.format(change.startTimeMillis())); + System.out.printf("Started: %s%n", FORMATTER.print(change.startTimeMillis())); System.out.printf("Deletions: %s%n", Joiner.on(", ").join(change.deletions())); System.out.printf("Additions: %s%n", Joiner.on(", ").join(change.additions())); } @@ -441,7 +442,7 @@ private static void printZone(Zone zone) { System.out.printf("%nName: %s%n", zone.name()); System.out.printf("ID: %s%n", zone.generatedId()); System.out.printf("Description: %s%n", zone.description()); - System.out.printf("Created: %s%n", FORMATTER.format(new Date(zone.creationTimeMillis()))); + System.out.printf("Created: %s%n", FORMATTER.print(zone.creationTimeMillis())); System.out.printf("Name servers: %s%n", Joiner.on(", ").join(zone.nameServers())); } From 33a81a0433d45e1ca2e203a1be9d93b27b28fc74 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 5 Apr 2016 11:21:13 +0200 Subject: [PATCH 232/375] Job.isDone() returns true if the job does not exist --- .../main/java/com/google/gcloud/bigquery/Job.java | 15 ++++++--------- .../java/com/google/gcloud/bigquery/JobTest.java | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Job.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Job.java index 586395a0f879..7f8237473b15 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Job.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Job.java @@ -128,22 +128,19 @@ public boolean exists() { /** * Checks if this job has completed its execution, either failing or succeeding. If the job does - * not exist this method returns {@code false}. To correctly wait for job's completion check that - * the job exists first, using {@link #exists()}: + * not exist this method returns {@code true}. You can wait for job completion with: *
     {@code
    -   * if (job.exists()) {
    -   *   while(!job.isDone()) {
    -   *     Thread.sleep(1000L);
    -   *   }
    +   * while(!job.isDone()) {
    +   *   Thread.sleep(1000L);
        * }}
    * - * @return {@code true} if this job is in {@link JobStatus.State#DONE} state, {@code false} if the - * state is not {@link JobStatus.State#DONE} or the job does not exist + * @return {@code true} if this job is in {@link JobStatus.State#DONE} state or if it does not + * exist, {@code false} if the state is not {@link JobStatus.State#DONE} * @throws BigQueryException upon failure */ public boolean isDone() { Job job = bigquery.getJob(jobId(), BigQuery.JobOption.fields(BigQuery.JobField.STATUS)); - return job != null && job.status().state() == JobStatus.State.DONE; + return job == null || job.status().state() == JobStatus.State.DONE; } /** diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java index e066bbed2fb4..61c9c521196a 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java @@ -172,7 +172,7 @@ public void testIsDone_NotExists() throws Exception { expect(bigquery.getJob(JOB_INFO.jobId(), expectedOptions)).andReturn(null); replay(bigquery); initializeJob(); - assertFalse(job.isDone()); + assertTrue(job.isDone()); } @Test From 804d44785aa5ff1c3d6654dbb57a56f8ee81b2af Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 6 Apr 2016 19:02:58 +0200 Subject: [PATCH 233/375] Add ServiceAccountSigner interface, enable signing for AE credentials --- .../com/google/gcloud/AuthCredentials.java | 104 ++++++++++++++++-- .../google/gcloud/ServiceAccountSigner.java | 67 +++++++++++ .../com/google/gcloud/SerializationTest.java | 49 +++++---- .../examples/storage/StorageExample.java | 2 +- .../java/com/google/gcloud/storage/Blob.java | 60 +++++----- .../com/google/gcloud/storage/Storage.java | 56 ++++++---- .../google/gcloud/storage/StorageImpl.java | 35 ++---- 7 files changed, 268 insertions(+), 105 deletions(-) create mode 100644 gcloud-java-core/src/main/java/com/google/gcloud/ServiceAccountSigner.java diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java index 27cafc181505..080d49ed3ccc 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java @@ -25,8 +25,13 @@ import java.io.IOException; import java.io.InputStream; import java.io.Serializable; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; +import java.security.Signature; +import java.security.SignatureException; import java.util.Collection; import java.util.Objects; @@ -35,16 +40,26 @@ */ public abstract class AuthCredentials implements Restorable { - private static class AppEngineAuthCredentials extends AuthCredentials { + /** + * Represents built-in credentials when running in Google App Engine. + */ + public static class AppEngineAuthCredentials extends AuthCredentials + implements ServiceAccountSigner { private static final AuthCredentials INSTANCE = new AppEngineAuthCredentials(); private static final AppEngineAuthCredentialsState STATE = new AppEngineAuthCredentialsState(); - private static class AppEngineCredentials extends GoogleCredentials { + private AppEngineCredentials credentials; + + private static class AppEngineCredentials extends GoogleCredentials + implements ServiceAccountSigner { private final Object appIdentityService; + private final String account; private final Method getAccessToken; private final Method getAccessTokenResult; + private final Method signForApp; + private final Method getSignature; private final Collection scopes; AppEngineCredentials() { @@ -59,6 +74,12 @@ private static class AppEngineCredentials extends GoogleCredentials { "com.google.appengine.api.appidentity.AppIdentityService$GetAccessTokenResult"); this.getAccessTokenResult = serviceClass.getMethod("getAccessToken", Iterable.class); this.getAccessToken = tokenResultClass.getMethod("getAccessToken"); + this.account = (String) serviceClass.getMethod("getServiceAccountName") + .invoke(appIdentityService); + this.signForApp = serviceClass.getMethod("signForApp", byte[].class); + Class signingResultClass = Class.forName( + "com.google.appengine.api.appidentity.AppIdentityService$SigningResult"); + this.getSignature = signingResultClass.getMethod("getSignature"); this.scopes = null; } catch (Exception e) { throw new RuntimeException("Could not create AppEngineCredentials.", e); @@ -69,11 +90,14 @@ private static class AppEngineCredentials extends GoogleCredentials { this.appIdentityService = unscoped.appIdentityService; this.getAccessToken = unscoped.getAccessToken; this.getAccessTokenResult = unscoped.getAccessTokenResult; + this.account = unscoped.account; + this.signForApp = unscoped.signForApp; + this.getSignature = unscoped.getSignature; this.scopes = scopes; } /** - * Refresh the access token by getting it from the App Identity service + * Refresh the access token by getting it from the App Identity service. */ @Override public AccessToken refreshAccessToken() throws IOException { @@ -98,6 +122,21 @@ public boolean createScopedRequired() { public GoogleCredentials createScoped(Collection scopes) { return new AppEngineCredentials(scopes, this); } + + @Override + public String account() { + return account; + } + + @Override + public byte[] sign(byte[] toSign) { + try { + Object signingResult = signForApp.invoke(appIdentityService, (Object) toSign); + return (byte[]) getSignature.invoke(signingResult); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { + throw new SigningException("Failed to sign the provided bytes", ex); + } + } } private static class AppEngineAuthCredentialsState @@ -122,14 +161,27 @@ public boolean equals(Object obj) { } @Override - public GoogleCredentials credentials() { - return new AppEngineCredentials(); + public AppEngineCredentials credentials() { + if (credentials == null) { + credentials = new AppEngineCredentials(); + } + return credentials; } @Override public RestorableState capture() { return STATE; } + + @Override + public String account() { + return credentials().account(); + } + + @Override + public byte[] sign(byte[] toSign) { + return credentials().sign(toSign); + } } /** @@ -138,8 +190,10 @@ public RestorableState capture() { * @see * User accounts and service accounts */ - public static class ServiceAccountAuthCredentials extends AuthCredentials { + public static class ServiceAccountAuthCredentials extends AuthCredentials + implements ServiceAccountSigner { + private final ServiceAccountCredentials credentials; private final String account; private final PrivateKey privateKey; @@ -178,23 +232,44 @@ public boolean equals(Object obj) { } ServiceAccountAuthCredentials(String account, PrivateKey privateKey) { - this.account = checkNotNull(account); - this.privateKey = checkNotNull(privateKey); + this(new ServiceAccountCredentials(null, account, privateKey, null, null)); + } + + ServiceAccountAuthCredentials(ServiceAccountCredentials credentials) { + this.credentials = checkNotNull(credentials); + this.account = checkNotNull(credentials.getClientEmail()); + this.privateKey = checkNotNull(credentials.getPrivateKey()); } @Override public ServiceAccountCredentials credentials() { - return new ServiceAccountCredentials(null, account, privateKey, null, null); + return credentials; } + @Override public String account() { return account; } + /** + * Returns the private key associated with the service account credentials. + */ public PrivateKey privateKey() { return privateKey; } + @Override + public byte[] sign(byte[] toSign) { + try { + Signature signer = Signature.getInstance("SHA256withRSA"); + signer.initSign(privateKey()); + signer.update(toSign); + return signer.sign(); + } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException ex) { + throw new SigningException("Failed to sign the provided bytes", ex); + } + } + @Override public RestorableState capture() { return new ServiceAccountAuthCredentialsState(account, privateKey); @@ -242,6 +317,10 @@ public boolean equals(Object obj) { } } + ApplicationDefaultAuthCredentials(GoogleCredentials credentials) { + googleCredentials = credentials; + } + ApplicationDefaultAuthCredentials() throws IOException { googleCredentials = GoogleCredentials.getApplicationDefault(); } @@ -320,7 +399,12 @@ public static AuthCredentials createForAppEngine() { * @throws IOException if the credentials cannot be created in the current environment */ public static AuthCredentials createApplicationDefaults() throws IOException { - return new ApplicationDefaultAuthCredentials(); + GoogleCredentials credentials = GoogleCredentials.getApplicationDefault(); + if (credentials instanceof ServiceAccountCredentials) { + ServiceAccountCredentials serviceAccountCredentials = (ServiceAccountCredentials) credentials; + return new ServiceAccountAuthCredentials(serviceAccountCredentials); + } + return new ApplicationDefaultAuthCredentials(credentials); } /** diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceAccountSigner.java b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceAccountSigner.java new file mode 100644 index 000000000000..2456d85e98a7 --- /dev/null +++ b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceAccountSigner.java @@ -0,0 +1,67 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud; + +import java.util.Objects; + +/** + * Interface for a service account signer. A signer for a service account is capable of signing + * bytes using the private key associated with its service account. + */ +public interface ServiceAccountSigner { + + class SigningException extends RuntimeException { + + private static final long serialVersionUID = 8962780757822799255L; + + SigningException(String message, Exception cause) { + super(message, cause); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof SigningException)) { + return false; + } + SigningException other = (SigningException) obj; + return Objects.equals(getCause(), other.getCause()) + && Objects.equals(getMessage(), other.getMessage()); + } + + @Override + public int hashCode() { + return Objects.hash(getMessage(), getCause()); + } + } + + /** + * Returns the service account associated with the signer. + */ + String account(); + + /** + * Signs the provided bytes using the private key associated with the service account. + * + * @param toSign bytes to sign + * @return signed bytes + * @throws SigningException if the attempt to sign the provided bytes failed + */ + byte[] sign(byte[] toSign); +} diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java index 3255a17333aa..8cf58f554de8 100644 --- a/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java +++ b/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java @@ -17,6 +17,7 @@ package com.google.gcloud; import com.google.common.collect.ImmutableList; +import com.google.gcloud.ServiceAccountSigner.SigningException; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -24,34 +25,14 @@ public class SerializationTest extends BaseSerializationTest { - private static class SomeIamPolicy extends IamPolicy { - - private static final long serialVersionUID = 271243551016958285L; - - private static class Builder extends IamPolicy.Builder { - - @Override - public SomeIamPolicy build() { - return new SomeIamPolicy(this); - } - } - - protected SomeIamPolicy(Builder builder) { - super(builder); - } - - @Override - public Builder toBuilder() { - return new Builder(); - } - } - private static final BaseServiceException BASE_SERVICE_EXCEPTION = new BaseServiceException(42, "message", "reason", true); private static final ExceptionHandler EXCEPTION_HANDLER = ExceptionHandler.defaultInstance(); private static final Identity IDENTITY = Identity.allAuthenticatedUsers(); private static final PageImpl PAGE = new PageImpl<>(null, "cursor", ImmutableList.of("string1", "string2")); + private static final SigningException SIGNING_EXCEPTION = + new SigningException("message", BASE_SERVICE_EXCEPTION); private static final RetryParams RETRY_PARAMS = RetryParams.defaultInstance(); private static final SomeIamPolicy SOME_IAM_POLICY = new SomeIamPolicy.Builder().build(); private static final String JSON_KEY = "{\n" @@ -81,10 +62,32 @@ public Builder toBuilder() { + " \"type\": \"service_account\"\n" + "}"; + private static class SomeIamPolicy extends IamPolicy { + + private static final long serialVersionUID = 271243551016958285L; + + private static class Builder extends IamPolicy.Builder { + + @Override + public SomeIamPolicy build() { + return new SomeIamPolicy(this); + } + } + + protected SomeIamPolicy(Builder builder) { + super(builder); + } + + @Override + public Builder toBuilder() { + return new Builder(); + } + } + @Override protected Serializable[] serializableObjects() { return new Serializable[]{BASE_SERVICE_EXCEPTION, EXCEPTION_HANDLER, IDENTITY, PAGE, - RETRY_PARAMS, SOME_IAM_POLICY}; + RETRY_PARAMS, SOME_IAM_POLICY, SIGNING_EXCEPTION}; } @Override diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java index a7260134202d..29abbff9c30f 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java @@ -489,7 +489,7 @@ public void run(Storage storage, Tuple private void run(Storage storage, ServiceAccountAuthCredentials cred, BlobInfo blobInfo) { Blob blob = storage.get(blobInfo.blobId()); System.out.println("Signed URL: " - + blob.signUrl(1, TimeUnit.DAYS, SignUrlOption.serviceAccount(cred))); + + blob.signUrl(1, TimeUnit.DAYS, SignUrlOption.signWith(cred))); } @Override diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java index 9bd9902fee56..9000d0fb8047 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java @@ -23,7 +23,11 @@ import com.google.api.services.storage.model.StorageObject; import com.google.common.base.Function; import com.google.gcloud.AuthCredentials; +import com.google.gcloud.AuthCredentials.AppEngineAuthCredentials; +import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials; import com.google.gcloud.ReadChannel; +import com.google.gcloud.ServiceAccountSigner; +import com.google.gcloud.ServiceAccountSigner.SigningException; import com.google.gcloud.WriteChannel; import com.google.gcloud.storage.Storage.BlobTargetOption; import com.google.gcloud.storage.Storage.BlobWriteOption; @@ -457,28 +461,35 @@ public WriteChannel writer(BlobWriteOption... options) { * Generates a signed URL for this blob. If you want to allow access for a fixed amount of time to * this blob, you can use this method to generate a URL that is only valid within a certain time * period. This is particularly useful if you don't want publicly accessible blobs, but also don't - * want to require users to explicitly log in. Signing a URL requires a service account and its - * associated private key. If a {@link AuthCredentials.ServiceAccountAuthCredentials} was passed - * to {@link StorageOptions.Builder#authCredentials(AuthCredentials)} or the default credentials - * are being used and the environment variable {@code GOOGLE_APPLICATION_CREDENTIALS} is set, then - * {@code signUrl} will use that service account and associated key to sign the URL. If the - * credentials passed to {@link StorageOptions} do not expose a private key (this is the case for - * App Engine credentials, Compute Engine credentials and Google Cloud SDK credentials) then - * {@code signUrl} will throw an {@link IllegalArgumentException} unless a service account with - * associated key is passed using the {@code SignUrlOption.serviceAccount()} option. The service - * account and private key passed with {@code SignUrlOption.serviceAccount()} have priority over - * any credentials set with {@link StorageOptions.Builder#authCredentials(AuthCredentials)}. + * want to require users to explicitly log in. Signing a URL requires + * a service account signer. If a {@link ServiceAccountAuthCredentials} or an + * {@link AppEngineAuthCredentials} was passed to + * {@link StorageOptions.Builder#authCredentials(AuthCredentials)} or the default credentials are + * being used and the environment variable {@code GOOGLE_APPLICATION_CREDENTIALS} is set, then + * {@code signUrl} will use that credentials to sign the URL. If the credentials passed to + * {@link StorageOptions} do not implement {@link ServiceAccountSigner} (this is the case for + * Compute Engine credentials and Google Cloud SDK credentials) then {@code signUrl} will throw an + * {@link IllegalStateException} unless an implementation of {@link ServiceAccountSigner} is + * passed using the {@link SignUrlOption#signWith(ServiceAccountSigner)} option. + * + *

    A service account signer is looked for in the following order: + *

      + *
    1. The signer passed with the option {@link SignUrlOption#signWith(ServiceAccountSigner)} + *
    2. The credentials passed to {@link StorageOptions.Builder#authCredentials(AuthCredentials)} + *
    3. The default credentials, if no credentials were passed to {@link StorageOptions} + *
    * *

    Example usage of creating a signed URL that is valid for 2 weeks, using the default - * credentials for signing the URL: + * credentials for signing the URL: *

     {@code
        * blob.signUrl(14, TimeUnit.DAYS);
        * }
    * - *

    Example usage of creating a signed URL passing the {@code SignUrlOption.serviceAccount()} - * option, that will be used for signing the URL: + *

    Example usage of creating a signed URL passing the + * {@link SignUrlOption#signWith(ServiceAccountSigner)} option, that will be used for signing the + * URL: *

     {@code
    -   * blob.signUrl(14, TimeUnit.DAYS, SignUrlOption.serviceAccount(
    +   * blob.signUrl(14, TimeUnit.DAYS, SignUrlOption.signWith(
        *     AuthCredentials.createForJson(new FileInputStream("/path/to/key.json"))));
        * }
    * @@ -486,16 +497,15 @@ public WriteChannel writer(BlobWriteOption... options) { * granularity supported is 1 second, finer granularities will be truncated * @param unit time unit of the {@code duration} parameter * @param options optional URL signing options - * @return a signed URL for this bucket and the specified options - * @throws IllegalArgumentException if - * {@link SignUrlOption#serviceAccount(AuthCredentials.ServiceAccountAuthCredentials)} was not - * used and no service account was provided to {@link StorageOptions} - * @throws IllegalArgumentException if the key associated to the provided service account is - * invalid - * @throws IllegalArgumentException if {@link SignUrlOption#withMd5()} option is used and - * {@link #md5()} is {@code null} - * @throws IllegalArgumentException if {@link SignUrlOption#withContentType()} option is used and - * {@link #contentType()} is {@code null} + * @return a signed URL for this blob and the specified options + * @throws IllegalStateException if {@link SignUrlOption#signWith(ServiceAccountSigner)} was not + * used and no implementation of {@link ServiceAccountSigner} was provided to + * {@link StorageOptions} + * @throws IllegalArgumentException if {@code SignUrlOption.withMd5()} option is used and + * {@code blobInfo.md5()} is {@code null} + * @throws IllegalArgumentException if {@code SignUrlOption.withContentType()} option is used and + * {@code blobInfo.contentType()} is {@code null} + * @throws SigningException if the attempt to sign the URL failed * @see Signed-URLs */ public URL signUrl(long duration, TimeUnit unit, SignUrlOption... options) { diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java index 72d89348f5fa..af91905a9f2a 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java @@ -23,12 +23,15 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.gcloud.AuthCredentials; +import com.google.gcloud.AuthCredentials.AppEngineAuthCredentials; import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials; import com.google.gcloud.FieldSelector; import com.google.gcloud.FieldSelector.Helper; import com.google.gcloud.Page; import com.google.gcloud.ReadChannel; import com.google.gcloud.Service; +import com.google.gcloud.ServiceAccountSigner; +import com.google.gcloud.ServiceAccountSigner.SigningException; import com.google.gcloud.WriteChannel; import com.google.gcloud.storage.spi.StorageRpc; import com.google.gcloud.storage.spi.StorageRpc.Tuple; @@ -765,14 +768,14 @@ public static SignUrlOption withMd5() { } /** - * Service account credentials which are used for signing the URL. - * If not provided an attempt will be made to get it from the environment. + * Provides a service account signer to sign the URL. If not provided an attempt will be made to + * get it from the environment. * * @see Service * account */ - public static SignUrlOption serviceAccount(ServiceAccountAuthCredentials credentials) { - return new SignUrlOption(Option.SERVICE_ACCOUNT_CRED, credentials); + public static SignUrlOption signWith(ServiceAccountSigner signer) { + return new SignUrlOption(Option.SERVICE_ACCOUNT_CRED, signer); } } @@ -1470,29 +1473,36 @@ public static Builder builder() { * Generates a signed URL for a blob. If you have a blob that you want to allow access to for a * fixed amount of time, you can use this method to generate a URL that is only valid within a * certain time period. This is particularly useful if you don't want publicly accessible blobs, - * but also don't want to require users to explicitly log in. Signing a URL requires a service - * account and its associated private key. If a {@link ServiceAccountAuthCredentials} was passed - * to {@link StorageOptions.Builder#authCredentials(AuthCredentials)} or the default credentials - * are being used and the environment variable {@code GOOGLE_APPLICATION_CREDENTIALS} is set, then - * {@code signUrl} will use that service account and associated key to sign the URL. If the - * credentials passed to {@link StorageOptions} do not expose a private key (this is the case for - * App Engine credentials, Compute Engine credentials and Google Cloud SDK credentials) then - * {@code signUrl} will throw an {@link IllegalArgumentException} unless a service account with - * associated key is passed using the {@code SignUrlOption.serviceAccount()} option. The service - * account and private key passed with {@code SignUrlOption.serviceAccount()} have priority over - * any credentials set with {@link StorageOptions.Builder#authCredentials(AuthCredentials)}. + * but also don't want to require users to explicitly log in. Signing a URL requires + * a service account signer. If a {@link ServiceAccountAuthCredentials} or an + * {@link AppEngineAuthCredentials} was passed to + * {@link StorageOptions.Builder#authCredentials(AuthCredentials)} or the default credentials are + * being used and the environment variable {@code GOOGLE_APPLICATION_CREDENTIALS} is set, then + * {@code signUrl} will use that credentials to sign the URL. If the credentials passed to + * {@link StorageOptions} do not implement {@link ServiceAccountSigner} (this is the case for + * Compute Engine credentials and Google Cloud SDK credentials) then {@code signUrl} will throw an + * {@link IllegalStateException} unless an implementation of {@link ServiceAccountSigner} is + * passed using the {@link SignUrlOption#signWith(ServiceAccountSigner)} option. + * + *

    A service account signer is looked for in the following order: + *

      + *
    1. The signer passed with the option {@link SignUrlOption#signWith(ServiceAccountSigner)} + *
    2. The credentials passed to {@link StorageOptions.Builder#authCredentials(AuthCredentials)} + *
    3. The default credentials, if no credentials were passed to {@link StorageOptions} + *
    * *

    Example usage of creating a signed URL that is valid for 2 weeks, using the default - * credentials for signing the URL: + * credentials for signing the URL: *

     {@code
        * service.signUrl(BlobInfo.builder("bucket", "name").build(), 14, TimeUnit.DAYS);
        * }
    * - *

    Example usage of creating a signed URL passing the {@code SignUrlOption.serviceAccount()} - * option, that will be used for signing the URL: + *

    Example usage of creating a signed URL passing the + * {@link SignUrlOption#signWith(ServiceAccountSigner)} option, that will be used for signing the + * URL: *

     {@code
        * service.signUrl(BlobInfo.builder("bucket", "name").build(), 14, TimeUnit.DAYS,
    -   *     SignUrlOption.serviceAccount(
    +   *     SignUrlOption.signWith(
        *         AuthCredentials.createForJson(new FileInputStream("/path/to/key.json"))));
        * }
    * @@ -1501,14 +1511,14 @@ public static Builder builder() { * granularity supported is 1 second, finer granularities will be truncated * @param unit time unit of the {@code duration} parameter * @param options optional URL signing options - * @throws IllegalArgumentException if {@code SignUrlOption.serviceAccount()} was not used and no - * service account was provided to {@link StorageOptions} - * @throws IllegalArgumentException if the key associated to the provided service account is - * invalid + * @throws IllegalStateException if {@link SignUrlOption#signWith(ServiceAccountSigner)} was not + * used and no implementation of {@link ServiceAccountSigner} was provided to + * {@link StorageOptions} * @throws IllegalArgumentException if {@code SignUrlOption.withMd5()} option is used and * {@code blobInfo.md5()} is {@code null} * @throws IllegalArgumentException if {@code SignUrlOption.withContentType()} option is used and * {@code blobInfo.contentType()} is {@code null} + * @throws SigningException if the attempt to sign the URL failed * @see Signed-URLs */ URL signUrl(BlobInfo blobInfo, long duration, TimeUnit unit, SignUrlOption... options); diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java index cf709ba5e293..fa56c84e8b92 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java @@ -18,6 +18,7 @@ import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; import static com.google.gcloud.RetryHelper.runWithRetries; import static com.google.gcloud.storage.spi.StorageRpc.Option.DELIMITER; import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_GENERATION_MATCH; @@ -31,7 +32,6 @@ import static java.nio.charset.StandardCharsets.UTF_8; import com.google.api.services.storage.model.StorageObject; -import com.google.auth.oauth2.ServiceAccountCredentials; import com.google.common.base.Function; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -41,13 +41,13 @@ import com.google.common.hash.Hashing; import com.google.common.io.BaseEncoding; import com.google.common.primitives.Ints; -import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials; import com.google.gcloud.BaseService; import com.google.gcloud.Page; import com.google.gcloud.PageImpl; import com.google.gcloud.PageImpl.NextPageFetcher; import com.google.gcloud.ReadChannel; import com.google.gcloud.RetryHelper.RetryHelperException; +import com.google.gcloud.ServiceAccountSigner; import com.google.gcloud.storage.spi.StorageRpc; import com.google.gcloud.storage.spi.StorageRpc.RewriteResponse; import com.google.gcloud.storage.spi.StorageRpc.Tuple; @@ -59,10 +59,6 @@ import java.net.MalformedURLException; import java.net.URL; import java.net.URLEncoder; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.Signature; -import java.security.SignatureException; import java.util.Arrays; import java.util.Collections; import java.util.EnumMap; @@ -538,15 +534,12 @@ public URL signUrl(BlobInfo blobInfo, long duration, TimeUnit unit, SignUrlOptio for (SignUrlOption option : options) { optionMap.put(option.option(), option.value()); } - ServiceAccountAuthCredentials authCred = - (ServiceAccountAuthCredentials) optionMap.get(SignUrlOption.Option.SERVICE_ACCOUNT_CRED); - ServiceAccountCredentials cred = authCred != null ? authCred.credentials() : null; - if (authCred == null) { - checkArgument( - this.options().authCredentials() != null - && this.options().authCredentials().credentials() instanceof ServiceAccountCredentials, + ServiceAccountSigner authCredentials = + (ServiceAccountSigner) optionMap.get(SignUrlOption.Option.SERVICE_ACCOUNT_CRED); + if (authCredentials == null) { + checkState(this.options().authCredentials() instanceof ServiceAccountSigner, "Signing key was not provided and could not be derived"); - cred = (ServiceAccountCredentials) this.options().authCredentials().credentials(); + authCredentials = (ServiceAccountSigner) this.options().authCredentials(); } // construct signature - see https://cloud.google.com/storage/docs/access-control#Signed-URLs StringBuilder stBuilder = new StringBuilder(); @@ -583,20 +576,16 @@ public URL signUrl(BlobInfo blobInfo, long duration, TimeUnit unit, SignUrlOptio path.append(blobInfo.name()); stBuilder.append(path); try { - Signature signer = Signature.getInstance("SHA256withRSA"); - signer.initSign(cred.getPrivateKey()); - signer.update(stBuilder.toString().getBytes(UTF_8)); + byte[] signatureBytes = authCredentials.sign(stBuilder.toString().getBytes(UTF_8)); stBuilder = new StringBuilder("https://storage.googleapis.com").append(path); String signature = - URLEncoder.encode(BaseEncoding.base64().encode(signer.sign()), UTF_8.name()); - stBuilder.append("?GoogleAccessId=").append(cred.getClientEmail()); + URLEncoder.encode(BaseEncoding.base64().encode(signatureBytes), UTF_8.name()); + stBuilder.append("?GoogleAccessId=").append(authCredentials.account()); stBuilder.append("&Expires=").append(expiration); stBuilder.append("&Signature=").append(signature); return new URL(stBuilder.toString()); - } catch (MalformedURLException | NoSuchAlgorithmException | UnsupportedEncodingException e) { - throw new IllegalStateException(e); - } catch (SignatureException | InvalidKeyException e) { - throw new IllegalArgumentException("Invalid service account private key"); + } catch (MalformedURLException | UnsupportedEncodingException ex) { + throw new IllegalStateException(ex); } } From 254fcc3638ef2aee7d36c1015deb178fbc912419 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Wed, 6 Apr 2016 18:59:09 -0700 Subject: [PATCH 234/375] Add getting-started-java repo to releasing docs * Add getting-started-java to releasing docs * Remove extraneous part of link --- RELEASING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASING.md b/RELEASING.md index 81a7bcd06129..3555f5beb7e7 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -26,7 +26,7 @@ As mentioned before, there is an optional version argument. By default, the scr 6. Create and merge in another PR to reflect the updated project version. For an example of what this PR should look like, see [#227](https://github.com/GoogleCloudPlatform/gcloud-java/pull/227). -7. Be sure to update App Engine documentation and [java-docs-samples](https://github.com/GoogleCloudPlatform/java-docs-samples) code as necessary. See directions [here](https://docs.google.com/a/google.com/document/d/1SS3xNn2v0qW7EadGUPBUAPIQAH5VY6WSFmT17ZjjUVE/edit?usp=sharing). +7. Be sure to update Google Cloud Platform docs, [java-docs-samples](https://github.com/GoogleCloudPlatform/java-docs-samples) code/docs, and [getting-started-java](https://github.com/GoogleCloudPlatform/getting-started-java) code/docs. See directions [here](https://docs.google.com/a/google.com/document/d/1SS3xNn2v0qW7EadGUPBUAPIQAH5VY6WSFmT17ZjjUVE/). ### To push a snapshot version From fae29087e5e66b8d9e355ec551a90ac014d9de81 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Wed, 6 Apr 2016 19:38:00 -0700 Subject: [PATCH 235/375] Add examples --- README.md | 7 ++++++- src/site/resources/index.html | 15 +++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6bd1e7211f2c..59db4cbcf482 100644 --- a/README.md +++ b/README.md @@ -53,12 +53,17 @@ Example Applications - Read more about using this application on the [`DatastoreExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/datastore/DatastoreExample.html). - [`DnsExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java) - A simple command line interface for Cloud DNS - Read more about using this application on the [`DnsExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/dns/DnsExample.html). +- [`Flexible Environment/Datastore example`](https://github.com/GoogleCloudPlatform/java-docs-samples/tree/master/managed_vms/datastore) - A simple app that uses Cloud Datastore to list the last 10 IP addresses that visited your site. + - Read about how to run the application [here](https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/managed_vms/README.md). +- [`Flexible Environment/Storage example`](https://github.com/GoogleCloudPlatform/java-docs-samples/tree/master/managed_vms/cloudstorage) - An app that uploads files to a public Cloud Storage bucket on the App Engine Flexible Environment runtime. - [`ResourceManagerExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/ResourceManagerExample.java) - A simple command line interface providing some of Cloud Resource Manager's functionality - Read more about using this application on the [`ResourceManagerExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/resourcemanager/ResourceManagerExample.html). -- [`SparkDemo`](https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/managed_vms/sparkjava) - An example of using gcloud-java-datastore from within the SparkJava and App Engine Managed VM frameworks. +- [`SparkDemo`](https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/managed_vms/sparkjava) - An example of using `gcloud-java-datastore` from within the SparkJava and App Engine Flexible Environment frameworks. - Read about how it works on the example's [README page](https://github.com/GoogleCloudPlatform/java-docs-samples/tree/master/managed_vms/sparkjava#how-does-it-work). - [`StorageExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java) - A simple command line interface providing some of Cloud Storage's functionality - Read more about using this application on the [`StorageExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/storage/StorageExample.html). +- [`TaskList`](https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/datastore/src/main/java/com/google/datastore/snippets/TaskList.java) - A command line application that uses Cloud Datastore to manage a to-do list. + - Read about how to run the application on its [README page](https://github.com/GoogleCloudPlatform/java-docs-samples/tree/master/datastore). Specifying a Project ID ----------------------- diff --git a/src/site/resources/index.html b/src/site/resources/index.html index 0e0933e7b68c..834d3987a343 100644 --- a/src/site/resources/index.html +++ b/src/site/resources/index.html @@ -178,10 +178,21 @@

    Examples

    • - SparkJava demo - Uses gcloud-java with App Engine Managed VMs, Datastore, and SparkJava. + Bookshelf - An App Engine app that manages a virtual bookshelf using gcloud-java libraries for Datastore and Storage. +
    • + +
    • + Flexible Environment/Datastore example - A simple app that uses Cloud Datastore to list the last 10 IP addresses that visited your site. Read about how to run the application here. +
    • +
    • + Flexible Environment/Storage example - An app that uploads files to a public Cloud Storage bucket on the App Engine Flexible Environment runtime. +
    • +
    • + SparkJava demo - Uses gcloud-java with App Engine Flexible Environment, Datastore, and SparkJava.
    • - Bookshelf - An App Engine app that manages a virtual bookshelf using gcloud-java libraries for Datastore and Storage. + TaskList - An command line app that manages a to-do list using Cloud Datastore. +
    From 5b4ea320271b7cdd2734415f5d6578530d551cc1 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Wed, 6 Apr 2016 19:39:59 -0700 Subject: [PATCH 236/375] Remove check for empty list and add deprecated to javadoc for meaning in builder. --- .../main/java/com/google/gcloud/datastore/ListValue.java | 1 - .../src/main/java/com/google/gcloud/datastore/Value.java | 5 +++-- .../java/com/google/gcloud/datastore/ValueBuilder.java | 1 + .../java/com/google/gcloud/datastore/DatastoreTest.java | 9 +++++++-- .../java/com/google/gcloud/datastore/ListValueTest.java | 8 +++++++- 5 files changed, 18 insertions(+), 6 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java index 9d4fe9c186d5..ad73303cd62d 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java @@ -108,7 +108,6 @@ public List> get() { @Override public ListValue build() { - Preconditions.checkState(!get().isEmpty(), "value list could not be empty"); return new ListValue(this); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java index 4f3d39f1dae1..4a87e48fa862 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java @@ -35,7 +35,6 @@ public abstract class Value extends Serializable, B extends BaseBuilder> implements ValueBuilder { @@ -113,11 +111,13 @@ public B excludeFromIndexes(boolean excludeFromIndexes) { return self(); } + @Deprecated @Override public int getMeaning() { return meaning; } + @Deprecated @Override public B meaning(int meaning) { this.meaning = meaning; @@ -144,6 +144,7 @@ private B self() { public abstract P build(); } + @SuppressWarnings("deprecation")

    , B extends BaseBuilder> Value(ValueBuilder builder) { valueType = builder.getValueType(); excludeFromIndexes = builder.getExcludeFromIndexes(); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueBuilder.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueBuilder.java index 236118a18620..0a24db3ff5a6 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueBuilder.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueBuilder.java @@ -33,6 +33,7 @@ public interface ValueBuilder, B extends ValueBuilder>emptyList()); private static final DateTimeValue DATE_TIME_VALUE = new DateTimeValue(DateTime.now()); private static final LatLngValue LAT_LNG_VALUE = new LatLngValue(new LatLng(37.422035, -122.084124)); @@ -110,6 +111,7 @@ public class DatastoreTest { .set("bool", BOOL_VALUE) .set("partial1", EntityValue.of(PARTIAL_ENTITY1)) .set("list", LIST_VALUE2) + .set("emptyList", EMPTY_LIST_VALUE) .build(); private static final Entity ENTITY2 = Entity.builder(ENTITY1).key(KEY2).remove("str") .set("name", "Dan").setNull("null").set("age", 20).build(); @@ -738,7 +740,9 @@ public void testGet() { assertEquals(LAT_LNG_VALUE, value5); FullEntity value6 = entity.getEntity("partial1"); assertEquals(PARTIAL_ENTITY1, value6); - assertEquals(6, entity.names().size()); + ListValue value7 = entity.getValue("emptyList"); + assertEquals(EMPTY_LIST_VALUE, value7); + assertEquals(7, entity.names().size()); assertFalse(entity.contains("bla")); } @@ -783,7 +787,8 @@ public void testGetArrayNoDeferredResults() { assertEquals(ENTITY2, partial2); assertEquals(ValueType.BOOLEAN, entity3.getValue("bool").type()); assertEquals(LAT_LNG_VALUE, entity3.getValue("latLng")); - assertEquals(7, entity3.names().size()); + assertEquals(EMPTY_LIST_VALUE, entity3.getValue("emptyList")); + assertEquals(8, entity3.names().size()); assertFalse(entity3.contains("bla")); try { entity3.getString("str"); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java index 6245c715d476..41551939eba4 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java @@ -24,6 +24,7 @@ import org.junit.Test; +import java.util.Collections; import java.util.List; public class ListValueTest { @@ -37,12 +38,14 @@ public void testToBuilder() throws Exception { assertEquals(value, value.toBuilder().build()); } - @SuppressWarnings("deprecation") @Test public void testOf() throws Exception { ListValue value = ListValue.of(CONTENT); assertEquals(CONTENT, value.get()); assertFalse(value.excludeFromIndexes()); + value = ListValue.of(Collections.>emptyList()); + assertEquals(Collections.>emptyList(), value.get()); + assertFalse(value.excludeFromIndexes()); } @SuppressWarnings("deprecation") @@ -59,5 +62,8 @@ public void testBuilder() throws Exception { builder.addValue(v); } assertEquals(CONTENT, builder.build().get()); + + builder = builder.set(Collections.>emptyList()); + assertEquals(Collections.>emptyList(), builder.build().get()); } } From a8ec412e31e65a5a846c737828f7b17a187f5aeb Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 7 Apr 2016 18:05:45 +0200 Subject: [PATCH 237/375] Fix checkstyle issues in gcloud-java-core (#871) * Fix checkstyle issues in gcloud-java-core --- .../main/java/com/google/gcloud/FieldSelector.java | 2 +- .../src/main/java/com/google/gcloud/Page.java | 7 +++---- .../src/main/java/com/google/gcloud/Restorable.java | 5 ++--- .../java/com/google/gcloud/RestorableState.java | 2 +- .../main/java/com/google/gcloud/ServiceOptions.java | 13 ++++++------- .../com/google/gcloud/spi/ServiceRpcFactory.java | 6 ++---- .../com/google/gcloud/BaseWriteChannelTest.java | 4 ++-- 7 files changed, 17 insertions(+), 22 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java b/gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java index be6ab73d00bf..fc6e77242082 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java @@ -54,7 +54,7 @@ public String apply(FieldSelector fieldSelector) { }; private static String selector(List required, FieldSelector[] others, - String... extraResourceFields) { + String... extraResourceFields) { Set fieldStrings = Sets.newHashSetWithExpectedSize(required.size() + others.length); fieldStrings.addAll(Lists.transform(required, FIELD_TO_STRING_FUNCTION)); fieldStrings.addAll(Lists.transform(Arrays.asList(others), FIELD_TO_STRING_FUNCTION)); diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/Page.java b/gcloud-java-core/src/main/java/com/google/gcloud/Page.java index 53f3a3842a18..fe192c0c0ceb 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/Page.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/Page.java @@ -21,8 +21,7 @@ /** * Interface for Google Cloud paginated results. * - *

    - * Use {@code Page} to iterate through all values (also in next pages): + *

    Use {@code Page} to iterate through all values (also in next pages): *

     {@code
      * Page page = ...; // get a Page instance
      * Iterator iterator = page.iterateAll();
    @@ -30,8 +29,8 @@
      *   T value = iterator.next();
      *   // do something with value
      * }}
    - *

    - * Or handle pagination explicitly: + * + *

    Or handle pagination explicitly: *

     {@code
      * Page page = ...; // get a Page instance
      * while (page != null) {
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/Restorable.java b/gcloud-java-core/src/main/java/com/google/gcloud/Restorable.java
    index 0b573522e370..d92c70eb9883 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/Restorable.java
    +++ b/gcloud-java-core/src/main/java/com/google/gcloud/Restorable.java
    @@ -19,15 +19,14 @@
     /**
      * Implementation of this interface can persist their state and restore from it.
      *
    - * 

    - * A typical capture usage: + *

    A typical capture usage: *

     {@code
      * X restorableObj; // X instanceof Restorable
      * RestorableState state = restorableObj.capture();
      * .. persist state
      * }
    * - * A typical restore usage: + *

    A typical restore usage: *

     {@code
      * RestorableState state = ... // read from persistence
      * X restorableObj = state.restore();
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/RestorableState.java b/gcloud-java-core/src/main/java/com/google/gcloud/RestorableState.java
    index d6ce736ae856..009a86e545f5 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/RestorableState.java
    +++ b/gcloud-java-core/src/main/java/com/google/gcloud/RestorableState.java
    @@ -20,7 +20,7 @@
      * A common interface for restorable states. Implementations of {@code RestorableState} are capable
      * of saving the state of an object to restore it for later use.
      *
    - * Implementations of this class must implement {@link java.io.Serializable} to ensure that the
    + * 

    Implementations of this class must implement {@link java.io.Serializable} to ensure that the * state of a the object can be correctly serialized. * * @param the restored object's type diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java index d53cfcdafe24..6a8656fcfa8a 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java @@ -100,8 +100,8 @@ public abstract class ServiceOptions, Service /** * A base interface for all {@link HttpTransport} factories. * - * Implementation must provide a public no-arg constructor. Loading of a factory implementation is - * done via {@link java.util.ServiceLoader}. + *

    Implementation must provide a public no-arg constructor. Loading of a factory implementation + * is done via {@link java.util.ServiceLoader}. */ public interface HttpTransportFactory { HttpTransport create(); @@ -129,7 +129,7 @@ public HttpTransport create() { * A class providing access to the current time in milliseconds. This class is mainly used for * testing and will be replaced by Java8's {@code java.time.Clock}. * - * Implementations should implement {@code Serializable} wherever possible and must document + *

    Implementations should implement {@code Serializable} wherever possible and must document * whether or not they do support serialization. */ public abstract static class Clock { @@ -490,7 +490,7 @@ protected static String appEngineProjectId() { protected static String serviceAccountProjectId() { String project = null; String credentialsPath = System.getenv("GOOGLE_APPLICATION_CREDENTIALS"); - if(credentialsPath != null) { + if (credentialsPath != null) { try (InputStream credentialsStream = new FileInputStream(credentialsPath)) { JSONObject json = new JSONObject(new JSONTokener(credentialsStream)); project = json.getString("project_id"); @@ -518,9 +518,8 @@ public ServiceRpcT rpc() { } /** - * Returns the project id. - * - * Return value can be null (for services that don't require a project id). + * Returns the project id. Return value can be null (for services that don't require a project + * id). */ public String projectId() { return projectId; diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/spi/ServiceRpcFactory.java b/gcloud-java-core/src/main/java/com/google/gcloud/spi/ServiceRpcFactory.java index d19f6047e4b2..8ee964ca8f39 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/spi/ServiceRpcFactory.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/spi/ServiceRpcFactory.java @@ -19,10 +19,8 @@ import com.google.gcloud.ServiceOptions; /** - * A base interface for all service RPC factories. - * - * Implementation must provide a public no-arg constructor. - * Loading of a factory implementation is done via {@link java.util.ServiceLoader}. + * A base interface for all service RPC factories. Implementation must provide a public no-arg + * constructor. Loading of a factory implementation is done via {@link java.util.ServiceLoader}. */ @SuppressWarnings("rawtypes") public interface ServiceRpcFactory { diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/BaseWriteChannelTest.java b/gcloud-java-core/src/test/java/com/google/gcloud/BaseWriteChannelTest.java index 6d5306a3bc7f..b44157b6557b 100644 --- a/gcloud-java-core/src/test/java/com/google/gcloud/BaseWriteChannelTest.java +++ b/gcloud-java-core/src/test/java/com/google/gcloud/BaseWriteChannelTest.java @@ -82,7 +82,7 @@ protected BaseState.Builder stateBuilder() { } @Test - public void testConstructor() throws IOException { + public void testConstructor() { assertEquals(null, channel.options()); assertEquals(ENTITY, channel.entity()); assertEquals(0, channel.position()); @@ -108,7 +108,7 @@ public void testValidateOpen() throws IOException { } @Test - public void testChunkSize() throws IOException { + public void testChunkSize() { channel.chunkSize(42); assertEquals(MIN_CHUNK_SIZE, channel.chunkSize()); channel.chunkSize(2 * MIN_CHUNK_SIZE); From bdc472a9737e6b21fca699130aef5007bfdb7891 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Thu, 7 Apr 2016 09:36:54 -0700 Subject: [PATCH 238/375] Add default retry params that align with SLA (#860) * Add default retry params that align with SLA * modify default retry params to conform with datastore, storage, and bigquery sla * Javadoc adjustments --- .../java/com/google/gcloud/RetryParams.java | 21 +++++++++++++++---- .../com/google/gcloud/ServiceOptions.java | 11 +++++++++- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/RetryParams.java b/gcloud-java-core/src/main/java/com/google/gcloud/RetryParams.java index ab3644c6d747..0b7381b9c3c5 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/RetryParams.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/RetryParams.java @@ -48,12 +48,16 @@ public final class RetryParams implements Serializable { private static final long serialVersionUID = -8492751576749007700L; + /** + * Note that App Engine Standard Environment front-end modules have a 60 second deadline for HTTP + * requests. For that reason, we set the default total retry period to less than 60 seconds. + */ + public static final long DEFAULT_TOTAL_RETRY_PERIOD_MILLIS = 50_000L; public static final int DEFAULT_RETRY_MIN_ATTEMPTS = 3; public static final int DEFAULT_RETRY_MAX_ATTEMPTS = 6; - public static final long DEFAULT_INITIAL_RETRY_DELAY_MILLIS = 250L; - public static final long DEFAULT_MAX_RETRY_DELAY_MILLIS = 10_000L; + public static final long DEFAULT_INITIAL_RETRY_DELAY_MILLIS = 1000L; + public static final long DEFAULT_MAX_RETRY_DELAY_MILLIS = 32_000L; public static final double DEFAULT_RETRY_DELAY_BACKOFF_FACTOR = 2.0; - public static final long DEFAULT_TOTAL_RETRY_PERIOD_MILLIS = 50_000L; private final int retryMinAttempts; private final int retryMaxAttempts; @@ -62,6 +66,9 @@ public final class RetryParams implements Serializable { private final double retryDelayBackoffFactor; private final long totalRetryPeriodMillis; + // Some services may have different backoff requirements listed in their SLAs. Be sure to override + // ServiceOptions.defaultRetryParams() in options subclasses when the service's backoff + // requirement differs from the default parameters used here. private static final RetryParams DEFAULT_INSTANCE = new RetryParams(new Builder()); private static final RetryParams NO_RETRIES = builder().retryMaxAttempts(1).retryMinAttempts(1).build(); @@ -156,7 +163,9 @@ public Builder retryDelayBackoffFactor(double retryDelayBackoffFactor) { } /** - * Sets totalRetryPeriodMillis. + * Sets totalRetryPeriodMillis. Note that App Engine Standard Environment front-end modules have + * a 60 second deadline for HTTP requests. For that reason, you should set the total retry + * period to under 60 seconds if you are using it on an App Engine front-end module. * * @param totalRetryPeriodMillis the totalRetryPeriodMillis to set * @return the Builder for chaining @@ -295,4 +304,8 @@ public String toString() { public static Builder builder() { return new Builder(); } + + public Builder toBuilder() { + return new Builder(this); + } } diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java index 6a8656fcfa8a..c523b1f34aa5 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java @@ -333,7 +333,7 @@ protected ServiceOptions(Class> ser authCredentials = builder.authCredentials != null ? builder.authCredentials : defaultAuthCredentials(); authCredentialsState = authCredentials != null ? authCredentials.capture() : null; - retryParams = firstNonNull(builder.retryParams, RetryParams.defaultInstance()); + retryParams = firstNonNull(builder.retryParams, defaultRetryParams()); serviceFactory = firstNonNull(builder.serviceFactory, getFromServiceLoader(serviceFactoryClass, defaultServiceFactory())); serviceFactoryClassName = serviceFactory.getClass().getName(); @@ -654,6 +654,15 @@ private static T newInstance(String className) throws IOException, ClassNotF public abstract > B toBuilder(); + /** + * Some services may have different backoff requirements listed in their SLAs. Be sure to override + * this method in options subclasses when the service's backoff requirement differs from the + * default parameters listed in {@link RetryParams}. + */ + protected RetryParams defaultRetryParams() { + return RetryParams.defaultInstance(); + } + private static T getFromServiceLoader(Class clazz, T defaultInstance) { return Iterables.getFirst(ServiceLoader.load(clazz), defaultInstance); } From 6987b00bdfc7657b4487e056c6c383b8b41c534d Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Thu, 7 Apr 2016 16:19:58 -0700 Subject: [PATCH 239/375] Remove unnecessary project ID normalization (#875) Remove unnecessary normalization in v1beta3 --- .../gcloud/datastore/DatastoreOptions.java | 49 ++----------------- .../datastore/DatastoreOptionsTest.java | 1 - .../gcloud/datastore/SerializationTest.java | 1 - 3 files changed, 3 insertions(+), 48 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java index bc0efd837755..6f0e76a4492a 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java @@ -20,14 +20,12 @@ import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; import com.google.gcloud.ServiceOptions; import com.google.gcloud.datastore.spi.DatastoreRpc; import com.google.gcloud.datastore.spi.DatastoreRpcFactory; import com.google.gcloud.datastore.spi.DefaultDatastoreRpc; import java.lang.reflect.Method; -import java.util.Iterator; import java.util.Objects; import java.util.Set; @@ -38,7 +36,6 @@ public class DatastoreOptions extends ServiceOptions SCOPES = ImmutableSet.of(DATASTORE_SCOPE); private final String namespace; - private final boolean normalizeDataset; public static class DefaultDatastoreFactory implements DatastoreFactory { @@ -64,7 +61,6 @@ public static class Builder extends ServiceOptions.Builder { private String namespace; - private boolean normalizeDataset = true; private Builder() { } @@ -72,59 +68,24 @@ private Builder() { private Builder(DatastoreOptions options) { super(options); namespace = options.namespace; - normalizeDataset = options.normalizeDataset; } @Override public DatastoreOptions build() { - DatastoreOptions options = new DatastoreOptions(this); - return normalizeDataset ? options.normalize() : options; + return new DatastoreOptions(this); } public Builder namespace(String namespace) { this.namespace = validateNamespace(namespace); return this; } - - Builder normalizeDataset(boolean normalizeDataset) { - this.normalizeDataset = normalizeDataset; - return this; - } } private DatastoreOptions(Builder builder) { super(DatastoreFactory.class, DatastoreRpcFactory.class, builder); - normalizeDataset = builder.normalizeDataset; namespace = builder.namespace != null ? builder.namespace : defaultNamespace(); } - private DatastoreOptions normalize() { - if (!normalizeDataset) { - return this; - } - - Builder builder = toBuilder(); - builder.normalizeDataset(false); - // Replace provided project-id with full project-id (s~xxx, e~xxx,...) - com.google.datastore.v1beta3.LookupRequest.Builder requestPb = - com.google.datastore.v1beta3.LookupRequest.newBuilder(); - com.google.datastore.v1beta3.Key key = com.google.datastore.v1beta3.Key.newBuilder() - .addPath(com.google.datastore.v1beta3.Key.PathElement.newBuilder() - .setKind("__foo__").setName("bar")) - .build(); - requestPb.addKeys(key); - com.google.datastore.v1beta3.LookupResponse responsePb = rpc().lookup(requestPb.build()); - if (responsePb.getDeferredCount() > 0) { - key = responsePb.getDeferred(0); - } else { - Iterator combinedIter = - Iterables.concat(responsePb.getMissingList(), responsePb.getFoundList()).iterator(); - key = combinedIter.next().getEntity().getKey(); - } - builder.projectId(key.getPartitionId().getProjectId()); - return new DatastoreOptions(builder); - } - @Override protected String defaultHost() { String host = System.getProperty( @@ -138,9 +99,6 @@ protected String defaultProject() { String projectId = System.getProperty( com.google.datastore.v1beta3.client.DatastoreHelper.PROJECT_ID_ENV_VAR, System.getenv(com.google.datastore.v1beta3.client.DatastoreHelper.PROJECT_ID_ENV_VAR)); - if (projectId == null) { - projectId = appEngineAppId(); - } return projectId != null ? projectId : super.defaultProject(); } @@ -192,7 +150,7 @@ public Builder toBuilder() { @Override public int hashCode() { - return baseHashCode() ^ Objects.hash(namespace, normalizeDataset); + return Objects.hash(baseHashCode(), namespace); } @Override @@ -201,8 +159,7 @@ public boolean equals(Object obj) { return false; } DatastoreOptions other = (DatastoreOptions) obj; - return baseEquals(other) && Objects.equals(namespace, other.namespace) - && Objects.equals(normalizeDataset, other.normalizeDataset); + return baseEquals(other) && Objects.equals(namespace, other.namespace); } public static Builder builder() { diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java index 5b77c035a714..9178bf12098b 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java @@ -41,7 +41,6 @@ public void setUp() { datastoreRpcFactory = EasyMock.createMock(DatastoreRpcFactory.class); datastoreRpc = EasyMock.createMock(DatastoreRpc.class); options = DatastoreOptions.builder() - .normalizeDataset(false) .serviceRpcFactory(datastoreRpcFactory) .projectId(PROJECT_ID) .host("http://localhost:" + PORT); diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java index 3679aba6825c..4bc90315b5d9 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java @@ -110,7 +110,6 @@ public class SerializationTest extends BaseSerializationTest { protected java.io.Serializable[] serializableObjects() { DatastoreOptions options = DatastoreOptions.builder() .authCredentials(AuthCredentials.createForAppEngine()) - .normalizeDataset(false) .projectId("ds1") .build(); DatastoreOptions otherOptions = options.toBuilder() From 53a60d1ce1067212b5c39b9eec0a9fec5c1c35ee Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 8 Apr 2016 09:20:01 -0700 Subject: [PATCH 240/375] Clean up LocalGcdHelper and docs (#821) * Cleans up local gcd helper and docs to be more consistent with other test helpers * Renames LocalGcdHelper to LocalDatastoreHelper and RemoteGcsHelper to RemoteStorageHelper * Updates the gcd.sh script version --- TESTING.md | 59 +++-- .../gcloud/bigquery/it/ITBigQueryTest.java | 10 +- .../com/google/gcloud/AuthCredentials.java | 4 +- ...dHelper.java => LocalDatastoreHelper.java} | 234 ++++++++---------- .../datastore/testing/package-info.java | 11 +- .../datastore/DatastoreOptionsTest.java | 5 +- .../gcloud/datastore/DatastoreTest.java | 28 +-- .../datastore/LocalDatastoreHelperTest.java | 53 ++++ .../gcloud/datastore/LocalGcdHelperTest.java | 73 ------ .../gcloud/dns/testing/package-info.java | 2 +- .../examples/datastore/DatastoreExample.java | 10 +- .../resourcemanager/testing/package-info.java | 2 +- ...csHelper.java => RemoteStorageHelper.java} | 37 +-- .../gcloud/storage/testing/package-info.java | 8 +- ...Test.java => RemoteStorageHelperTest.java} | 18 +- .../gcloud/storage/it/ITStorageTest.java | 14 +- 16 files changed, 254 insertions(+), 314 deletions(-) rename gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/{LocalGcdHelper.java => LocalDatastoreHelper.java} (80%) create mode 100644 gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalDatastoreHelperTest.java delete mode 100644 gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelperTest.java rename gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/{RemoteGcsHelper.java => RemoteStorageHelper.java} (84%) rename gcloud-java-storage/src/test/java/com/google/gcloud/storage/{RemoteGcsHelperTest.java => RemoteStorageHelperTest.java} (92%) diff --git a/TESTING.md b/TESTING.md index 3ad181310b17..dcdbe548b87b 100644 --- a/TESTING.md +++ b/TESTING.md @@ -11,55 +11,64 @@ This library provides tools to help write tests for code that uses the following #### On your machine -You can test against a temporary local datastore by following these steps: +You can test against a temporary local Datastore by following these steps: -1. Start the local datastore emulator using `LocalGcdHelper`. This can be done in two ways: - - Run `LocalGcdHelper.java`'s `main` method with arguments `START` and (optionally) `--port=`. This will create a temporary folder on your computer and bind `localhost:` for communication with the local datastore. The port number is an optional argument. If no port number is specified, port 8080 will be used. - - Call `LocalGcdHelper.start(, )` before running your tests. Save the `LocalGcdHelper` object returned so that you can stop the emulator later. +1. Start the local Datastore emulator before running your tests using `LocalDatastoreHelper`'s `create` and `start` methods. This will create a temporary folder on your computer and bind a port for communication with the local Datastore. There is an optional argument for `create`: consistency. The consistency setting controls the fraction of Datastore writes that are immediately visible in global queries. + ```java + // Use the default consistency setting of 0.9 + LocalDatastoreHelper helper = LocalDatastoreHelper.create(); + // or explicitly set the consistency + helper = LocalDatastoreHelper.create(0.6); + + helper.start(); // Starts the local Datastore emulator in a separate process + ``` -2. In your program, create and use a datastore whose host is set host to `localhost:`. For example, +2. Create and use a `Datastore` object with the options given by the `LocalDatastoreHelper` instance. For example: ```java - DatastoreOptions options = DatastoreOptions.builder() - .projectId(PROJECT_ID) - .host("http://localhost:8080") - .build(); - Datastore localDatastore = options.service(); + Datastore localDatastore = helper.options().service(); ``` + 3. Run your tests. -4. Stop the local datastore emulator. - - If you ran `LocalGcdHelper.java`'s `main` function to start the emulator, run `LocalGcdHelper.java`'s `main` method with arguments `STOP` and (optionally) `--port=`. If the port is not supplied, the program will attempt to close the last port started. - - If you ran `LocalGcdHelper.start()` to start the emulator, call the `stop()` method on the `LocalGcdHelper` object returned by `LocalGcdHelper.start()`. +4. Stop the local datastore emulator by calling the `stop()` method, like so: + ```java + helper.stop(); + ``` #### On a remote machine -You can test against a remote datastore emulator as well. To do this, set the `DatastoreOptions` project endpoint to the hostname of the remote machine, like the example below. +You can test against a remote Datastore emulator as well. To do this, set the `DatastoreOptions` project endpoint to the hostname of the remote machine, like the example below. ```java DatastoreOptions options = DatastoreOptions.builder() - .projectId(PROJECT_ID) + .projectId("my-project-id") // must match project ID specified on remote machine .host("http://:") + .authCredentials(AuthCredentials.noAuth()) .build(); Datastore localDatastore = options.service(); ``` -Note that the remote datastore must be running before your tests are run. +We recommend that you start the emulator on the remote machine using the [Google Cloud SDK](https://cloud.google.com/sdk/gcloud/reference/beta/emulators/datastore/) from command line, as shown below: + +``` +gcloud beta emulators datastore start --host-port : +``` ### Testing code that uses Storage -Currently, there isn't an emulator for Google Cloud Storage, so an alternative is to create a test project. `RemoteGcsHelper` contains convenience methods to make setting up and cleaning up the test project easier. To use this class, follow the steps below: +Currently, there isn't an emulator for Google Cloud Storage, so an alternative is to create a test project. `RemoteStorageHelper` contains convenience methods to make setting up and cleaning up the test project easier. To use this class, follow the steps below: 1. Create a test Google Cloud project. 2. Download a JSON service account credentials file from the Google Developer's Console. See more about this on the [Google Cloud Platform Storage Authentication page][cloud-platform-storage-authentication]. -3. Create a `RemoteGcsHelper` object using your project ID and JSON key. -Here is an example that uses the `RemoteGcsHelper` to create a bucket. +3. Create a `RemoteStorageHelper` object using your project ID and JSON key. +Here is an example that uses the `RemoteStorageHelper` to create a bucket. ```java - RemoteGcsHelper gcsHelper = - RemoteGcsHelper.create(PROJECT_ID, new FileInputStream("/path/to/my/JSON/key.json")); - Storage storage = gcsHelper.options().service(); - String bucket = RemoteGcsHelper.generateBucketName(); + RemoteStorageHelper helper = + RemoteStorageHelper.create(PROJECT_ID, new FileInputStream("/path/to/my/JSON/key.json")); + Storage storage = helper.options().service(); + String bucket = RemoteStorageHelper.generateBucketName(); storage.create(BucketInfo.of(bucket)); ``` @@ -68,7 +77,7 @@ Here is an example that uses the `RemoteGcsHelper` to create a bucket. 5. Clean up the test project by using `forceDelete` to clear any buckets used. Here is an example that clears the bucket created in Step 3 with a timeout of 5 seconds. ```java - RemoteGcsHelper.forceDelete(storage, bucket, 5, TimeUnit.SECONDS); + RemoteStorageHelper.forceDelete(storage, bucket, 5, TimeUnit.SECONDS); ``` ### Testing code that uses Resource Manager @@ -134,4 +143,4 @@ Here is an example that clears the dataset created in Step 3. ``` [cloud-platform-storage-authentication]:https://cloud.google.com/storage/docs/authentication?hl=en#service_accounts -[create-service-account]:https://developers.google.com/identity/protocols/OAuth2ServiceAccount#creatinganaccount \ No newline at end of file +[create-service-account]:https://developers.google.com/identity/protocols/OAuth2ServiceAccount#creatinganaccount diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java index cc7f06a251db..a75c12f86c1d 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java @@ -67,7 +67,7 @@ import com.google.gcloud.storage.BlobInfo; import com.google.gcloud.storage.BucketInfo; import com.google.gcloud.storage.Storage; -import com.google.gcloud.storage.testing.RemoteGcsHelper; +import com.google.gcloud.storage.testing.RemoteStorageHelper; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -135,7 +135,7 @@ public class ITBigQueryTest { private static final String LOAD_FILE = "load.csv"; private static final String JSON_LOAD_FILE = "load.json"; private static final String EXTRACT_FILE = "extract.csv"; - private static final String BUCKET = RemoteGcsHelper.generateBucketName(); + private static final String BUCKET = RemoteStorageHelper.generateBucketName(); private static final TableId TABLE_ID = TableId.of(DATASET, "testing_table"); private static final String CSV_CONTENT = "StringValue1\nStringValue2\n"; private static final String JSON_CONTENT = "{" @@ -172,9 +172,9 @@ public class ITBigQueryTest { @BeforeClass public static void beforeClass() throws InterruptedException { RemoteBigQueryHelper bigqueryHelper = RemoteBigQueryHelper.create(); - RemoteGcsHelper gcsHelper = RemoteGcsHelper.create(); + RemoteStorageHelper storageHelper = RemoteStorageHelper.create(); bigquery = bigqueryHelper.options().service(); - storage = gcsHelper.options().service(); + storage = storageHelper.options().service(); storage.create(BucketInfo.of(BUCKET)); storage.create(BlobInfo.builder(BUCKET, LOAD_FILE).contentType("text/plain").build(), CSV_CONTENT.getBytes(StandardCharsets.UTF_8)); @@ -200,7 +200,7 @@ public static void afterClass() throws ExecutionException, InterruptedException RemoteBigQueryHelper.forceDelete(bigquery, DATASET); } if (storage != null) { - boolean wasDeleted = RemoteGcsHelper.forceDelete(storage, BUCKET, 10, TimeUnit.SECONDS); + boolean wasDeleted = RemoteStorageHelper.forceDelete(storage, BUCKET, 10, TimeUnit.SECONDS); if (!wasDeleted && LOG.isLoggable(Level.WARNING)) { LOG.log(Level.WARNING, "Deletion of bucket {0} timed out, bucket is not empty", BUCKET); } diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java index 080d49ed3ccc..18370ec01fa4 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java @@ -339,7 +339,7 @@ public RestorableState capture() { /** * A placeholder for credentials to signify that requests sent to the server should not be * authenticated. This is typically useful when using the local service emulators, such as - * {@code LocalGcdHelper} and {@code LocalResourceManagerHelper}. + * {@code LocalDatastoreHelper} and {@code LocalResourceManagerHelper}. */ public static class NoAuthCredentials extends AuthCredentials { @@ -425,7 +425,7 @@ public static ServiceAccountAuthCredentials createFor(String account, PrivateKey /** * Creates a placeholder denoting that no credentials should be used. This is typically useful - * when using the local service emulators, such as {@code LocalGcdHelper} and + * when using the local service emulators, such as {@code LocalDatastoreHelper} and * {@code LocalResourceManagerHelper}. */ public static AuthCredentials noAuth() { diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalDatastoreHelper.java similarity index 80% rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java rename to gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalDatastoreHelper.java index 6f1a76b0a482..c37265965337 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalGcdHelper.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalDatastoreHelper.java @@ -18,9 +18,11 @@ import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.Preconditions.checkArgument; -import static java.nio.charset.StandardCharsets.UTF_8; import com.google.common.base.Strings; +import com.google.gcloud.AuthCredentials; +import com.google.gcloud.RetryParams; +import com.google.gcloud.datastore.DatastoreOptions; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; @@ -28,8 +30,6 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; -import java.io.FileReader; -import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -52,10 +52,9 @@ import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.List; import java.util.Locale; -import java.util.Map; +import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; @@ -65,28 +64,27 @@ /** * Utility to start and stop local Google Cloud Datastore process. */ -public class LocalGcdHelper { - private static final Logger log = Logger.getLogger(LocalGcdHelper.class.getName()); - - private final String projectId; - private Path gcdPath; - private Process startProcess; - private ProcessStreamReader processReader; - private ProcessErrorStreamReader processErrorReader; - private final int port; - - public static final String DEFAULT_PROJECT_ID = "projectid1"; - public static final int DEFAULT_PORT = 8080; +public class LocalDatastoreHelper { + private static final Logger log = Logger.getLogger(LocalDatastoreHelper.class.getName()); private static final String GCD_VERSION = "v1beta3"; - private static final String GCD_BUILD = "1.0.0"; + private static final String GCD_BUILD = "1.0.1"; + private static final double DEFAULT_CONSISTENCY = 0.9; private static final String GCD_BASENAME = "gcd-" + GCD_VERSION + "-" + GCD_BUILD; private static final String GCD_FILENAME = GCD_BASENAME + ".zip"; - private static final String MD5_CHECKSUM = "72156cc993835c57f72789519b85249b"; + private static final String MD5_CHECKSUM = "df876ba8f054d69acff30ec9540ec386"; private static final URL GCD_URL; private static final String GCLOUD = "gcloud"; private static final Path INSTALLED_GCD_PATH; private static final String GCD_VERSION_PREFIX = "gcd-emulator "; - private static final double DEFAULT_CONSISTENCY = 0.9; + private static final String PROJECT_ID_PREFIX = "test-project-"; + + private final String projectId; + private Path gcdPath; + private Process startProcess; + private ProcessStreamReader processReader; + private ProcessErrorStreamReader processErrorReader; + private final int port; + private final double consistency; static { INSTALLED_GCD_PATH = installedGcdPath(); @@ -101,14 +99,6 @@ public class LocalGcdHelper { } } - public static int findAvailablePort(int defaultPort) { - try (ServerSocket tempSocket = new ServerSocket(0)) { - return tempSocket.getLocalPort(); - } catch (IOException e) { - return defaultPort; - } - } - private static Path installedGcdPath() { String gcloudExecutableName; if (isWindows()) { @@ -388,44 +378,6 @@ public static CommandWrapper create() { } } - public LocalGcdHelper(String projectId, int port) { - this.projectId = projectId; - this.port = port; - } - - /** - * Starts the local datastore for the specific project. - * - * This will unzip the gcd tool, create the project and start it. - * All content is written to a temporary directory that will be deleted when - * {@link #stop()} is called or when the program terminates) to make sure that no left-over - * data from prior runs is used. - * - * @param consistency the fraction of job application attempts that will succeed, with 0.0 - * resulting in no attempts succeeding, and 1.0 resulting in all attempts succeeding. Defaults - * to 0.9. Note that setting this to 1.0 may mask incorrect assumptions about the consistency - * of non-ancestor queries; non-ancestor queries are eventually consistent. - */ - public void start(double consistency) throws IOException, InterruptedException { - // send a quick request in case we have a hanging process from a previous run - checkArgument(consistency >= 0.0 && consistency <= 1.0, "Consistency must be between 0 and 1"); - sendQuitRequest(port); - // Each run is associated with its own folder that is deleted once test completes. - gcdPath = Files.createTempDirectory("gcd"); - File gcdFolder = gcdPath.toFile(); - gcdFolder.deleteOnExit(); - - Path gcdExecutablePath; - // If cloud is available we use it, otherwise we download and start gcd - if (INSTALLED_GCD_PATH == null) { - downloadGcd(); - gcdExecutablePath = gcdPath.resolve("gcd"); - } else { - gcdExecutablePath = INSTALLED_GCD_PATH; - } - startGcd(gcdExecutablePath, consistency); - } - private void downloadGcd() throws IOException { // check if we already have a local copy of the gcd utility and download it if not. File gcdZipFile = new File(System.getProperty("java.io.tmpdir"), GCD_FILENAME); @@ -589,80 +541,96 @@ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IO }); } - public static LocalGcdHelper start(String projectId, int port, double consistency) - throws IOException, InterruptedException { - LocalGcdHelper helper = new LocalGcdHelper(projectId, port); - helper.start(consistency); - return helper; + private LocalDatastoreHelper(double consistency) { + checkArgument(consistency >= 0.0 && consistency <= 1.0, "Consistency must be between 0 and 1"); + projectId = PROJECT_ID_PREFIX + UUID.randomUUID().toString(); + this.consistency = consistency; + this.port = findAvailablePort(); } - public static void main(String... args) throws IOException, InterruptedException { - Map parsedArgs = parseArgs(args); - String action = parsedArgs.get("action"); - int port = - (parsedArgs.get("port") == null) ? DEFAULT_PORT : Integer.parseInt(parsedArgs.get("port")); - switch (action) { - case "START": - if (!isActive(DEFAULT_PROJECT_ID, port)) { - double consistency = parsedArgs.get("consistency") == null - ? DEFAULT_CONSISTENCY : Double.parseDouble(parsedArgs.get("consistency")); - LocalGcdHelper helper = start(DEFAULT_PROJECT_ID, port, consistency); - try (FileWriter writer = new FileWriter(".local_gcd_helper")) { - writer.write(helper.gcdPath.toAbsolutePath().toString() + System.lineSeparator()); - writer.write(Integer.toString(port)); - } - } - return; - case "STOP": - File file = new File(".local_gcd_helper"); - String path = null; - boolean fileExists = file.exists(); - if (fileExists) { - try (BufferedReader reader = new BufferedReader(new FileReader(file))) { - path = reader.readLine(); - port = Integer.parseInt(reader.readLine()); - } - } - sendQuitRequest(port); - if (fileExists) { - deleteRecurse(Paths.get(path)); - file.delete(); - } - return; - default: - break; + private static int findAvailablePort() { + try (ServerSocket tempSocket = new ServerSocket(0)) { + return tempSocket.getLocalPort(); + } catch (IOException e) { + return -1; } } - private static Map parseArgs(String[] args) { - Map parsedArgs = new HashMap(); - for (String arg : args) { - if (arg.startsWith("--port=")) { - parsedArgs.put("port", arg.substring("--port=".length())); - } else if (arg.equals("START") || arg.equals("STOP")) { - parsedArgs.put("action", arg); - } else { - throw new RuntimeException("Only accepts START, STOP, and --port= as arguments"); - } - } - if (parsedArgs.get("action") == null) { - throw new RuntimeException("EXPECTING START | STOP"); - } - return parsedArgs; + /** + * Returns a {@link DatastoreOptions} instance that sets the host to use the Datastore emulator on + * localhost. + */ + public DatastoreOptions options() { + return DatastoreOptions.builder() + .projectId(projectId) + .host("localhost:" + Integer.toString(port)) + .authCredentials(AuthCredentials.noAuth()) + .retryParams(RetryParams.noRetries()) + .build(); } - public static boolean isActive(String projectId, int port) { - try { - StringBuilder urlBuilder = new StringBuilder("http://localhost:").append(port); - urlBuilder.append("/datastore/v1beta3/projects/").append(projectId).append(":lookup"); - URL url = new URL(urlBuilder.toString()); - try (BufferedReader reader = - new BufferedReader(new InputStreamReader(url.openStream(), UTF_8))) { - return "Valid RPC".equals(reader.readLine()); - } - } catch (IOException ignore) { - // assume not active - return false; + /** + * Returns the project ID associated with this local Datastore emulator. + */ + public String projectId() { + return projectId; + } + + /** + * Returns the consistency setting for the local Datastore emulator. + */ + public double consistency() { + return consistency; + } + + /** + * Creates a local Datastore helper with the specified settings for project ID and consistency. + * + * @param consistency the fraction of Datastore writes that are immediately visible to global + * queries, with 0.0 meaning no writes are immediately visible and 1.0 meaning all writes + * are immediately visible. Note that setting this to 1.0 may mask incorrect assumptions + * about the consistency of non-ancestor queries; non-ancestor queries are eventually + * consistent. + */ + public static LocalDatastoreHelper create(double consistency) { + LocalDatastoreHelper helper = new LocalDatastoreHelper(consistency); + return helper; + } + + /** + * Creates a local Datastore helper with a placeholder project ID and the default consistency + * setting of 0.9. Consistency refers to the fraction of Datastore writes that are immediately + * visible to global queries, with 0.0 meaning no writes are immediately visible and 1.0 meaning + * all writes are immediately visible. + */ + public static LocalDatastoreHelper create() { + return create(DEFAULT_CONSISTENCY); + } + + /** + * Starts the local Datastore emulator. Leftover data from previous uses of the emulator will be + * removed. + * + * @throws InterruptedException if emulator-related tasks are interrupted + * @throws IOException if there are socket exceptions or issues creating/deleting the temporary + * data folder + */ + public void start() throws IOException, InterruptedException { + // send a quick request in case we have a hanging process from a previous run + sendQuitRequest(port); + // Each run is associated with its own folder that is deleted once test completes. + gcdPath = Files.createTempDirectory("gcd"); + File gcdFolder = gcdPath.toFile(); + gcdFolder.deleteOnExit(); + + Path gcdExecutablePath; + // If cloud is available we use it, otherwise we download and start gcd + if (INSTALLED_GCD_PATH == null) { + downloadGcd(); + gcdExecutablePath = gcdPath.resolve("gcd"); + } else { + gcdExecutablePath = INSTALLED_GCD_PATH; } + startGcd(gcdExecutablePath, consistency); } } diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/package-info.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/package-info.java index d03c9d85cd09..fae9860275c6 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/package-info.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/package-info.java @@ -20,17 +20,14 @@ *

    A simple usage example: *

    Before the test: *

     {@code
    - * LocalGcdHelper gcdHelper = LocalGcdHelper.start(PROJECT_ID, PORT_NUMBER);
    - * DatastoreOptions options = DatastoreOptions.builder()
    - *     .projectId(PROJECT_ID)
    - *     .host("localhost:8080")
    - *     .build();
    - * Datastore localDatastore = options.service();
    + * LocalDatastoreHelper helper = LocalDatastoreHelper.create();
    + * helper.start();
    + * Datastore localDatastore = helper.options().service();
      * } 
    * *

    After the test: *

     {@code
    - * gcdHelper.stop();
    + * helper.stop();
      * } 
    * * @see diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java index 9178bf12098b..fa74243049de 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java @@ -22,7 +22,6 @@ import com.google.gcloud.datastore.spi.DatastoreRpc; import com.google.gcloud.datastore.spi.DatastoreRpcFactory; -import com.google.gcloud.datastore.testing.LocalGcdHelper; import org.easymock.EasyMock; import org.junit.Before; @@ -30,8 +29,8 @@ public class DatastoreOptionsTest { - private static final String PROJECT_ID = "project_id"; - private static final int PORT = LocalGcdHelper.findAvailablePort(LocalGcdHelper.DEFAULT_PORT); + private static final String PROJECT_ID = "project-id"; + private static final int PORT = 8080; private DatastoreRpcFactory datastoreRpcFactory; private DatastoreRpc datastoreRpc; private DatastoreOptions.Builder options; diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java index 25c161a5d91d..4f2487916fd8 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java @@ -37,14 +37,13 @@ import com.google.datastore.v1beta3.ReadOptions.ReadConsistency; import com.google.datastore.v1beta3.RunQueryRequest; import com.google.datastore.v1beta3.RunQueryResponse; -import com.google.gcloud.AuthCredentials; import com.google.gcloud.RetryParams; import com.google.gcloud.datastore.Query.ResultType; import com.google.gcloud.datastore.StructuredQuery.OrderBy; import com.google.gcloud.datastore.StructuredQuery.PropertyFilter; import com.google.gcloud.datastore.spi.DatastoreRpc; import com.google.gcloud.datastore.spi.DatastoreRpcFactory; -import com.google.gcloud.datastore.testing.LocalGcdHelper; +import com.google.gcloud.datastore.testing.LocalDatastoreHelper; import com.google.protobuf.ByteString; import org.easymock.EasyMock; @@ -68,7 +67,10 @@ @RunWith(JUnit4.class) public class DatastoreTest { - private static final String PROJECT_ID = LocalGcdHelper.DEFAULT_PROJECT_ID; + private static LocalDatastoreHelper helper = LocalDatastoreHelper.create(1.0); + private static final DatastoreOptions options = helper.options(); + private static final Datastore datastore = options.service(); + private static final String PROJECT_ID = options.projectId(); private static final String KIND1 = "kind1"; private static final String KIND2 = "kind2"; private static final String KIND3 = "kind3"; @@ -118,34 +120,20 @@ public class DatastoreTest { private static final Entity ENTITY3 = Entity.builder(ENTITY1).key(KEY3).remove("str") .set("null", NULL_VALUE).set("partial1", PARTIAL_ENTITY2).set("partial2", ENTITY2).build(); - private DatastoreOptions options; private DatastoreOptions rpcMockOptions; - private Datastore datastore; private DatastoreRpcFactory rpcFactoryMock; private DatastoreRpc rpcMock; - private static LocalGcdHelper gcdHelper; - private static final int PORT = LocalGcdHelper.findAvailablePort(LocalGcdHelper.DEFAULT_PORT); - @Rule public ExpectedException thrown = ExpectedException.none(); @BeforeClass public static void beforeClass() throws IOException, InterruptedException { - if (!LocalGcdHelper.isActive(PROJECT_ID, PORT)) { - gcdHelper = LocalGcdHelper.start(PROJECT_ID, PORT, 1.0); - } + helper.start(); } @Before public void setUp() { - options = DatastoreOptions.builder() - .projectId(PROJECT_ID) - .host("localhost:" + PORT) - .authCredentials(AuthCredentials.noAuth()) - .retryParams(RetryParams.noRetries()) - .build(); - datastore = options.service(); rpcFactoryMock = EasyMock.createStrictMock(DatastoreRpcFactory.class); rpcMock = EasyMock.createStrictMock(DatastoreRpc.class); rpcMockOptions = options @@ -162,9 +150,7 @@ public void setUp() { @AfterClass public static void afterClass() throws IOException, InterruptedException { - if (gcdHelper != null) { - gcdHelper.stop(); - } + helper.stop(); } @Test diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalDatastoreHelperTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalDatastoreHelperTest.java new file mode 100644 index 000000000000..f731657d6bcc --- /dev/null +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalDatastoreHelperTest.java @@ -0,0 +1,53 @@ +/* + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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.gcloud.datastore; + +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import com.google.gcloud.AuthCredentials; +import com.google.gcloud.datastore.testing.LocalDatastoreHelper; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +@RunWith(JUnit4.class) +public class LocalDatastoreHelperTest { + + private static final double TOLERANCE = 0.00001; + private static final String PROJECT_ID_PREFIX = "test-project-"; + + @Test + public void testCreate() { + LocalDatastoreHelper helper = LocalDatastoreHelper.create(0.75); + assertTrue(Math.abs(0.75 - helper.consistency()) < TOLERANCE); + assertTrue(helper.projectId().startsWith(PROJECT_ID_PREFIX)); + helper = LocalDatastoreHelper.create(); + assertTrue(Math.abs(0.9 - helper.consistency()) < TOLERANCE); + assertTrue(helper.projectId().startsWith(PROJECT_ID_PREFIX)); + } + + @Test + public void testOptions() { + LocalDatastoreHelper helper = LocalDatastoreHelper.create(); + DatastoreOptions options = helper.options(); + assertTrue(options.projectId().startsWith(PROJECT_ID_PREFIX)); + assertTrue(options.host().startsWith("localhost:")); + assertSame(AuthCredentials.noAuth(), options.authCredentials()); + } +} diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelperTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelperTest.java deleted file mode 100644 index 5d761a713506..000000000000 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalGcdHelperTest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * 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.gcloud.datastore; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import com.google.gcloud.datastore.testing.LocalGcdHelper; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -import java.io.IOException; -import java.net.ServerSocket; - -@RunWith(JUnit4.class) -public class LocalGcdHelperTest { - - private static final String PROJECT_ID = LocalGcdHelper.DEFAULT_PROJECT_ID; - private static final int PORT = LocalGcdHelper.findAvailablePort(LocalGcdHelper.DEFAULT_PORT); - - @Test - public void testFindAvailablePort() { - int chosenPort = LocalGcdHelper.findAvailablePort(LocalGcdHelper.DEFAULT_PORT); - try (ServerSocket tempSocket = new ServerSocket(chosenPort)) { - // success - } catch (IOException e) { - if (chosenPort != LocalGcdHelper.DEFAULT_PORT) { - fail("Chosen port not free, even though LocalGcdHelper claimed it was."); - } - } - } - - @Test - public void testSendQuitRequest() throws IOException, InterruptedException { - LocalGcdHelper gcdHelper = LocalGcdHelper.start(PROJECT_ID, PORT, 0.75); - assertTrue(LocalGcdHelper.sendQuitRequest(PORT)); - long timeoutMillis = 30000; - long startTime = System.currentTimeMillis(); - boolean datastoreActive = LocalGcdHelper.isActive(PROJECT_ID, PORT); - while (datastoreActive && System.currentTimeMillis() - startTime < timeoutMillis) { - datastoreActive = LocalGcdHelper.isActive(PROJECT_ID, PORT); - } - assertFalse(datastoreActive); - assertFalse(LocalGcdHelper.sendQuitRequest(PORT)); - gcdHelper.stop(); - } - - @Test - public void testStartStop() throws IOException, InterruptedException { - LocalGcdHelper gcdHelper = LocalGcdHelper.start(PROJECT_ID, PORT, 0.75); - assertFalse(LocalGcdHelper.isActive("wrong-project-id", PORT)); - assertTrue(LocalGcdHelper.isActive(PROJECT_ID, PORT)); - gcdHelper.stop(); - assertFalse(LocalGcdHelper.isActive(PROJECT_ID, PORT)); - } -} diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/package-info.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/package-info.java index a0a0c593c2b7..85c332e56dd8 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/package-info.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/package-info.java @@ -24,8 +24,8 @@ * // request processing synchronous. * long delay = 0; * LocalDnsHelper dnsHelper = LocalDnsHelper.create(delay); - * Dns dns = dnsHelper.options().service(); * dnsHelper.start(); + * Dns dns = dnsHelper.options().service(); * }
    * *

    After the test: diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/DatastoreExample.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/DatastoreExample.java index cc4331734200..00cfa90325c5 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/DatastoreExample.java +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/DatastoreExample.java @@ -182,16 +182,14 @@ public String getRequiredParams() { public static void main(String... args) { String projectId = args.length > 0 ? args[0] : null; - // If you want to access a local Datastore running via the gcd sdk, do + // If you want to access a local Datastore running via the Google Cloud SDK, do // DatastoreOptions options = DatastoreOptions.builder() // .projectId(projectId) // .namespace(NAMESPACE) - // .host("http://localhost:8080") + // .host("http://localhost:8080") // change 8080 to the port that the emulator listens to // .build(); - DatastoreOptions options = DatastoreOptions.builder() - .projectId(projectId) - .namespace(NAMESPACE) - .build(); + DatastoreOptions options = + DatastoreOptions.builder().projectId(projectId).namespace(NAMESPACE).build(); String name = args.length > 1 ? args[1] : System.getProperty("user.name"); Datastore datastore = options.service(); KeyFactory keyFactory = datastore.newKeyFactory().kind(USER_KIND); diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/package-info.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/package-info.java index b0165c1ddd9d..e00b6eda1822 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/package-info.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/package-info.java @@ -21,8 +21,8 @@ * Before the test: *

     {@code
      * LocalResourceManagerHelper resourceManagerHelper = LocalResourceManagerHelper.create();
    - * ResourceManager resourceManager = resourceManagerHelper.options().service();
      * resourceManagerHelper.start();
    + * ResourceManager resourceManager = resourceManagerHelper.options().service();
      * }
    * *

    After the test: diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/RemoteGcsHelper.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/RemoteStorageHelper.java similarity index 84% rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/RemoteGcsHelper.java rename to gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/RemoteStorageHelper.java index 1287ede746d5..b1a836be255a 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/RemoteGcsHelper.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/RemoteStorageHelper.java @@ -47,13 +47,13 @@ * {@link StorageOptions#connectTimeout()} and {@link StorageOptions#readTimeout()} are both set * to {@code 60000}. */ -public class RemoteGcsHelper { +public class RemoteStorageHelper { - private static final Logger log = Logger.getLogger(RemoteGcsHelper.class.getName()); + private static final Logger log = Logger.getLogger(RemoteStorageHelper.class.getName()); private static final String BUCKET_NAME_PREFIX = "gcloud-test-bucket-temp-"; private final StorageOptions options; - private RemoteGcsHelper(StorageOptions options) { + private RemoteStorageHelper(StorageOptions options) { this.options = options; } @@ -111,16 +111,17 @@ public static String generateBucketName() { } /** - * Creates a {@code RemoteGcsHelper} object for the given project id and JSON key input stream. + * Creates a {@code RemoteStorageHelper} object for the given project id and JSON key input + * stream. * * @param projectId id of the project to be used for running the tests * @param keyStream input stream for a JSON key - * @return A {@code RemoteGcsHelper} object for the provided options - * @throws com.google.gcloud.storage.testing.RemoteGcsHelper.GcsHelperException if + * @return A {@code RemoteStorageHelper} object for the provided options + * @throws com.google.gcloud.storage.testing.RemoteStorageHelper.StorageHelperException if * {@code keyStream} is not a valid JSON key stream */ - public static RemoteGcsHelper create(String projectId, InputStream keyStream) - throws GcsHelperException { + public static RemoteStorageHelper create(String projectId, InputStream keyStream) + throws StorageHelperException { try { StorageOptions storageOptions = StorageOptions.builder() .authCredentials(AuthCredentials.createForJson(keyStream)) @@ -129,26 +130,26 @@ public static RemoteGcsHelper create(String projectId, InputStream keyStream) .connectTimeout(60000) .readTimeout(60000) .build(); - return new RemoteGcsHelper(storageOptions); + return new RemoteStorageHelper(storageOptions); } catch (IOException ex) { if (log.isLoggable(Level.WARNING)) { log.log(Level.WARNING, ex.getMessage()); } - throw GcsHelperException.translate(ex); + throw StorageHelperException.translate(ex); } } /** - * Creates a {@code RemoteGcsHelper} object using default project id and authentication + * Creates a {@code RemoteStorageHelper} object using default project id and authentication * credentials. */ - public static RemoteGcsHelper create() throws GcsHelperException { + public static RemoteStorageHelper create() throws StorageHelperException { StorageOptions storageOptions = StorageOptions.builder() .retryParams(retryParams()) .connectTimeout(60000) .readTimeout(60000) .build(); - return new RemoteGcsHelper(storageOptions); + return new RemoteStorageHelper(storageOptions); } private static RetryParams retryParams() { @@ -196,20 +197,20 @@ public Boolean call() { } } - public static class GcsHelperException extends RuntimeException { + public static class StorageHelperException extends RuntimeException { private static final long serialVersionUID = -7756074894502258736L; - public GcsHelperException(String message) { + public StorageHelperException(String message) { super(message); } - public GcsHelperException(String message, Throwable cause) { + public StorageHelperException(String message, Throwable cause) { super(message, cause); } - public static GcsHelperException translate(Exception ex) { - return new GcsHelperException(ex.getMessage(), ex); + public static StorageHelperException translate(Exception ex) { + return new StorageHelperException(ex.getMessage(), ex); } } } diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/package-info.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/package-info.java index 8afdd8a9660d..3d30cbb9f37e 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/package-info.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/package-info.java @@ -21,15 +21,15 @@ * *

    Before the test: *

     {@code
    - * RemoteGcsHelper gcsHelper = RemoteGcsHelper.create();
    - * Storage storage = gcsHelper.options().service();
    - * String bucket = RemoteGcsHelper.generateBucketName();
    + * RemoteStorageHelper helper = RemoteStorageHelper.create();
    + * Storage storage = helper.options().service();
    + * String bucket = RemoteStorageHelper.generateBucketName();
      * storage.create(BucketInfo.of(bucket));
      * } 
    * *

    After the test: *

     {@code
    - * RemoteGcsHelper.forceDelete(storage, bucket, 5, TimeUnit.SECONDS);
    + * RemoteStorageHelper.forceDelete(storage, bucket, 5, TimeUnit.SECONDS);
      * } 
    * * @see
    diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteGcsHelperTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteStorageHelperTest.java similarity index 92% rename from gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteGcsHelperTest.java rename to gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteStorageHelperTest.java index 146922a9dae9..0702d8aba65f 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteGcsHelperTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteStorageHelperTest.java @@ -17,12 +17,13 @@ package com.google.gcloud.storage; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import com.google.common.collect.ImmutableList; import com.google.gcloud.Page; import com.google.gcloud.storage.Storage.BlobListOption; -import com.google.gcloud.storage.testing.RemoteGcsHelper; +import com.google.gcloud.storage.testing.RemoteStorageHelper; import org.easymock.EasyMock; import org.junit.Before; @@ -37,7 +38,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; -public class RemoteGcsHelperTest { +public class RemoteStorageHelperTest { private static final String BUCKET_NAME = "bucket-name"; private static final String PROJECT_ID = "project-id"; @@ -125,7 +126,7 @@ public void testForceDelete() throws InterruptedException, ExecutionException { } EasyMock.expect(storageMock.delete(BUCKET_NAME)).andReturn(true); EasyMock.replay(storageMock); - assertTrue(RemoteGcsHelper.forceDelete(storageMock, BUCKET_NAME, 5, TimeUnit.SECONDS)); + assertTrue(RemoteStorageHelper.forceDelete(storageMock, BUCKET_NAME, 5, TimeUnit.SECONDS)); EasyMock.verify(storageMock); } @@ -139,7 +140,8 @@ public void testForceDeleteTimeout() throws InterruptedException, ExecutionExcep } EasyMock.expect(storageMock.delete(BUCKET_NAME)).andThrow(RETRYABLE_EXCEPTION).anyTimes(); EasyMock.replay(storageMock); - assertTrue(!RemoteGcsHelper.forceDelete(storageMock, BUCKET_NAME, 50, TimeUnit.MICROSECONDS)); + assertFalse( + RemoteStorageHelper.forceDelete(storageMock, BUCKET_NAME, 50, TimeUnit.MICROSECONDS)); EasyMock.verify(storageMock); } @@ -155,7 +157,7 @@ public void testForceDeleteFail() throws InterruptedException, ExecutionExceptio EasyMock.replay(storageMock); thrown.expect(ExecutionException.class); try { - RemoteGcsHelper.forceDelete(storageMock, BUCKET_NAME, 5, TimeUnit.SECONDS); + RemoteStorageHelper.forceDelete(storageMock, BUCKET_NAME, 5, TimeUnit.SECONDS); } finally { EasyMock.verify(storageMock); } @@ -171,7 +173,7 @@ public void testForceDeleteNoTimeout() { } EasyMock.expect(storageMock.delete(BUCKET_NAME)).andReturn(true); EasyMock.replay(storageMock); - RemoteGcsHelper.forceDelete(storageMock, BUCKET_NAME); + RemoteStorageHelper.forceDelete(storageMock, BUCKET_NAME); EasyMock.verify(storageMock); } @@ -187,7 +189,7 @@ public void testForceDeleteNoTimeoutFail() { EasyMock.replay(storageMock); thrown.expect(StorageException.class); try { - RemoteGcsHelper.forceDelete(storageMock, BUCKET_NAME); + RemoteStorageHelper.forceDelete(storageMock, BUCKET_NAME); } finally { EasyMock.verify(storageMock); } @@ -195,7 +197,7 @@ public void testForceDeleteNoTimeoutFail() { @Test public void testCreateFromStream() { - RemoteGcsHelper helper = RemoteGcsHelper.create(PROJECT_ID, JSON_KEY_STREAM); + RemoteStorageHelper helper = RemoteStorageHelper.create(PROJECT_ID, JSON_KEY_STREAM); StorageOptions options = helper.options(); assertEquals(PROJECT_ID, options.projectId()); assertEquals(60000, options.connectTimeout()); diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java index 542cf966d269..b6d9b0e46607 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java @@ -47,7 +47,7 @@ import com.google.gcloud.storage.Storage.BlobField; import com.google.gcloud.storage.Storage.BucketField; import com.google.gcloud.storage.StorageException; -import com.google.gcloud.storage.testing.RemoteGcsHelper; +import com.google.gcloud.storage.testing.RemoteStorageHelper; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -77,7 +77,7 @@ public class ITStorageTest { private static Storage storage; private static final Logger log = Logger.getLogger(ITStorageTest.class.getName()); - private static final String BUCKET = RemoteGcsHelper.generateBucketName(); + private static final String BUCKET = RemoteStorageHelper.generateBucketName(); private static final String CONTENT_TYPE = "text/plain"; private static final byte[] BLOB_BYTE_CONTENT = {0xD, 0xE, 0xA, 0xD}; private static final String BLOB_STRING_CONTENT = "Hello Google Cloud Storage!"; @@ -85,15 +85,15 @@ public class ITStorageTest { @BeforeClass public static void beforeClass() { - RemoteGcsHelper gcsHelper = RemoteGcsHelper.create(); - storage = gcsHelper.options().service(); + RemoteStorageHelper helper = RemoteStorageHelper.create(); + storage = helper.options().service(); storage.create(BucketInfo.of(BUCKET)); } @AfterClass public static void afterClass() throws ExecutionException, InterruptedException { if (storage != null) { - boolean wasDeleted = RemoteGcsHelper.forceDelete(storage, BUCKET, 5, TimeUnit.SECONDS); + boolean wasDeleted = RemoteStorageHelper.forceDelete(storage, BUCKET, 5, TimeUnit.SECONDS); if (!wasDeleted && log.isLoggable(Level.WARNING)) { log.log(Level.WARNING, "Deletion of bucket {0} timed out, bucket is not empty", BUCKET); } @@ -368,7 +368,7 @@ public void testListBlobsEmptySelectedFields() throws InterruptedException { @Test(timeout = 15000) public void testListBlobsVersioned() throws ExecutionException, InterruptedException { - String bucketName = RemoteGcsHelper.generateBucketName(); + String bucketName = RemoteStorageHelper.generateBucketName(); Bucket bucket = storage.create(BucketInfo.builder(bucketName).versioningEnabled(true).build()); try { String[] blobNames = {"test-list-blobs-versioned-blob1", "test-list-blobs-versioned-blob2"}; @@ -407,7 +407,7 @@ public void testListBlobsVersioned() throws ExecutionException, InterruptedExcep assertTrue(remoteBlob2.delete()); assertTrue(remoteBlob3.delete()); } finally { - RemoteGcsHelper.forceDelete(storage, bucketName, 5, TimeUnit.SECONDS); + RemoteStorageHelper.forceDelete(storage, bucketName, 5, TimeUnit.SECONDS); } } From 1eb3522c432ca7a6664bfc0ae2a6902c0aca9578 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 8 Apr 2016 11:58:43 -0700 Subject: [PATCH 241/375] Add javadoc for meaning deprecation (#878) --- .../main/java/com/google/gcloud/datastore/ValueBuilder.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueBuilder.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueBuilder.java index 0a24db3ff5a6..ee1579c8444d 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueBuilder.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueBuilder.java @@ -33,9 +33,15 @@ public interface ValueBuilder, B extends ValueBuilder Date: Sat, 9 Apr 2016 00:36:02 +0200 Subject: [PATCH 242/375] Suppress unchecked warning for defaultServiceFactory, defaultRpcFactory and toBuilder (#881) --- .../main/java/com/google/gcloud/bigquery/BigQueryOptions.java | 1 + .../src/main/java/com/google/gcloud/ServiceOptions.java | 4 ++-- .../java/com/google/gcloud/datastore/DatastoreOptions.java | 2 -- .../src/main/java/com/google/gcloud/dns/DnsOptions.java | 2 -- .../google/gcloud/resourcemanager/ResourceManagerOptions.java | 1 + .../main/java/com/google/gcloud/storage/StorageOptions.java | 2 -- 6 files changed, 4 insertions(+), 8 deletions(-) diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryOptions.java b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryOptions.java index d48cf646f349..c9d298affdfc 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryOptions.java +++ b/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryOptions.java @@ -85,6 +85,7 @@ protected Set scopes() { return SCOPES; } + @SuppressWarnings("unchecked") @Override public Builder toBuilder() { return new Builder(this); diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java index c523b1f34aa5..5f47b2cd05aa 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java @@ -646,9 +646,9 @@ private static T newInstance(String className) throws IOException, ClassNotF } } - protected abstract > T defaultServiceFactory(); + protected abstract ServiceFactory defaultServiceFactory(); - protected abstract > T defaultRpcFactory(); + protected abstract ServiceRpcFactory defaultRpcFactory(); protected abstract Set scopes(); diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java index 6f0e76a4492a..8761867f29e0 100644 --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java +++ b/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java @@ -102,13 +102,11 @@ protected String defaultProject() { return projectId != null ? projectId : super.defaultProject(); } - @SuppressWarnings("unchecked") @Override protected DatastoreFactory defaultServiceFactory() { return DefaultDatastoreFactory.INSTANCE; } - @SuppressWarnings("unchecked") @Override protected DatastoreRpcFactory defaultRpcFactory() { return DefaultDatastoreRpcFactory.INSTANCE; diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java index 541e7a6c6ea7..9594448579ee 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java @@ -69,13 +69,11 @@ private DnsOptions(Builder builder) { super(DnsFactory.class, DnsRpcFactory.class, builder); } - @SuppressWarnings("unchecked") @Override protected DnsFactory defaultServiceFactory() { return DefaultDnsFactory.INSTANCE; } - @SuppressWarnings("unchecked") @Override protected DnsRpcFactory defaultRpcFactory() { return DefaultDnsRpcFactory.INSTANCE; diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerOptions.java b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerOptions.java index c744864147c2..2020be3d2ece 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerOptions.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerOptions.java @@ -112,6 +112,7 @@ public int hashCode() { return baseHashCode(); } + @SuppressWarnings("unchecked") @Override public Builder toBuilder() { return new Builder(this); diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageOptions.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageOptions.java index e7e1c2778fa9..df8753efba95 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageOptions.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageOptions.java @@ -69,13 +69,11 @@ private StorageOptions(Builder builder) { super(StorageFactory.class, StorageRpcFactory.class, builder); } - @SuppressWarnings("unchecked") @Override protected StorageFactory defaultServiceFactory() { return DefaultStorageFactory.INSTANCE; } - @SuppressWarnings("unchecked") @Override protected StorageRpcFactory defaultRpcFactory() { return DefaultStorageRpcFactory.INSTANCE; From 5dadf6a85a8bd65f64500b123b7b7cc352bf17de Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 11 Apr 2016 19:50:13 +0200 Subject: [PATCH 243/375] Move test helpers' tests to testing package (#891) --- .../RemoteBigQueryHelperTest.java | 5 +- .../LocalDatastoreHelperTest.java | 4 +- .../LocalResourceManagerHelperTest.java | 4 +- .../java/com/google/gcloud/storage/Blob.java | 4 +- .../RemoteStorageHelperTest.java | 75 ++++++++++--------- 5 files changed, 49 insertions(+), 43 deletions(-) rename gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/{ => testing}/RemoteBigQueryHelperTest.java (97%) rename gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/{ => testing}/LocalDatastoreHelperTest.java (94%) rename gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/{ => testing}/LocalResourceManagerHelperTest.java (99%) rename gcloud-java-storage/src/test/java/com/google/gcloud/storage/{ => testing}/RemoteStorageHelperTest.java (78%) diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/RemoteBigQueryHelperTest.java b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/testing/RemoteBigQueryHelperTest.java similarity index 97% rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/RemoteBigQueryHelperTest.java rename to gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/testing/RemoteBigQueryHelperTest.java index 267ae161b7aa..a9c0f63d68ea 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/RemoteBigQueryHelperTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/testing/RemoteBigQueryHelperTest.java @@ -14,13 +14,14 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.gcloud.bigquery.testing; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import com.google.gcloud.bigquery.BigQuery; import com.google.gcloud.bigquery.BigQuery.DatasetDeleteOption; -import com.google.gcloud.bigquery.testing.RemoteBigQueryHelper; +import com.google.gcloud.bigquery.BigQueryOptions; import org.easymock.EasyMock; import org.junit.Rule; diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalDatastoreHelperTest.java b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/testing/LocalDatastoreHelperTest.java similarity index 94% rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalDatastoreHelperTest.java rename to gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/testing/LocalDatastoreHelperTest.java index f731657d6bcc..25ddef1ee4be 100644 --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LocalDatastoreHelperTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/testing/LocalDatastoreHelperTest.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.google.gcloud.datastore; +package com.google.gcloud.datastore.testing; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import com.google.gcloud.AuthCredentials; -import com.google.gcloud.datastore.testing.LocalDatastoreHelper; +import com.google.gcloud.datastore.DatastoreOptions; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelperTest.java similarity index 99% rename from gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java rename to gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelperTest.java index 75df0ef9e3ae..612a4752df6d 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/LocalResourceManagerHelperTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelperTest.java @@ -1,4 +1,4 @@ -package com.google.gcloud.resourcemanager; +package com.google.gcloud.resourcemanager.testing; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -11,10 +11,10 @@ import com.google.api.services.cloudresourcemanager.model.Binding; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.gcloud.resourcemanager.ResourceManagerException; import com.google.gcloud.resourcemanager.spi.DefaultResourceManagerRpc; import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc; import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc.Tuple; -import com.google.gcloud.resourcemanager.testing.LocalResourceManagerHelper; import org.junit.AfterClass; import org.junit.Before; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java index 9000d0fb8047..72fcfeff034f 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java +++ b/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java @@ -526,7 +526,9 @@ public Builder toBuilder() { @Override public final boolean equals(Object obj) { - return obj instanceof Blob && Objects.equals(toPb(), ((Blob) obj).toPb()) + return this == obj + || obj instanceof Blob + && Objects.equals(toPb(), ((Blob) obj).toPb()) && Objects.equals(options, ((Blob) obj).options); } diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteStorageHelperTest.java b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/testing/RemoteStorageHelperTest.java similarity index 78% rename from gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteStorageHelperTest.java rename to gcloud-java-storage/src/test/java/com/google/gcloud/storage/testing/RemoteStorageHelperTest.java index 0702d8aba65f..7b8033fc69bb 100644 --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/RemoteStorageHelperTest.java +++ b/gcloud-java-storage/src/test/java/com/google/gcloud/storage/testing/RemoteStorageHelperTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.storage; +package com.google.gcloud.storage.testing; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -22,8 +22,12 @@ import com.google.common.collect.ImmutableList; import com.google.gcloud.Page; +import com.google.gcloud.storage.Blob; +import com.google.gcloud.storage.BlobId; +import com.google.gcloud.storage.Storage; import com.google.gcloud.storage.Storage.BlobListOption; -import com.google.gcloud.storage.testing.RemoteStorageHelper; +import com.google.gcloud.storage.StorageException; +import com.google.gcloud.storage.StorageOptions; import org.easymock.EasyMock; import org.junit.Before; @@ -71,8 +75,11 @@ public class RemoteStorageHelperTest { private static final InputStream JSON_KEY_STREAM = new ByteArrayInputStream(JSON_KEY.getBytes()); private static final StorageException RETRYABLE_EXCEPTION = new StorageException(409, ""); private static final StorageException FATAL_EXCEPTION = new StorageException(500, ""); + private static final BlobId BLOB_ID1 = BlobId.of(BUCKET_NAME, "n1"); + private static final BlobId BLOB_ID2 = BlobId.of(BUCKET_NAME, "n2"); - private static Storage serviceMockReturnsOptions; + private Blob blob1; + private Blob blob2; private List blobList; private Page blobPage; @@ -81,18 +88,9 @@ public class RemoteStorageHelperTest { @Before public void setUp() { - serviceMockReturnsOptions = EasyMock.createMock(Storage.class); - EasyMock.expect(serviceMockReturnsOptions.options()) - .andReturn(EasyMock.createMock(StorageOptions.class)) - .times(2); - EasyMock.replay(serviceMockReturnsOptions); - blobList = ImmutableList.of( - new Blob( - serviceMockReturnsOptions, - new BlobInfo.BuilderImpl(BlobInfo.builder(BUCKET_NAME, "n1").build())), - new Blob( - serviceMockReturnsOptions, - new BlobInfo.BuilderImpl(BlobInfo.builder(BUCKET_NAME, "n2").build()))); + blob1 = EasyMock.createMock(Blob.class); + blob2 = EasyMock.createMock(Blob.class); + blobList = ImmutableList.of(blob1, blob2); blobPage = new Page() { @Override public String nextPageCursor() { @@ -119,27 +117,29 @@ public Iterator iterateAll() { @Test public void testForceDelete() throws InterruptedException, ExecutionException { Storage storageMock = EasyMock.createMock(Storage.class); + EasyMock.expect(blob1.blobId()).andReturn(BLOB_ID1); + EasyMock.expect(storageMock.delete(BLOB_ID1)).andReturn(true); + EasyMock.expect(blob2.blobId()).andReturn(BLOB_ID2); + EasyMock.expect(storageMock.delete(BLOB_ID2)).andReturn(true); EasyMock.expect(storageMock.list(BUCKET_NAME, BlobListOption.versions(true))) .andReturn(blobPage); - for (BlobInfo info : blobList) { - EasyMock.expect(storageMock.delete(info.blobId())).andReturn(true); - } EasyMock.expect(storageMock.delete(BUCKET_NAME)).andReturn(true); - EasyMock.replay(storageMock); + EasyMock.replay(storageMock, blob1, blob2); assertTrue(RemoteStorageHelper.forceDelete(storageMock, BUCKET_NAME, 5, TimeUnit.SECONDS)); - EasyMock.verify(storageMock); + EasyMock.verify(storageMock, blob1, blob2); } @Test public void testForceDeleteTimeout() throws InterruptedException, ExecutionException { Storage storageMock = EasyMock.createMock(Storage.class); + EasyMock.expect(blob1.blobId()).andReturn(BLOB_ID1).anyTimes(); + EasyMock.expect(storageMock.delete(BLOB_ID1)).andReturn(true).anyTimes(); + EasyMock.expect(blob2.blobId()).andReturn(BLOB_ID2).anyTimes(); + EasyMock.expect(storageMock.delete(BLOB_ID2)).andReturn(true).anyTimes(); EasyMock.expect(storageMock.list(BUCKET_NAME, BlobListOption.versions(true))) .andReturn(blobPage).anyTimes(); - for (BlobInfo info : blobList) { - EasyMock.expect(storageMock.delete(info.blobId())).andReturn(true).anyTimes(); - } EasyMock.expect(storageMock.delete(BUCKET_NAME)).andThrow(RETRYABLE_EXCEPTION).anyTimes(); - EasyMock.replay(storageMock); + EasyMock.replay(storageMock, blob1, blob2); assertFalse( RemoteStorageHelper.forceDelete(storageMock, BUCKET_NAME, 50, TimeUnit.MICROSECONDS)); EasyMock.verify(storageMock); @@ -148,13 +148,14 @@ public void testForceDeleteTimeout() throws InterruptedException, ExecutionExcep @Test public void testForceDeleteFail() throws InterruptedException, ExecutionException { Storage storageMock = EasyMock.createMock(Storage.class); + EasyMock.expect(blob1.blobId()).andReturn(BLOB_ID1); + EasyMock.expect(storageMock.delete(BLOB_ID1)).andReturn(true); + EasyMock.expect(blob2.blobId()).andReturn(BLOB_ID2); + EasyMock.expect(storageMock.delete(BLOB_ID2)).andReturn(true); EasyMock.expect(storageMock.list(BUCKET_NAME, BlobListOption.versions(true))) .andReturn(blobPage); - for (BlobInfo info : blobList) { - EasyMock.expect(storageMock.delete(info.blobId())).andReturn(true); - } EasyMock.expect(storageMock.delete(BUCKET_NAME)).andThrow(FATAL_EXCEPTION); - EasyMock.replay(storageMock); + EasyMock.replay(storageMock, blob1, blob2); thrown.expect(ExecutionException.class); try { RemoteStorageHelper.forceDelete(storageMock, BUCKET_NAME, 5, TimeUnit.SECONDS); @@ -166,13 +167,14 @@ public void testForceDeleteFail() throws InterruptedException, ExecutionExceptio @Test public void testForceDeleteNoTimeout() { Storage storageMock = EasyMock.createMock(Storage.class); + EasyMock.expect(blob1.blobId()).andReturn(BLOB_ID1); + EasyMock.expect(storageMock.delete(BLOB_ID1)).andReturn(true); + EasyMock.expect(blob2.blobId()).andReturn(BLOB_ID2); + EasyMock.expect(storageMock.delete(BLOB_ID2)).andReturn(true); EasyMock.expect(storageMock.list(BUCKET_NAME, BlobListOption.versions(true))) .andReturn(blobPage); - for (BlobInfo info : blobList) { - EasyMock.expect(storageMock.delete(info.blobId())).andReturn(true); - } EasyMock.expect(storageMock.delete(BUCKET_NAME)).andReturn(true); - EasyMock.replay(storageMock); + EasyMock.replay(storageMock, blob1, blob2); RemoteStorageHelper.forceDelete(storageMock, BUCKET_NAME); EasyMock.verify(storageMock); } @@ -180,13 +182,14 @@ public void testForceDeleteNoTimeout() { @Test public void testForceDeleteNoTimeoutFail() { Storage storageMock = EasyMock.createMock(Storage.class); + EasyMock.expect(blob1.blobId()).andReturn(BLOB_ID1); + EasyMock.expect(storageMock.delete(BLOB_ID1)).andReturn(true); + EasyMock.expect(blob2.blobId()).andReturn(BLOB_ID2); + EasyMock.expect(storageMock.delete(BLOB_ID2)).andReturn(true); EasyMock.expect(storageMock.list(BUCKET_NAME, BlobListOption.versions(true))) .andReturn(blobPage); - for (BlobInfo info : blobList) { - EasyMock.expect(storageMock.delete(info.blobId())).andReturn(true); - } EasyMock.expect(storageMock.delete(BUCKET_NAME)).andThrow(FATAL_EXCEPTION); - EasyMock.replay(storageMock); + EasyMock.replay(storageMock, blob1, blob2); thrown.expect(StorageException.class); try { RemoteStorageHelper.forceDelete(storageMock, BUCKET_NAME); From 099ada0000cb7731d1b99f0ff1744420e18df9bb Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Mon, 11 Apr 2016 14:29:14 -0700 Subject: [PATCH 244/375] Add expiration date to App Engine credentials (#894) --- .../src/main/java/com/google/gcloud/AuthCredentials.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java index 18370ec01fa4..4cd424bed993 100644 --- a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java +++ b/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java @@ -33,6 +33,7 @@ import java.security.Signature; import java.security.SignatureException; import java.util.Collection; +import java.util.Date; import java.util.Objects; /** @@ -58,6 +59,7 @@ private static class AppEngineCredentials extends GoogleCredentials private final String account; private final Method getAccessToken; private final Method getAccessTokenResult; + private final Method getExpirationTime; private final Method signForApp; private final Method getSignature; private final Collection scopes; @@ -74,6 +76,7 @@ private static class AppEngineCredentials extends GoogleCredentials "com.google.appengine.api.appidentity.AppIdentityService$GetAccessTokenResult"); this.getAccessTokenResult = serviceClass.getMethod("getAccessToken", Iterable.class); this.getAccessToken = tokenResultClass.getMethod("getAccessToken"); + this.getExpirationTime = tokenResultClass.getMethod("getExpirationTime"); this.account = (String) serviceClass.getMethod("getServiceAccountName") .invoke(appIdentityService); this.signForApp = serviceClass.getMethod("signForApp", byte[].class); @@ -90,6 +93,7 @@ private static class AppEngineCredentials extends GoogleCredentials this.appIdentityService = unscoped.appIdentityService; this.getAccessToken = unscoped.getAccessToken; this.getAccessTokenResult = unscoped.getAccessTokenResult; + this.getExpirationTime = unscoped.getExpirationTime; this.account = unscoped.account; this.signForApp = unscoped.signForApp; this.getSignature = unscoped.getSignature; @@ -107,7 +111,8 @@ public AccessToken refreshAccessToken() throws IOException { try { Object accessTokenResult = getAccessTokenResult.invoke(appIdentityService, scopes); String accessToken = (String) getAccessToken.invoke(accessTokenResult); - return new AccessToken(accessToken, null); + Date expirationTime = (Date) getExpirationTime.invoke(accessTokenResult); + return new AccessToken(accessToken, expirationTime); } catch (Exception e) { throw new IOException("Could not get the access token.", e); } @@ -131,7 +136,7 @@ public String account() { @Override public byte[] sign(byte[] toSign) { try { - Object signingResult = signForApp.invoke(appIdentityService, (Object) toSign); + Object signingResult = signForApp.invoke(appIdentityService, toSign); return (byte[]) getSignature.invoke(signingResult); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { throw new SigningException("Failed to sign the provided bytes", ex); From e9888a664951a470bfdceaa64d280fedcf6076d1 Mon Sep 17 00:00:00 2001 From: Shin Fan Date: Mon, 11 Apr 2016 15:20:52 -0700 Subject: [PATCH 245/375] Update pubsub client with latest surface changes. (#885) Update pubsub client with latest surface changes, add throws in javadoc and update gax dependency to 0.0.9 --- .../gcloud/pubsub/spi/v1/PublisherApi.java | 70 +-- .../pubsub/spi/v1/PublisherSettings.java | 429 +++++++++------- .../gcloud/pubsub/spi/v1/SubscriberApi.java | 70 ++- .../pubsub/spi/v1/SubscriberSettings.java | 463 ++++++++++-------- gcloud-java-pubsub/pom.xml | 2 +- .../gcloud/pubsub/spi/v1/PublisherApi.java | 70 +-- .../pubsub/spi/v1/PublisherSettings.java | 429 +++++++++------- .../gcloud/pubsub/spi/v1/SubscriberApi.java | 70 ++- .../pubsub/spi/v1/SubscriberSettings.java | 463 ++++++++++-------- .../pubsub/spi/v1/PublisherApiTest.java | 26 +- 10 files changed, 1211 insertions(+), 881 deletions(-) diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java index 8394e5ae74ed..1d8c00c4e910 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java @@ -34,8 +34,6 @@ package com.google.gcloud.pubsub.spi.v1; import com.google.api.gax.grpc.ApiCallable; -import com.google.api.gax.grpc.ApiCallable.BundlableApiCallableInfo; -import com.google.api.gax.grpc.BundlerFactory; import com.google.api.gax.protobuf.PathTemplate; import com.google.protobuf.Empty; import com.google.pubsub.v1.DeleteTopicRequest; @@ -80,23 +78,9 @@ public class PublisherApi implements AutoCloseable { listTopicSubscriptionsIterableCallable; private final ApiCallable deleteTopicCallable; - /** - * A PathTemplate representing the fully-qualified path to represent - * a project resource. - * - * - * - */ private static final PathTemplate PROJECT_PATH_TEMPLATE = PathTemplate.create("projects/{project}"); - /** - * A PathTemplate representing the fully-qualified path to represent - * a topic resource. - * - * - * - */ private static final PathTemplate TOPIC_PATH_TEMPLATE = PathTemplate.create("projects/{project}/topics/{topic}"); @@ -161,8 +145,8 @@ public static final String parseTopicFromTopicName(String topicName) { * * */ - public static final PublisherApi create() throws IOException { - return create(PublisherSettings.create()); + public static final PublisherApi defaultInstance() throws IOException { + return create(PublisherSettings.defaultInstance()); } /** @@ -188,22 +172,20 @@ public static final PublisherApi create(PublisherSettings settings) throws IOExc protected PublisherApi(PublisherSettings settings) throws IOException { this.channel = settings.getChannel(); - this.createTopicCallable = settings.createTopicMethod().build(settings); - BundlableApiCallableInfo bundlablePublish = - settings.publishMethod().buildBundlable(settings); - this.publishCallable = bundlablePublish.getApiCallable(); - BundlerFactory publishBundlerFactory = - bundlablePublish.getBundlerFactory(); - if (publishBundlerFactory != null) { - this.closeables.add(publishBundlerFactory); + this.createTopicCallable = ApiCallable.create(settings.createTopicSettings(), settings); + this.publishCallable = ApiCallable.create(settings.publishSettings(), settings); + if (settings.publishSettings().getBundlerFactory() != null) { + closeables.add(settings.publishSettings().getBundlerFactory()); } - this.getTopicCallable = settings.getTopicMethod().build(settings); - this.listTopicsCallable = settings.listTopicsMethod().build(settings); - this.listTopicsIterableCallable = settings.listTopicsMethod().buildPageStreaming(settings); - this.listTopicSubscriptionsCallable = settings.listTopicSubscriptionsMethod().build(settings); + this.getTopicCallable = ApiCallable.create(settings.getTopicSettings(), settings); + this.listTopicsCallable = ApiCallable.create(settings.listTopicsSettings(), settings); + this.listTopicsIterableCallable = + ApiCallable.createIterable(settings.listTopicsSettings(), settings); + this.listTopicSubscriptionsCallable = + ApiCallable.create(settings.listTopicSubscriptionsSettings(), settings); this.listTopicSubscriptionsIterableCallable = - settings.listTopicSubscriptionsMethod().buildPageStreaming(settings); - this.deleteTopicCallable = settings.deleteTopicMethod().build(settings); + ApiCallable.createIterable(settings.listTopicSubscriptionsSettings(), settings); + this.deleteTopicCallable = ApiCallable.create(settings.deleteTopicSettings(), settings); if (settings.shouldAutoCloseChannel()) { closeables.add( @@ -231,6 +213,7 @@ public void close() throws IOException { * underscores (`_`), periods (`.`), tildes (`~`), plus (`+`) or percent * signs (`%`). It must be between 3 and 255 characters in length, and it * must not start with `"goog"`. + * @throws ApiException if the remote call fails */ public final Topic createTopic(String name) { Topic request = Topic.newBuilder().setName(name).build(); @@ -246,6 +229,7 @@ public final Topic createTopic(String name) { * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ private Topic createTopic(Topic request) { return createTopicCallable().call(request); @@ -257,6 +241,7 @@ private Topic createTopic(Topic request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable createTopicCallable() { return createTopicCallable; @@ -275,6 +260,7 @@ public final ApiCallable createTopicCallable() { * * @param topic The messages in the request will be published on this topic. * @param messages The messages to publish. + * @throws ApiException if the remote call fails */ public final PublishResponse publish(String topic, List messages) { PublishRequest request = @@ -293,6 +279,7 @@ public final PublishResponse publish(String topic, List messages) * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ public PublishResponse publish(PublishRequest request) { return publishCallable().call(request); @@ -306,6 +293,7 @@ public PublishResponse publish(PublishRequest request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable publishCallable() { return publishCallable; @@ -321,6 +309,7 @@ public final ApiCallable publishCallable() { * * * @param topic The name of the topic to get. + * @throws ApiException if the remote call fails */ public final Topic getTopic(String topic) { GetTopicRequest request = GetTopicRequest.newBuilder().setTopic(topic).build(); @@ -336,6 +325,7 @@ public final Topic getTopic(String topic) { * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ private Topic getTopic(GetTopicRequest request) { return getTopicCallable().call(request); @@ -347,6 +337,7 @@ private Topic getTopic(GetTopicRequest request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable getTopicCallable() { return getTopicCallable; @@ -360,6 +351,9 @@ public final ApiCallable getTopicCallable() { * * * + * + * @param project The name of the cloud project that topics belong to. + * @throws ApiException if the remote call fails */ public final Iterable listTopics(String project) { ListTopicsRequest request = ListTopicsRequest.newBuilder().setProject(project).build(); @@ -374,6 +368,7 @@ public final Iterable listTopics(String project) { * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ public final Iterable listTopics(ListTopicsRequest request) { return listTopicsIterableCallable().call(request); @@ -385,6 +380,7 @@ public final Iterable listTopics(ListTopicsRequest request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable> listTopicsIterableCallable() { return listTopicsIterableCallable; @@ -396,6 +392,7 @@ public final ApiCallable> listTopicsIterableC * * * + * @throws ApiException if the remote call fails */ public final ApiCallable listTopicsCallable() { return listTopicsCallable; @@ -409,6 +406,9 @@ public final ApiCallable listTopicsCallab * * * + * + * @param topic The name of the topic that subscriptions are attached to. + * @throws ApiException if the remote call fails */ public final Iterable listTopicSubscriptions(String topic) { ListTopicSubscriptionsRequest request = @@ -424,6 +424,7 @@ public final Iterable listTopicSubscriptions(String topic) { * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ public final Iterable listTopicSubscriptions(ListTopicSubscriptionsRequest request) { return listTopicSubscriptionsIterableCallable().call(request); @@ -435,6 +436,7 @@ public final Iterable listTopicSubscriptions(ListTopicSubscriptionsReque * * * + * @throws ApiException if the remote call fails */ public final ApiCallable> listTopicSubscriptionsIterableCallable() { @@ -447,6 +449,7 @@ public final Iterable listTopicSubscriptions(ListTopicSubscriptionsReque * * * + * @throws ApiException if the remote call fails */ public final ApiCallable listTopicSubscriptionsCallable() { @@ -467,6 +470,7 @@ public final Iterable listTopicSubscriptions(ListTopicSubscriptionsReque * * * @param topic Name of the topic to delete. + * @throws ApiException if the remote call fails */ public final void deleteTopic(String topic) { DeleteTopicRequest request = DeleteTopicRequest.newBuilder().setTopic(topic).build(); @@ -486,6 +490,7 @@ public final void deleteTopic(String topic) { * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ private void deleteTopic(DeleteTopicRequest request) { deleteTopicCallable().call(request); @@ -501,6 +506,7 @@ private void deleteTopic(DeleteTopicRequest request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable deleteTopicCallable() { return deleteTopicCallable; diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java index 8b3d434b8e49..11c709024144 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java @@ -33,19 +33,17 @@ package com.google.gcloud.pubsub.spi.v1; -import com.google.api.gax.core.BackoffParams; import com.google.api.gax.core.ConnectionSettings; -import com.google.api.gax.core.RetryParams; +import com.google.api.gax.core.RetrySettings; import com.google.api.gax.grpc.ApiCallSettings; -import com.google.api.gax.grpc.ApiCallable; -import com.google.api.gax.grpc.ApiCallable.Builder; -import com.google.api.gax.grpc.ApiCallable.BundlableBuilder; -import com.google.api.gax.grpc.ApiCallable.PageStreamingBuilder; +import com.google.api.gax.grpc.BundlingCallSettings; import com.google.api.gax.grpc.BundlingDescriptor; import com.google.api.gax.grpc.BundlingSettings; +import com.google.api.gax.grpc.PageStreamingCallSettings; import com.google.api.gax.grpc.PageStreamingDescriptor; import com.google.api.gax.grpc.RequestIssuer; import com.google.api.gax.grpc.ServiceApiSettings; +import com.google.api.gax.grpc.SimpleCallSettings; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; @@ -63,10 +61,13 @@ import com.google.pubsub.v1.PublisherGrpc; import com.google.pubsub.v1.PubsubMessage; import com.google.pubsub.v1.Topic; +import io.grpc.ManagedChannel; import io.grpc.Status; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.concurrent.ScheduledExecutorService; import org.joda.time.Duration; // Manually-added imports: add custom (non-generated) imports after this point. @@ -100,202 +101,74 @@ public class PublisherSettings extends ServiceApiSettings { .add("https://www.googleapis.com/auth/cloud-platform") .build(); - private static final ImmutableMap> RETRYABLE_CODE_DEFINITIONS; - - static { - ImmutableMap.Builder> definitions = ImmutableMap.builder(); - definitions.put( - "idempotent", - Sets.immutableEnumSet( - Lists.newArrayList( - Status.Code.DEADLINE_EXCEEDED, Status.Code.UNAVAILABLE))); - definitions.put("non_idempotent", Sets.immutableEnumSet(Lists.newArrayList())); - RETRYABLE_CODE_DEFINITIONS = definitions.build(); - } + private final SimpleCallSettings createTopicSettings; + private final BundlingCallSettings publishSettings; + private final SimpleCallSettings getTopicSettings; + private final PageStreamingCallSettings + listTopicsSettings; - private static final ImmutableMap RETRY_PARAM_DEFINITIONS; - - static { - ImmutableMap.Builder definitions = ImmutableMap.builder(); - RetryParams params = null; - params = - RetryParams.newBuilder() - .setRetryBackoff( - BackoffParams.newBuilder() - .setInitialDelay(Duration.millis(100L)) - .setDelayMultiplier(1.2) - .setMaxDelay(Duration.millis(1000L)) - .build()) - .setTimeoutBackoff( - BackoffParams.newBuilder() - .setInitialDelay(Duration.millis(2000L)) - .setDelayMultiplier(1.5) - .setMaxDelay(Duration.millis(30000L)) - .build()) - .setTotalTimeout(Duration.millis(45000L)) - .build(); - definitions.put("default", params); - RETRY_PARAM_DEFINITIONS = definitions.build(); - } + private final PageStreamingCallSettings< + ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> + listTopicSubscriptionsSettings; - private final MethodBuilders methods; + private final SimpleCallSettings deleteTopicSettings; - private static class MethodBuilders { - private final ApiCallable.Builder createTopicMethod; - private final ApiCallable.BundlableBuilder publishMethod; - private final ApiCallable.Builder getTopicMethod; - private final ApiCallable.PageStreamingBuilder - listTopicsMethod; - private final ApiCallable.PageStreamingBuilder< - ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> - listTopicSubscriptionsMethod; - private final ApiCallable.Builder deleteTopicMethod; - private final ImmutableList allMethods; - - public MethodBuilders() { - createTopicMethod = new Builder<>(PublisherGrpc.METHOD_CREATE_TOPIC); - createTopicMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); - createTopicMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + public SimpleCallSettings createTopicSettings() { + return createTopicSettings; + } - BundlingSettings publishBundlingSettings = - BundlingSettings.newBuilder() - .setElementCountThreshold(800) - .setElementCountLimit(1000) - .setRequestByteThreshold(8388608) - .setRequestByteLimit(10485760) - .setDelayThreshold(Duration.millis(100)) - .setBlockingCallCountThreshold(1) - .build(); - publishMethod = - new BundlableBuilder<>( - PublisherGrpc.METHOD_PUBLISH, PUBLISH_BUNDLING_DESC, publishBundlingSettings); - publishMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); - publishMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - getTopicMethod = new Builder<>(PublisherGrpc.METHOD_GET_TOPIC); - getTopicMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); - getTopicMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - listTopicsMethod = - new PageStreamingBuilder<>(PublisherGrpc.METHOD_LIST_TOPICS, LIST_TOPICS_PAGE_STR_DESC); - listTopicsMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); - listTopicsMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - listTopicSubscriptionsMethod = - new PageStreamingBuilder<>( - PublisherGrpc.METHOD_LIST_TOPIC_SUBSCRIPTIONS, - LIST_TOPIC_SUBSCRIPTIONS_PAGE_STR_DESC); - listTopicSubscriptionsMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); - listTopicSubscriptionsMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - deleteTopicMethod = new Builder<>(PublisherGrpc.METHOD_DELETE_TOPIC); - deleteTopicMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); - deleteTopicMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - allMethods = - ImmutableList.builder() - .add( - createTopicMethod, - publishMethod, - getTopicMethod, - listTopicsMethod, - listTopicSubscriptionsMethod, - deleteTopicMethod) - .build(); - } + public BundlingCallSettings publishSettings() { + return publishSettings; } - /** - * Constructs an instance of PublisherSettings with default settings. - * - * - * - */ - public static PublisherSettings create() { - PublisherSettings settings = new PublisherSettings(new MethodBuilders()); - settings.provideChannelWith( - ConnectionSettings.builder() - .setServiceAddress(DEFAULT_SERVICE_ADDRESS) - .setPort(DEFAULT_SERVICE_PORT) - .provideCredentialsWith(DEFAULT_SERVICE_SCOPES) - .build()); - return settings; + public SimpleCallSettings getTopicSettings() { + return getTopicSettings; } - /** - * Constructs an instance of PublisherSettings with default settings. This is protected - * so that it easy to make a subclass, but otherwise, the static factory methods should be - * preferred. - * - * - * - */ - protected PublisherSettings(MethodBuilders methods) { - super(methods.allMethods); - this.methods = methods; + public PageStreamingCallSettings + listTopicsSettings() { + return listTopicsSettings; } - /** - * Returns the builder for the API method createTopic. - * - * - * - */ - public final ApiCallable.Builder createTopicMethod() { - return methods.createTopicMethod; + public PageStreamingCallSettings< + ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> + listTopicSubscriptionsSettings() { + return listTopicSubscriptionsSettings; } - /** - * Returns the builder for the API method publish. - * - * - * - */ - public final ApiCallable.BundlableBuilder publishMethod() { - return methods.publishMethod; + public SimpleCallSettings deleteTopicSettings() { + return deleteTopicSettings; } - /** - * Returns the builder for the API method getTopic. - * - * - * - */ - public final ApiCallable.Builder getTopicMethod() { - return methods.getTopicMethod; + public static PublisherSettings defaultInstance() throws IOException { + return newBuilder().build(); } - /** - * Returns the builder for the API method listTopics. - * - * - * - */ - public final ApiCallable.PageStreamingBuilder - listTopicsMethod() { - return methods.listTopicsMethod; + public static Builder newBuilder() { + return new Builder(); } - /** - * Returns the builder for the API method listTopicSubscriptions. - * - * - * - */ - public final ApiCallable.PageStreamingBuilder< - ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> - listTopicSubscriptionsMethod() { - return methods.listTopicSubscriptionsMethod; + public Builder toBuilder() { + return new Builder(this); } - /** - * Returns the builder for the API method deleteTopic. - * - * - * - */ - public final ApiCallable.Builder deleteTopicMethod() { - return methods.deleteTopicMethod; + private PublisherSettings(Builder settingsBuilder) throws IOException { + super( + settingsBuilder.getOrBuildChannel(), + settingsBuilder.shouldAutoCloseChannel(), + settingsBuilder.getOrBuildExecutor(), + settingsBuilder.getConnectionSettings(), + settingsBuilder.getGeneratorName(), + settingsBuilder.getGeneratorVersion(), + settingsBuilder.getClientLibName(), + settingsBuilder.getClientLibVersion()); + + createTopicSettings = settingsBuilder.createTopicSettings().build(); + publishSettings = settingsBuilder.publishSettings().build(); + getTopicSettings = settingsBuilder.getTopicSettings().build(); + listTopicsSettings = settingsBuilder.listTopicsSettings().build(); + listTopicSubscriptionsSettings = settingsBuilder.listTopicSubscriptionsSettings().build(); + deleteTopicSettings = settingsBuilder.deleteTopicSettings().build(); } private static PageStreamingDescriptor @@ -412,4 +285,196 @@ public long countBytes(PublishRequest request) { return request.getSerializedSize(); } }; + + public static class Builder extends ServiceApiSettings.Builder { + private final ImmutableList methodSettingsBuilders; + + private SimpleCallSettings.Builder createTopicSettings; + private BundlingCallSettings.Builder publishSettings; + private SimpleCallSettings.Builder getTopicSettings; + private PageStreamingCallSettings.Builder + listTopicsSettings; + private PageStreamingCallSettings.Builder< + ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> + listTopicSubscriptionsSettings; + private SimpleCallSettings.Builder deleteTopicSettings; + + private static final ImmutableMap> RETRYABLE_CODE_DEFINITIONS; + + static { + ImmutableMap.Builder> definitions = ImmutableMap.builder(); + definitions.put( + "idempotent", + Sets.immutableEnumSet( + Lists.newArrayList( + Status.Code.DEADLINE_EXCEEDED, Status.Code.UNAVAILABLE))); + definitions.put("non_idempotent", Sets.immutableEnumSet(Lists.newArrayList())); + RETRYABLE_CODE_DEFINITIONS = definitions.build(); + } + + private static final ImmutableMap RETRY_PARAM_DEFINITIONS; + + static { + ImmutableMap.Builder definitions = ImmutableMap.builder(); + RetrySettings.Builder settingsBuilder = null; + settingsBuilder = + RetrySettings.newBuilder() + .setInitialRetryDelay(Duration.millis(100L)) + .setRetryDelayMultiplier(1.2) + .setMaxRetryDelay(Duration.millis(1000L)) + .setInitialRpcTimeout(Duration.millis(2000L)) + .setRpcTimeoutMultiplier(1.5) + .setMaxRpcTimeout(Duration.millis(30000L)) + .setTotalTimeout(Duration.millis(45000L)); + definitions.put("default", settingsBuilder); + RETRY_PARAM_DEFINITIONS = definitions.build(); + } + + private Builder() { + super( + ConnectionSettings.builder() + .setServiceAddress(DEFAULT_SERVICE_ADDRESS) + .setPort(DEFAULT_SERVICE_PORT) + .provideCredentialsWith(DEFAULT_SERVICE_SCOPES) + .build()); + + createTopicSettings = + SimpleCallSettings.newBuilder(PublisherGrpc.METHOD_CREATE_TOPIC) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + BundlingSettings.Builder publishBundlingSettingsBuilder = + BundlingSettings.newBuilder() + .setElementCountThreshold(800) + .setElementCountLimit(1000) + .setRequestByteThreshold(8388608) + .setRequestByteLimit(10485760) + .setDelayThreshold(Duration.millis(100)) + .setBlockingCallCountThreshold(1); + publishSettings = + BundlingCallSettings.newBuilder(PublisherGrpc.METHOD_PUBLISH, PUBLISH_BUNDLING_DESC) + .setBundlingSettingsBuilder(publishBundlingSettingsBuilder) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + getTopicSettings = + SimpleCallSettings.newBuilder(PublisherGrpc.METHOD_GET_TOPIC) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + listTopicsSettings = + PageStreamingCallSettings.newBuilder( + PublisherGrpc.METHOD_LIST_TOPICS, LIST_TOPICS_PAGE_STR_DESC) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + listTopicSubscriptionsSettings = + PageStreamingCallSettings.newBuilder( + PublisherGrpc.METHOD_LIST_TOPIC_SUBSCRIPTIONS, + LIST_TOPIC_SUBSCRIPTIONS_PAGE_STR_DESC) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + deleteTopicSettings = + SimpleCallSettings.newBuilder(PublisherGrpc.METHOD_DELETE_TOPIC) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + methodSettingsBuilders = + ImmutableList.of( + createTopicSettings, + publishSettings, + getTopicSettings, + listTopicsSettings, + listTopicSubscriptionsSettings, + deleteTopicSettings); + } + + private Builder(PublisherSettings settings) { + super(settings); + + createTopicSettings = settings.createTopicSettings.toBuilder(); + publishSettings = settings.publishSettings.toBuilder(); + getTopicSettings = settings.getTopicSettings.toBuilder(); + listTopicsSettings = settings.listTopicsSettings.toBuilder(); + listTopicSubscriptionsSettings = settings.listTopicSubscriptionsSettings.toBuilder(); + deleteTopicSettings = settings.deleteTopicSettings.toBuilder(); + + methodSettingsBuilders = + ImmutableList.of( + createTopicSettings, + publishSettings, + getTopicSettings, + listTopicsSettings, + listTopicSubscriptionsSettings, + deleteTopicSettings); + } + + @Override + public Builder provideChannelWith(ManagedChannel channel, boolean shouldAutoClose) { + super.provideChannelWith(channel, shouldAutoClose); + return this; + } + + @Override + public Builder provideChannelWith(ConnectionSettings settings) { + super.provideChannelWith(settings); + return this; + } + + @Override + public Builder setExecutor(ScheduledExecutorService executor) { + super.setExecutor(executor); + return this; + } + + @Override + public Builder setGeneratorHeader(String name, String version) { + super.setGeneratorHeader(name, version); + return this; + } + + @Override + public Builder setClientLibHeader(String name, String version) { + super.setClientLibHeader(name, version); + return this; + } + + public Builder applyToAllApiMethods(ApiCallSettings.Builder apiCallSettings) throws Exception { + super.applyToAllApiMethods(methodSettingsBuilders, apiCallSettings); + return this; + } + + public SimpleCallSettings.Builder createTopicSettings() { + return createTopicSettings; + } + + public BundlingCallSettings.Builder publishSettings() { + return publishSettings; + } + + public SimpleCallSettings.Builder getTopicSettings() { + return getTopicSettings; + } + + public PageStreamingCallSettings.Builder + listTopicsSettings() { + return listTopicsSettings; + } + + public PageStreamingCallSettings.Builder< + ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> + listTopicSubscriptionsSettings() { + return listTopicSubscriptionsSettings; + } + + public SimpleCallSettings.Builder deleteTopicSettings() { + return deleteTopicSettings; + } + + @Override + public PublisherSettings build() throws IOException { + return new PublisherSettings(this); + } + } } diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java index 3040af41efd8..17c1dfdf0c37 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java @@ -80,23 +80,9 @@ public class SubscriberApi implements AutoCloseable { private final ApiCallable pullCallable; private final ApiCallable modifyPushConfigCallable; - /** - * A PathTemplate representing the fully-qualified path to represent - * a project resource. - * - * - * - */ private static final PathTemplate PROJECT_PATH_TEMPLATE = PathTemplate.create("projects/{project}"); - /** - * A PathTemplate representing the fully-qualified path to represent - * a subscription resource. - * - * - * - */ private static final PathTemplate SUBSCRIPTION_PATH_TEMPLATE = PathTemplate.create("projects/{project}/subscriptions/{subscription}"); @@ -161,8 +147,8 @@ public static final String parseSubscriptionFromSubscriptionName(String subscrip * * */ - public static final SubscriberApi create() throws IOException { - return create(SubscriberSettings.create()); + public static final SubscriberApi defaultInstance() throws IOException { + return create(SubscriberSettings.defaultInstance()); } /** @@ -188,16 +174,21 @@ public static final SubscriberApi create(SubscriberSettings settings) throws IOE protected SubscriberApi(SubscriberSettings settings) throws IOException { this.channel = settings.getChannel(); - this.createSubscriptionCallable = settings.createSubscriptionMethod().build(settings); - this.getSubscriptionCallable = settings.getSubscriptionMethod().build(settings); - this.listSubscriptionsCallable = settings.listSubscriptionsMethod().build(settings); + this.createSubscriptionCallable = + ApiCallable.create(settings.createSubscriptionSettings(), settings); + this.getSubscriptionCallable = ApiCallable.create(settings.getSubscriptionSettings(), settings); + this.listSubscriptionsCallable = + ApiCallable.create(settings.listSubscriptionsSettings(), settings); this.listSubscriptionsIterableCallable = - settings.listSubscriptionsMethod().buildPageStreaming(settings); - this.deleteSubscriptionCallable = settings.deleteSubscriptionMethod().build(settings); - this.modifyAckDeadlineCallable = settings.modifyAckDeadlineMethod().build(settings); - this.acknowledgeCallable = settings.acknowledgeMethod().build(settings); - this.pullCallable = settings.pullMethod().build(settings); - this.modifyPushConfigCallable = settings.modifyPushConfigMethod().build(settings); + ApiCallable.createIterable(settings.listSubscriptionsSettings(), settings); + this.deleteSubscriptionCallable = + ApiCallable.create(settings.deleteSubscriptionSettings(), settings); + this.modifyAckDeadlineCallable = + ApiCallable.create(settings.modifyAckDeadlineSettings(), settings); + this.acknowledgeCallable = ApiCallable.create(settings.acknowledgeSettings(), settings); + this.pullCallable = ApiCallable.create(settings.pullSettings(), settings); + this.modifyPushConfigCallable = + ApiCallable.create(settings.modifyPushConfigSettings(), settings); if (settings.shouldAutoCloseChannel()) { closeables.add( @@ -252,6 +243,7 @@ public void close() throws IOException { * system will eventually redeliver the message. * * If this parameter is not set, the default value of 10 seconds is used. + * @throws ApiException if the remote call fails */ public final Subscription createSubscription( String name, String topic, PushConfig pushConfig, int ackDeadlineSeconds) { @@ -279,6 +271,7 @@ public final Subscription createSubscription( * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ public Subscription createSubscription(Subscription request) { return createSubscriptionCallable().call(request); @@ -295,6 +288,7 @@ public Subscription createSubscription(Subscription request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable createSubscriptionCallable() { return createSubscriptionCallable; @@ -313,6 +307,7 @@ public final ApiCallable createSubscriptionCallable( * * * @param subscription The name of the subscription to get. + * @throws ApiException if the remote call fails */ public final Subscription getSubscription(String subscription) { GetSubscriptionRequest request = @@ -332,6 +327,7 @@ public final Subscription getSubscription(String subscription) { * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ private Subscription getSubscription(GetSubscriptionRequest request) { return getSubscriptionCallable().call(request); @@ -346,6 +342,7 @@ private Subscription getSubscription(GetSubscriptionRequest request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable getSubscriptionCallable() { return getSubscriptionCallable; @@ -362,6 +359,9 @@ public final ApiCallable getSubscriptionCa * * * + * + * @param project The name of the cloud project that subscriptions belong to. + * @throws ApiException if the remote call fails */ public final Iterable listSubscriptions(String project) { ListSubscriptionsRequest request = @@ -380,6 +380,7 @@ public final Iterable listSubscriptions(String project) { * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ public final Iterable listSubscriptions(ListSubscriptionsRequest request) { return listSubscriptionsIterableCallable().call(request); @@ -394,6 +395,7 @@ public final Iterable listSubscriptions(ListSubscriptionsRequest r * * * + * @throws ApiException if the remote call fails */ public final ApiCallable> listSubscriptionsIterableCallable() { @@ -409,6 +411,7 @@ public final Iterable listSubscriptions(ListSubscriptionsRequest r * * * + * @throws ApiException if the remote call fails */ public final ApiCallable listSubscriptionsCallable() { @@ -429,6 +432,7 @@ public final Iterable listSubscriptions(ListSubscriptionsRequest r * * * @param subscription The subscription to delete. + * @throws ApiException if the remote call fails */ public final void deleteSubscription(String subscription) { DeleteSubscriptionRequest request = @@ -449,6 +453,7 @@ public final void deleteSubscription(String subscription) { * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ private void deleteSubscription(DeleteSubscriptionRequest request) { deleteSubscriptionCallable().call(request); @@ -464,6 +469,7 @@ private void deleteSubscription(DeleteSubscriptionRequest request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable deleteSubscriptionCallable() { return deleteSubscriptionCallable; @@ -484,10 +490,11 @@ public final ApiCallable deleteSubscriptionCal * @param subscription The name of the subscription. * @param ackIds List of acknowledgment IDs. * @param ackDeadlineSeconds The new ack deadline with respect to the time this request was sent to - * the Pub/Sub system. Must be >= 0. For example, if the value is 10, the new + * the Pub/Sub system. Must be >= 0. For example, if the value is 10, the new * ack deadline will expire 10 seconds after the `ModifyAckDeadline` call * was made. Specifying zero may immediately make the message available for * another pull request. + * @throws ApiException if the remote call fails */ public final void modifyAckDeadline( String subscription, List ackIds, int ackDeadlineSeconds) { @@ -512,6 +519,7 @@ public final void modifyAckDeadline( * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ public void modifyAckDeadline(ModifyAckDeadlineRequest request) { modifyAckDeadlineCallable().call(request); @@ -526,6 +534,7 @@ public void modifyAckDeadline(ModifyAckDeadlineRequest request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable modifyAckDeadlineCallable() { return modifyAckDeadlineCallable; @@ -549,6 +558,7 @@ public final ApiCallable modifyAckDeadlineCalla * @param subscription The subscription whose message is being acknowledged. * @param ackIds The acknowledgment ID for the messages being acknowledged that was returned * by the Pub/Sub system in the `Pull` response. Must not be empty. + * @throws ApiException if the remote call fails */ public final void acknowledge(String subscription, List ackIds) { AcknowledgeRequest request = @@ -571,6 +581,7 @@ public final void acknowledge(String subscription, List ackIds) { * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ public void acknowledge(AcknowledgeRequest request) { acknowledgeCallable().call(request); @@ -588,6 +599,7 @@ public void acknowledge(AcknowledgeRequest request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable acknowledgeCallable() { return acknowledgeCallable; @@ -612,6 +624,7 @@ public final ApiCallable acknowledgeCallable() { * than returning no messages. * @param maxMessages The maximum number of messages returned for this request. The Pub/Sub * system may return fewer than the number specified. + * @throws ApiException if the remote call fails */ public final PullResponse pull(String subscription, boolean returnImmediately, int maxMessages) { PullRequest request = @@ -635,6 +648,7 @@ public final PullResponse pull(String subscription, boolean returnImmediately, i * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ public PullResponse pull(PullRequest request) { return pullCallable().call(request); @@ -649,6 +663,7 @@ public PullResponse pull(PullRequest request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable pullCallable() { return pullCallable; @@ -675,6 +690,7 @@ public final ApiCallable pullCallable() { * stop pushing messages from the given subscription and allow * messages to be pulled and acknowledged - effectively pausing * the subscription if `Pull` is not called. + * @throws ApiException if the remote call fails */ public final void modifyPushConfig(String subscription, PushConfig pushConfig) { ModifyPushConfigRequest request = @@ -699,6 +715,7 @@ public final void modifyPushConfig(String subscription, PushConfig pushConfig) { * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ public void modifyPushConfig(ModifyPushConfigRequest request) { modifyPushConfigCallable().call(request); @@ -715,6 +732,7 @@ public void modifyPushConfig(ModifyPushConfigRequest request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable modifyPushConfigCallable() { return modifyPushConfigCallable; diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java index e0204a4171f8..918ec77e9f04 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java @@ -33,15 +33,13 @@ package com.google.gcloud.pubsub.spi.v1; -import com.google.api.gax.core.BackoffParams; import com.google.api.gax.core.ConnectionSettings; -import com.google.api.gax.core.RetryParams; +import com.google.api.gax.core.RetrySettings; import com.google.api.gax.grpc.ApiCallSettings; -import com.google.api.gax.grpc.ApiCallable; -import com.google.api.gax.grpc.ApiCallable.Builder; -import com.google.api.gax.grpc.ApiCallable.PageStreamingBuilder; +import com.google.api.gax.grpc.PageStreamingCallSettings; import com.google.api.gax.grpc.PageStreamingDescriptor; import com.google.api.gax.grpc.ServiceApiSettings; +import com.google.api.gax.grpc.SimpleCallSettings; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; @@ -59,7 +57,10 @@ import com.google.pubsub.v1.PullResponse; import com.google.pubsub.v1.SubscriberGrpc; import com.google.pubsub.v1.Subscription; +import io.grpc.ManagedChannel; import io.grpc.Status; +import java.io.IOException; +import java.util.concurrent.ScheduledExecutorService; import org.joda.time.Duration; // Manually-added imports: add custom (non-generated) imports after this point. @@ -93,219 +94,83 @@ public class SubscriberSettings extends ServiceApiSettings { .add("https://www.googleapis.com/auth/cloud-platform") .build(); - private static final ImmutableMap> RETRYABLE_CODE_DEFINITIONS; - - static { - ImmutableMap.Builder> definitions = ImmutableMap.builder(); - definitions.put( - "idempotent", - Sets.immutableEnumSet( - Lists.newArrayList( - Status.Code.DEADLINE_EXCEEDED, Status.Code.UNAVAILABLE))); - definitions.put("non_idempotent", Sets.immutableEnumSet(Lists.newArrayList())); - RETRYABLE_CODE_DEFINITIONS = definitions.build(); - } + private final SimpleCallSettings createSubscriptionSettings; + private final SimpleCallSettings getSubscriptionSettings; + private final PageStreamingCallSettings< + ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> + listSubscriptionsSettings; - private static final ImmutableMap RETRY_PARAM_DEFINITIONS; - - static { - ImmutableMap.Builder definitions = ImmutableMap.builder(); - RetryParams params = null; - params = - RetryParams.newBuilder() - .setRetryBackoff( - BackoffParams.newBuilder() - .setInitialDelay(Duration.millis(100L)) - .setDelayMultiplier(1.2) - .setMaxDelay(Duration.millis(1000L)) - .build()) - .setTimeoutBackoff( - BackoffParams.newBuilder() - .setInitialDelay(Duration.millis(2000L)) - .setDelayMultiplier(1.5) - .setMaxDelay(Duration.millis(30000L)) - .build()) - .setTotalTimeout(Duration.millis(45000L)) - .build(); - definitions.put("default", params); - RETRY_PARAM_DEFINITIONS = definitions.build(); - } + private final SimpleCallSettings deleteSubscriptionSettings; + private final SimpleCallSettings modifyAckDeadlineSettings; + private final SimpleCallSettings acknowledgeSettings; + private final SimpleCallSettings pullSettings; + private final SimpleCallSettings modifyPushConfigSettings; - private final MethodBuilders methods; + public SimpleCallSettings createSubscriptionSettings() { + return createSubscriptionSettings; + } - private static class MethodBuilders { - private final ApiCallable.Builder createSubscriptionMethod; - private final ApiCallable.Builder getSubscriptionMethod; - private final ApiCallable.PageStreamingBuilder< - ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> - listSubscriptionsMethod; - private final ApiCallable.Builder deleteSubscriptionMethod; - private final ApiCallable.Builder modifyAckDeadlineMethod; - private final ApiCallable.Builder acknowledgeMethod; - private final ApiCallable.Builder pullMethod; - private final ApiCallable.Builder modifyPushConfigMethod; - private final ImmutableList allMethods; - - public MethodBuilders() { - createSubscriptionMethod = new Builder<>(SubscriberGrpc.METHOD_CREATE_SUBSCRIPTION); - createSubscriptionMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); - createSubscriptionMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - getSubscriptionMethod = new Builder<>(SubscriberGrpc.METHOD_GET_SUBSCRIPTION); - getSubscriptionMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); - getSubscriptionMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - listSubscriptionsMethod = - new PageStreamingBuilder<>( - SubscriberGrpc.METHOD_LIST_SUBSCRIPTIONS, LIST_SUBSCRIPTIONS_PAGE_STR_DESC); - listSubscriptionsMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); - listSubscriptionsMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - deleteSubscriptionMethod = new Builder<>(SubscriberGrpc.METHOD_DELETE_SUBSCRIPTION); - deleteSubscriptionMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); - deleteSubscriptionMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - modifyAckDeadlineMethod = new Builder<>(SubscriberGrpc.METHOD_MODIFY_ACK_DEADLINE); - modifyAckDeadlineMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); - modifyAckDeadlineMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - acknowledgeMethod = new Builder<>(SubscriberGrpc.METHOD_ACKNOWLEDGE); - acknowledgeMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); - acknowledgeMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - pullMethod = new Builder<>(SubscriberGrpc.METHOD_PULL); - pullMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); - pullMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - modifyPushConfigMethod = new Builder<>(SubscriberGrpc.METHOD_MODIFY_PUSH_CONFIG); - modifyPushConfigMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); - modifyPushConfigMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - allMethods = - ImmutableList.builder() - .add( - createSubscriptionMethod, - getSubscriptionMethod, - listSubscriptionsMethod, - deleteSubscriptionMethod, - modifyAckDeadlineMethod, - acknowledgeMethod, - pullMethod, - modifyPushConfigMethod) - .build(); - } + public SimpleCallSettings getSubscriptionSettings() { + return getSubscriptionSettings; } - /** - * Constructs an instance of SubscriberSettings with default settings. - * - * - * - */ - public static SubscriberSettings create() { - SubscriberSettings settings = new SubscriberSettings(new MethodBuilders()); - settings.provideChannelWith( - ConnectionSettings.builder() - .setServiceAddress(DEFAULT_SERVICE_ADDRESS) - .setPort(DEFAULT_SERVICE_PORT) - .provideCredentialsWith(DEFAULT_SERVICE_SCOPES) - .build()); - return settings; + public PageStreamingCallSettings< + ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> + listSubscriptionsSettings() { + return listSubscriptionsSettings; } - /** - * Constructs an instance of SubscriberSettings with default settings. This is protected - * so that it easy to make a subclass, but otherwise, the static factory methods should be - * preferred. - * - * - * - */ - protected SubscriberSettings(MethodBuilders methods) { - super(methods.allMethods); - this.methods = methods; + public SimpleCallSettings deleteSubscriptionSettings() { + return deleteSubscriptionSettings; } - /** - * Returns the builder for the API method createSubscription. - * - * - * - */ - public final ApiCallable.Builder createSubscriptionMethod() { - return methods.createSubscriptionMethod; + public SimpleCallSettings modifyAckDeadlineSettings() { + return modifyAckDeadlineSettings; } - /** - * Returns the builder for the API method getSubscription. - * - * - * - */ - public final ApiCallable.Builder getSubscriptionMethod() { - return methods.getSubscriptionMethod; + public SimpleCallSettings acknowledgeSettings() { + return acknowledgeSettings; } - /** - * Returns the builder for the API method listSubscriptions. - * - * - * - */ - public final ApiCallable.PageStreamingBuilder< - ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> - listSubscriptionsMethod() { - return methods.listSubscriptionsMethod; + public SimpleCallSettings pullSettings() { + return pullSettings; } - /** - * Returns the builder for the API method deleteSubscription. - * - * - * - */ - public final ApiCallable.Builder deleteSubscriptionMethod() { - return methods.deleteSubscriptionMethod; + public SimpleCallSettings modifyPushConfigSettings() { + return modifyPushConfigSettings; } - /** - * Returns the builder for the API method modifyAckDeadline. - * - * - * - */ - public final ApiCallable.Builder modifyAckDeadlineMethod() { - return methods.modifyAckDeadlineMethod; + public static SubscriberSettings defaultInstance() throws IOException { + return newBuilder().build(); } - /** - * Returns the builder for the API method acknowledge. - * - * - * - */ - public final ApiCallable.Builder acknowledgeMethod() { - return methods.acknowledgeMethod; + public static Builder newBuilder() { + return new Builder(); } - /** - * Returns the builder for the API method pull. - * - * - * - */ - public final ApiCallable.Builder pullMethod() { - return methods.pullMethod; + public Builder toBuilder() { + return new Builder(this); } - /** - * Returns the builder for the API method modifyPushConfig. - * - * - * - */ - public final ApiCallable.Builder modifyPushConfigMethod() { - return methods.modifyPushConfigMethod; + private SubscriberSettings(Builder settingsBuilder) throws IOException { + super( + settingsBuilder.getOrBuildChannel(), + settingsBuilder.shouldAutoCloseChannel(), + settingsBuilder.getOrBuildExecutor(), + settingsBuilder.getConnectionSettings(), + settingsBuilder.getGeneratorName(), + settingsBuilder.getGeneratorVersion(), + settingsBuilder.getClientLibName(), + settingsBuilder.getClientLibVersion()); + + createSubscriptionSettings = settingsBuilder.createSubscriptionSettings().build(); + getSubscriptionSettings = settingsBuilder.getSubscriptionSettings().build(); + listSubscriptionsSettings = settingsBuilder.listSubscriptionsSettings().build(); + deleteSubscriptionSettings = settingsBuilder.deleteSubscriptionSettings().build(); + modifyAckDeadlineSettings = settingsBuilder.modifyAckDeadlineSettings().build(); + acknowledgeSettings = settingsBuilder.acknowledgeSettings().build(); + pullSettings = settingsBuilder.pullSettings().build(); + modifyPushConfigSettings = settingsBuilder.modifyPushConfigSettings().build(); } private static PageStreamingDescriptor< @@ -336,4 +201,212 @@ public Iterable extractResources(ListSubscriptionsResponse payload return payload.getSubscriptionsList(); } }; + + public static class Builder extends ServiceApiSettings.Builder { + private final ImmutableList methodSettingsBuilders; + + private SimpleCallSettings.Builder createSubscriptionSettings; + private SimpleCallSettings.Builder + getSubscriptionSettings; + private PageStreamingCallSettings.Builder< + ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> + listSubscriptionsSettings; + private SimpleCallSettings.Builder deleteSubscriptionSettings; + private SimpleCallSettings.Builder modifyAckDeadlineSettings; + private SimpleCallSettings.Builder acknowledgeSettings; + private SimpleCallSettings.Builder pullSettings; + private SimpleCallSettings.Builder modifyPushConfigSettings; + + private static final ImmutableMap> RETRYABLE_CODE_DEFINITIONS; + + static { + ImmutableMap.Builder> definitions = ImmutableMap.builder(); + definitions.put( + "idempotent", + Sets.immutableEnumSet( + Lists.newArrayList( + Status.Code.DEADLINE_EXCEEDED, Status.Code.UNAVAILABLE))); + definitions.put("non_idempotent", Sets.immutableEnumSet(Lists.newArrayList())); + RETRYABLE_CODE_DEFINITIONS = definitions.build(); + } + + private static final ImmutableMap RETRY_PARAM_DEFINITIONS; + + static { + ImmutableMap.Builder definitions = ImmutableMap.builder(); + RetrySettings.Builder settingsBuilder = null; + settingsBuilder = + RetrySettings.newBuilder() + .setInitialRetryDelay(Duration.millis(100L)) + .setRetryDelayMultiplier(1.2) + .setMaxRetryDelay(Duration.millis(1000L)) + .setInitialRpcTimeout(Duration.millis(2000L)) + .setRpcTimeoutMultiplier(1.5) + .setMaxRpcTimeout(Duration.millis(30000L)) + .setTotalTimeout(Duration.millis(45000L)); + definitions.put("default", settingsBuilder); + RETRY_PARAM_DEFINITIONS = definitions.build(); + } + + private Builder() { + super( + ConnectionSettings.builder() + .setServiceAddress(DEFAULT_SERVICE_ADDRESS) + .setPort(DEFAULT_SERVICE_PORT) + .provideCredentialsWith(DEFAULT_SERVICE_SCOPES) + .build()); + + createSubscriptionSettings = + SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_CREATE_SUBSCRIPTION) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + getSubscriptionSettings = + SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_GET_SUBSCRIPTION) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + listSubscriptionsSettings = + PageStreamingCallSettings.newBuilder( + SubscriberGrpc.METHOD_LIST_SUBSCRIPTIONS, LIST_SUBSCRIPTIONS_PAGE_STR_DESC) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + deleteSubscriptionSettings = + SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_DELETE_SUBSCRIPTION) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + modifyAckDeadlineSettings = + SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_MODIFY_ACK_DEADLINE) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + acknowledgeSettings = + SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_ACKNOWLEDGE) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + pullSettings = + SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_PULL) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + modifyPushConfigSettings = + SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_MODIFY_PUSH_CONFIG) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + methodSettingsBuilders = + ImmutableList.of( + createSubscriptionSettings, + getSubscriptionSettings, + listSubscriptionsSettings, + deleteSubscriptionSettings, + modifyAckDeadlineSettings, + acknowledgeSettings, + pullSettings, + modifyPushConfigSettings); + } + + private Builder(SubscriberSettings settings) { + super(settings); + + createSubscriptionSettings = settings.createSubscriptionSettings.toBuilder(); + getSubscriptionSettings = settings.getSubscriptionSettings.toBuilder(); + listSubscriptionsSettings = settings.listSubscriptionsSettings.toBuilder(); + deleteSubscriptionSettings = settings.deleteSubscriptionSettings.toBuilder(); + modifyAckDeadlineSettings = settings.modifyAckDeadlineSettings.toBuilder(); + acknowledgeSettings = settings.acknowledgeSettings.toBuilder(); + pullSettings = settings.pullSettings.toBuilder(); + modifyPushConfigSettings = settings.modifyPushConfigSettings.toBuilder(); + + methodSettingsBuilders = + ImmutableList.of( + createSubscriptionSettings, + getSubscriptionSettings, + listSubscriptionsSettings, + deleteSubscriptionSettings, + modifyAckDeadlineSettings, + acknowledgeSettings, + pullSettings, + modifyPushConfigSettings); + } + + @Override + public Builder provideChannelWith(ManagedChannel channel, boolean shouldAutoClose) { + super.provideChannelWith(channel, shouldAutoClose); + return this; + } + + @Override + public Builder provideChannelWith(ConnectionSettings settings) { + super.provideChannelWith(settings); + return this; + } + + @Override + public Builder setExecutor(ScheduledExecutorService executor) { + super.setExecutor(executor); + return this; + } + + @Override + public Builder setGeneratorHeader(String name, String version) { + super.setGeneratorHeader(name, version); + return this; + } + + @Override + public Builder setClientLibHeader(String name, String version) { + super.setClientLibHeader(name, version); + return this; + } + + public Builder applyToAllApiMethods(ApiCallSettings.Builder apiCallSettings) throws Exception { + super.applyToAllApiMethods(methodSettingsBuilders, apiCallSettings); + return this; + } + + public SimpleCallSettings.Builder createSubscriptionSettings() { + return createSubscriptionSettings; + } + + public SimpleCallSettings.Builder + getSubscriptionSettings() { + return getSubscriptionSettings; + } + + public PageStreamingCallSettings.Builder< + ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> + listSubscriptionsSettings() { + return listSubscriptionsSettings; + } + + public SimpleCallSettings.Builder + deleteSubscriptionSettings() { + return deleteSubscriptionSettings; + } + + public SimpleCallSettings.Builder modifyAckDeadlineSettings() { + return modifyAckDeadlineSettings; + } + + public SimpleCallSettings.Builder acknowledgeSettings() { + return acknowledgeSettings; + } + + public SimpleCallSettings.Builder pullSettings() { + return pullSettings; + } + + public SimpleCallSettings.Builder modifyPushConfigSettings() { + return modifyPushConfigSettings; + } + + @Override + public SubscriberSettings build() throws IOException { + return new SubscriberSettings(this); + } + } } diff --git a/gcloud-java-pubsub/pom.xml b/gcloud-java-pubsub/pom.xml index 18738ac989cd..16a82879b9f4 100644 --- a/gcloud-java-pubsub/pom.xml +++ b/gcloud-java-pubsub/pom.xml @@ -21,7 +21,7 @@ com.google.api gax - 0.0.6 + 0.0.9 com.google.api.grpc diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java index 8394e5ae74ed..1d8c00c4e910 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java @@ -34,8 +34,6 @@ package com.google.gcloud.pubsub.spi.v1; import com.google.api.gax.grpc.ApiCallable; -import com.google.api.gax.grpc.ApiCallable.BundlableApiCallableInfo; -import com.google.api.gax.grpc.BundlerFactory; import com.google.api.gax.protobuf.PathTemplate; import com.google.protobuf.Empty; import com.google.pubsub.v1.DeleteTopicRequest; @@ -80,23 +78,9 @@ public class PublisherApi implements AutoCloseable { listTopicSubscriptionsIterableCallable; private final ApiCallable deleteTopicCallable; - /** - * A PathTemplate representing the fully-qualified path to represent - * a project resource. - * - * - * - */ private static final PathTemplate PROJECT_PATH_TEMPLATE = PathTemplate.create("projects/{project}"); - /** - * A PathTemplate representing the fully-qualified path to represent - * a topic resource. - * - * - * - */ private static final PathTemplate TOPIC_PATH_TEMPLATE = PathTemplate.create("projects/{project}/topics/{topic}"); @@ -161,8 +145,8 @@ public static final String parseTopicFromTopicName(String topicName) { * * */ - public static final PublisherApi create() throws IOException { - return create(PublisherSettings.create()); + public static final PublisherApi defaultInstance() throws IOException { + return create(PublisherSettings.defaultInstance()); } /** @@ -188,22 +172,20 @@ public static final PublisherApi create(PublisherSettings settings) throws IOExc protected PublisherApi(PublisherSettings settings) throws IOException { this.channel = settings.getChannel(); - this.createTopicCallable = settings.createTopicMethod().build(settings); - BundlableApiCallableInfo bundlablePublish = - settings.publishMethod().buildBundlable(settings); - this.publishCallable = bundlablePublish.getApiCallable(); - BundlerFactory publishBundlerFactory = - bundlablePublish.getBundlerFactory(); - if (publishBundlerFactory != null) { - this.closeables.add(publishBundlerFactory); + this.createTopicCallable = ApiCallable.create(settings.createTopicSettings(), settings); + this.publishCallable = ApiCallable.create(settings.publishSettings(), settings); + if (settings.publishSettings().getBundlerFactory() != null) { + closeables.add(settings.publishSettings().getBundlerFactory()); } - this.getTopicCallable = settings.getTopicMethod().build(settings); - this.listTopicsCallable = settings.listTopicsMethod().build(settings); - this.listTopicsIterableCallable = settings.listTopicsMethod().buildPageStreaming(settings); - this.listTopicSubscriptionsCallable = settings.listTopicSubscriptionsMethod().build(settings); + this.getTopicCallable = ApiCallable.create(settings.getTopicSettings(), settings); + this.listTopicsCallable = ApiCallable.create(settings.listTopicsSettings(), settings); + this.listTopicsIterableCallable = + ApiCallable.createIterable(settings.listTopicsSettings(), settings); + this.listTopicSubscriptionsCallable = + ApiCallable.create(settings.listTopicSubscriptionsSettings(), settings); this.listTopicSubscriptionsIterableCallable = - settings.listTopicSubscriptionsMethod().buildPageStreaming(settings); - this.deleteTopicCallable = settings.deleteTopicMethod().build(settings); + ApiCallable.createIterable(settings.listTopicSubscriptionsSettings(), settings); + this.deleteTopicCallable = ApiCallable.create(settings.deleteTopicSettings(), settings); if (settings.shouldAutoCloseChannel()) { closeables.add( @@ -231,6 +213,7 @@ public void close() throws IOException { * underscores (`_`), periods (`.`), tildes (`~`), plus (`+`) or percent * signs (`%`). It must be between 3 and 255 characters in length, and it * must not start with `"goog"`. + * @throws ApiException if the remote call fails */ public final Topic createTopic(String name) { Topic request = Topic.newBuilder().setName(name).build(); @@ -246,6 +229,7 @@ public final Topic createTopic(String name) { * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ private Topic createTopic(Topic request) { return createTopicCallable().call(request); @@ -257,6 +241,7 @@ private Topic createTopic(Topic request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable createTopicCallable() { return createTopicCallable; @@ -275,6 +260,7 @@ public final ApiCallable createTopicCallable() { * * @param topic The messages in the request will be published on this topic. * @param messages The messages to publish. + * @throws ApiException if the remote call fails */ public final PublishResponse publish(String topic, List messages) { PublishRequest request = @@ -293,6 +279,7 @@ public final PublishResponse publish(String topic, List messages) * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ public PublishResponse publish(PublishRequest request) { return publishCallable().call(request); @@ -306,6 +293,7 @@ public PublishResponse publish(PublishRequest request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable publishCallable() { return publishCallable; @@ -321,6 +309,7 @@ public final ApiCallable publishCallable() { * * * @param topic The name of the topic to get. + * @throws ApiException if the remote call fails */ public final Topic getTopic(String topic) { GetTopicRequest request = GetTopicRequest.newBuilder().setTopic(topic).build(); @@ -336,6 +325,7 @@ public final Topic getTopic(String topic) { * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ private Topic getTopic(GetTopicRequest request) { return getTopicCallable().call(request); @@ -347,6 +337,7 @@ private Topic getTopic(GetTopicRequest request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable getTopicCallable() { return getTopicCallable; @@ -360,6 +351,9 @@ public final ApiCallable getTopicCallable() { * * * + * + * @param project The name of the cloud project that topics belong to. + * @throws ApiException if the remote call fails */ public final Iterable listTopics(String project) { ListTopicsRequest request = ListTopicsRequest.newBuilder().setProject(project).build(); @@ -374,6 +368,7 @@ public final Iterable listTopics(String project) { * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ public final Iterable listTopics(ListTopicsRequest request) { return listTopicsIterableCallable().call(request); @@ -385,6 +380,7 @@ public final Iterable listTopics(ListTopicsRequest request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable> listTopicsIterableCallable() { return listTopicsIterableCallable; @@ -396,6 +392,7 @@ public final ApiCallable> listTopicsIterableC * * * + * @throws ApiException if the remote call fails */ public final ApiCallable listTopicsCallable() { return listTopicsCallable; @@ -409,6 +406,9 @@ public final ApiCallable listTopicsCallab * * * + * + * @param topic The name of the topic that subscriptions are attached to. + * @throws ApiException if the remote call fails */ public final Iterable listTopicSubscriptions(String topic) { ListTopicSubscriptionsRequest request = @@ -424,6 +424,7 @@ public final Iterable listTopicSubscriptions(String topic) { * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ public final Iterable listTopicSubscriptions(ListTopicSubscriptionsRequest request) { return listTopicSubscriptionsIterableCallable().call(request); @@ -435,6 +436,7 @@ public final Iterable listTopicSubscriptions(ListTopicSubscriptionsReque * * * + * @throws ApiException if the remote call fails */ public final ApiCallable> listTopicSubscriptionsIterableCallable() { @@ -447,6 +449,7 @@ public final Iterable listTopicSubscriptions(ListTopicSubscriptionsReque * * * + * @throws ApiException if the remote call fails */ public final ApiCallable listTopicSubscriptionsCallable() { @@ -467,6 +470,7 @@ public final Iterable listTopicSubscriptions(ListTopicSubscriptionsReque * * * @param topic Name of the topic to delete. + * @throws ApiException if the remote call fails */ public final void deleteTopic(String topic) { DeleteTopicRequest request = DeleteTopicRequest.newBuilder().setTopic(topic).build(); @@ -486,6 +490,7 @@ public final void deleteTopic(String topic) { * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ private void deleteTopic(DeleteTopicRequest request) { deleteTopicCallable().call(request); @@ -501,6 +506,7 @@ private void deleteTopic(DeleteTopicRequest request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable deleteTopicCallable() { return deleteTopicCallable; diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java index 8b3d434b8e49..11c709024144 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java @@ -33,19 +33,17 @@ package com.google.gcloud.pubsub.spi.v1; -import com.google.api.gax.core.BackoffParams; import com.google.api.gax.core.ConnectionSettings; -import com.google.api.gax.core.RetryParams; +import com.google.api.gax.core.RetrySettings; import com.google.api.gax.grpc.ApiCallSettings; -import com.google.api.gax.grpc.ApiCallable; -import com.google.api.gax.grpc.ApiCallable.Builder; -import com.google.api.gax.grpc.ApiCallable.BundlableBuilder; -import com.google.api.gax.grpc.ApiCallable.PageStreamingBuilder; +import com.google.api.gax.grpc.BundlingCallSettings; import com.google.api.gax.grpc.BundlingDescriptor; import com.google.api.gax.grpc.BundlingSettings; +import com.google.api.gax.grpc.PageStreamingCallSettings; import com.google.api.gax.grpc.PageStreamingDescriptor; import com.google.api.gax.grpc.RequestIssuer; import com.google.api.gax.grpc.ServiceApiSettings; +import com.google.api.gax.grpc.SimpleCallSettings; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; @@ -63,10 +61,13 @@ import com.google.pubsub.v1.PublisherGrpc; import com.google.pubsub.v1.PubsubMessage; import com.google.pubsub.v1.Topic; +import io.grpc.ManagedChannel; import io.grpc.Status; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.concurrent.ScheduledExecutorService; import org.joda.time.Duration; // Manually-added imports: add custom (non-generated) imports after this point. @@ -100,202 +101,74 @@ public class PublisherSettings extends ServiceApiSettings { .add("https://www.googleapis.com/auth/cloud-platform") .build(); - private static final ImmutableMap> RETRYABLE_CODE_DEFINITIONS; - - static { - ImmutableMap.Builder> definitions = ImmutableMap.builder(); - definitions.put( - "idempotent", - Sets.immutableEnumSet( - Lists.newArrayList( - Status.Code.DEADLINE_EXCEEDED, Status.Code.UNAVAILABLE))); - definitions.put("non_idempotent", Sets.immutableEnumSet(Lists.newArrayList())); - RETRYABLE_CODE_DEFINITIONS = definitions.build(); - } + private final SimpleCallSettings createTopicSettings; + private final BundlingCallSettings publishSettings; + private final SimpleCallSettings getTopicSettings; + private final PageStreamingCallSettings + listTopicsSettings; - private static final ImmutableMap RETRY_PARAM_DEFINITIONS; - - static { - ImmutableMap.Builder definitions = ImmutableMap.builder(); - RetryParams params = null; - params = - RetryParams.newBuilder() - .setRetryBackoff( - BackoffParams.newBuilder() - .setInitialDelay(Duration.millis(100L)) - .setDelayMultiplier(1.2) - .setMaxDelay(Duration.millis(1000L)) - .build()) - .setTimeoutBackoff( - BackoffParams.newBuilder() - .setInitialDelay(Duration.millis(2000L)) - .setDelayMultiplier(1.5) - .setMaxDelay(Duration.millis(30000L)) - .build()) - .setTotalTimeout(Duration.millis(45000L)) - .build(); - definitions.put("default", params); - RETRY_PARAM_DEFINITIONS = definitions.build(); - } + private final PageStreamingCallSettings< + ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> + listTopicSubscriptionsSettings; - private final MethodBuilders methods; + private final SimpleCallSettings deleteTopicSettings; - private static class MethodBuilders { - private final ApiCallable.Builder createTopicMethod; - private final ApiCallable.BundlableBuilder publishMethod; - private final ApiCallable.Builder getTopicMethod; - private final ApiCallable.PageStreamingBuilder - listTopicsMethod; - private final ApiCallable.PageStreamingBuilder< - ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> - listTopicSubscriptionsMethod; - private final ApiCallable.Builder deleteTopicMethod; - private final ImmutableList allMethods; - - public MethodBuilders() { - createTopicMethod = new Builder<>(PublisherGrpc.METHOD_CREATE_TOPIC); - createTopicMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); - createTopicMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); + public SimpleCallSettings createTopicSettings() { + return createTopicSettings; + } - BundlingSettings publishBundlingSettings = - BundlingSettings.newBuilder() - .setElementCountThreshold(800) - .setElementCountLimit(1000) - .setRequestByteThreshold(8388608) - .setRequestByteLimit(10485760) - .setDelayThreshold(Duration.millis(100)) - .setBlockingCallCountThreshold(1) - .build(); - publishMethod = - new BundlableBuilder<>( - PublisherGrpc.METHOD_PUBLISH, PUBLISH_BUNDLING_DESC, publishBundlingSettings); - publishMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); - publishMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - getTopicMethod = new Builder<>(PublisherGrpc.METHOD_GET_TOPIC); - getTopicMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); - getTopicMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - listTopicsMethod = - new PageStreamingBuilder<>(PublisherGrpc.METHOD_LIST_TOPICS, LIST_TOPICS_PAGE_STR_DESC); - listTopicsMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); - listTopicsMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - listTopicSubscriptionsMethod = - new PageStreamingBuilder<>( - PublisherGrpc.METHOD_LIST_TOPIC_SUBSCRIPTIONS, - LIST_TOPIC_SUBSCRIPTIONS_PAGE_STR_DESC); - listTopicSubscriptionsMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); - listTopicSubscriptionsMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - deleteTopicMethod = new Builder<>(PublisherGrpc.METHOD_DELETE_TOPIC); - deleteTopicMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); - deleteTopicMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - allMethods = - ImmutableList.builder() - .add( - createTopicMethod, - publishMethod, - getTopicMethod, - listTopicsMethod, - listTopicSubscriptionsMethod, - deleteTopicMethod) - .build(); - } + public BundlingCallSettings publishSettings() { + return publishSettings; } - /** - * Constructs an instance of PublisherSettings with default settings. - * - * - * - */ - public static PublisherSettings create() { - PublisherSettings settings = new PublisherSettings(new MethodBuilders()); - settings.provideChannelWith( - ConnectionSettings.builder() - .setServiceAddress(DEFAULT_SERVICE_ADDRESS) - .setPort(DEFAULT_SERVICE_PORT) - .provideCredentialsWith(DEFAULT_SERVICE_SCOPES) - .build()); - return settings; + public SimpleCallSettings getTopicSettings() { + return getTopicSettings; } - /** - * Constructs an instance of PublisherSettings with default settings. This is protected - * so that it easy to make a subclass, but otherwise, the static factory methods should be - * preferred. - * - * - * - */ - protected PublisherSettings(MethodBuilders methods) { - super(methods.allMethods); - this.methods = methods; + public PageStreamingCallSettings + listTopicsSettings() { + return listTopicsSettings; } - /** - * Returns the builder for the API method createTopic. - * - * - * - */ - public final ApiCallable.Builder createTopicMethod() { - return methods.createTopicMethod; + public PageStreamingCallSettings< + ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> + listTopicSubscriptionsSettings() { + return listTopicSubscriptionsSettings; } - /** - * Returns the builder for the API method publish. - * - * - * - */ - public final ApiCallable.BundlableBuilder publishMethod() { - return methods.publishMethod; + public SimpleCallSettings deleteTopicSettings() { + return deleteTopicSettings; } - /** - * Returns the builder for the API method getTopic. - * - * - * - */ - public final ApiCallable.Builder getTopicMethod() { - return methods.getTopicMethod; + public static PublisherSettings defaultInstance() throws IOException { + return newBuilder().build(); } - /** - * Returns the builder for the API method listTopics. - * - * - * - */ - public final ApiCallable.PageStreamingBuilder - listTopicsMethod() { - return methods.listTopicsMethod; + public static Builder newBuilder() { + return new Builder(); } - /** - * Returns the builder for the API method listTopicSubscriptions. - * - * - * - */ - public final ApiCallable.PageStreamingBuilder< - ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> - listTopicSubscriptionsMethod() { - return methods.listTopicSubscriptionsMethod; + public Builder toBuilder() { + return new Builder(this); } - /** - * Returns the builder for the API method deleteTopic. - * - * - * - */ - public final ApiCallable.Builder deleteTopicMethod() { - return methods.deleteTopicMethod; + private PublisherSettings(Builder settingsBuilder) throws IOException { + super( + settingsBuilder.getOrBuildChannel(), + settingsBuilder.shouldAutoCloseChannel(), + settingsBuilder.getOrBuildExecutor(), + settingsBuilder.getConnectionSettings(), + settingsBuilder.getGeneratorName(), + settingsBuilder.getGeneratorVersion(), + settingsBuilder.getClientLibName(), + settingsBuilder.getClientLibVersion()); + + createTopicSettings = settingsBuilder.createTopicSettings().build(); + publishSettings = settingsBuilder.publishSettings().build(); + getTopicSettings = settingsBuilder.getTopicSettings().build(); + listTopicsSettings = settingsBuilder.listTopicsSettings().build(); + listTopicSubscriptionsSettings = settingsBuilder.listTopicSubscriptionsSettings().build(); + deleteTopicSettings = settingsBuilder.deleteTopicSettings().build(); } private static PageStreamingDescriptor @@ -412,4 +285,196 @@ public long countBytes(PublishRequest request) { return request.getSerializedSize(); } }; + + public static class Builder extends ServiceApiSettings.Builder { + private final ImmutableList methodSettingsBuilders; + + private SimpleCallSettings.Builder createTopicSettings; + private BundlingCallSettings.Builder publishSettings; + private SimpleCallSettings.Builder getTopicSettings; + private PageStreamingCallSettings.Builder + listTopicsSettings; + private PageStreamingCallSettings.Builder< + ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> + listTopicSubscriptionsSettings; + private SimpleCallSettings.Builder deleteTopicSettings; + + private static final ImmutableMap> RETRYABLE_CODE_DEFINITIONS; + + static { + ImmutableMap.Builder> definitions = ImmutableMap.builder(); + definitions.put( + "idempotent", + Sets.immutableEnumSet( + Lists.newArrayList( + Status.Code.DEADLINE_EXCEEDED, Status.Code.UNAVAILABLE))); + definitions.put("non_idempotent", Sets.immutableEnumSet(Lists.newArrayList())); + RETRYABLE_CODE_DEFINITIONS = definitions.build(); + } + + private static final ImmutableMap RETRY_PARAM_DEFINITIONS; + + static { + ImmutableMap.Builder definitions = ImmutableMap.builder(); + RetrySettings.Builder settingsBuilder = null; + settingsBuilder = + RetrySettings.newBuilder() + .setInitialRetryDelay(Duration.millis(100L)) + .setRetryDelayMultiplier(1.2) + .setMaxRetryDelay(Duration.millis(1000L)) + .setInitialRpcTimeout(Duration.millis(2000L)) + .setRpcTimeoutMultiplier(1.5) + .setMaxRpcTimeout(Duration.millis(30000L)) + .setTotalTimeout(Duration.millis(45000L)); + definitions.put("default", settingsBuilder); + RETRY_PARAM_DEFINITIONS = definitions.build(); + } + + private Builder() { + super( + ConnectionSettings.builder() + .setServiceAddress(DEFAULT_SERVICE_ADDRESS) + .setPort(DEFAULT_SERVICE_PORT) + .provideCredentialsWith(DEFAULT_SERVICE_SCOPES) + .build()); + + createTopicSettings = + SimpleCallSettings.newBuilder(PublisherGrpc.METHOD_CREATE_TOPIC) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + BundlingSettings.Builder publishBundlingSettingsBuilder = + BundlingSettings.newBuilder() + .setElementCountThreshold(800) + .setElementCountLimit(1000) + .setRequestByteThreshold(8388608) + .setRequestByteLimit(10485760) + .setDelayThreshold(Duration.millis(100)) + .setBlockingCallCountThreshold(1); + publishSettings = + BundlingCallSettings.newBuilder(PublisherGrpc.METHOD_PUBLISH, PUBLISH_BUNDLING_DESC) + .setBundlingSettingsBuilder(publishBundlingSettingsBuilder) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + getTopicSettings = + SimpleCallSettings.newBuilder(PublisherGrpc.METHOD_GET_TOPIC) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + listTopicsSettings = + PageStreamingCallSettings.newBuilder( + PublisherGrpc.METHOD_LIST_TOPICS, LIST_TOPICS_PAGE_STR_DESC) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + listTopicSubscriptionsSettings = + PageStreamingCallSettings.newBuilder( + PublisherGrpc.METHOD_LIST_TOPIC_SUBSCRIPTIONS, + LIST_TOPIC_SUBSCRIPTIONS_PAGE_STR_DESC) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + deleteTopicSettings = + SimpleCallSettings.newBuilder(PublisherGrpc.METHOD_DELETE_TOPIC) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + methodSettingsBuilders = + ImmutableList.of( + createTopicSettings, + publishSettings, + getTopicSettings, + listTopicsSettings, + listTopicSubscriptionsSettings, + deleteTopicSettings); + } + + private Builder(PublisherSettings settings) { + super(settings); + + createTopicSettings = settings.createTopicSettings.toBuilder(); + publishSettings = settings.publishSettings.toBuilder(); + getTopicSettings = settings.getTopicSettings.toBuilder(); + listTopicsSettings = settings.listTopicsSettings.toBuilder(); + listTopicSubscriptionsSettings = settings.listTopicSubscriptionsSettings.toBuilder(); + deleteTopicSettings = settings.deleteTopicSettings.toBuilder(); + + methodSettingsBuilders = + ImmutableList.of( + createTopicSettings, + publishSettings, + getTopicSettings, + listTopicsSettings, + listTopicSubscriptionsSettings, + deleteTopicSettings); + } + + @Override + public Builder provideChannelWith(ManagedChannel channel, boolean shouldAutoClose) { + super.provideChannelWith(channel, shouldAutoClose); + return this; + } + + @Override + public Builder provideChannelWith(ConnectionSettings settings) { + super.provideChannelWith(settings); + return this; + } + + @Override + public Builder setExecutor(ScheduledExecutorService executor) { + super.setExecutor(executor); + return this; + } + + @Override + public Builder setGeneratorHeader(String name, String version) { + super.setGeneratorHeader(name, version); + return this; + } + + @Override + public Builder setClientLibHeader(String name, String version) { + super.setClientLibHeader(name, version); + return this; + } + + public Builder applyToAllApiMethods(ApiCallSettings.Builder apiCallSettings) throws Exception { + super.applyToAllApiMethods(methodSettingsBuilders, apiCallSettings); + return this; + } + + public SimpleCallSettings.Builder createTopicSettings() { + return createTopicSettings; + } + + public BundlingCallSettings.Builder publishSettings() { + return publishSettings; + } + + public SimpleCallSettings.Builder getTopicSettings() { + return getTopicSettings; + } + + public PageStreamingCallSettings.Builder + listTopicsSettings() { + return listTopicsSettings; + } + + public PageStreamingCallSettings.Builder< + ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> + listTopicSubscriptionsSettings() { + return listTopicSubscriptionsSettings; + } + + public SimpleCallSettings.Builder deleteTopicSettings() { + return deleteTopicSettings; + } + + @Override + public PublisherSettings build() throws IOException { + return new PublisherSettings(this); + } + } } diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java index 3040af41efd8..17c1dfdf0c37 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java @@ -80,23 +80,9 @@ public class SubscriberApi implements AutoCloseable { private final ApiCallable pullCallable; private final ApiCallable modifyPushConfigCallable; - /** - * A PathTemplate representing the fully-qualified path to represent - * a project resource. - * - * - * - */ private static final PathTemplate PROJECT_PATH_TEMPLATE = PathTemplate.create("projects/{project}"); - /** - * A PathTemplate representing the fully-qualified path to represent - * a subscription resource. - * - * - * - */ private static final PathTemplate SUBSCRIPTION_PATH_TEMPLATE = PathTemplate.create("projects/{project}/subscriptions/{subscription}"); @@ -161,8 +147,8 @@ public static final String parseSubscriptionFromSubscriptionName(String subscrip * * */ - public static final SubscriberApi create() throws IOException { - return create(SubscriberSettings.create()); + public static final SubscriberApi defaultInstance() throws IOException { + return create(SubscriberSettings.defaultInstance()); } /** @@ -188,16 +174,21 @@ public static final SubscriberApi create(SubscriberSettings settings) throws IOE protected SubscriberApi(SubscriberSettings settings) throws IOException { this.channel = settings.getChannel(); - this.createSubscriptionCallable = settings.createSubscriptionMethod().build(settings); - this.getSubscriptionCallable = settings.getSubscriptionMethod().build(settings); - this.listSubscriptionsCallable = settings.listSubscriptionsMethod().build(settings); + this.createSubscriptionCallable = + ApiCallable.create(settings.createSubscriptionSettings(), settings); + this.getSubscriptionCallable = ApiCallable.create(settings.getSubscriptionSettings(), settings); + this.listSubscriptionsCallable = + ApiCallable.create(settings.listSubscriptionsSettings(), settings); this.listSubscriptionsIterableCallable = - settings.listSubscriptionsMethod().buildPageStreaming(settings); - this.deleteSubscriptionCallable = settings.deleteSubscriptionMethod().build(settings); - this.modifyAckDeadlineCallable = settings.modifyAckDeadlineMethod().build(settings); - this.acknowledgeCallable = settings.acknowledgeMethod().build(settings); - this.pullCallable = settings.pullMethod().build(settings); - this.modifyPushConfigCallable = settings.modifyPushConfigMethod().build(settings); + ApiCallable.createIterable(settings.listSubscriptionsSettings(), settings); + this.deleteSubscriptionCallable = + ApiCallable.create(settings.deleteSubscriptionSettings(), settings); + this.modifyAckDeadlineCallable = + ApiCallable.create(settings.modifyAckDeadlineSettings(), settings); + this.acknowledgeCallable = ApiCallable.create(settings.acknowledgeSettings(), settings); + this.pullCallable = ApiCallable.create(settings.pullSettings(), settings); + this.modifyPushConfigCallable = + ApiCallable.create(settings.modifyPushConfigSettings(), settings); if (settings.shouldAutoCloseChannel()) { closeables.add( @@ -252,6 +243,7 @@ public void close() throws IOException { * system will eventually redeliver the message. * * If this parameter is not set, the default value of 10 seconds is used. + * @throws ApiException if the remote call fails */ public final Subscription createSubscription( String name, String topic, PushConfig pushConfig, int ackDeadlineSeconds) { @@ -279,6 +271,7 @@ public final Subscription createSubscription( * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ public Subscription createSubscription(Subscription request) { return createSubscriptionCallable().call(request); @@ -295,6 +288,7 @@ public Subscription createSubscription(Subscription request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable createSubscriptionCallable() { return createSubscriptionCallable; @@ -313,6 +307,7 @@ public final ApiCallable createSubscriptionCallable( * * * @param subscription The name of the subscription to get. + * @throws ApiException if the remote call fails */ public final Subscription getSubscription(String subscription) { GetSubscriptionRequest request = @@ -332,6 +327,7 @@ public final Subscription getSubscription(String subscription) { * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ private Subscription getSubscription(GetSubscriptionRequest request) { return getSubscriptionCallable().call(request); @@ -346,6 +342,7 @@ private Subscription getSubscription(GetSubscriptionRequest request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable getSubscriptionCallable() { return getSubscriptionCallable; @@ -362,6 +359,9 @@ public final ApiCallable getSubscriptionCa * * * + * + * @param project The name of the cloud project that subscriptions belong to. + * @throws ApiException if the remote call fails */ public final Iterable listSubscriptions(String project) { ListSubscriptionsRequest request = @@ -380,6 +380,7 @@ public final Iterable listSubscriptions(String project) { * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ public final Iterable listSubscriptions(ListSubscriptionsRequest request) { return listSubscriptionsIterableCallable().call(request); @@ -394,6 +395,7 @@ public final Iterable listSubscriptions(ListSubscriptionsRequest r * * * + * @throws ApiException if the remote call fails */ public final ApiCallable> listSubscriptionsIterableCallable() { @@ -409,6 +411,7 @@ public final Iterable listSubscriptions(ListSubscriptionsRequest r * * * + * @throws ApiException if the remote call fails */ public final ApiCallable listSubscriptionsCallable() { @@ -429,6 +432,7 @@ public final Iterable listSubscriptions(ListSubscriptionsRequest r * * * @param subscription The subscription to delete. + * @throws ApiException if the remote call fails */ public final void deleteSubscription(String subscription) { DeleteSubscriptionRequest request = @@ -449,6 +453,7 @@ public final void deleteSubscription(String subscription) { * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ private void deleteSubscription(DeleteSubscriptionRequest request) { deleteSubscriptionCallable().call(request); @@ -464,6 +469,7 @@ private void deleteSubscription(DeleteSubscriptionRequest request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable deleteSubscriptionCallable() { return deleteSubscriptionCallable; @@ -484,10 +490,11 @@ public final ApiCallable deleteSubscriptionCal * @param subscription The name of the subscription. * @param ackIds List of acknowledgment IDs. * @param ackDeadlineSeconds The new ack deadline with respect to the time this request was sent to - * the Pub/Sub system. Must be >= 0. For example, if the value is 10, the new + * the Pub/Sub system. Must be >= 0. For example, if the value is 10, the new * ack deadline will expire 10 seconds after the `ModifyAckDeadline` call * was made. Specifying zero may immediately make the message available for * another pull request. + * @throws ApiException if the remote call fails */ public final void modifyAckDeadline( String subscription, List ackIds, int ackDeadlineSeconds) { @@ -512,6 +519,7 @@ public final void modifyAckDeadline( * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ public void modifyAckDeadline(ModifyAckDeadlineRequest request) { modifyAckDeadlineCallable().call(request); @@ -526,6 +534,7 @@ public void modifyAckDeadline(ModifyAckDeadlineRequest request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable modifyAckDeadlineCallable() { return modifyAckDeadlineCallable; @@ -549,6 +558,7 @@ public final ApiCallable modifyAckDeadlineCalla * @param subscription The subscription whose message is being acknowledged. * @param ackIds The acknowledgment ID for the messages being acknowledged that was returned * by the Pub/Sub system in the `Pull` response. Must not be empty. + * @throws ApiException if the remote call fails */ public final void acknowledge(String subscription, List ackIds) { AcknowledgeRequest request = @@ -571,6 +581,7 @@ public final void acknowledge(String subscription, List ackIds) { * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ public void acknowledge(AcknowledgeRequest request) { acknowledgeCallable().call(request); @@ -588,6 +599,7 @@ public void acknowledge(AcknowledgeRequest request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable acknowledgeCallable() { return acknowledgeCallable; @@ -612,6 +624,7 @@ public final ApiCallable acknowledgeCallable() { * than returning no messages. * @param maxMessages The maximum number of messages returned for this request. The Pub/Sub * system may return fewer than the number specified. + * @throws ApiException if the remote call fails */ public final PullResponse pull(String subscription, boolean returnImmediately, int maxMessages) { PullRequest request = @@ -635,6 +648,7 @@ public final PullResponse pull(String subscription, boolean returnImmediately, i * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ public PullResponse pull(PullRequest request) { return pullCallable().call(request); @@ -649,6 +663,7 @@ public PullResponse pull(PullRequest request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable pullCallable() { return pullCallable; @@ -675,6 +690,7 @@ public final ApiCallable pullCallable() { * stop pushing messages from the given subscription and allow * messages to be pulled and acknowledged - effectively pausing * the subscription if `Pull` is not called. + * @throws ApiException if the remote call fails */ public final void modifyPushConfig(String subscription, PushConfig pushConfig) { ModifyPushConfigRequest request = @@ -699,6 +715,7 @@ public final void modifyPushConfig(String subscription, PushConfig pushConfig) { * * * @param request The request object containing all of the parameters for the API call. + * @throws ApiException if the remote call fails */ public void modifyPushConfig(ModifyPushConfigRequest request) { modifyPushConfigCallable().call(request); @@ -715,6 +732,7 @@ public void modifyPushConfig(ModifyPushConfigRequest request) { * * * + * @throws ApiException if the remote call fails */ public final ApiCallable modifyPushConfigCallable() { return modifyPushConfigCallable; diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java index e0204a4171f8..918ec77e9f04 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java +++ b/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java @@ -33,15 +33,13 @@ package com.google.gcloud.pubsub.spi.v1; -import com.google.api.gax.core.BackoffParams; import com.google.api.gax.core.ConnectionSettings; -import com.google.api.gax.core.RetryParams; +import com.google.api.gax.core.RetrySettings; import com.google.api.gax.grpc.ApiCallSettings; -import com.google.api.gax.grpc.ApiCallable; -import com.google.api.gax.grpc.ApiCallable.Builder; -import com.google.api.gax.grpc.ApiCallable.PageStreamingBuilder; +import com.google.api.gax.grpc.PageStreamingCallSettings; import com.google.api.gax.grpc.PageStreamingDescriptor; import com.google.api.gax.grpc.ServiceApiSettings; +import com.google.api.gax.grpc.SimpleCallSettings; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; @@ -59,7 +57,10 @@ import com.google.pubsub.v1.PullResponse; import com.google.pubsub.v1.SubscriberGrpc; import com.google.pubsub.v1.Subscription; +import io.grpc.ManagedChannel; import io.grpc.Status; +import java.io.IOException; +import java.util.concurrent.ScheduledExecutorService; import org.joda.time.Duration; // Manually-added imports: add custom (non-generated) imports after this point. @@ -93,219 +94,83 @@ public class SubscriberSettings extends ServiceApiSettings { .add("https://www.googleapis.com/auth/cloud-platform") .build(); - private static final ImmutableMap> RETRYABLE_CODE_DEFINITIONS; - - static { - ImmutableMap.Builder> definitions = ImmutableMap.builder(); - definitions.put( - "idempotent", - Sets.immutableEnumSet( - Lists.newArrayList( - Status.Code.DEADLINE_EXCEEDED, Status.Code.UNAVAILABLE))); - definitions.put("non_idempotent", Sets.immutableEnumSet(Lists.newArrayList())); - RETRYABLE_CODE_DEFINITIONS = definitions.build(); - } + private final SimpleCallSettings createSubscriptionSettings; + private final SimpleCallSettings getSubscriptionSettings; + private final PageStreamingCallSettings< + ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> + listSubscriptionsSettings; - private static final ImmutableMap RETRY_PARAM_DEFINITIONS; - - static { - ImmutableMap.Builder definitions = ImmutableMap.builder(); - RetryParams params = null; - params = - RetryParams.newBuilder() - .setRetryBackoff( - BackoffParams.newBuilder() - .setInitialDelay(Duration.millis(100L)) - .setDelayMultiplier(1.2) - .setMaxDelay(Duration.millis(1000L)) - .build()) - .setTimeoutBackoff( - BackoffParams.newBuilder() - .setInitialDelay(Duration.millis(2000L)) - .setDelayMultiplier(1.5) - .setMaxDelay(Duration.millis(30000L)) - .build()) - .setTotalTimeout(Duration.millis(45000L)) - .build(); - definitions.put("default", params); - RETRY_PARAM_DEFINITIONS = definitions.build(); - } + private final SimpleCallSettings deleteSubscriptionSettings; + private final SimpleCallSettings modifyAckDeadlineSettings; + private final SimpleCallSettings acknowledgeSettings; + private final SimpleCallSettings pullSettings; + private final SimpleCallSettings modifyPushConfigSettings; - private final MethodBuilders methods; + public SimpleCallSettings createSubscriptionSettings() { + return createSubscriptionSettings; + } - private static class MethodBuilders { - private final ApiCallable.Builder createSubscriptionMethod; - private final ApiCallable.Builder getSubscriptionMethod; - private final ApiCallable.PageStreamingBuilder< - ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> - listSubscriptionsMethod; - private final ApiCallable.Builder deleteSubscriptionMethod; - private final ApiCallable.Builder modifyAckDeadlineMethod; - private final ApiCallable.Builder acknowledgeMethod; - private final ApiCallable.Builder pullMethod; - private final ApiCallable.Builder modifyPushConfigMethod; - private final ImmutableList allMethods; - - public MethodBuilders() { - createSubscriptionMethod = new Builder<>(SubscriberGrpc.METHOD_CREATE_SUBSCRIPTION); - createSubscriptionMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); - createSubscriptionMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - getSubscriptionMethod = new Builder<>(SubscriberGrpc.METHOD_GET_SUBSCRIPTION); - getSubscriptionMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); - getSubscriptionMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - listSubscriptionsMethod = - new PageStreamingBuilder<>( - SubscriberGrpc.METHOD_LIST_SUBSCRIPTIONS, LIST_SUBSCRIPTIONS_PAGE_STR_DESC); - listSubscriptionsMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); - listSubscriptionsMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - deleteSubscriptionMethod = new Builder<>(SubscriberGrpc.METHOD_DELETE_SUBSCRIPTION); - deleteSubscriptionMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")); - deleteSubscriptionMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - modifyAckDeadlineMethod = new Builder<>(SubscriberGrpc.METHOD_MODIFY_ACK_DEADLINE); - modifyAckDeadlineMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); - modifyAckDeadlineMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - acknowledgeMethod = new Builder<>(SubscriberGrpc.METHOD_ACKNOWLEDGE); - acknowledgeMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); - acknowledgeMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - pullMethod = new Builder<>(SubscriberGrpc.METHOD_PULL); - pullMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); - pullMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - modifyPushConfigMethod = new Builder<>(SubscriberGrpc.METHOD_MODIFY_PUSH_CONFIG); - modifyPushConfigMethod.setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")); - modifyPushConfigMethod.setRetryParams(RETRY_PARAM_DEFINITIONS.get("default")); - - allMethods = - ImmutableList.builder() - .add( - createSubscriptionMethod, - getSubscriptionMethod, - listSubscriptionsMethod, - deleteSubscriptionMethod, - modifyAckDeadlineMethod, - acknowledgeMethod, - pullMethod, - modifyPushConfigMethod) - .build(); - } + public SimpleCallSettings getSubscriptionSettings() { + return getSubscriptionSettings; } - /** - * Constructs an instance of SubscriberSettings with default settings. - * - * - * - */ - public static SubscriberSettings create() { - SubscriberSettings settings = new SubscriberSettings(new MethodBuilders()); - settings.provideChannelWith( - ConnectionSettings.builder() - .setServiceAddress(DEFAULT_SERVICE_ADDRESS) - .setPort(DEFAULT_SERVICE_PORT) - .provideCredentialsWith(DEFAULT_SERVICE_SCOPES) - .build()); - return settings; + public PageStreamingCallSettings< + ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> + listSubscriptionsSettings() { + return listSubscriptionsSettings; } - /** - * Constructs an instance of SubscriberSettings with default settings. This is protected - * so that it easy to make a subclass, but otherwise, the static factory methods should be - * preferred. - * - * - * - */ - protected SubscriberSettings(MethodBuilders methods) { - super(methods.allMethods); - this.methods = methods; + public SimpleCallSettings deleteSubscriptionSettings() { + return deleteSubscriptionSettings; } - /** - * Returns the builder for the API method createSubscription. - * - * - * - */ - public final ApiCallable.Builder createSubscriptionMethod() { - return methods.createSubscriptionMethod; + public SimpleCallSettings modifyAckDeadlineSettings() { + return modifyAckDeadlineSettings; } - /** - * Returns the builder for the API method getSubscription. - * - * - * - */ - public final ApiCallable.Builder getSubscriptionMethod() { - return methods.getSubscriptionMethod; + public SimpleCallSettings acknowledgeSettings() { + return acknowledgeSettings; } - /** - * Returns the builder for the API method listSubscriptions. - * - * - * - */ - public final ApiCallable.PageStreamingBuilder< - ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> - listSubscriptionsMethod() { - return methods.listSubscriptionsMethod; + public SimpleCallSettings pullSettings() { + return pullSettings; } - /** - * Returns the builder for the API method deleteSubscription. - * - * - * - */ - public final ApiCallable.Builder deleteSubscriptionMethod() { - return methods.deleteSubscriptionMethod; + public SimpleCallSettings modifyPushConfigSettings() { + return modifyPushConfigSettings; } - /** - * Returns the builder for the API method modifyAckDeadline. - * - * - * - */ - public final ApiCallable.Builder modifyAckDeadlineMethod() { - return methods.modifyAckDeadlineMethod; + public static SubscriberSettings defaultInstance() throws IOException { + return newBuilder().build(); } - /** - * Returns the builder for the API method acknowledge. - * - * - * - */ - public final ApiCallable.Builder acknowledgeMethod() { - return methods.acknowledgeMethod; + public static Builder newBuilder() { + return new Builder(); } - /** - * Returns the builder for the API method pull. - * - * - * - */ - public final ApiCallable.Builder pullMethod() { - return methods.pullMethod; + public Builder toBuilder() { + return new Builder(this); } - /** - * Returns the builder for the API method modifyPushConfig. - * - * - * - */ - public final ApiCallable.Builder modifyPushConfigMethod() { - return methods.modifyPushConfigMethod; + private SubscriberSettings(Builder settingsBuilder) throws IOException { + super( + settingsBuilder.getOrBuildChannel(), + settingsBuilder.shouldAutoCloseChannel(), + settingsBuilder.getOrBuildExecutor(), + settingsBuilder.getConnectionSettings(), + settingsBuilder.getGeneratorName(), + settingsBuilder.getGeneratorVersion(), + settingsBuilder.getClientLibName(), + settingsBuilder.getClientLibVersion()); + + createSubscriptionSettings = settingsBuilder.createSubscriptionSettings().build(); + getSubscriptionSettings = settingsBuilder.getSubscriptionSettings().build(); + listSubscriptionsSettings = settingsBuilder.listSubscriptionsSettings().build(); + deleteSubscriptionSettings = settingsBuilder.deleteSubscriptionSettings().build(); + modifyAckDeadlineSettings = settingsBuilder.modifyAckDeadlineSettings().build(); + acknowledgeSettings = settingsBuilder.acknowledgeSettings().build(); + pullSettings = settingsBuilder.pullSettings().build(); + modifyPushConfigSettings = settingsBuilder.modifyPushConfigSettings().build(); } private static PageStreamingDescriptor< @@ -336,4 +201,212 @@ public Iterable extractResources(ListSubscriptionsResponse payload return payload.getSubscriptionsList(); } }; + + public static class Builder extends ServiceApiSettings.Builder { + private final ImmutableList methodSettingsBuilders; + + private SimpleCallSettings.Builder createSubscriptionSettings; + private SimpleCallSettings.Builder + getSubscriptionSettings; + private PageStreamingCallSettings.Builder< + ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> + listSubscriptionsSettings; + private SimpleCallSettings.Builder deleteSubscriptionSettings; + private SimpleCallSettings.Builder modifyAckDeadlineSettings; + private SimpleCallSettings.Builder acknowledgeSettings; + private SimpleCallSettings.Builder pullSettings; + private SimpleCallSettings.Builder modifyPushConfigSettings; + + private static final ImmutableMap> RETRYABLE_CODE_DEFINITIONS; + + static { + ImmutableMap.Builder> definitions = ImmutableMap.builder(); + definitions.put( + "idempotent", + Sets.immutableEnumSet( + Lists.newArrayList( + Status.Code.DEADLINE_EXCEEDED, Status.Code.UNAVAILABLE))); + definitions.put("non_idempotent", Sets.immutableEnumSet(Lists.newArrayList())); + RETRYABLE_CODE_DEFINITIONS = definitions.build(); + } + + private static final ImmutableMap RETRY_PARAM_DEFINITIONS; + + static { + ImmutableMap.Builder definitions = ImmutableMap.builder(); + RetrySettings.Builder settingsBuilder = null; + settingsBuilder = + RetrySettings.newBuilder() + .setInitialRetryDelay(Duration.millis(100L)) + .setRetryDelayMultiplier(1.2) + .setMaxRetryDelay(Duration.millis(1000L)) + .setInitialRpcTimeout(Duration.millis(2000L)) + .setRpcTimeoutMultiplier(1.5) + .setMaxRpcTimeout(Duration.millis(30000L)) + .setTotalTimeout(Duration.millis(45000L)); + definitions.put("default", settingsBuilder); + RETRY_PARAM_DEFINITIONS = definitions.build(); + } + + private Builder() { + super( + ConnectionSettings.builder() + .setServiceAddress(DEFAULT_SERVICE_ADDRESS) + .setPort(DEFAULT_SERVICE_PORT) + .provideCredentialsWith(DEFAULT_SERVICE_SCOPES) + .build()); + + createSubscriptionSettings = + SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_CREATE_SUBSCRIPTION) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + getSubscriptionSettings = + SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_GET_SUBSCRIPTION) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + listSubscriptionsSettings = + PageStreamingCallSettings.newBuilder( + SubscriberGrpc.METHOD_LIST_SUBSCRIPTIONS, LIST_SUBSCRIPTIONS_PAGE_STR_DESC) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + deleteSubscriptionSettings = + SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_DELETE_SUBSCRIPTION) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + modifyAckDeadlineSettings = + SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_MODIFY_ACK_DEADLINE) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + acknowledgeSettings = + SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_ACKNOWLEDGE) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + pullSettings = + SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_PULL) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + modifyPushConfigSettings = + SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_MODIFY_PUSH_CONFIG) + .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent")) + .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default")); + + methodSettingsBuilders = + ImmutableList.of( + createSubscriptionSettings, + getSubscriptionSettings, + listSubscriptionsSettings, + deleteSubscriptionSettings, + modifyAckDeadlineSettings, + acknowledgeSettings, + pullSettings, + modifyPushConfigSettings); + } + + private Builder(SubscriberSettings settings) { + super(settings); + + createSubscriptionSettings = settings.createSubscriptionSettings.toBuilder(); + getSubscriptionSettings = settings.getSubscriptionSettings.toBuilder(); + listSubscriptionsSettings = settings.listSubscriptionsSettings.toBuilder(); + deleteSubscriptionSettings = settings.deleteSubscriptionSettings.toBuilder(); + modifyAckDeadlineSettings = settings.modifyAckDeadlineSettings.toBuilder(); + acknowledgeSettings = settings.acknowledgeSettings.toBuilder(); + pullSettings = settings.pullSettings.toBuilder(); + modifyPushConfigSettings = settings.modifyPushConfigSettings.toBuilder(); + + methodSettingsBuilders = + ImmutableList.of( + createSubscriptionSettings, + getSubscriptionSettings, + listSubscriptionsSettings, + deleteSubscriptionSettings, + modifyAckDeadlineSettings, + acknowledgeSettings, + pullSettings, + modifyPushConfigSettings); + } + + @Override + public Builder provideChannelWith(ManagedChannel channel, boolean shouldAutoClose) { + super.provideChannelWith(channel, shouldAutoClose); + return this; + } + + @Override + public Builder provideChannelWith(ConnectionSettings settings) { + super.provideChannelWith(settings); + return this; + } + + @Override + public Builder setExecutor(ScheduledExecutorService executor) { + super.setExecutor(executor); + return this; + } + + @Override + public Builder setGeneratorHeader(String name, String version) { + super.setGeneratorHeader(name, version); + return this; + } + + @Override + public Builder setClientLibHeader(String name, String version) { + super.setClientLibHeader(name, version); + return this; + } + + public Builder applyToAllApiMethods(ApiCallSettings.Builder apiCallSettings) throws Exception { + super.applyToAllApiMethods(methodSettingsBuilders, apiCallSettings); + return this; + } + + public SimpleCallSettings.Builder createSubscriptionSettings() { + return createSubscriptionSettings; + } + + public SimpleCallSettings.Builder + getSubscriptionSettings() { + return getSubscriptionSettings; + } + + public PageStreamingCallSettings.Builder< + ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> + listSubscriptionsSettings() { + return listSubscriptionsSettings; + } + + public SimpleCallSettings.Builder + deleteSubscriptionSettings() { + return deleteSubscriptionSettings; + } + + public SimpleCallSettings.Builder modifyAckDeadlineSettings() { + return modifyAckDeadlineSettings; + } + + public SimpleCallSettings.Builder acknowledgeSettings() { + return acknowledgeSettings; + } + + public SimpleCallSettings.Builder pullSettings() { + return pullSettings; + } + + public SimpleCallSettings.Builder modifyPushConfigSettings() { + return modifyPushConfigSettings; + } + + @Override + public SubscriberSettings build() throws IOException { + return new SubscriberSettings(this); + } + } } diff --git a/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/v1/PublisherApiTest.java b/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/v1/PublisherApiTest.java index dac4be9ae8fc..109c537c3f4a 100644 --- a/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/v1/PublisherApiTest.java +++ b/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/v1/PublisherApiTest.java @@ -58,23 +58,29 @@ public static void stopServer() throws IOException, InterruptedException { public void setUp() throws Exception { ManagedChannel channel = pubsubHelper.createChannel(); - PublisherSettings publisherSettings = PublisherSettings.create(); - publisherSettings.provideChannelWith(channel, true); + PublisherSettings publisherSettings = + PublisherSettings.newBuilder() + .provideChannelWith(channel, true) + .build(); publisherApi = PublisherApi.create(publisherSettings); - BundlingSettings bundlingSettings = + BundlingSettings.Builder bundlingSettings = BundlingSettings.newBuilder() .setElementCountThreshold(10) - .setDelayThreshold(Duration.standardSeconds(30)) - .build(); + .setDelayThreshold(Duration.standardSeconds(30)); + + PublisherSettings.Builder bundledPublisherSettingsBuilder = PublisherSettings.newBuilder(); + bundledPublisherSettingsBuilder + .provideChannelWith(channel, true) + .publishSettings() + .setBundlingSettingsBuilder(bundlingSettings); - PublisherSettings bundledPublisherSettings = PublisherSettings.create(); - bundledPublisherSettings.provideChannelWith(channel, true); - bundledPublisherSettings.publishMethod().setBundlingSettings(bundlingSettings); + PublisherSettings bundledPublisherSettings = bundledPublisherSettingsBuilder.build(); bundledPublisherApi = PublisherApi.create(bundledPublisherSettings); - SubscriberSettings subscriberSettings = SubscriberSettings.create(); - subscriberSettings.provideChannelWith(channel, true); + SubscriberSettings subscriberSettings = SubscriberSettings.newBuilder() + .provideChannelWith(channel, true) + .build(); subscriberApi = SubscriberApi.create(subscriberSettings); } From de23a122d17844ce59a95060877309fbe2daef34 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 12 Apr 2016 10:12:32 +0200 Subject: [PATCH 246/375] Add release profile and use it to deploy artifacts (#889) --- pom.xml | 61 ++++++++++++++++++++++---------------- utilities/after_success.sh | 4 +-- utilities/verify.sh | 4 +-- 3 files changed, 39 insertions(+), 30 deletions(-) diff --git a/pom.xml b/pom.xml index 42f9bd73cdfb..4f13ff6306d5 100644 --- a/pom.xml +++ b/pom.xml @@ -234,32 +234,6 @@ -Xlint:unchecked - - org.apache.maven.plugins - maven-source-plugin - 3.0.0 - - - attach-sources - - jar-no-fork - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.10.3 - - - attach-javadocs - - jar - - - - org.apache.maven.plugins maven-gpg-plugin @@ -444,4 +418,39 @@ + + + release + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.0 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.3 + + + attach-javadocs + + jar + + + + + + + + diff --git a/utilities/after_success.sh b/utilities/after_success.sh index be7484806c46..d8eb94520ebb 100755 --- a/utilities/after_success.sh +++ b/utilities/after_success.sh @@ -34,9 +34,9 @@ if [ "${TRAVIS_JDK_VERSION}" == "oraclejdk7" ]; then cd .. utilities/update_docs_version.sh # Update version in READMEs - mvn clean deploy --settings ~/.m2/settings.xml -P sign-deploy + mvn clean deploy --settings ~/.m2/settings.xml -P sign-deploy,release else - mvn clean deploy -DskipTests=true -Dgpg.skip=true --settings ~/.m2/settings.xml + mvn clean deploy -DskipTests=true -Dgpg.skip=true --settings ~/.m2/settings.xml -P release fi else echo "Not deploying artifacts. This is only done with non-pull-request commits to master branch with Oracle Java 7 builds." diff --git a/utilities/verify.sh b/utilities/verify.sh index b29ab8d8f747..26c490a55806 100755 --- a/utilities/verify.sh +++ b/utilities/verify.sh @@ -10,7 +10,7 @@ if [ "${TRAVIS_PULL_REQUEST}" == "false" ]; then chmod 700 $TRAVIS_BUILD_DIR/signing-tools tar xvf $TRAVIS_BUILD_DIR/signing-tools.tar -C $TRAVIS_BUILD_DIR/signing-tools # Run verify - mvn verify + mvn verify -P release else - mvn verify -DskipITs + mvn verify -DskipITs -P release fi From 67609eef22aa04194cf2c40bd197522a0cfd60bb Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 12 Apr 2016 08:19:34 -0700 Subject: [PATCH 247/375] Cleanup build scripts (#858) --- RELEASING.md | 4 ++-- utilities/after_success.sh | 23 +++++++++++++++++------ utilities/update_docs_version.sh | 2 +- utilities/update_pom_version.sh | 3 +-- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/RELEASING.md b/RELEASING.md index 3555f5beb7e7..97b6e6f716ca 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -8,9 +8,9 @@ Most of the release process is handled by the `after_success.sh` script, trigger This script takes an optional argument denoting the new version. By default, if the current version is X.Y.Z-SNAPSHOT, the script will update the version in all the pom.xml files to X.Y.Z. If desired, another version can be supplied via command line argument instead. 2. Create a PR to update the pom.xml version. If releasing a new client library, this PR should also update javadoc grouping in the base directory's [pom.xml](./pom.xml). -PRs that don't release new modules should look something like [#225](https://github.com/GoogleCloudPlatform/gcloud-java/pull/225). PRs that do release a new module should also add the appropriate packages to the javadoc groups "SPI" and "Test helpers", as shown in [#802](https://github.com/GoogleCloudPlatform/gcloud-java/pull/802) for `gcloud-java-dns`. After this PR is merged into GoogleCloudPlatform/gcloud-java, Travis CI will push a new website to GoogleCloudPlatform/gh-pages, push a new artifact to the Maven Central Repository, and update versions in the README files. +PRs that don't release new modules should look something like [#225](https://github.com/GoogleCloudPlatform/gcloud-java/pull/225). PRs that do release a new module should also add the appropriate packages to the javadoc groups "SPI" and "Test helpers", as shown in [#802](https://github.com/GoogleCloudPlatform/gcloud-java/pull/802) for `gcloud-java-dns`. After this PR is merged into GoogleCloudPlatform/gcloud-java, Travis CI will push a new website to GoogleCloudPlatform/gh-pages, push a new artifact to the Maven Central Repository, and update versions in the README files. Do not merge in any non-release-related pull requests between the start of step 2 and the end of step 6. Between these steps, the project version is a non-snapshot version, so any commits to the master branch will cause Travis to spend extra resources attempting to redeploy artifacts. -3. Before moving on, verify that the artifacts have successfully been pushed to the Maven Central Repository. Open Travis CI, click the ["Build History" tab](https://travis-ci.org/GoogleCloudPlatform/gcloud-java/builds), and open the second build's logs for Step 2's PR. Be sure that you are not opening the "Pull Request" build logs. When the build finishes, scroll to the end of the log and verify that the artifacts were successfully staged and deployed. You can also search for `gcloud-java` on the [Sonatype website](https://oss.sonatype.org/#nexus-search;quick~gcloud-java) and check the latest version number. If the deployment didn't succeed because of a flaky test, rerun the build. +3. Before moving on, verify that the artifacts have successfully been pushed to the Maven Central Repository. Open Travis CI, click the ["Build History" tab](https://travis-ci.org/GoogleCloudPlatform/gcloud-java/builds), and open the second build's logs for Step 2's PR. Be sure that you are not opening the "Pull Request" build logs. When the build finishes, scroll to the end of the log and verify that the artifacts were successfully staged and deployed. Search for `gcloud-java` on the [Sonatype website](https://oss.sonatype.org/#nexus-search;quick~gcloud-java) and check the latest version number. In rare cases (when the Maven plugin that determines the version of the repository fails), the artifacts may not be deployed even if the version in the pom.xml files doesn't contain `SNAPSHOT`. If the artifacts weren't deployed due to invalid version parsing or a flaky test, rerun the build. 4. Publish a release on Github manually. Go to the [releases page](https://github.com/GoogleCloudPlatform/gcloud-java/releases) and open the appropriate release draft. Make sure the "Tag Version" is `vX.Y.Z` and the "Release Title" is `X.Y.Z`, where `X.Y.Z` is the release version as listed in the `pom.xml` files. The draft should already have all changes that impact users since the previous release. To double check this, you can use the `git log` command and look through the merged master branch pull requests. Here is an example of the log command to get non-merge commits between v0.0.12 and v0.1.0: diff --git a/utilities/after_success.sh b/utilities/after_success.sh index d8eb94520ebb..352b7dd4dfda 100755 --- a/utilities/after_success.sh +++ b/utilities/after_success.sh @@ -12,8 +12,23 @@ if [ "${TRAVIS_JDK_VERSION}" == "oraclejdk7" ]; then if [ "${TRAVIS_PULL_REQUEST}" == "false" -a "${TRAVIS_BRANCH}" == "master" ]; then source ./utilities/integration_test_env.sh SITE_VERSION=$(mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -Ev '(^\[|\w+:)') + echo "Used the maven-help-plugin to determine that the version is $SITE_VERSION" + if [ "$SITE_VERSION" == "" ]; then + echo "Could not determine the version, so we're exiting." + exit 1 + fi if [ "${SITE_VERSION##*-}" != "SNAPSHOT" ]; then - # Deploy site if not a SNAPSHOT + # Deploy Maven artifacts (if they don't exist yet) and update artifact version in READMEs. + URL=https://oss.sonatype.org/content/repositories/releases/com/google/gcloud/gcloud-java/$SITE_VERSION/ + if curl --output /dev/null --silent --head --fail "$URL"; then + echo "Not deploying artifacts because it seems like they already exist." + echo "Existence was checked using the url $URL" + else + mvn clean deploy -DskipITs --settings ~/.m2/settings.xml -P sign-deploy,release + fi + utilities/update_docs_version.sh + + # Create website git config --global user.name "travis-ci" git config --global user.email "travis@travis-ci.org" git clone --branch gh-pages --single-branch https://github.com/GoogleCloudPlatform/gcloud-java/ tmp_gh-pages @@ -28,13 +43,9 @@ if [ "${TRAVIS_JDK_VERSION}" == "oraclejdk7" ]; then git add index.html echo "" > apidocs/index.html git add apidocs/index.html - git commit -m "Added a new site for version $SITE_VERSION and updated the root directory's redirect." + git commit -m "Added a new site for version $SITE_VERSION and updated the root directory's redirect. [ci skip]" git config --global push.default simple git push --quiet "https://${CI_DEPLOY_USERNAME}:${CI_DEPLOY_PASSWORD}@github.com/GoogleCloudPlatform/gcloud-java.git" > /dev/null 2>&1 - - cd .. - utilities/update_docs_version.sh # Update version in READMEs - mvn clean deploy --settings ~/.m2/settings.xml -P sign-deploy,release else mvn clean deploy -DskipTests=true -Dgpg.skip=true --settings ~/.m2/settings.xml -P release fi diff --git a/utilities/update_docs_version.sh b/utilities/update_docs_version.sh index 4fc0aa772963..c7d39c4a5c4e 100755 --- a/utilities/update_docs_version.sh +++ b/utilities/update_docs_version.sh @@ -10,7 +10,7 @@ RELEASED_VERSION=$(mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate if [ "${RELEASED_VERSION##*-}" != "SNAPSHOT" ]; then echo "Changing version to $RELEASED_VERSION in README files" # Get list of directories for which README.md must be updated - module_folders=($(find . -maxdepth 1 -name 'gcloud-java*' -type d) .) + module_folders=($(find . -maxdepth 2 -type d | sed -E -n "/^\.\/(gcloud-java-contrib\/)?gcloud-java(-[a-z]+)+$/p") . ./gcloud-java) for item in ${module_folders[*]} do sed -ri "s/[0-9]+\.[0-9]+\.[0-9]+<\/version>/${RELEASED_VERSION}<\/version>/g" ${item}/README.md diff --git a/utilities/update_pom_version.sh b/utilities/update_pom_version.sh index d750ee4e9650..d4251bf053cf 100755 --- a/utilities/update_pom_version.sh +++ b/utilities/update_pom_version.sh @@ -11,8 +11,7 @@ # Get the previous maven project version. CURRENT_VERSION=$(mvn org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -Ev '(^\[|\w+:)') # Get list of directories for which pom.xml must be updated -module_folders=($(find . -maxdepth 1 -name 'gcloud-java*' -type d) .) - +module_folders=($(find . -maxdepth 2 -type d | sed -E -n "/^\.\/(gcloud-java-contrib\/)?gcloud-java(-[a-z]+)+$/p") . ./gcloud-java) if [ $# -eq 1 ]; then NEW_VERSION=$1 elif [ "${CURRENT_VERSION##*-}" != "SNAPSHOT" ]; then From 2fc3c21d94cc7ce36c918d979e6309d30c07752b Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 12 Apr 2016 11:04:17 -0700 Subject: [PATCH 248/375] Rename com.google.gcloud to com.google.cloud (#899) * Rename com.google.gcloud to com.google.cloud * Update readmes with package name change * Fix links in readmes * Update link used to check for artifact deployment --- README.md | 140 +++++++++--------- TESTING.md | 2 - gcloud-java-bigquery/README.md | 46 +++--- gcloud-java-bigquery/pom.xml | 2 +- .../{gcloud => cloud}/bigquery/Acl.java | 2 +- .../{gcloud => cloud}/bigquery/BigQuery.java | 12 +- .../bigquery/BigQueryError.java | 2 +- .../bigquery/BigQueryException.java | 8 +- .../bigquery/BigQueryFactory.java | 4 +- .../bigquery/BigQueryImpl.java | 18 +-- .../bigquery/BigQueryOptions.java | 10 +- .../bigquery/CopyJobConfiguration.java | 2 +- .../bigquery/CsvOptions.java | 2 +- .../{gcloud => cloud}/bigquery/Dataset.java | 4 +- .../{gcloud => cloud}/bigquery/DatasetId.java | 2 +- .../bigquery/DatasetInfo.java | 2 +- .../bigquery/ExternalTableDefinition.java | 2 +- .../bigquery/ExtractJobConfiguration.java | 2 +- .../{gcloud => cloud}/bigquery/Field.java | 2 +- .../bigquery/FieldValue.java | 2 +- .../bigquery/FormatOptions.java | 2 +- .../bigquery/InsertAllRequest.java | 2 +- .../bigquery/InsertAllResponse.java | 2 +- .../{gcloud => cloud}/bigquery/Job.java | 2 +- .../bigquery/JobConfiguration.java | 2 +- .../{gcloud => cloud}/bigquery/JobId.java | 2 +- .../{gcloud => cloud}/bigquery/JobInfo.java | 2 +- .../bigquery/JobStatistics.java | 2 +- .../{gcloud => cloud}/bigquery/JobStatus.java | 2 +- .../bigquery/LoadConfiguration.java | 8 +- .../bigquery/LoadJobConfiguration.java | 2 +- .../{gcloud => cloud}/bigquery/Option.java | 4 +- .../bigquery/QueryJobConfiguration.java | 6 +- .../bigquery/QueryRequest.java | 2 +- .../bigquery/QueryResponse.java | 2 +- .../bigquery/QueryResult.java | 4 +- .../bigquery/QueryStage.java | 2 +- .../{gcloud => cloud}/bigquery/Schema.java | 2 +- .../bigquery/StandardTableDefinition.java | 2 +- .../{gcloud => cloud}/bigquery/Table.java | 4 +- .../bigquery/TableDataWriteChannel.java | 12 +- .../bigquery/TableDefinition.java | 2 +- .../{gcloud => cloud}/bigquery/TableId.java | 2 +- .../{gcloud => cloud}/bigquery/TableInfo.java | 2 +- .../bigquery/UserDefinedFunction.java | 2 +- .../bigquery/ViewDefinition.java | 2 +- .../bigquery/WriteChannelConfiguration.java | 8 +- .../bigquery/package-info.java | 4 +- .../bigquery/spi/BigQueryRpc.java | 4 +- .../bigquery/spi/BigQueryRpcFactory.java | 6 +- .../bigquery/spi/DefaultBigQueryRpc.java | 24 +-- .../testing/RemoteBigQueryHelper.java | 12 +- .../bigquery/testing/package-info.java | 2 +- .../{gcloud => cloud}/bigquery/AclTest.java | 16 +- .../bigquery/BigQueryErrorTest.java | 2 +- .../bigquery/BigQueryExceptionTest.java | 6 +- .../bigquery/BigQueryImplTest.java | 16 +- .../bigquery/CopyJobConfigurationTest.java | 6 +- .../bigquery/CsvOptionsTest.java | 2 +- .../bigquery/DatasetIdTest.java | 2 +- .../bigquery/DatasetInfoTest.java | 2 +- .../bigquery/DatasetTest.java | 6 +- .../bigquery/ExternalTableDefinitionTest.java | 2 +- .../bigquery/ExtractJobConfigurationTest.java | 2 +- .../{gcloud => cloud}/bigquery/FieldTest.java | 2 +- .../bigquery/FieldValueTest.java | 2 +- .../bigquery/FormatOptionsTest.java | 2 +- .../bigquery/InsertAllRequestTest.java | 2 +- .../bigquery/InsertAllResponseTest.java | 2 +- .../{gcloud => cloud}/bigquery/JobIdTest.java | 2 +- .../bigquery/JobInfoTest.java | 12 +- .../bigquery/JobStatisticsTest.java | 10 +- .../bigquery/JobStatusTest.java | 2 +- .../{gcloud => cloud}/bigquery/JobTest.java | 2 +- .../bigquery/LoadJobConfigurationTest.java | 6 +- .../bigquery/OptionTest.java | 4 +- .../bigquery/QueryJobConfigurationTest.java | 8 +- .../bigquery/QueryRequestTest.java | 2 +- .../bigquery/QueryResponseTest.java | 2 +- .../bigquery/QueryResultTest.java | 2 +- .../bigquery/QueryStageTest.java | 4 +- .../bigquery/SchemaTest.java | 2 +- .../bigquery/SerializationTest.java | 10 +- .../bigquery/TableDataWriteChannelTest.java | 10 +- .../bigquery/TableDefinitionTest.java | 4 +- .../bigquery/TableIdTest.java | 2 +- .../bigquery/TableInfoTest.java | 2 +- .../{gcloud => cloud}/bigquery/TableTest.java | 8 +- .../bigquery/UserDefinedFunctionTest.java | 2 +- .../bigquery/ViewDefinitionTest.java | 2 +- .../WriteChannelConfigurationTest.java | 6 +- .../bigquery/it/ITBigQueryTest.java | 88 +++++------ .../testing/RemoteBigQueryHelperTest.java | 8 +- gcloud-java-contrib/README.md | 8 +- gcloud-java-contrib/pom.xml | 2 +- gcloud-java-core/README.md | 10 +- gcloud-java-core/pom.xml | 2 +- .../{gcloud => cloud}/AuthCredentials.java | 2 +- .../google/{gcloud => cloud}/BaseService.java | 4 +- .../BaseServiceException.java | 2 +- .../{gcloud => cloud}/BaseWriteChannel.java | 2 +- .../{gcloud => cloud}/ExceptionHandler.java | 2 +- .../{gcloud => cloud}/FieldSelector.java | 2 +- .../google/{gcloud => cloud}/IamPolicy.java | 2 +- .../google/{gcloud => cloud}/Identity.java | 2 +- .../com/google/{gcloud => cloud}/Page.java | 2 +- .../google/{gcloud => cloud}/PageImpl.java | 2 +- .../google/{gcloud => cloud}/ReadChannel.java | 2 +- .../google/{gcloud => cloud}/Restorable.java | 2 +- .../{gcloud => cloud}/RestorableState.java | 2 +- .../google/{gcloud => cloud}/RetryHelper.java | 2 +- .../google/{gcloud => cloud}/RetryParams.java | 2 +- .../com/google/{gcloud => cloud}/Service.java | 2 +- .../ServiceAccountSigner.java | 2 +- .../{gcloud => cloud}/ServiceFactory.java | 2 +- .../{gcloud => cloud}/ServiceOptions.java | 4 +- .../{gcloud => cloud}/WriteChannel.java | 2 +- .../{gcloud => cloud}/package-info.java | 2 +- .../spi/ServiceRpcFactory.java | 4 +- .../BaseSerializationTest.java | 2 +- .../BaseServiceExceptionTest.java | 4 +- .../BaseWriteChannelTest.java | 4 +- .../ExceptionHandlerTest.java | 6 +- .../FieldSelectorHelperTest.java | 4 +- .../{gcloud => cloud}/IamPolicyTest.java | 2 +- .../{gcloud => cloud}/IdentityTest.java | 2 +- .../{gcloud => cloud}/PageImplTest.java | 2 +- .../{gcloud => cloud}/RetryHelperTest.java | 6 +- .../{gcloud => cloud}/RetryParamsTest.java | 16 +- .../{gcloud => cloud}/SerializationTest.java | 4 +- .../{gcloud => cloud}/ServiceOptionsTest.java | 10 +- gcloud-java-datastore/README.md | 34 ++--- gcloud-java-datastore/pom.xml | 2 +- .../datastore/BaseDatastoreBatchWriter.java | 2 +- .../datastore/BaseEntity.java | 28 ++-- .../{gcloud => cloud}/datastore/BaseKey.java | 8 +- .../{gcloud => cloud}/datastore/Batch.java | 2 +- .../datastore/BatchImpl.java | 2 +- .../{gcloud => cloud}/datastore/Blob.java | 2 +- .../datastore/BlobValue.java | 2 +- .../datastore/BooleanValue.java | 2 +- .../{gcloud => cloud}/datastore/Cursor.java | 2 +- .../datastore/Datastore.java | 6 +- .../datastore/DatastoreBatchWriter.java | 2 +- .../datastore/DatastoreException.java | 8 +- .../datastore/DatastoreFactory.java | 4 +- .../datastore/DatastoreHelper.java | 2 +- .../datastore/DatastoreImpl.java | 14 +- .../datastore/DatastoreOptions.java | 12 +- .../datastore/DatastoreReader.java | 2 +- .../datastore/DatastoreReaderWriter.java | 2 +- .../datastore/DatastoreWriter.java | 2 +- .../{gcloud => cloud}/datastore/DateTime.java | 2 +- .../datastore/DateTimeValue.java | 2 +- .../datastore/DoubleValue.java | 2 +- .../{gcloud => cloud}/datastore/Entity.java | 2 +- .../datastore/EntityQuery.java | 2 +- .../datastore/EntityValue.java | 2 +- .../datastore/FullEntity.java | 2 +- .../{gcloud => cloud}/datastore/GqlQuery.java | 4 +- .../datastore/IncompleteKey.java | 2 +- .../{gcloud => cloud}/datastore/Key.java | 2 +- .../datastore/KeyFactory.java | 2 +- .../{gcloud => cloud}/datastore/KeyQuery.java | 2 +- .../{gcloud => cloud}/datastore/KeyValue.java | 2 +- .../{gcloud => cloud}/datastore/LatLng.java | 2 +- .../datastore/LatLngValue.java | 2 +- .../datastore/ListValue.java | 4 +- .../datastore/LongValue.java | 2 +- .../datastore/NullValue.java | 2 +- .../datastore/PathElement.java | 2 +- .../datastore/ProjectionEntity.java | 2 +- .../datastore/ProjectionEntityQuery.java | 2 +- .../{gcloud => cloud}/datastore/Query.java | 2 +- .../datastore/QueryResults.java | 2 +- .../datastore/QueryResultsImpl.java | 4 +- .../{gcloud => cloud}/datastore/RawValue.java | 2 +- .../datastore/ReadOption.java | 2 +- .../datastore/Serializable.java | 2 +- .../datastore/StringValue.java | 2 +- .../datastore/StructuredQuery.java | 16 +- .../datastore/Transaction.java | 2 +- .../datastore/TransactionImpl.java | 2 +- .../datastore/Validator.java | 2 +- .../{gcloud => cloud}/datastore/Value.java | 2 +- .../datastore/ValueBuilder.java | 2 +- .../datastore/ValueMarshaller.java | 2 +- .../datastore/ValueType.java | 2 +- .../datastore/package-info.java | 6 +- .../datastore/spi/DatastoreRpc.java | 4 +- .../datastore/spi/DatastoreRpcFactory.java | 6 +- .../datastore/spi/DefaultDatastoreRpc.java | 6 +- .../testing/LocalDatastoreHelper.java | 8 +- .../datastore/testing/package-info.java | 2 +- .../BaseDatastoreBatchWriterTest.java | 2 +- .../datastore/BaseEntityTest.java | 2 +- .../datastore/BaseKeyTest.java | 2 +- .../{gcloud => cloud}/datastore/BlobTest.java | 2 +- .../datastore/BlobValueTest.java | 2 +- .../datastore/BooleanValueTest.java | 2 +- .../datastore/CursorTest.java | 2 +- .../datastore/DatastoreExceptionTest.java | 6 +- .../datastore/DatastoreHelperTest.java | 4 +- .../datastore/DatastoreOptionsTest.java | 6 +- .../datastore/DatastoreTest.java | 16 +- .../datastore/DateTimeTest.java | 2 +- .../datastore/DateTimeValueTest.java | 2 +- .../datastore/DoubleValueTest.java | 2 +- .../datastore/EntityTest.java | 2 +- .../datastore/EntityValueTest.java | 2 +- .../datastore/FullEntityTest.java | 2 +- .../datastore/IncompleteKeyTest.java | 2 +- .../datastore/KeyFactoryTest.java | 2 +- .../{gcloud => cloud}/datastore/KeyTest.java | 2 +- .../datastore/KeyValueTest.java | 2 +- .../datastore/LatLngTest.java | 2 +- .../datastore/LatLngValueTest.java | 2 +- .../datastore/ListValueTest.java | 2 +- .../datastore/LongValueTest.java | 2 +- .../datastore/NullValueTest.java | 2 +- .../datastore/PathElementTest.java | 2 +- .../datastore/ProjectionEntityTest.java | 2 +- .../datastore/RawValueTest.java | 2 +- .../datastore/SerializationTest.java | 14 +- .../datastore/StringValueTest.java | 2 +- .../datastore/StructuredQueryTest.java | 12 +- .../datastore/ValueTest.java | 2 +- .../testing/LocalDatastoreHelperTest.java | 6 +- gcloud-java-dns/README.md | 36 ++--- gcloud-java-dns/pom.xml | 2 +- .../{gcloud => cloud}/dns/ChangeRequest.java | 2 +- .../dns/ChangeRequestInfo.java | 2 +- .../com/google/{gcloud => cloud}/dns/Dns.java | 12 +- .../{gcloud => cloud}/dns/DnsException.java | 8 +- .../{gcloud => cloud}/dns/DnsFactory.java | 4 +- .../google/{gcloud => cloud}/dns/DnsImpl.java | 14 +- .../{gcloud => cloud}/dns/DnsOptions.java | 10 +- .../google/{gcloud => cloud}/dns/Option.java | 4 +- .../{gcloud => cloud}/dns/ProjectInfo.java | 2 +- .../{gcloud => cloud}/dns/RecordSet.java | 2 +- .../google/{gcloud => cloud}/dns/Zone.java | 4 +- .../{gcloud => cloud}/dns/ZoneInfo.java | 2 +- .../{gcloud => cloud}/dns/package-info.java | 22 ++- .../dns/spi/DefaultDnsRpc.java | 24 +-- .../{gcloud => cloud}/dns/spi/DnsRpc.java | 4 +- .../dns/spi/DnsRpcFactory.java | 6 +- .../dns/testing/LocalDnsHelper.java | 4 +- .../dns/testing/OptionParsers.java | 2 +- .../dns/testing/package-info.java | 2 +- .../dns/ChangeRequestInfoTest.java | 2 +- .../dns/ChangeRequestTest.java | 2 +- .../{gcloud => cloud}/dns/DnsImplTest.java | 12 +- .../google/{gcloud => cloud}/dns/DnsTest.java | 4 +- .../{gcloud => cloud}/dns/OptionTest.java | 4 +- .../dns/ProjectInfoTest.java | 2 +- .../{gcloud => cloud}/dns/RecordSetTest.java | 2 +- .../dns/SerializationTest.java | 10 +- .../{gcloud => cloud}/dns/ZoneInfoTest.java | 2 +- .../{gcloud => cloud}/dns/ZoneTest.java | 4 +- .../{gcloud => cloud}/dns/it/ITDnsTest.java | 22 +-- .../dns/testing/LocalDnsHelperTest.java | 8 +- gcloud-java-examples/README.md | 56 +++---- gcloud-java-examples/pom.xml | 2 +- .../examples/bigquery/BigQueryExample.java | 58 ++++---- .../snippets/CreateTableAndLoadData.java | 22 +-- .../snippets/InsertDataAndQueryTable.java | 28 ++-- .../examples/datastore/DatastoreExample.java | 30 ++-- .../snippets/AddEntitiesAndRunQuery.java | 18 +-- .../datastore/snippets/CreateEntity.java | 14 +- .../datastore/snippets/UpdateEntity.java | 14 +- .../examples/dns/DnsExample.java | 20 +-- .../snippets/CreateOrUpdateRecordSets.java | 12 +- .../examples/dns/snippets/CreateZone.java | 10 +- .../examples/dns/snippets/DeleteZone.java | 12 +- .../ManipulateZonesAndRecordSets.java | 18 +-- .../ResourceManagerExample.java | 12 +- .../snippets/GetOrCreateProject.java | 10 +- .../snippets/ModifyPolicy.java | 16 +- .../snippets/UpdateAndListProjects.java | 8 +- .../examples/storage/StorageExample.java | 36 ++--- .../CreateAndListBucketsAndBlobs.java | 12 +- .../examples/storage/snippets/CreateBlob.java | 12 +- .../examples/storage/snippets/UpdateBlob.java | 10 +- gcloud-java-resourcemanager/README.md | 36 ++--- gcloud-java-resourcemanager/pom.xml | 2 +- .../resourcemanager/Option.java | 4 +- .../resourcemanager/Policy.java | 6 +- .../resourcemanager/Project.java | 2 +- .../resourcemanager/ProjectInfo.java | 2 +- .../resourcemanager/ResourceManager.java | 14 +- .../ResourceManagerException.java | 8 +- .../ResourceManagerFactory.java | 4 +- .../resourcemanager/ResourceManagerImpl.java | 18 +-- .../ResourceManagerOptions.java | 10 +- .../resourcemanager/package-info.java | 6 +- .../spi/DefaultResourceManagerRpc.java | 14 +- .../spi/ResourceManagerRpc.java | 4 +- .../spi/ResourceManagerRpcFactory.java | 6 +- .../testing/LocalResourceManagerHelper.java | 6 +- .../resourcemanager/testing/package-info.java | 2 +- .../resourcemanager/OptionTest.java | 4 +- .../resourcemanager/PolicyTest.java | 6 +- .../resourcemanager/ProjectInfoTest.java | 2 +- .../resourcemanager/ProjectTest.java | 8 +- .../ResourceManagerExceptionTest.java | 6 +- .../ResourceManagerImplTest.java | 22 +-- .../resourcemanager/SerializationTest.java | 12 +- .../LocalResourceManagerHelperTest.java | 10 +- gcloud-java-storage/README.md | 26 ++-- gcloud-java-storage/pom.xml | 2 +- .../google/{gcloud => cloud}/storage/Acl.java | 2 +- .../storage/BatchRequest.java | 8 +- .../storage/BatchResponse.java | 2 +- .../{gcloud => cloud}/storage/Blob.java | 32 ++-- .../{gcloud => cloud}/storage/BlobId.java | 2 +- .../{gcloud => cloud}/storage/BlobInfo.java | 2 +- .../storage/BlobReadChannel.java | 14 +- .../storage/BlobWriteChannel.java | 14 +- .../{gcloud => cloud}/storage/Bucket.java | 22 +-- .../{gcloud => cloud}/storage/BucketInfo.java | 4 +- .../{gcloud => cloud}/storage/CopyWriter.java | 16 +- .../{gcloud => cloud}/storage/Cors.java | 2 +- .../{gcloud => cloud}/storage/HttpMethod.java | 2 +- .../{gcloud => cloud}/storage/Option.java | 4 +- .../{gcloud => cloud}/storage/Storage.java | 28 ++-- .../storage/StorageException.java | 8 +- .../storage/StorageFactory.java | 4 +- .../storage/StorageImpl.java | 42 +++--- .../storage/StorageOptions.java | 10 +- .../storage/package-info.java | 6 +- .../storage/spi/DefaultStorageRpc.java | 38 ++--- .../storage/spi/StorageRpc.java | 4 +- .../storage/spi/StorageRpcFactory.java | 6 +- .../storage/testing/RemoteStorageHelper.java | 18 +-- .../storage/testing/package-info.java | 2 +- .../{gcloud => cloud}/storage/AclTest.java | 20 +-- .../storage/BatchRequestTest.java | 10 +- .../storage/BatchResponseTest.java | 4 +- .../{gcloud => cloud}/storage/BlobIdTest.java | 2 +- .../storage/BlobInfoTest.java | 12 +- .../storage/BlobReadChannelTest.java | 12 +- .../{gcloud => cloud}/storage/BlobTest.java | 16 +- .../storage/BlobWriteChannelTest.java | 12 +- .../storage/BucketInfoTest.java | 24 +-- .../{gcloud => cloud}/storage/BucketTest.java | 22 +-- .../storage/CopyRequestTest.java | 8 +- .../storage/CopyWriterTest.java | 14 +- .../{gcloud => cloud}/storage/CorsTest.java | 4 +- .../{gcloud => cloud}/storage/OptionTest.java | 4 +- .../storage/SerializationTest.java | 16 +- .../storage/StorageExceptionTest.java | 6 +- .../storage/StorageImplTest.java | 22 +-- .../storage/it/ITStorageTest.java | 38 ++--- .../testing/RemoteStorageHelperTest.java | 16 +- gcloud-java/README.md | 12 +- gcloud-java/pom.xml | 2 +- pom.xml | 14 +- src/site/apt/gcloud-java-core/index.apt | 2 +- src/site/apt/gcloud-java-datastore/index.apt | 2 +- src/site/apt/gcloud-java-examples/index.apt | 2 +- src/site/apt/gcloud-java-storage/index.apt | 2 +- src/site/resources/index.html | 24 +-- utilities/after_success.sh | 2 +- 363 files changed, 1363 insertions(+), 1359 deletions(-) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/Acl.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/BigQuery.java (98%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/BigQueryError.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/BigQueryException.java (93%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/BigQueryFactory.java (90%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/BigQueryImpl.java (98%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/BigQueryOptions.java (92%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/CopyJobConfiguration.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/CsvOptions.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/Dataset.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/DatasetId.java (98%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/DatasetInfo.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/ExternalTableDefinition.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/ExtractJobConfiguration.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/Field.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/FieldValue.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/FormatOptions.java (98%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/InsertAllRequest.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/InsertAllResponse.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/Job.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/JobConfiguration.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/JobId.java (98%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/JobInfo.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/JobStatistics.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/JobStatus.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/LoadConfiguration.java (96%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/LoadJobConfiguration.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/Option.java (95%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/QueryJobConfiguration.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/QueryRequest.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/QueryResponse.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/QueryResult.java (98%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/QueryStage.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/Schema.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/StandardTableDefinition.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/Table.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/TableDataWriteChannel.java (91%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/TableDefinition.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/TableId.java (98%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/TableInfo.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/UserDefinedFunction.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/ViewDefinition.java (99%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/WriteChannelConfiguration.java (98%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/package-info.java (92%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/spi/BigQueryRpc.java (98%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/spi/BigQueryRpcFactory.java (85%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/spi/DefaultBigQueryRpc.java (95%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/testing/RemoteBigQueryHelper.java (94%) rename gcloud-java-bigquery/src/main/java/com/google/{gcloud => cloud}/bigquery/testing/package-info.java (96%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/AclTest.java (88%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/BigQueryErrorTest.java (97%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/BigQueryExceptionTest.java (96%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/BigQueryImplTest.java (99%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/CopyJobConfigurationTest.java (97%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/CsvOptionsTest.java (98%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/DatasetIdTest.java (98%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/DatasetInfoTest.java (99%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/DatasetTest.java (99%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/ExternalTableDefinitionTest.java (99%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/ExtractJobConfigurationTest.java (99%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/FieldTest.java (99%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/FieldValueTest.java (99%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/FormatOptionsTest.java (98%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/InsertAllRequestTest.java (99%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/InsertAllResponseTest.java (98%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/JobIdTest.java (97%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/JobInfoTest.java (97%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/JobStatisticsTest.java (96%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/JobStatusTest.java (98%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/JobTest.java (99%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/LoadJobConfigurationTest.java (97%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/OptionTest.java (96%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/QueryJobConfigurationTest.java (97%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/QueryRequestTest.java (99%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/QueryResponseTest.java (99%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/QueryResultTest.java (98%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/QueryStageTest.java (98%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/SchemaTest.java (98%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/SerializationTest.java (97%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/TableDataWriteChannelTest.java (97%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/TableDefinitionTest.java (97%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/TableIdTest.java (98%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/TableInfoTest.java (99%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/TableTest.java (98%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/UserDefinedFunctionTest.java (98%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/ViewDefinitionTest.java (98%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/WriteChannelConfigurationTest.java (97%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/it/ITBigQueryTest.java (95%) rename gcloud-java-bigquery/src/test/java/com/google/{gcloud => cloud}/bigquery/testing/RemoteBigQueryHelperTest.java (95%) rename gcloud-java-core/src/main/java/com/google/{gcloud => cloud}/AuthCredentials.java (99%) rename gcloud-java-core/src/main/java/com/google/{gcloud => cloud}/BaseService.java (95%) rename gcloud-java-core/src/main/java/com/google/{gcloud => cloud}/BaseServiceException.java (99%) rename gcloud-java-core/src/main/java/com/google/{gcloud => cloud}/BaseWriteChannel.java (99%) rename gcloud-java-core/src/main/java/com/google/{gcloud => cloud}/ExceptionHandler.java (99%) rename gcloud-java-core/src/main/java/com/google/{gcloud => cloud}/FieldSelector.java (99%) rename gcloud-java-core/src/main/java/com/google/{gcloud => cloud}/IamPolicy.java (99%) rename gcloud-java-core/src/main/java/com/google/{gcloud => cloud}/Identity.java (99%) rename gcloud-java-core/src/main/java/com/google/{gcloud => cloud}/Page.java (98%) rename gcloud-java-core/src/main/java/com/google/{gcloud => cloud}/PageImpl.java (99%) rename gcloud-java-core/src/main/java/com/google/{gcloud => cloud}/ReadChannel.java (98%) rename gcloud-java-core/src/main/java/com/google/{gcloud => cloud}/Restorable.java (98%) rename gcloud-java-core/src/main/java/com/google/{gcloud => cloud}/RestorableState.java (97%) rename gcloud-java-core/src/main/java/com/google/{gcloud => cloud}/RetryHelper.java (99%) rename gcloud-java-core/src/main/java/com/google/{gcloud => cloud}/RetryParams.java (99%) rename gcloud-java-core/src/main/java/com/google/{gcloud => cloud}/Service.java (96%) rename gcloud-java-core/src/main/java/com/google/{gcloud => cloud}/ServiceAccountSigner.java (98%) rename gcloud-java-core/src/main/java/com/google/{gcloud => cloud}/ServiceFactory.java (97%) rename gcloud-java-core/src/main/java/com/google/{gcloud => cloud}/ServiceOptions.java (99%) rename gcloud-java-core/src/main/java/com/google/{gcloud => cloud}/WriteChannel.java (98%) rename gcloud-java-core/src/main/java/com/google/{gcloud => cloud}/package-info.java (96%) rename gcloud-java-core/src/main/java/com/google/{gcloud => cloud}/spi/ServiceRpcFactory.java (93%) rename gcloud-java-core/src/test/java/com/google/{gcloud => cloud}/BaseSerializationTest.java (99%) rename gcloud-java-core/src/test/java/com/google/{gcloud => cloud}/BaseServiceExceptionTest.java (98%) rename gcloud-java-core/src/test/java/com/google/{gcloud => cloud}/BaseWriteChannelTest.java (98%) rename gcloud-java-core/src/test/java/com/google/{gcloud => cloud}/ExceptionHandlerTest.java (97%) rename gcloud-java-core/src/test/java/com/google/{gcloud => cloud}/FieldSelectorHelperTest.java (97%) rename gcloud-java-core/src/test/java/com/google/{gcloud => cloud}/IamPolicyTest.java (99%) rename gcloud-java-core/src/test/java/com/google/{gcloud => cloud}/IdentityTest.java (99%) rename gcloud-java-core/src/test/java/com/google/{gcloud => cloud}/PageImplTest.java (98%) rename gcloud-java-core/src/test/java/com/google/{gcloud => cloud}/RetryHelperTest.java (98%) rename gcloud-java-core/src/test/java/com/google/{gcloud => cloud}/RetryParamsTest.java (87%) rename gcloud-java-core/src/test/java/com/google/{gcloud => cloud}/SerializationTest.java (98%) rename gcloud-java-core/src/test/java/com/google/{gcloud => cloud}/ServiceOptionsTest.java (97%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/BaseDatastoreBatchWriter.java (99%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/BaseEntity.java (96%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/BaseKey.java (95%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/Batch.java (97%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/BatchImpl.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/Blob.java (99%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/BlobValue.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/BooleanValue.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/Cursor.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/Datastore.java (97%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/DatastoreBatchWriter.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/DatastoreException.java (93%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/DatastoreFactory.java (90%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/DatastoreHelper.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/DatastoreImpl.java (97%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/DatastoreOptions.java (93%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/DatastoreReader.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/DatastoreReaderWriter.java (95%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/DatastoreWriter.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/DateTime.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/DateTimeValue.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/DoubleValue.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/Entity.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/EntityQuery.java (97%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/EntityValue.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/FullEntity.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/GqlQuery.java (99%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/IncompleteKey.java (99%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/Key.java (99%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/KeyFactory.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/KeyQuery.java (97%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/KeyValue.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/LatLng.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/LatLngValue.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/ListValue.java (97%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/LongValue.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/NullValue.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/PathElement.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/ProjectionEntity.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/ProjectionEntityQuery.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/Query.java (99%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/QueryResults.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/QueryResultsImpl.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/RawValue.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/ReadOption.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/Serializable.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/StringValue.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/StructuredQuery.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/Transaction.java (99%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/TransactionImpl.java (99%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/Validator.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/Value.java (99%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/ValueBuilder.java (97%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/ValueMarshaller.java (96%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/ValueType.java (98%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/package-info.java (90%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/spi/DatastoreRpc.java (96%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/spi/DatastoreRpcFactory.java (85%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/spi/DefaultDatastoreRpc.java (97%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/testing/LocalDatastoreHelper.java (99%) rename gcloud-java-datastore/src/main/java/com/google/{gcloud => cloud}/datastore/testing/package-info.java (96%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/BaseDatastoreBatchWriterTest.java (99%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/BaseEntityTest.java (99%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/BaseKeyTest.java (99%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/BlobTest.java (98%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/BlobValueTest.java (97%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/BooleanValueTest.java (97%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/CursorTest.java (97%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/DatastoreExceptionTest.java (96%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/DatastoreHelperTest.java (98%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/DatastoreOptionsTest.java (94%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/DatastoreTest.java (98%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/DateTimeTest.java (98%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/DateTimeValueTest.java (97%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/DoubleValueTest.java (97%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/EntityTest.java (98%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/EntityValueTest.java (97%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/FullEntityTest.java (98%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/IncompleteKeyTest.java (98%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/KeyFactoryTest.java (99%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/KeyTest.java (98%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/KeyValueTest.java (97%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/LatLngTest.java (98%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/LatLngValueTest.java (97%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/ListValueTest.java (98%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/LongValueTest.java (97%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/NullValueTest.java (97%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/PathElementTest.java (98%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/ProjectionEntityTest.java (98%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/RawValueTest.java (97%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/SerializationTest.java (94%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/StringValueTest.java (97%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/StructuredQueryTest.java (94%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/ValueTest.java (99%) rename gcloud-java-datastore/src/test/java/com/google/{gcloud => cloud}/datastore/testing/LocalDatastoreHelperTest.java (92%) rename gcloud-java-dns/src/main/java/com/google/{gcloud => cloud}/dns/ChangeRequest.java (99%) rename gcloud-java-dns/src/main/java/com/google/{gcloud => cloud}/dns/ChangeRequestInfo.java (99%) rename gcloud-java-dns/src/main/java/com/google/{gcloud => cloud}/dns/Dns.java (98%) rename gcloud-java-dns/src/main/java/com/google/{gcloud => cloud}/dns/DnsException.java (90%) rename gcloud-java-dns/src/main/java/com/google/{gcloud => cloud}/dns/DnsFactory.java (91%) rename gcloud-java-dns/src/main/java/com/google/{gcloud => cloud}/dns/DnsImpl.java (97%) rename gcloud-java-dns/src/main/java/com/google/{gcloud => cloud}/dns/DnsOptions.java (93%) rename gcloud-java-dns/src/main/java/com/google/{gcloud => cloud}/dns/Option.java (96%) rename gcloud-java-dns/src/main/java/com/google/{gcloud => cloud}/dns/ProjectInfo.java (99%) rename gcloud-java-dns/src/main/java/com/google/{gcloud => cloud}/dns/RecordSet.java (99%) rename gcloud-java-dns/src/main/java/com/google/{gcloud => cloud}/dns/Zone.java (99%) rename gcloud-java-dns/src/main/java/com/google/{gcloud => cloud}/dns/ZoneInfo.java (99%) rename gcloud-java-dns/src/main/java/com/google/{gcloud => cloud}/dns/package-info.java (68%) rename gcloud-java-dns/src/main/java/com/google/{gcloud => cloud}/dns/spi/DefaultDnsRpc.java (91%) rename gcloud-java-dns/src/main/java/com/google/{gcloud => cloud}/dns/spi/DnsRpc.java (98%) rename gcloud-java-dns/src/main/java/com/google/{gcloud => cloud}/dns/spi/DnsRpcFactory.java (86%) rename gcloud-java-dns/src/main/java/com/google/{gcloud => cloud}/dns/testing/LocalDnsHelper.java (99%) rename gcloud-java-dns/src/main/java/com/google/{gcloud => cloud}/dns/testing/OptionParsers.java (99%) rename gcloud-java-dns/src/main/java/com/google/{gcloud => cloud}/dns/testing/package-info.java (96%) rename gcloud-java-dns/src/test/java/com/google/{gcloud => cloud}/dns/ChangeRequestInfoTest.java (99%) rename gcloud-java-dns/src/test/java/com/google/{gcloud => cloud}/dns/ChangeRequestTest.java (99%) rename gcloud-java-dns/src/test/java/com/google/{gcloud => cloud}/dns/DnsImplTest.java (98%) rename gcloud-java-dns/src/test/java/com/google/{gcloud => cloud}/dns/DnsTest.java (98%) rename gcloud-java-dns/src/test/java/com/google/{gcloud => cloud}/dns/OptionTest.java (96%) rename gcloud-java-dns/src/test/java/com/google/{gcloud => cloud}/dns/ProjectInfoTest.java (99%) rename gcloud-java-dns/src/test/java/com/google/{gcloud => cloud}/dns/RecordSetTest.java (99%) rename gcloud-java-dns/src/test/java/com/google/{gcloud => cloud}/dns/SerializationTest.java (96%) rename gcloud-java-dns/src/test/java/com/google/{gcloud => cloud}/dns/ZoneInfoTest.java (99%) rename gcloud-java-dns/src/test/java/com/google/{gcloud => cloud}/dns/ZoneTest.java (99%) rename gcloud-java-dns/src/test/java/com/google/{gcloud => cloud}/dns/it/ITDnsTest.java (98%) rename gcloud-java-dns/src/test/java/com/google/{gcloud => cloud}/dns/testing/LocalDnsHelperTest.java (99%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/bigquery/BigQueryExample.java (94%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/bigquery/snippets/CreateTableAndLoadData.java (79%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/bigquery/snippets/InsertDataAndQueryTable.java (82%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/datastore/DatastoreExample.java (90%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/datastore/snippets/AddEntitiesAndRunQuery.java (85%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/datastore/snippets/CreateEntity.java (80%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/datastore/snippets/UpdateEntity.java (81%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/dns/DnsExample.java (97%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/dns/snippets/CreateOrUpdateRecordSets.java (90%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/dns/snippets/CreateZone.java (89%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/dns/snippets/DeleteZone.java (91%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/dns/snippets/ManipulateZonesAndRecordSets.java (94%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/resourcemanager/ResourceManagerExample.java (95%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/resourcemanager/snippets/GetOrCreateProject.java (84%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/resourcemanager/snippets/ModifyPolicy.java (83%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/resourcemanager/snippets/UpdateAndListProjects.java (89%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/storage/StorageExample.java (95%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/storage/snippets/CreateAndListBucketsAndBlobs.java (89%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/storage/snippets/CreateBlob.java (82%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/storage/snippets/UpdateBlob.java (87%) rename gcloud-java-resourcemanager/src/main/java/com/google/{gcloud => cloud}/resourcemanager/Option.java (94%) rename gcloud-java-resourcemanager/src/main/java/com/google/{gcloud => cloud}/resourcemanager/Policy.java (97%) rename gcloud-java-resourcemanager/src/main/java/com/google/{gcloud => cloud}/resourcemanager/Project.java (99%) rename gcloud-java-resourcemanager/src/main/java/com/google/{gcloud => cloud}/resourcemanager/ProjectInfo.java (99%) rename gcloud-java-resourcemanager/src/main/java/com/google/{gcloud => cloud}/resourcemanager/ResourceManager.java (97%) rename gcloud-java-resourcemanager/src/main/java/com/google/{gcloud => cloud}/resourcemanager/ResourceManagerException.java (92%) rename gcloud-java-resourcemanager/src/main/java/com/google/{gcloud => cloud}/resourcemanager/ResourceManagerFactory.java (90%) rename gcloud-java-resourcemanager/src/main/java/com/google/{gcloud => cloud}/resourcemanager/ResourceManagerImpl.java (95%) rename gcloud-java-resourcemanager/src/main/java/com/google/{gcloud => cloud}/resourcemanager/ResourceManagerOptions.java (92%) rename gcloud-java-resourcemanager/src/main/java/com/google/{gcloud => cloud}/resourcemanager/package-info.java (90%) rename gcloud-java-resourcemanager/src/main/java/com/google/{gcloud => cloud}/resourcemanager/spi/DefaultResourceManagerRpc.java (91%) rename gcloud-java-resourcemanager/src/main/java/com/google/{gcloud => cloud}/resourcemanager/spi/ResourceManagerRpc.java (97%) rename gcloud-java-resourcemanager/src/main/java/com/google/{gcloud => cloud}/resourcemanager/spi/ResourceManagerRpcFactory.java (84%) rename gcloud-java-resourcemanager/src/main/java/com/google/{gcloud => cloud}/resourcemanager/testing/LocalResourceManagerHelper.java (99%) rename gcloud-java-resourcemanager/src/main/java/com/google/{gcloud => cloud}/resourcemanager/testing/package-info.java (95%) rename gcloud-java-resourcemanager/src/test/java/com/google/{gcloud => cloud}/resourcemanager/OptionTest.java (95%) rename gcloud-java-resourcemanager/src/test/java/com/google/{gcloud => cloud}/resourcemanager/PolicyTest.java (94%) rename gcloud-java-resourcemanager/src/test/java/com/google/{gcloud => cloud}/resourcemanager/ProjectInfoTest.java (99%) rename gcloud-java-resourcemanager/src/test/java/com/google/{gcloud => cloud}/resourcemanager/ProjectTest.java (97%) rename gcloud-java-resourcemanager/src/test/java/com/google/{gcloud => cloud}/resourcemanager/ResourceManagerExceptionTest.java (95%) rename gcloud-java-resourcemanager/src/test/java/com/google/{gcloud => cloud}/resourcemanager/ResourceManagerImplTest.java (96%) rename gcloud-java-resourcemanager/src/test/java/com/google/{gcloud => cloud}/resourcemanager/SerializationTest.java (91%) rename gcloud-java-resourcemanager/src/test/java/com/google/{gcloud => cloud}/resourcemanager/testing/LocalResourceManagerHelperTest.java (98%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/Acl.java (99%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/BatchRequest.java (94%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/BatchResponse.java (99%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/Blob.java (95%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/BlobId.java (99%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/BlobInfo.java (99%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/BlobReadChannel.java (96%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/BlobWriteChannel.java (89%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/Bucket.java (97%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/BucketInfo.java (99%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/CopyWriter.java (96%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/Cors.java (99%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/HttpMethod.java (95%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/Option.java (95%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/Storage.java (98%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/StorageException.java (91%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/StorageFactory.java (90%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/StorageImpl.java (95%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/StorageOptions.java (92%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/package-info.java (89%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/spi/DefaultStorageRpc.java (94%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/spi/StorageRpc.java (99%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/spi/StorageRpcFactory.java (85%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/testing/RemoteStorageHelper.java (94%) rename gcloud-java-storage/src/main/java/com/google/{gcloud => cloud}/storage/testing/package-info.java (96%) rename gcloud-java-storage/src/test/java/com/google/{gcloud => cloud}/storage/AclTest.java (84%) rename gcloud-java-storage/src/test/java/com/google/{gcloud => cloud}/storage/BatchRequestTest.java (95%) rename gcloud-java-storage/src/test/java/com/google/{gcloud => cloud}/storage/BatchResponseTest.java (97%) rename gcloud-java-storage/src/test/java/com/google/{gcloud => cloud}/storage/BlobIdTest.java (97%) rename gcloud-java-storage/src/test/java/com/google/{gcloud => cloud}/storage/BlobInfoTest.java (96%) rename gcloud-java-storage/src/test/java/com/google/{gcloud => cloud}/storage/BlobReadChannelTest.java (97%) rename gcloud-java-storage/src/test/java/com/google/{gcloud => cloud}/storage/BlobTest.java (97%) rename gcloud-java-storage/src/test/java/com/google/{gcloud => cloud}/storage/BlobWriteChannelTest.java (97%) rename gcloud-java-storage/src/test/java/com/google/{gcloud => cloud}/storage/BucketInfoTest.java (90%) rename gcloud-java-storage/src/test/java/com/google/{gcloud => cloud}/storage/BucketTest.java (97%) rename gcloud-java-storage/src/test/java/com/google/{gcloud => cloud}/storage/CopyRequestTest.java (95%) rename gcloud-java-storage/src/test/java/com/google/{gcloud => cloud}/storage/CopyWriterTest.java (96%) rename gcloud-java-storage/src/test/java/com/google/{gcloud => cloud}/storage/CorsTest.java (95%) rename gcloud-java-storage/src/test/java/com/google/{gcloud => cloud}/storage/OptionTest.java (96%) rename gcloud-java-storage/src/test/java/com/google/{gcloud => cloud}/storage/SerializationTest.java (93%) rename gcloud-java-storage/src/test/java/com/google/{gcloud => cloud}/storage/StorageExceptionTest.java (96%) rename gcloud-java-storage/src/test/java/com/google/{gcloud => cloud}/storage/StorageImplTest.java (99%) rename gcloud-java-storage/src/test/java/com/google/{gcloud => cloud}/storage/it/ITStorageTest.java (98%) rename gcloud-java-storage/src/test/java/com/google/{gcloud => cloud}/storage/testing/RemoteStorageHelperTest.java (96%) diff --git a/README.md b/README.md index 59db4cbcf482..296a9eabd0b9 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Java idiomatic client for [Google Cloud Platform][cloud-platform] services. [![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java) [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) -[![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java.svg) +[![Maven](https://img.shields.io/maven-central/v/com.google.cloud/gcloud-java.svg)]( https://img.shields.io/maven-central/v/com.google.cloud/gcloud-java.svg) [![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) [![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969) @@ -28,40 +28,40 @@ Quickstart If you are using Maven, add this to your pom.xml file ```xml - com.google.gcloud + com.google.cloud gcloud-java 0.1.7 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java:0.1.7' +compile 'com.google.cloud:gcloud-java:0.1.7' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java" % "0.1.7" +libraryDependencies += "com.google.cloud" % "gcloud-java" % "0.1.7" ``` Example Applications -------------------- -- [`BigQueryExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/BigQueryExample.java) - A simple command line interface providing some of Cloud BigQuery's functionality - - Read more about using this application on the [`BigQueryExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/bigquery/BigQueryExample.html). +- [`BigQueryExample`](./gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java) - A simple command line interface providing some of Cloud BigQuery's functionality + - Read more about using this application on the [`BigQueryExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/cloud/examples/bigquery/BigQueryExample.html). - [`Bookshelf`](https://github.com/GoogleCloudPlatform/getting-started-java/tree/master/bookshelf) - An App Engine app that manages a virtual bookshelf. - This app uses `gcloud-java` to interface with Cloud Datastore and Cloud Storage. It also uses Cloud SQL, another Google Cloud Platform service. -- [`DatastoreExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/DatastoreExample.java) - A simple command line interface for Cloud Datastore - - Read more about using this application on the [`DatastoreExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/datastore/DatastoreExample.html). -- [`DnsExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java) - A simple command line interface for Cloud DNS - - Read more about using this application on the [`DnsExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/dns/DnsExample.html). +- [`DatastoreExample`](./gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/DatastoreExample.java) - A simple command line interface for Cloud Datastore + - Read more about using this application on the [`DatastoreExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/cloud/examples/datastore/DatastoreExample.html). +- [`DnsExample`](./gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/DnsExample.java) - A simple command line interface for Cloud DNS + - Read more about using this application on the [`DnsExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/cloud/examples/dns/DnsExample.html). - [`Flexible Environment/Datastore example`](https://github.com/GoogleCloudPlatform/java-docs-samples/tree/master/managed_vms/datastore) - A simple app that uses Cloud Datastore to list the last 10 IP addresses that visited your site. - Read about how to run the application [here](https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/managed_vms/README.md). - [`Flexible Environment/Storage example`](https://github.com/GoogleCloudPlatform/java-docs-samples/tree/master/managed_vms/cloudstorage) - An app that uploads files to a public Cloud Storage bucket on the App Engine Flexible Environment runtime. -- [`ResourceManagerExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/ResourceManagerExample.java) - A simple command line interface providing some of Cloud Resource Manager's functionality - - Read more about using this application on the [`ResourceManagerExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/resourcemanager/ResourceManagerExample.html). +- [`ResourceManagerExample`](./gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/ResourceManagerExample.java) - A simple command line interface providing some of Cloud Resource Manager's functionality + - Read more about using this application on the [`ResourceManagerExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/cloud/examples/resourcemanager/ResourceManagerExample.html). - [`SparkDemo`](https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/managed_vms/sparkjava) - An example of using `gcloud-java-datastore` from within the SparkJava and App Engine Flexible Environment frameworks. - Read about how it works on the example's [README page](https://github.com/GoogleCloudPlatform/java-docs-samples/tree/master/managed_vms/sparkjava#how-does-it-work). -- [`StorageExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java) - A simple command line interface providing some of Cloud Storage's functionality - - Read more about using this application on the [`StorageExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/storage/StorageExample.html). +- [`StorageExample`](./gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/StorageExample.java) - A simple command line interface providing some of Cloud Storage's functionality + - Read more about using this application on the [`StorageExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/cloud/examples/storage/StorageExample.html). - [`TaskList`](https://github.com/GoogleCloudPlatform/java-docs-samples/blob/master/datastore/src/main/java/com/google/datastore/snippets/TaskList.java) - A command line application that uses Cloud Datastore to manage a to-do list. - Read about how to run the application on its [README page](https://github.com/GoogleCloudPlatform/java-docs-samples/tree/master/datastore). @@ -135,19 +135,19 @@ Google Cloud BigQuery (Alpha) Here is a code snippet showing a simple usage example from within Compute/App Engine. Note that you must [supply credentials](#authentication) and a project ID if running this snippet elsewhere. Complete source code can be found at -[CreateTableAndLoadData.java](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/snippets/CreateTableAndLoadData.java). +[CreateTableAndLoadData.java](./gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/snippets/CreateTableAndLoadData.java). ```java -import com.google.gcloud.bigquery.BigQuery; -import com.google.gcloud.bigquery.BigQueryOptions; -import com.google.gcloud.bigquery.Field; -import com.google.gcloud.bigquery.FormatOptions; -import com.google.gcloud.bigquery.Job; -import com.google.gcloud.bigquery.Schema; -import com.google.gcloud.bigquery.StandardTableDefinition; -import com.google.gcloud.bigquery.Table; -import com.google.gcloud.bigquery.TableId; -import com.google.gcloud.bigquery.TableInfo; +import com.google.cloud.bigquery.BigQuery; +import com.google.cloud.bigquery.BigQueryOptions; +import com.google.cloud.bigquery.Field; +import com.google.cloud.bigquery.FormatOptions; +import com.google.cloud.bigquery.Job; +import com.google.cloud.bigquery.Schema; +import com.google.cloud.bigquery.StandardTableDefinition; +import com.google.cloud.bigquery.Table; +import com.google.cloud.bigquery.TableId; +import com.google.cloud.bigquery.TableInfo; BigQuery bigquery = BigQueryOptions.defaultInstance().service(); TableId tableId = TableId.of("dataset", "table"); @@ -183,15 +183,15 @@ Google Cloud Datastore Here are two code snippets showing simple usage examples from within Compute/App Engine. Note that you must [supply credentials](#authentication) and a project ID if running this snippet elsewhere. The first snippet shows how to create a Datastore entity. Complete source code can be found at -[CreateEntity.java](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/CreateEntity.java). +[CreateEntity.java](./gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/snippets/CreateEntity.java). ```java -import com.google.gcloud.datastore.Datastore; -import com.google.gcloud.datastore.DatastoreOptions; -import com.google.gcloud.datastore.DateTime; -import com.google.gcloud.datastore.Entity; -import com.google.gcloud.datastore.Key; -import com.google.gcloud.datastore.KeyFactory; +import com.google.cloud.datastore.Datastore; +import com.google.cloud.datastore.DatastoreOptions; +import com.google.cloud.datastore.DateTime; +import com.google.cloud.datastore.Entity; +import com.google.cloud.datastore.Key; +import com.google.cloud.datastore.KeyFactory; Datastore datastore = DatastoreOptions.defaultInstance().service(); KeyFactory keyFactory = datastore.newKeyFactory().kind("keyKind"); @@ -205,14 +205,14 @@ datastore.put(entity); ``` The second snippet shows how to update a Datastore entity if it exists. Complete source code can be found at -[UpdateEntity.java](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/UpdateEntity.java). +[UpdateEntity.java](./gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/snippets/UpdateEntity.java). ```java -import com.google.gcloud.datastore.Datastore; -import com.google.gcloud.datastore.DatastoreOptions; -import com.google.gcloud.datastore.DateTime; -import com.google.gcloud.datastore.Entity; -import com.google.gcloud.datastore.Key; -import com.google.gcloud.datastore.KeyFactory; +import com.google.cloud.datastore.Datastore; +import com.google.cloud.datastore.DatastoreOptions; +import com.google.cloud.datastore.DateTime; +import com.google.cloud.datastore.Entity; +import com.google.cloud.datastore.Key; +import com.google.cloud.datastore.KeyFactory; Datastore datastore = DatastoreOptions.defaultInstance().service(); KeyFactory keyFactory = datastore.newKeyFactory().kind("keyKind"); @@ -239,13 +239,13 @@ Google Cloud DNS (Alpha) Here are two code snippets showing simple usage examples from within Compute/App Engine. Note that you must [supply credentials](#authentication) and a project ID if running this snippet elsewhere. The first snippet shows how to create a zone resource. Complete source code can be found on -[CreateZone.java](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateZone.java). +[CreateZone.java](./gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/snippets/CreateZone.java). ```java -import com.google.gcloud.dns.Dns; -import com.google.gcloud.dns.DnsOptions; -import com.google.gcloud.dns.Zone; -import com.google.gcloud.dns.ZoneInfo; +import com.google.cloud.dns.Dns; +import com.google.cloud.dns.DnsOptions; +import com.google.cloud.dns.Zone; +import com.google.cloud.dns.ZoneInfo; Dns dns = DnsOptions.defaultInstance().service(); String zoneName = "my-unique-zone"; @@ -255,14 +255,14 @@ ZoneInfo zoneInfo = ZoneInfo.of(zoneName, domainName, description); Zone zone = dns.create(zoneInfo); ``` -The second snippet shows how to create records inside a zone. The complete code can be found on [CreateOrUpdateRecordSets.java](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateRecordSets.java). +The second snippet shows how to create records inside a zone. The complete code can be found on [CreateOrUpdateRecordSets.java](./gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/snippets/CreateOrUpdateRecordSets.java). ```java -import com.google.gcloud.dns.ChangeRequestInfo; -import com.google.gcloud.dns.Dns; -import com.google.gcloud.dns.DnsOptions; -import com.google.gcloud.dns.RecordSet; -import com.google.gcloud.dns.Zone; +import com.google.cloud.dns.ChangeRequestInfo; +import com.google.cloud.dns.Dns; +import com.google.cloud.dns.DnsOptions; +import com.google.cloud.dns.RecordSet; +import com.google.cloud.dns.Zone; import java.util.Iterator; import java.util.concurrent.TimeUnit; @@ -302,11 +302,11 @@ Google Cloud Resource Manager (Alpha) Here is a code snippet showing a simple usage example. Note that you must supply Google SDK credentials for this service, not other forms of authentication listed in the [Authentication section](#authentication). Complete source code can be found at -[UpdateAndListProjects.java](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/UpdateAndListProjects.java). +[UpdateAndListProjects.java](./gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/UpdateAndListProjects.java). ```java -import com.google.gcloud.resourcemanager.Project; -import com.google.gcloud.resourcemanager.ResourceManager; -import com.google.gcloud.resourcemanager.ResourceManagerOptions; +import com.google.cloud.resourcemanager.Project; +import com.google.cloud.resourcemanager.ResourceManager; +import com.google.cloud.resourcemanager.ResourceManagerOptions; import java.util.Iterator; @@ -340,16 +340,16 @@ Google Cloud Storage Here are two code snippets showing simple usage examples from within Compute/App Engine. Note that you must [supply credentials](#authentication) and a project ID if running this snippet elsewhere. The first snippet shows how to create a Storage blob. Complete source code can be found at -[CreateBlob.java](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/CreateBlob.java). +[CreateBlob.java](./gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/snippets/CreateBlob.java). ```java import static java.nio.charset.StandardCharsets.UTF_8; -import com.google.gcloud.storage.Blob; -import com.google.gcloud.storage.BlobId; -import com.google.gcloud.storage.BlobInfo; -import com.google.gcloud.storage.Storage; -import com.google.gcloud.storage.StorageOptions; +import com.google.cloud.storage.Blob; +import com.google.cloud.storage.BlobId; +import com.google.cloud.storage.BlobInfo; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.StorageOptions; Storage storage = StorageOptions.defaultInstance().service(); BlobId blobId = BlobId.of("bucket", "blob_name"); @@ -358,14 +358,14 @@ Blob blob = storage.create(blobInfo, "Hello, Cloud Storage!".getBytes(UTF_8)); ``` The second snippet shows how to update a Storage blob if it exists. Complete source code can be found at -[UpdateBlob.java](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/UpdateBlob.java). +[UpdateBlob.java](./gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/snippets/UpdateBlob.java). ```java import static java.nio.charset.StandardCharsets.UTF_8; -import com.google.gcloud.storage.Blob; -import com.google.gcloud.storage.BlobId; -import com.google.gcloud.storage.Storage; -import com.google.gcloud.storage.StorageOptions; +import com.google.cloud.storage.Blob; +import com.google.cloud.storage.BlobId; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.StorageOptions; import java.nio.ByteBuffer; import java.nio.channels.WritableByteChannel; @@ -431,9 +431,9 @@ Apache 2.0 - See [LICENSE] for more information. [cloud-datastore]: https://cloud.google.com/datastore/docs [cloud-datastore-docs]: https://cloud.google.com/datastore/docs [cloud-datastore-activation]: https://cloud.google.com/datastore/docs/activate -[datastore-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/datastore/package-summary.html +[datastore-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/datastore/package-summary.html -[dns-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/dns/package-summary.html +[dns-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/dns/package-summary.html [cloud-dns-docs]: https://cloud.google.com/dns/docs [cloud-dns-activation]: https://console.cloud.google.com/start/api?id=dns @@ -444,11 +444,11 @@ Apache 2.0 - See [LICENSE] for more information. [cloud-storage-docs]: https://cloud.google.com/storage/docs/overview [cloud-storage-create-bucket]: https://cloud.google.com/storage/docs/cloud-console#_creatingbuckets [cloud-storage-activation]: https://cloud.google.com/storage/docs/signup -[storage-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/storage/package-summary.html +[storage-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/storage/package-summary.html -[resourcemanager-api]:http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/resourcemanager/package-summary.html +[resourcemanager-api]:http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/resourcemanager/package-summary.html [cloud-resourcemanager-docs]:https://cloud.google.com/resource-manager/ [cloud-bigquery]: https://cloud.google.com/bigquery/ [cloud-bigquery-docs]: https://cloud.google.com/bigquery/docs/overview -[bigquery-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/bigquery/package-summary.html +[bigquery-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/bigquery/package-summary.html diff --git a/TESTING.md b/TESTING.md index dcdbe548b87b..aecd6140b79f 100644 --- a/TESTING.md +++ b/TESTING.md @@ -89,8 +89,6 @@ You can test against a temporary local Resource Manager by following these steps 1. Before running your testing code, start the Resource Manager emulator `LocalResourceManagerHelper`. This can be done as follows: ```java - import com.google.gcloud.resourcemanager.testing.LocalResourceManagerHelper; - LocalResourceManagerHelper helper = LocalResourceManagerHelper.create(); helper.start(); ``` diff --git a/gcloud-java-bigquery/README.md b/gcloud-java-bigquery/README.md index d300d3969c40..69efc011ee64 100644 --- a/gcloud-java-bigquery/README.md +++ b/gcloud-java-bigquery/README.md @@ -5,12 +5,12 @@ Java idiomatic client for [Google Cloud BigQuery] (https://cloud.google.com/bigq [![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java) [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) -[![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-bigquery.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-bigquery.svg) +[![Maven](https://img.shields.io/maven-central/v/com.google.cloud/gcloud-java-bigquery.svg)]( https://img.shields.io/maven-central/v/com.google.cloud/gcloud-java-bigquery.svg) [![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) [![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969) - [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) -- [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/bigquery/package-summary.html) +- [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/bigquery/package-summary.html) > Note: This client is a work-in-progress, and may occasionally > make backwards-incompatible changes. @@ -20,24 +20,24 @@ Quickstart If you are using Maven, add this to your pom.xml file ```xml - com.google.gcloud + com.google.cloud gcloud-java-bigquery 0.1.7 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-bigquery:0.1.7' +compile 'com.google.cloud:gcloud-java-bigquery:0.1.7' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-bigquery" % "0.1.7" +libraryDependencies += "com.google.cloud" % "gcloud-java-bigquery" % "0.1.7" ``` Example Application ------------------- -- [`BigQueryExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/BigQueryExample.java) - A simple command line interface providing some of Cloud BigQuery's functionality. -Read more about using this application on the [`BigQueryExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/bigquery/BigQueryExample.html). +- [`BigQueryExample`](../gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java) - A simple command line interface providing some of Cloud BigQuery's functionality. +Read more about using this application on the [`BigQueryExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/cloud/examples/bigquery/BigQueryExample.html). Authentication -------------- @@ -82,8 +82,8 @@ These credentials are automatically inferred from your environment, so you only code to create your service object: ```java -import com.google.gcloud.bigquery.BigQuery; -import com.google.gcloud.bigquery.BigQueryOptions; +import com.google.cloud.bigquery.BigQuery; +import com.google.cloud.bigquery.BigQueryOptions; BigQuery bigquery = BigQueryOptions.defaultInstance().service(); ``` @@ -96,7 +96,7 @@ With BigQuery you can create datasets. A dataset is a grouping mechanism that ho tables. Add the following import at the top of your file: ```java -import com.google.gcloud.bigquery.DatasetInfo; +import com.google.cloud.bigquery.DatasetInfo; ``` Then, to create the dataset, use the following code: @@ -113,12 +113,12 @@ are created from a BigQuery SQL query. In this code snippet we show how to creat with only one string field. Add the following imports at the top of your file: ```java -import com.google.gcloud.bigquery.Field; -import com.google.gcloud.bigquery.Schema; -import com.google.gcloud.bigquery.StandardTableDefinition; -import com.google.gcloud.bigquery.Table; -import com.google.gcloud.bigquery.TableId; -import com.google.gcloud.bigquery.TableInfo; +import com.google.cloud.bigquery.Field; +import com.google.cloud.bigquery.Schema; +import com.google.cloud.bigquery.StandardTableDefinition; +import com.google.cloud.bigquery.Table; +import com.google.cloud.bigquery.TableId; +import com.google.cloud.bigquery.TableInfo; ``` Then add the following code to create the table: @@ -139,8 +139,8 @@ Google Cloud Storage file. In this code snippet we show how to stream rows into Add the following imports at the top of your file: ```java -import com.google.gcloud.bigquery.InsertAllRequest; -import com.google.gcloud.bigquery.InsertAllResponse; +import com.google.cloud.bigquery.InsertAllRequest; +import com.google.cloud.bigquery.InsertAllResponse; import java.util.HashMap; import java.util.Map; @@ -171,9 +171,9 @@ directly or through a Query Job. In this code snippet we show how to run a query for the result. Add the following imports at the top of your file: ```java -import com.google.gcloud.bigquery.FieldValue; -import com.google.gcloud.bigquery.QueryRequest; -import com.google.gcloud.bigquery.QueryResponse; +import com.google.cloud.bigquery.FieldValue; +import com.google.cloud.bigquery.QueryRequest; +import com.google.cloud.bigquery.QueryResponse; import java.util.Iterator; import java.util.List; @@ -203,7 +203,7 @@ while (rowIterator.hasNext()) { #### Complete source code In -[InsertDataAndQueryTable.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/snippets/InsertDataAndQueryTable.java) +[InsertDataAndQueryTable.java](../gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/snippets/InsertDataAndQueryTable.java) we put together all the code shown above into one program. The program assumes that you are running on Compute Engine or from your own desktop. To run the example on App Engine, simply move the code from the main method to your application's servlet class and change the print statements to @@ -255,4 +255,4 @@ Apache 2.0 - See [LICENSE] for more information. [cloud-bigquery]: https://cloud.google.com/bigquery/ [cloud-storage]: https://cloud.google.com/storage/ -[bigquery-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/bigquery/package-summary.html +[bigquery-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/bigquery/package-summary.html diff --git a/gcloud-java-bigquery/pom.xml b/gcloud-java-bigquery/pom.xml index 39b0d6fc4e37..7d4c02794e45 100644 --- a/gcloud-java-bigquery/pom.xml +++ b/gcloud-java-bigquery/pom.xml @@ -8,7 +8,7 @@ Java idiomatic client for Google Cloud BigQuery. - com.google.gcloud + com.google.cloud gcloud-java-pom 0.1.8-SNAPSHOT diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Acl.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Acl.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Acl.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Acl.java index b8e1a817c836..376b090973a5 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Acl.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Acl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQuery.java similarity index 98% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQuery.java index d40cc8145feb..bbfd45fe999e 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQuery.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQuery.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkArgument; import com.google.common.base.Function; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; -import com.google.gcloud.FieldSelector; -import com.google.gcloud.FieldSelector.Helper; -import com.google.gcloud.Page; -import com.google.gcloud.Service; -import com.google.gcloud.bigquery.spi.BigQueryRpc; +import com.google.cloud.FieldSelector; +import com.google.cloud.FieldSelector.Helper; +import com.google.cloud.Page; +import com.google.cloud.Service; +import com.google.cloud.bigquery.spi.BigQueryRpc; import java.util.List; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryError.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryError.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryError.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryError.java index e58f0d0b7213..a5e94ae8b70c 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryError.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryError.java @@ -1,4 +1,4 @@ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import com.google.api.services.bigquery.model.ErrorProto; import com.google.common.base.Function; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryException.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryException.java similarity index 93% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryException.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryException.java index e78734a2899e..42223c827bcd 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryException.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryException.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import com.google.common.collect.ImmutableSet; -import com.google.gcloud.BaseServiceException; -import com.google.gcloud.RetryHelper.RetryHelperException; -import com.google.gcloud.RetryHelper.RetryInterruptedException; +import com.google.cloud.BaseServiceException; +import com.google.cloud.RetryHelper.RetryHelperException; +import com.google.cloud.RetryHelper.RetryInterruptedException; import java.io.IOException; import java.util.Objects; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryFactory.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryFactory.java similarity index 90% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryFactory.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryFactory.java index 90e7bbccd483..064a7c9ba46e 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryFactory.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryFactory.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; -import com.google.gcloud.ServiceFactory; +import com.google.cloud.ServiceFactory; /** * An interface for BigQuery factories. diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryImpl.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryImpl.java similarity index 98% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryImpl.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryImpl.java index 27f4af5d5007..e269d0599964 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryImpl.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryImpl.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkArgument; -import static com.google.gcloud.RetryHelper.runWithRetries; +import static com.google.cloud.RetryHelper.runWithRetries; import com.google.api.services.bigquery.model.GetQueryResultsResponse; import com.google.api.services.bigquery.model.TableDataInsertAllRequest; @@ -29,13 +29,13 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import com.google.gcloud.BaseService; -import com.google.gcloud.Page; -import com.google.gcloud.PageImpl; -import com.google.gcloud.PageImpl.NextPageFetcher; -import com.google.gcloud.RetryHelper; -import com.google.gcloud.bigquery.InsertAllRequest.RowToInsert; -import com.google.gcloud.bigquery.spi.BigQueryRpc; +import com.google.cloud.BaseService; +import com.google.cloud.Page; +import com.google.cloud.PageImpl; +import com.google.cloud.PageImpl.NextPageFetcher; +import com.google.cloud.RetryHelper; +import com.google.cloud.bigquery.InsertAllRequest.RowToInsert; +import com.google.cloud.bigquery.spi.BigQueryRpc; import java.util.List; import java.util.Map; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryOptions.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryOptions.java similarity index 92% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryOptions.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryOptions.java index c9d298affdfc..b0cc56fa0298 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/BigQueryOptions.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryOptions.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import com.google.common.collect.ImmutableSet; -import com.google.gcloud.ServiceOptions; -import com.google.gcloud.bigquery.spi.BigQueryRpc; -import com.google.gcloud.bigquery.spi.BigQueryRpcFactory; -import com.google.gcloud.bigquery.spi.DefaultBigQueryRpc; +import com.google.cloud.ServiceOptions; +import com.google.cloud.bigquery.spi.BigQueryRpc; +import com.google.cloud.bigquery.spi.BigQueryRpcFactory; +import com.google.cloud.bigquery.spi.DefaultBigQueryRpc; import java.util.Set; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/CopyJobConfiguration.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/CopyJobConfiguration.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/CopyJobConfiguration.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/CopyJobConfiguration.java index c12cbf5fe432..3717ff039c7b 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/CopyJobConfiguration.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/CopyJobConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/CsvOptions.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/CsvOptions.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/CsvOptions.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/CsvOptions.java index 9576e7d75640..e07347f2b873 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/CsvOptions.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/CsvOptions.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import com.google.common.base.MoreObjects; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Dataset.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Dataset.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Dataset.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Dataset.java index 215a0c662c3b..31dee897aada 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Dataset.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Dataset.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkNotNull; -import com.google.gcloud.Page; +import com.google.cloud.Page; import java.io.IOException; import java.io.ObjectInputStream; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/DatasetId.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/DatasetId.java similarity index 98% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/DatasetId.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/DatasetId.java index 006c089f8d63..634327f2189d 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/DatasetId.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/DatasetId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/DatasetInfo.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/DatasetInfo.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/DatasetInfo.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/DatasetInfo.java index 9f1d25f05925..284cf5aebeac 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/DatasetInfo.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/DatasetInfo.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/ExternalTableDefinition.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/ExternalTableDefinition.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/ExternalTableDefinition.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/ExternalTableDefinition.java index 5f396d948f5a..0b191d3af761 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/ExternalTableDefinition.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/ExternalTableDefinition.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/ExtractJobConfiguration.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/ExtractJobConfiguration.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/ExtractJobConfiguration.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/ExtractJobConfiguration.java index 7c5a2698b159..6c31e2781d9e 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/ExtractJobConfiguration.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/ExtractJobConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Field.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Field.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Field.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Field.java index 55fae44c5eed..c1342ead8f2a 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Field.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Field.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.Preconditions.checkArgument; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/FieldValue.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/FieldValue.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/FieldValue.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/FieldValue.java index 8b27c70db782..0bd15da9d908 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/FieldValue.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/FieldValue.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/FormatOptions.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/FormatOptions.java similarity index 98% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/FormatOptions.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/FormatOptions.java index f46e7b40f4c1..98e199f6b644 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/FormatOptions.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/FormatOptions.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/InsertAllRequest.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/InsertAllRequest.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/InsertAllRequest.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/InsertAllRequest.java index f0d61583f83f..6907abaaae33 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/InsertAllRequest.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/InsertAllRequest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/InsertAllResponse.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/InsertAllResponse.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/InsertAllResponse.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/InsertAllResponse.java index 992c5d851bbc..1b998947f068 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/InsertAllResponse.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/InsertAllResponse.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import com.google.api.services.bigquery.model.ErrorProto; import com.google.api.services.bigquery.model.TableDataInsertAllResponse; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Job.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Job.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Job.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Job.java index 7f8237473b15..17b58426afc4 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Job.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Job.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/JobConfiguration.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobConfiguration.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/JobConfiguration.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobConfiguration.java index 2244969567ef..85653e357a96 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/JobConfiguration.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/JobId.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobId.java similarity index 98% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/JobId.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobId.java index 898c894f9a21..bc81fe11f700 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/JobId.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/JobInfo.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobInfo.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/JobInfo.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobInfo.java index b15ba38f8912..500eaabcaf17 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/JobInfo.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobInfo.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import com.google.api.services.bigquery.model.Job; import com.google.common.base.Function; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/JobStatistics.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobStatistics.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/JobStatistics.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobStatistics.java index 34e4917921ba..58ae9045e7cc 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/JobStatistics.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobStatistics.java @@ -1,4 +1,4 @@ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import com.google.api.services.bigquery.model.JobStatistics2; import com.google.api.services.bigquery.model.JobStatistics3; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/JobStatus.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobStatus.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/JobStatus.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobStatus.java index 738a644a5dde..8d8da43e00de 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/JobStatus.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobStatus.java @@ -1,4 +1,4 @@ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/LoadConfiguration.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/LoadConfiguration.java similarity index 96% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/LoadConfiguration.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/LoadConfiguration.java index 223a25a478e0..99baa2a7086f 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/LoadConfiguration.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/LoadConfiguration.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; -import com.google.gcloud.bigquery.JobInfo.CreateDisposition; -import com.google.gcloud.bigquery.JobInfo.WriteDisposition; +import com.google.cloud.bigquery.JobInfo.CreateDisposition; +import com.google.cloud.bigquery.JobInfo.WriteDisposition; import java.util.List; /** * Common interface for a load configuration. A load configuration * ({@link WriteChannelConfiguration}) can be used to load data into a table with a - * {@link com.google.gcloud.WriteChannel} ({@link BigQuery#writer(WriteChannelConfiguration)}). + * {@link com.google.cloud.WriteChannel} ({@link BigQuery#writer(WriteChannelConfiguration)}). * A load configuration ({@link LoadJobConfiguration}) can also be used to create a load job * ({@link JobInfo#of(JobConfiguration)}). */ diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/LoadJobConfiguration.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/LoadJobConfiguration.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/LoadJobConfiguration.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/LoadJobConfiguration.java index 9c9fa7a769b6..a4abbce89137 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/LoadJobConfiguration.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/LoadJobConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Option.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Option.java similarity index 95% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Option.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Option.java index e7ac0d0a8cc4..d2edbbe7b4c5 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Option.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Option.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.MoreObjects; -import com.google.gcloud.bigquery.spi.BigQueryRpc; +import com.google.cloud.bigquery.spi.BigQueryRpc; import java.io.Serializable; import java.util.Objects; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryJobConfiguration.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryJobConfiguration.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryJobConfiguration.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryJobConfiguration.java index 688611d07526..1743b64d0576 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryJobConfiguration.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryJobConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkNotNull; @@ -24,8 +24,8 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import com.google.gcloud.bigquery.JobInfo.CreateDisposition; -import com.google.gcloud.bigquery.JobInfo.WriteDisposition; +import com.google.cloud.bigquery.JobInfo.CreateDisposition; +import com.google.cloud.bigquery.JobInfo.WriteDisposition; import java.util.List; import java.util.Map; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryRequest.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryRequest.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryRequest.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryRequest.java index b3522a2a6ba3..8cd3530f9227 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryRequest.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryRequest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryResponse.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryResponse.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryResponse.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryResponse.java index 12000cc1cbd2..ceb1099d4faf 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryResponse.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryResponse.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryResult.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryResult.java similarity index 98% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryResult.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryResult.java index 692abab937a9..fb4b15e8d3f0 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryResult.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryResult.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; -import com.google.gcloud.PageImpl; +import com.google.cloud.PageImpl; import java.util.List; import java.util.Objects; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryStage.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryStage.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryStage.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryStage.java index 9404fbf5d9ad..c88175279a3d 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/QueryStage.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryStage.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import com.google.api.services.bigquery.model.ExplainQueryStage; import com.google.api.services.bigquery.model.ExplainQueryStep; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Schema.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Schema.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Schema.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Schema.java index 787bb0d7f35f..88114d47ae6c 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Schema.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Schema.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/StandardTableDefinition.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/StandardTableDefinition.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/StandardTableDefinition.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/StandardTableDefinition.java index d0e49157a99c..bb5007dfcd3b 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/StandardTableDefinition.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/StandardTableDefinition.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import com.google.api.services.bigquery.model.Streamingbuffer; import com.google.api.services.bigquery.model.Table; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Table.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Table.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Table.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Table.java index b007771645df..cd151063fca5 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/Table.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Table.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.collect.ImmutableList; -import com.google.gcloud.Page; +import com.google.cloud.Page; import java.io.IOException; import java.io.ObjectInputStream; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableDataWriteChannel.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableDataWriteChannel.java similarity index 91% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableDataWriteChannel.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableDataWriteChannel.java index 9c6a950ca27f..9319b59cfea3 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableDataWriteChannel.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableDataWriteChannel.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; -import static com.google.gcloud.RetryHelper.runWithRetries; +import static com.google.cloud.RetryHelper.runWithRetries; import static java.util.concurrent.Executors.callable; -import com.google.gcloud.BaseWriteChannel; -import com.google.gcloud.RestorableState; -import com.google.gcloud.RetryHelper; -import com.google.gcloud.WriteChannel; +import com.google.cloud.BaseWriteChannel; +import com.google.cloud.RestorableState; +import com.google.cloud.RetryHelper; +import com.google.cloud.WriteChannel; /** * WriteChannel implementation to stream data into a BigQuery table. diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableDefinition.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableDefinition.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableDefinition.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableDefinition.java index 26e7bcc76f55..2570c50373a7 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableDefinition.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableDefinition.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableId.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableId.java similarity index 98% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableId.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableId.java index 20ed53cc1a5d..cee20332db9e 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableId.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableInfo.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableInfo.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableInfo.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableInfo.java index 938907e245e7..2c6083eaea75 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/TableInfo.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableInfo.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/UserDefinedFunction.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/UserDefinedFunction.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/UserDefinedFunction.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/UserDefinedFunction.java index 2135e0ddc941..09fa2563c59f 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/UserDefinedFunction.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/UserDefinedFunction.java @@ -1,4 +1,4 @@ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import com.google.api.services.bigquery.model.UserDefinedFunctionResource; import com.google.common.base.Function; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/ViewDefinition.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/ViewDefinition.java similarity index 99% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/ViewDefinition.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/ViewDefinition.java index 796dd411b4a1..89ca9674508e 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/ViewDefinition.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/ViewDefinition.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/WriteChannelConfiguration.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/WriteChannelConfiguration.java similarity index 98% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/WriteChannelConfiguration.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/WriteChannelConfiguration.java index 6cc44ce7d5d6..bd5c29f830c1 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/WriteChannelConfiguration.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/WriteChannelConfiguration.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package com.google.gcloud.bigquery; +package com.google.cloud.bigquery; import static com.google.common.base.Preconditions.checkNotNull; import com.google.api.services.bigquery.model.JobConfigurationLoad; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; -import com.google.gcloud.bigquery.JobInfo.CreateDisposition; -import com.google.gcloud.bigquery.JobInfo.WriteDisposition; +import com.google.cloud.bigquery.JobInfo.CreateDisposition; +import com.google.cloud.bigquery.JobInfo.WriteDisposition; import java.io.Serializable; import java.util.List; @@ -30,7 +30,7 @@ /** * Google BigQuery Configuration for a load operation. A load configuration can be used to load data - * into a table with a {@link com.google.gcloud.WriteChannel} + * into a table with a {@link com.google.cloud.WriteChannel} * ({@link BigQuery#writer(WriteChannelConfiguration)}). */ public class WriteChannelConfiguration implements LoadConfiguration, Serializable { diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/package-info.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/package-info.java similarity index 92% rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/package-info.java rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/package-info.java index db5e956e0a12..a701b82c1c2c 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/package-info.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/package-info.java @@ -19,7 +19,7 @@ * *

    A simple usage example showing how to create a table if it does not exist and load data into * it. For the complete source code see - * + * * CreateTableAndLoadData.java. *

     {@code
      * BigQuery bigquery = BigQueryOptions.defaultInstance().service();
    @@ -44,4 +44,4 @@
      *
      * @see Google Cloud BigQuery
      */
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
    diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/spi/BigQueryRpc.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/spi/BigQueryRpc.java
    similarity index 98%
    rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/spi/BigQueryRpc.java
    rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/spi/BigQueryRpc.java
    index d0b740e9e390..e221079cdd03 100644
    --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/spi/BigQueryRpc.java
    +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/spi/BigQueryRpc.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery.spi;
    +package com.google.cloud.bigquery.spi;
     
     import com.google.api.services.bigquery.model.Dataset;
     import com.google.api.services.bigquery.model.GetQueryResultsResponse;
    @@ -26,7 +26,7 @@
     import com.google.api.services.bigquery.model.TableDataInsertAllRequest;
     import com.google.api.services.bigquery.model.TableDataInsertAllResponse;
     import com.google.api.services.bigquery.model.TableRow;
    -import com.google.gcloud.bigquery.BigQueryException;
    +import com.google.cloud.bigquery.BigQueryException;
     
     import java.util.Map;
     
    diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/spi/BigQueryRpcFactory.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/spi/BigQueryRpcFactory.java
    similarity index 85%
    rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/spi/BigQueryRpcFactory.java
    rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/spi/BigQueryRpcFactory.java
    index 1323ec0624f4..8c9fb2413a41 100644
    --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/spi/BigQueryRpcFactory.java
    +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/spi/BigQueryRpcFactory.java
    @@ -14,10 +14,10 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery.spi;
    +package com.google.cloud.bigquery.spi;
     
    -import com.google.gcloud.bigquery.BigQueryOptions;
    -import com.google.gcloud.spi.ServiceRpcFactory;
    +import com.google.cloud.bigquery.BigQueryOptions;
    +import com.google.cloud.spi.ServiceRpcFactory;
     
     /**
      * An interface for BigQuery RPC factory.
    diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/spi/DefaultBigQueryRpc.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/spi/DefaultBigQueryRpc.java
    similarity index 95%
    rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/spi/DefaultBigQueryRpc.java
    rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/spi/DefaultBigQueryRpc.java
    index 71712bda7806..59cc7730107f 100644
    --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/spi/DefaultBigQueryRpc.java
    +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/spi/DefaultBigQueryRpc.java
    @@ -12,17 +12,17 @@
      * the License.
      */
     
    -package com.google.gcloud.bigquery.spi;
    +package com.google.cloud.bigquery.spi;
     
    -import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.ALL_DATASETS;
    -import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.ALL_USERS;
    -import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.DELETE_CONTENTS;
    -import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.FIELDS;
    -import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.MAX_RESULTS;
    -import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.PAGE_TOKEN;
    -import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.START_INDEX;
    -import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.STATE_FILTER;
    -import static com.google.gcloud.bigquery.spi.BigQueryRpc.Option.TIMEOUT;
    +import static com.google.cloud.bigquery.spi.BigQueryRpc.Option.ALL_DATASETS;
    +import static com.google.cloud.bigquery.spi.BigQueryRpc.Option.ALL_USERS;
    +import static com.google.cloud.bigquery.spi.BigQueryRpc.Option.DELETE_CONTENTS;
    +import static com.google.cloud.bigquery.spi.BigQueryRpc.Option.FIELDS;
    +import static com.google.cloud.bigquery.spi.BigQueryRpc.Option.MAX_RESULTS;
    +import static com.google.cloud.bigquery.spi.BigQueryRpc.Option.PAGE_TOKEN;
    +import static com.google.cloud.bigquery.spi.BigQueryRpc.Option.START_INDEX;
    +import static com.google.cloud.bigquery.spi.BigQueryRpc.Option.STATE_FILTER;
    +import static com.google.cloud.bigquery.spi.BigQueryRpc.Option.TIMEOUT;
     import static java.net.HttpURLConnection.HTTP_CREATED;
     import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
     import static java.net.HttpURLConnection.HTTP_OK;
    @@ -60,8 +60,8 @@
     import com.google.common.collect.ImmutableList;
     import com.google.common.collect.Iterables;
     
    -import com.google.gcloud.bigquery.BigQueryException;
    -import com.google.gcloud.bigquery.BigQueryOptions;
    +import com.google.cloud.bigquery.BigQueryException;
    +import com.google.cloud.bigquery.BigQueryOptions;
     
     import java.io.IOException;
     import java.math.BigInteger;
    diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/testing/RemoteBigQueryHelper.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/testing/RemoteBigQueryHelper.java
    similarity index 94%
    rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/testing/RemoteBigQueryHelper.java
    rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/testing/RemoteBigQueryHelper.java
    index 491e822d683c..d844ad56235a 100644
    --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/testing/RemoteBigQueryHelper.java
    +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/testing/RemoteBigQueryHelper.java
    @@ -14,13 +14,13 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery.testing;
    +package com.google.cloud.bigquery.testing;
     
    -import com.google.gcloud.AuthCredentials;
    -import com.google.gcloud.RetryParams;
    -import com.google.gcloud.bigquery.BigQuery;
    -import com.google.gcloud.bigquery.BigQueryException;
    -import com.google.gcloud.bigquery.BigQueryOptions;
    +import com.google.cloud.AuthCredentials;
    +import com.google.cloud.RetryParams;
    +import com.google.cloud.bigquery.BigQuery;
    +import com.google.cloud.bigquery.BigQueryException;
    +import com.google.cloud.bigquery.BigQueryOptions;
     
     import java.io.IOException;
     import java.io.InputStream;
    diff --git a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/testing/package-info.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/testing/package-info.java
    similarity index 96%
    rename from gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/testing/package-info.java
    rename to gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/testing/package-info.java
    index 9ca792ecd77d..be00683c9ce8 100644
    --- a/gcloud-java-bigquery/src/main/java/com/google/gcloud/bigquery/testing/package-info.java
    +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/testing/package-info.java
    @@ -35,4 +35,4 @@
      * @see 
      *     gcloud-java tools for testing
      */
    -package com.google.gcloud.bigquery.testing;
    +package com.google.cloud.bigquery.testing;
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/AclTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/AclTest.java
    similarity index 88%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/AclTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/AclTest.java
    index 438526b95b6e..51b5e1ad496e 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/AclTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/AclTest.java
    @@ -14,18 +14,18 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     
     import com.google.api.services.bigquery.model.Dataset;
    -import com.google.gcloud.bigquery.Acl.Domain;
    -import com.google.gcloud.bigquery.Acl.Entity;
    -import com.google.gcloud.bigquery.Acl.Entity.Type;
    -import com.google.gcloud.bigquery.Acl.Group;
    -import com.google.gcloud.bigquery.Acl.Role;
    -import com.google.gcloud.bigquery.Acl.User;
    -import com.google.gcloud.bigquery.Acl.View;
    +import com.google.cloud.bigquery.Acl.Domain;
    +import com.google.cloud.bigquery.Acl.Entity;
    +import com.google.cloud.bigquery.Acl.Entity.Type;
    +import com.google.cloud.bigquery.Acl.Group;
    +import com.google.cloud.bigquery.Acl.Role;
    +import com.google.cloud.bigquery.Acl.User;
    +import com.google.cloud.bigquery.Acl.View;
     
     import org.junit.Test;
     
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryErrorTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/BigQueryErrorTest.java
    similarity index 97%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryErrorTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/BigQueryErrorTest.java
    index c8de039e233f..1d30bb87815e 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryErrorTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/BigQueryErrorTest.java
    @@ -1,4 +1,4 @@
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryExceptionTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/BigQueryExceptionTest.java
    similarity index 96%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryExceptionTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/BigQueryExceptionTest.java
    index 66e5289424e2..b0a32cd7f0c7 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryExceptionTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/BigQueryExceptionTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.easymock.EasyMock.createMock;
     import static org.easymock.EasyMock.expect;
    @@ -25,8 +25,8 @@
     import static org.junit.Assert.assertNull;
     import static org.junit.Assert.assertTrue;
     
    -import com.google.gcloud.BaseServiceException;
    -import com.google.gcloud.RetryHelper.RetryHelperException;
    +import com.google.cloud.BaseServiceException;
    +import com.google.cloud.RetryHelper.RetryHelperException;
     
     import org.junit.Test;
     
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/BigQueryImplTest.java
    similarity index 99%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/BigQueryImplTest.java
    index c7d7cf846ef2..7cb7b162fd10 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/BigQueryImplTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/BigQueryImplTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.easymock.EasyMock.capture;
     import static org.easymock.EasyMock.eq;
    @@ -36,13 +36,13 @@
     import com.google.common.collect.ImmutableMap;
     import com.google.common.collect.Iterables;
     import com.google.common.collect.Lists;
    -import com.google.gcloud.Page;
    -import com.google.gcloud.RetryParams;
    -import com.google.gcloud.WriteChannel;
    -import com.google.gcloud.bigquery.InsertAllRequest.RowToInsert;
    -import com.google.gcloud.bigquery.spi.BigQueryRpc;
    -import com.google.gcloud.bigquery.spi.BigQueryRpc.Tuple;
    -import com.google.gcloud.bigquery.spi.BigQueryRpcFactory;
    +import com.google.cloud.Page;
    +import com.google.cloud.RetryParams;
    +import com.google.cloud.WriteChannel;
    +import com.google.cloud.bigquery.InsertAllRequest.RowToInsert;
    +import com.google.cloud.bigquery.spi.BigQueryRpc;
    +import com.google.cloud.bigquery.spi.BigQueryRpc.Tuple;
    +import com.google.cloud.bigquery.spi.BigQueryRpcFactory;
     
     import org.easymock.Capture;
     import org.easymock.EasyMock;
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/CopyJobConfigurationTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/CopyJobConfigurationTest.java
    similarity index 97%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/CopyJobConfigurationTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/CopyJobConfigurationTest.java
    index 3f3f6f0fd15c..54d2370b1c57 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/CopyJobConfigurationTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/CopyJobConfigurationTest.java
    @@ -14,15 +14,15 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertNotNull;
     import static org.junit.Assert.assertNull;
     
     import com.google.common.collect.ImmutableList;
    -import com.google.gcloud.bigquery.JobInfo.CreateDisposition;
    -import com.google.gcloud.bigquery.JobInfo.WriteDisposition;
    +import com.google.cloud.bigquery.JobInfo.CreateDisposition;
    +import com.google.cloud.bigquery.JobInfo.WriteDisposition;
     
     import org.junit.Test;
     
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/CsvOptionsTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/CsvOptionsTest.java
    similarity index 98%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/CsvOptionsTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/CsvOptionsTest.java
    index 371202174431..df56a5ae096e 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/CsvOptionsTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/CsvOptionsTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetIdTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/DatasetIdTest.java
    similarity index 98%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetIdTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/DatasetIdTest.java
    index ec645d71c96f..5cf627a42e38 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetIdTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/DatasetIdTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetInfoTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/DatasetInfoTest.java
    similarity index 99%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetInfoTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/DatasetInfoTest.java
    index 474a31d44a20..6e9c961f207f 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetInfoTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/DatasetInfoTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertNull;
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/DatasetTest.java
    similarity index 99%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/DatasetTest.java
    index 43c550c59d11..747c8ae4f0dc 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/DatasetTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/DatasetTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.easymock.EasyMock.createMock;
     import static org.easymock.EasyMock.createStrictMock;
    @@ -32,8 +32,8 @@
     
     import com.google.common.collect.ImmutableList;
     import com.google.common.collect.Iterables;
    -import com.google.gcloud.Page;
    -import com.google.gcloud.PageImpl;
    +import com.google.cloud.Page;
    +import com.google.cloud.PageImpl;
     
     import org.junit.After;
     import org.junit.Test;
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/ExternalTableDefinitionTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/ExternalTableDefinitionTest.java
    similarity index 99%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/ExternalTableDefinitionTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/ExternalTableDefinitionTest.java
    index 247032dff890..e3e1c01b9403 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/ExternalTableDefinitionTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/ExternalTableDefinitionTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/ExtractJobConfigurationTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/ExtractJobConfigurationTest.java
    similarity index 99%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/ExtractJobConfigurationTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/ExtractJobConfigurationTest.java
    index 7ac67f41b1f8..62d5274e491d 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/ExtractJobConfigurationTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/ExtractJobConfigurationTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertNotNull;
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/FieldTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/FieldTest.java
    similarity index 99%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/FieldTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/FieldTest.java
    index 5f039eaed206..8e044d889313 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/FieldTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/FieldTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/FieldValueTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/FieldValueTest.java
    similarity index 99%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/FieldValueTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/FieldValueTest.java
    index d6d879dbd58f..82086768b8ce 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/FieldValueTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/FieldValueTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/FormatOptionsTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/FormatOptionsTest.java
    similarity index 98%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/FormatOptionsTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/FormatOptionsTest.java
    index df939143156b..7406d8a7a283 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/FormatOptionsTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/FormatOptionsTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/InsertAllRequestTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/InsertAllRequestTest.java
    similarity index 99%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/InsertAllRequestTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/InsertAllRequestTest.java
    index 0866f0b9349e..607b6c4145a8 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/InsertAllRequestTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/InsertAllRequestTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/InsertAllResponseTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/InsertAllResponseTest.java
    similarity index 98%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/InsertAllResponseTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/InsertAllResponseTest.java
    index b2eb0458f27f..dc30620200bc 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/InsertAllResponseTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/InsertAllResponseTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobIdTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobIdTest.java
    similarity index 97%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobIdTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobIdTest.java
    index 740830f07544..68caf62413c9 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobIdTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobIdTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobInfoTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobInfoTest.java
    similarity index 97%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobInfoTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobInfoTest.java
    index 9c90fbe7b05f..16fe980fe171 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobInfoTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobInfoTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertNotNull;
    @@ -23,11 +23,11 @@
     
     import com.google.common.collect.ImmutableList;
     import com.google.common.collect.ImmutableMap;
    -import com.google.gcloud.bigquery.JobInfo.CreateDisposition;
    -import com.google.gcloud.bigquery.JobInfo.WriteDisposition;
    -import com.google.gcloud.bigquery.JobStatistics.ExtractStatistics;
    -import com.google.gcloud.bigquery.JobStatistics.LoadStatistics;
    -import com.google.gcloud.bigquery.JobStatistics.QueryStatistics;
    +import com.google.cloud.bigquery.JobInfo.CreateDisposition;
    +import com.google.cloud.bigquery.JobInfo.WriteDisposition;
    +import com.google.cloud.bigquery.JobStatistics.ExtractStatistics;
    +import com.google.cloud.bigquery.JobStatistics.LoadStatistics;
    +import com.google.cloud.bigquery.JobStatistics.QueryStatistics;
     
     import org.junit.Test;
     
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobStatisticsTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobStatisticsTest.java
    similarity index 96%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobStatisticsTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobStatisticsTest.java
    index 4a3940ba4543..0dc5fea0b1d7 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobStatisticsTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobStatisticsTest.java
    @@ -14,15 +14,15 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     
     import com.google.common.collect.ImmutableList;
    -import com.google.gcloud.bigquery.JobStatistics.ExtractStatistics;
    -import com.google.gcloud.bigquery.JobStatistics.LoadStatistics;
    -import com.google.gcloud.bigquery.JobStatistics.QueryStatistics;
    -import com.google.gcloud.bigquery.QueryStage.QueryStep;
    +import com.google.cloud.bigquery.JobStatistics.ExtractStatistics;
    +import com.google.cloud.bigquery.JobStatistics.LoadStatistics;
    +import com.google.cloud.bigquery.JobStatistics.QueryStatistics;
    +import com.google.cloud.bigquery.QueryStage.QueryStep;
     
     import org.junit.Test;
     
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobStatusTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobStatusTest.java
    similarity index 98%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobStatusTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobStatusTest.java
    index c44386a3e72c..78a4345a339b 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobStatusTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobStatusTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobTest.java
    similarity index 99%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobTest.java
    index 61c9c521196a..b2a2461f1267 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/JobTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.easymock.EasyMock.createMock;
     import static org.easymock.EasyMock.createStrictMock;
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/LoadJobConfigurationTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/LoadJobConfigurationTest.java
    similarity index 97%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/LoadJobConfigurationTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/LoadJobConfigurationTest.java
    index 88ae6a4fc1b8..d811f7d1b569 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/LoadJobConfigurationTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/LoadJobConfigurationTest.java
    @@ -14,13 +14,13 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     
     import com.google.common.collect.ImmutableList;
    -import com.google.gcloud.bigquery.JobInfo.CreateDisposition;
    -import com.google.gcloud.bigquery.JobInfo.WriteDisposition;
    +import com.google.cloud.bigquery.JobInfo.CreateDisposition;
    +import com.google.cloud.bigquery.JobInfo.WriteDisposition;
     
     import org.junit.Test;
     
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/OptionTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/OptionTest.java
    similarity index 96%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/OptionTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/OptionTest.java
    index 42f19830fb6c..2e40d63ff80c 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/OptionTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/OptionTest.java
    @@ -14,13 +14,13 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertNotEquals;
     import static org.junit.Assert.assertNull;
     
    -import com.google.gcloud.bigquery.spi.BigQueryRpc;
    +import com.google.cloud.bigquery.spi.BigQueryRpc;
     
     import org.junit.Rule;
     import org.junit.Test;
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryJobConfigurationTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/QueryJobConfigurationTest.java
    similarity index 97%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryJobConfigurationTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/QueryJobConfigurationTest.java
    index 1ef270ee69cf..6ad2facb3288 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryJobConfigurationTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/QueryJobConfigurationTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertNotNull;
    @@ -23,9 +23,9 @@
     
     import com.google.common.collect.ImmutableList;
     import com.google.common.collect.ImmutableMap;
    -import com.google.gcloud.bigquery.JobInfo.CreateDisposition;
    -import com.google.gcloud.bigquery.JobInfo.WriteDisposition;
    -import com.google.gcloud.bigquery.QueryJobConfiguration.Priority;
    +import com.google.cloud.bigquery.JobInfo.CreateDisposition;
    +import com.google.cloud.bigquery.JobInfo.WriteDisposition;
    +import com.google.cloud.bigquery.QueryJobConfiguration.Priority;
     
     import org.junit.Test;
     
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryRequestTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/QueryRequestTest.java
    similarity index 99%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryRequestTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/QueryRequestTest.java
    index 7875dee9e315..f3682aa78457 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryRequestTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/QueryRequestTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertNull;
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryResponseTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/QueryResponseTest.java
    similarity index 99%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryResponseTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/QueryResponseTest.java
    index 08e885c8b3aa..8eae6a9e03e3 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryResponseTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/QueryResponseTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryResultTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/QueryResultTest.java
    similarity index 98%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryResultTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/QueryResultTest.java
    index b6810ed93143..db4df54bfc0c 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryResultTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/QueryResultTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryStageTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/QueryStageTest.java
    similarity index 98%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryStageTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/QueryStageTest.java
    index ac60967a8bee..0270abe7efd1 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/QueryStageTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/QueryStageTest.java
    @@ -14,13 +14,13 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     
     import com.google.api.services.bigquery.model.ExplainQueryStep;
     import com.google.common.collect.ImmutableList;
    -import com.google.gcloud.bigquery.QueryStage.QueryStep;
    +import com.google.cloud.bigquery.QueryStage.QueryStep;
     
     import org.junit.Test;
     
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SchemaTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/SchemaTest.java
    similarity index 98%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SchemaTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/SchemaTest.java
    index d24268d2e7cd..312b7e674991 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SchemaTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/SchemaTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/SerializationTest.java
    similarity index 97%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/SerializationTest.java
    index 61e763f9a539..9797a5a5139e 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/SerializationTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/SerializationTest.java
    @@ -14,14 +14,14 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import com.google.common.collect.ImmutableList;
     import com.google.common.collect.ImmutableMap;
    -import com.google.gcloud.AuthCredentials;
    -import com.google.gcloud.BaseSerializationTest;
    -import com.google.gcloud.Restorable;
    -import com.google.gcloud.bigquery.StandardTableDefinition.StreamingBuffer;
    +import com.google.cloud.AuthCredentials;
    +import com.google.cloud.BaseSerializationTest;
    +import com.google.cloud.Restorable;
    +import com.google.cloud.bigquery.StandardTableDefinition.StreamingBuffer;
     
     import java.io.Serializable;
     import java.nio.charset.StandardCharsets;
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableDataWriteChannelTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/TableDataWriteChannelTest.java
    similarity index 97%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableDataWriteChannelTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/TableDataWriteChannelTest.java
    index 4c1be470ff57..646d82603950 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableDataWriteChannelTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/TableDataWriteChannelTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.easymock.EasyMock.anyObject;
     import static org.easymock.EasyMock.capture;
    @@ -30,10 +30,10 @@
     import static org.junit.Assert.assertTrue;
     import static org.junit.Assert.fail;
     
    -import com.google.gcloud.RestorableState;
    -import com.google.gcloud.WriteChannel;
    -import com.google.gcloud.bigquery.spi.BigQueryRpc;
    -import com.google.gcloud.bigquery.spi.BigQueryRpcFactory;
    +import com.google.cloud.RestorableState;
    +import com.google.cloud.WriteChannel;
    +import com.google.cloud.bigquery.spi.BigQueryRpc;
    +import com.google.cloud.bigquery.spi.BigQueryRpcFactory;
     
     import org.easymock.Capture;
     import org.easymock.CaptureType;
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableDefinitionTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/TableDefinitionTest.java
    similarity index 97%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableDefinitionTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/TableDefinitionTest.java
    index d1e3635d00cb..7c7cf2568462 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableDefinitionTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/TableDefinitionTest.java
    @@ -14,12 +14,12 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertTrue;
     
    -import com.google.gcloud.bigquery.StandardTableDefinition.StreamingBuffer;
    +import com.google.cloud.bigquery.StandardTableDefinition.StreamingBuffer;
     
     import org.junit.Test;
     
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableIdTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/TableIdTest.java
    similarity index 98%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableIdTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/TableIdTest.java
    index bc013bfa5c31..7db923bdd7ca 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableIdTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/TableIdTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableInfoTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/TableInfoTest.java
    similarity index 99%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableInfoTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/TableInfoTest.java
    index 84d224f220cb..0b67f4be3adf 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableInfoTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/TableInfoTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/TableTest.java
    similarity index 98%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/TableTest.java
    index cab71d4705d5..58f187c1cedd 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/TableTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/TableTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.easymock.EasyMock.createMock;
     import static org.easymock.EasyMock.createStrictMock;
    @@ -31,9 +31,9 @@
     import com.google.common.collect.ImmutableList;
     import com.google.common.collect.ImmutableMap;
     import com.google.common.collect.Iterators;
    -import com.google.gcloud.Page;
    -import com.google.gcloud.PageImpl;
    -import com.google.gcloud.bigquery.InsertAllRequest.RowToInsert;
    +import com.google.cloud.Page;
    +import com.google.cloud.PageImpl;
    +import com.google.cloud.bigquery.InsertAllRequest.RowToInsert;
     
     import org.junit.After;
     import org.junit.Test;
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/UserDefinedFunctionTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/UserDefinedFunctionTest.java
    similarity index 98%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/UserDefinedFunctionTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/UserDefinedFunctionTest.java
    index 2741aaed89a5..db6cada4e0e5 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/UserDefinedFunctionTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/UserDefinedFunctionTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/ViewDefinitionTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/ViewDefinitionTest.java
    similarity index 98%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/ViewDefinitionTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/ViewDefinitionTest.java
    index ebab7a6e87ca..25c880bc8b78 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/ViewDefinitionTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/ViewDefinitionTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertTrue;
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/WriteChannelConfigurationTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/WriteChannelConfigurationTest.java
    similarity index 97%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/WriteChannelConfigurationTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/WriteChannelConfigurationTest.java
    index dfde4795dacd..03ffbcaf38e3 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/WriteChannelConfigurationTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/WriteChannelConfigurationTest.java
    @@ -14,14 +14,14 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery;
    +package com.google.cloud.bigquery;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertNull;
     
     import com.google.common.collect.ImmutableList;
    -import com.google.gcloud.bigquery.JobInfo.CreateDisposition;
    -import com.google.gcloud.bigquery.JobInfo.WriteDisposition;
    +import com.google.cloud.bigquery.JobInfo.CreateDisposition;
    +import com.google.cloud.bigquery.JobInfo.WriteDisposition;
     
     import org.junit.Test;
     
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java
    similarity index 95%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java
    index a75c12f86c1d..738245bc80f7 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/it/ITBigQueryTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery.it;
    +package com.google.cloud.bigquery.it;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
    @@ -25,49 +25,49 @@
     
     import com.google.common.collect.ImmutableList;
     import com.google.common.collect.ImmutableMap;
    -import com.google.gcloud.Page;
    -import com.google.gcloud.WriteChannel;
    -import com.google.gcloud.bigquery.BigQuery;
    -import com.google.gcloud.bigquery.BigQuery.DatasetField;
    -import com.google.gcloud.bigquery.BigQuery.DatasetOption;
    -import com.google.gcloud.bigquery.BigQuery.JobField;
    -import com.google.gcloud.bigquery.BigQuery.JobListOption;
    -import com.google.gcloud.bigquery.BigQuery.JobOption;
    -import com.google.gcloud.bigquery.BigQuery.TableField;
    -import com.google.gcloud.bigquery.BigQuery.TableOption;
    -import com.google.gcloud.bigquery.BigQueryError;
    -import com.google.gcloud.bigquery.BigQueryException;
    -import com.google.gcloud.bigquery.CopyJobConfiguration;
    -import com.google.gcloud.bigquery.Dataset;
    -import com.google.gcloud.bigquery.DatasetId;
    -import com.google.gcloud.bigquery.DatasetInfo;
    -import com.google.gcloud.bigquery.ExternalTableDefinition;
    -import com.google.gcloud.bigquery.ExtractJobConfiguration;
    -import com.google.gcloud.bigquery.Field;
    -import com.google.gcloud.bigquery.FieldValue;
    -import com.google.gcloud.bigquery.FormatOptions;
    -import com.google.gcloud.bigquery.InsertAllRequest;
    -import com.google.gcloud.bigquery.InsertAllResponse;
    -import com.google.gcloud.bigquery.Job;
    -import com.google.gcloud.bigquery.JobInfo;
    -import com.google.gcloud.bigquery.JobStatistics;
    -import com.google.gcloud.bigquery.LoadJobConfiguration;
    -import com.google.gcloud.bigquery.QueryJobConfiguration;
    -import com.google.gcloud.bigquery.QueryRequest;
    -import com.google.gcloud.bigquery.QueryResponse;
    -import com.google.gcloud.bigquery.Schema;
    -import com.google.gcloud.bigquery.StandardTableDefinition;
    -import com.google.gcloud.bigquery.Table;
    -import com.google.gcloud.bigquery.TableDefinition;
    -import com.google.gcloud.bigquery.TableId;
    -import com.google.gcloud.bigquery.TableInfo;
    -import com.google.gcloud.bigquery.ViewDefinition;
    -import com.google.gcloud.bigquery.WriteChannelConfiguration;
    -import com.google.gcloud.bigquery.testing.RemoteBigQueryHelper;
    -import com.google.gcloud.storage.BlobInfo;
    -import com.google.gcloud.storage.BucketInfo;
    -import com.google.gcloud.storage.Storage;
    -import com.google.gcloud.storage.testing.RemoteStorageHelper;
    +import com.google.cloud.Page;
    +import com.google.cloud.WriteChannel;
    +import com.google.cloud.bigquery.BigQuery;
    +import com.google.cloud.bigquery.BigQuery.DatasetField;
    +import com.google.cloud.bigquery.BigQuery.DatasetOption;
    +import com.google.cloud.bigquery.BigQuery.JobField;
    +import com.google.cloud.bigquery.BigQuery.JobListOption;
    +import com.google.cloud.bigquery.BigQuery.JobOption;
    +import com.google.cloud.bigquery.BigQuery.TableField;
    +import com.google.cloud.bigquery.BigQuery.TableOption;
    +import com.google.cloud.bigquery.BigQueryError;
    +import com.google.cloud.bigquery.BigQueryException;
    +import com.google.cloud.bigquery.CopyJobConfiguration;
    +import com.google.cloud.bigquery.Dataset;
    +import com.google.cloud.bigquery.DatasetId;
    +import com.google.cloud.bigquery.DatasetInfo;
    +import com.google.cloud.bigquery.ExternalTableDefinition;
    +import com.google.cloud.bigquery.ExtractJobConfiguration;
    +import com.google.cloud.bigquery.Field;
    +import com.google.cloud.bigquery.FieldValue;
    +import com.google.cloud.bigquery.FormatOptions;
    +import com.google.cloud.bigquery.InsertAllRequest;
    +import com.google.cloud.bigquery.InsertAllResponse;
    +import com.google.cloud.bigquery.Job;
    +import com.google.cloud.bigquery.JobInfo;
    +import com.google.cloud.bigquery.JobStatistics;
    +import com.google.cloud.bigquery.LoadJobConfiguration;
    +import com.google.cloud.bigquery.QueryJobConfiguration;
    +import com.google.cloud.bigquery.QueryRequest;
    +import com.google.cloud.bigquery.QueryResponse;
    +import com.google.cloud.bigquery.Schema;
    +import com.google.cloud.bigquery.StandardTableDefinition;
    +import com.google.cloud.bigquery.Table;
    +import com.google.cloud.bigquery.TableDefinition;
    +import com.google.cloud.bigquery.TableId;
    +import com.google.cloud.bigquery.TableInfo;
    +import com.google.cloud.bigquery.ViewDefinition;
    +import com.google.cloud.bigquery.WriteChannelConfiguration;
    +import com.google.cloud.bigquery.testing.RemoteBigQueryHelper;
    +import com.google.cloud.storage.BlobInfo;
    +import com.google.cloud.storage.BucketInfo;
    +import com.google.cloud.storage.Storage;
    +import com.google.cloud.storage.testing.RemoteStorageHelper;
     
     import org.junit.AfterClass;
     import org.junit.BeforeClass;
    diff --git a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/testing/RemoteBigQueryHelperTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/testing/RemoteBigQueryHelperTest.java
    similarity index 95%
    rename from gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/testing/RemoteBigQueryHelperTest.java
    rename to gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/testing/RemoteBigQueryHelperTest.java
    index a9c0f63d68ea..46badf7bb7be 100644
    --- a/gcloud-java-bigquery/src/test/java/com/google/gcloud/bigquery/testing/RemoteBigQueryHelperTest.java
    +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/testing/RemoteBigQueryHelperTest.java
    @@ -14,14 +14,14 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.bigquery.testing;
    +package com.google.cloud.bigquery.testing;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertTrue;
     
    -import com.google.gcloud.bigquery.BigQuery;
    -import com.google.gcloud.bigquery.BigQuery.DatasetDeleteOption;
    -import com.google.gcloud.bigquery.BigQueryOptions;
    +import com.google.cloud.bigquery.BigQuery;
    +import com.google.cloud.bigquery.BigQuery.DatasetDeleteOption;
    +import com.google.cloud.bigquery.BigQueryOptions;
     
     import org.easymock.EasyMock;
     import org.junit.Rule;
    diff --git a/gcloud-java-contrib/README.md b/gcloud-java-contrib/README.md
    index f0ead8c79dea..c83b1f47e7a6 100644
    --- a/gcloud-java-contrib/README.md
    +++ b/gcloud-java-contrib/README.md
    @@ -5,7 +5,7 @@ Packages that provide higher-level abstraction/functionality for common gcloud-j
     
     [![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java)
     [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master)
    -[![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-bigquery.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-bigquery.svg)
    +[![Maven](https://img.shields.io/maven-central/v/com.google.cloud/gcloud-java-bigquery.svg)]( https://img.shields.io/maven-central/v/com.google.cloud/gcloud-java-bigquery.svg)
     [![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java)
     [![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969)
     
    @@ -14,18 +14,18 @@ Quickstart
     If you are using Maven, add this to your pom.xml file
     ```xml
     
    -  com.google.gcloud
    +  com.google.cloud
       gcloud-java-contrib
       0.1.7
     
     ```
     If you are using Gradle, add this to your dependencies
     ```Groovy
    -compile 'com.google.gcloud:gcloud-java-contrib:0.1.7'
    +compile 'com.google.cloud:gcloud-java-contrib:0.1.7'
     ```
     If you are using SBT, add this to your dependencies
     ```Scala
    -libraryDependencies += "com.google.gcloud" % "gcloud-java-contrib" % "0.1.7"
    +libraryDependencies += "com.google.cloud" % "gcloud-java-contrib" % "0.1.7"
     ```
     
     Java Versions
    diff --git a/gcloud-java-contrib/pom.xml b/gcloud-java-contrib/pom.xml
    index 1ef855a1ae5d..bf9d58e18c9e 100644
    --- a/gcloud-java-contrib/pom.xml
    +++ b/gcloud-java-contrib/pom.xml
    @@ -8,7 +8,7 @@
         Contains packages that provide higher-level abstraction/functionality for common gcloud-java use cases.
       
       
    -    com.google.gcloud
    +    com.google.cloud
         gcloud-java-pom
         0.1.8-SNAPSHOT
       
    diff --git a/gcloud-java-core/README.md b/gcloud-java-core/README.md
    index 067505179bc9..ca34b9789d8a 100644
    --- a/gcloud-java-core/README.md
    +++ b/gcloud-java-core/README.md
    @@ -5,30 +5,30 @@ This module provides common functionality required by service-specific modules o
     
     [![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java)
     [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master)
    -[![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-core.svg)](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-core.svg)
    +[![Maven](https://img.shields.io/maven-central/v/com.google.cloud/gcloud-java-core.svg)](https://img.shields.io/maven-central/v/com.google.cloud/gcloud-java-core.svg)
     [![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java)
     [![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969)
     
     -  [Homepage] (https://googlecloudplatform.github.io/gcloud-java/)
    --  [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/package-summary.html)
    +-  [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/package-summary.html)
     
     Quickstart
     ----------
     If you are using Maven, add this to your pom.xml file
     ```xml
     
    -  com.google.gcloud
    +  com.google.cloud
       gcloud-java-core
       0.1.7
     
     ```
     If you are using Gradle, add this to your dependencies
     ```Groovy
    -compile 'com.google.gcloud:gcloud-java-core:0.1.7'
    +compile 'com.google.cloud:gcloud-java-core:0.1.7'
     ```
     If you are using SBT, add this to your dependencies
     ```Scala
    -libraryDependencies += "com.google.gcloud" % "gcloud-java-core" % "0.1.7"
    +libraryDependencies += "com.google.cloud" % "gcloud-java-core" % "0.1.7"
     ```
     
     Troubleshooting
    diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml
    index df116b0b1be4..2a164ae3288c 100644
    --- a/gcloud-java-core/pom.xml
    +++ b/gcloud-java-core/pom.xml
    @@ -8,7 +8,7 @@
         Core module for the gcloud-java.
       
       
    -    com.google.gcloud
    +    com.google.cloud
         gcloud-java-pom
         0.1.8-SNAPSHOT
       
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java b/gcloud-java-core/src/main/java/com/google/cloud/AuthCredentials.java
    similarity index 99%
    rename from gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java
    rename to gcloud-java-core/src/main/java/com/google/cloud/AuthCredentials.java
    index 4cd424bed993..ec5a631f5f54 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/AuthCredentials.java
    +++ b/gcloud-java-core/src/main/java/com/google/cloud/AuthCredentials.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import static com.google.common.base.Preconditions.checkNotNull;
     
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/BaseService.java b/gcloud-java-core/src/main/java/com/google/cloud/BaseService.java
    similarity index 95%
    rename from gcloud-java-core/src/main/java/com/google/gcloud/BaseService.java
    rename to gcloud-java-core/src/main/java/com/google/cloud/BaseService.java
    index d9e6f2db7c95..d0476b66c29c 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/BaseService.java
    +++ b/gcloud-java-core/src/main/java/com/google/cloud/BaseService.java
    @@ -14,9 +14,9 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
    -import com.google.gcloud.ExceptionHandler.Interceptor;
    +import com.google.cloud.ExceptionHandler.Interceptor;
     
     /**
      * Base class for service objects.
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/BaseServiceException.java b/gcloud-java-core/src/main/java/com/google/cloud/BaseServiceException.java
    similarity index 99%
    rename from gcloud-java-core/src/main/java/com/google/gcloud/BaseServiceException.java
    rename to gcloud-java-core/src/main/java/com/google/cloud/BaseServiceException.java
    index 4e0d03e0073a..6dc87f4abb3e 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/BaseServiceException.java
    +++ b/gcloud-java-core/src/main/java/com/google/cloud/BaseServiceException.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import com.google.api.client.googleapis.json.GoogleJsonError;
     import com.google.api.client.googleapis.json.GoogleJsonResponseException;
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/BaseWriteChannel.java b/gcloud-java-core/src/main/java/com/google/cloud/BaseWriteChannel.java
    similarity index 99%
    rename from gcloud-java-core/src/main/java/com/google/gcloud/BaseWriteChannel.java
    rename to gcloud-java-core/src/main/java/com/google/cloud/BaseWriteChannel.java
    index 1d18a5a27e81..f803cd6bbacf 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/BaseWriteChannel.java
    +++ b/gcloud-java-core/src/main/java/com/google/cloud/BaseWriteChannel.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import com.google.common.base.MoreObjects;
     
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ExceptionHandler.java b/gcloud-java-core/src/main/java/com/google/cloud/ExceptionHandler.java
    similarity index 99%
    rename from gcloud-java-core/src/main/java/com/google/gcloud/ExceptionHandler.java
    rename to gcloud-java-core/src/main/java/com/google/cloud/ExceptionHandler.java
    index 0b3c923d1eb9..e72eb1edcf88 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/ExceptionHandler.java
    +++ b/gcloud-java-core/src/main/java/com/google/cloud/ExceptionHandler.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import static com.google.common.base.Preconditions.checkNotNull;
     
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java b/gcloud-java-core/src/main/java/com/google/cloud/FieldSelector.java
    similarity index 99%
    rename from gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java
    rename to gcloud-java-core/src/main/java/com/google/cloud/FieldSelector.java
    index fc6e77242082..a2b92d752eaf 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/FieldSelector.java
    +++ b/gcloud-java-core/src/main/java/com/google/cloud/FieldSelector.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import com.google.common.base.Function;
     import com.google.common.base.Joiner;
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java b/gcloud-java-core/src/main/java/com/google/cloud/IamPolicy.java
    similarity index 99%
    rename from gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java
    rename to gcloud-java-core/src/main/java/com/google/cloud/IamPolicy.java
    index 9cce4b23c864..1f214e1b0f71 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/IamPolicy.java
    +++ b/gcloud-java-core/src/main/java/com/google/cloud/IamPolicy.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import static com.google.common.base.Preconditions.checkArgument;
     import static com.google.common.base.Preconditions.checkNotNull;
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/Identity.java b/gcloud-java-core/src/main/java/com/google/cloud/Identity.java
    similarity index 99%
    rename from gcloud-java-core/src/main/java/com/google/gcloud/Identity.java
    rename to gcloud-java-core/src/main/java/com/google/cloud/Identity.java
    index 687a76ffc42c..fab70dfe6d37 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/Identity.java
    +++ b/gcloud-java-core/src/main/java/com/google/cloud/Identity.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import static com.google.common.base.Preconditions.checkNotNull;
     
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/Page.java b/gcloud-java-core/src/main/java/com/google/cloud/Page.java
    similarity index 98%
    rename from gcloud-java-core/src/main/java/com/google/gcloud/Page.java
    rename to gcloud-java-core/src/main/java/com/google/cloud/Page.java
    index fe192c0c0ceb..8881a98b46ae 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/Page.java
    +++ b/gcloud-java-core/src/main/java/com/google/cloud/Page.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import java.util.Iterator;
     
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/PageImpl.java b/gcloud-java-core/src/main/java/com/google/cloud/PageImpl.java
    similarity index 99%
    rename from gcloud-java-core/src/main/java/com/google/gcloud/PageImpl.java
    rename to gcloud-java-core/src/main/java/com/google/cloud/PageImpl.java
    index 2dc031ab9bd4..de1a3506b750 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/PageImpl.java
    +++ b/gcloud-java-core/src/main/java/com/google/cloud/PageImpl.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import com.google.common.collect.AbstractIterator;
     import com.google.common.collect.ImmutableMap;
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ReadChannel.java b/gcloud-java-core/src/main/java/com/google/cloud/ReadChannel.java
    similarity index 98%
    rename from gcloud-java-core/src/main/java/com/google/gcloud/ReadChannel.java
    rename to gcloud-java-core/src/main/java/com/google/cloud/ReadChannel.java
    index 7537c5a8ce0b..2afb8b2d5b32 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/ReadChannel.java
    +++ b/gcloud-java-core/src/main/java/com/google/cloud/ReadChannel.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import java.io.Closeable;
     import java.io.IOException;
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/Restorable.java b/gcloud-java-core/src/main/java/com/google/cloud/Restorable.java
    similarity index 98%
    rename from gcloud-java-core/src/main/java/com/google/gcloud/Restorable.java
    rename to gcloud-java-core/src/main/java/com/google/cloud/Restorable.java
    index d92c70eb9883..e2a515c7861a 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/Restorable.java
    +++ b/gcloud-java-core/src/main/java/com/google/cloud/Restorable.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     /**
      * Implementation of this interface can persist their state and restore from it.
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/RestorableState.java b/gcloud-java-core/src/main/java/com/google/cloud/RestorableState.java
    similarity index 97%
    rename from gcloud-java-core/src/main/java/com/google/gcloud/RestorableState.java
    rename to gcloud-java-core/src/main/java/com/google/cloud/RestorableState.java
    index 009a86e545f5..4874756527f7 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/RestorableState.java
    +++ b/gcloud-java-core/src/main/java/com/google/cloud/RestorableState.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     /**
      * A common interface for restorable states. Implementations of {@code RestorableState} are capable
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/RetryHelper.java b/gcloud-java-core/src/main/java/com/google/cloud/RetryHelper.java
    similarity index 99%
    rename from gcloud-java-core/src/main/java/com/google/gcloud/RetryHelper.java
    rename to gcloud-java-core/src/main/java/com/google/cloud/RetryHelper.java
    index 9b9c1f6a3124..48bd5fcf9324 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/RetryHelper.java
    +++ b/gcloud-java-core/src/main/java/com/google/cloud/RetryHelper.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import static com.google.common.base.Preconditions.checkNotNull;
     import static java.lang.StrictMath.max;
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/RetryParams.java b/gcloud-java-core/src/main/java/com/google/cloud/RetryParams.java
    similarity index 99%
    rename from gcloud-java-core/src/main/java/com/google/gcloud/RetryParams.java
    rename to gcloud-java-core/src/main/java/com/google/cloud/RetryParams.java
    index 0b7381b9c3c5..02ffda18134f 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/RetryParams.java
    +++ b/gcloud-java-core/src/main/java/com/google/cloud/RetryParams.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import static com.google.common.base.Preconditions.checkArgument;
     
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/Service.java b/gcloud-java-core/src/main/java/com/google/cloud/Service.java
    similarity index 96%
    rename from gcloud-java-core/src/main/java/com/google/gcloud/Service.java
    rename to gcloud-java-core/src/main/java/com/google/cloud/Service.java
    index 60bc26670f2e..a3797eca30b9 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/Service.java
    +++ b/gcloud-java-core/src/main/java/com/google/cloud/Service.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     /**
      * Interface for service objects.
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceAccountSigner.java b/gcloud-java-core/src/main/java/com/google/cloud/ServiceAccountSigner.java
    similarity index 98%
    rename from gcloud-java-core/src/main/java/com/google/gcloud/ServiceAccountSigner.java
    rename to gcloud-java-core/src/main/java/com/google/cloud/ServiceAccountSigner.java
    index 2456d85e98a7..c68d14116aa8 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceAccountSigner.java
    +++ b/gcloud-java-core/src/main/java/com/google/cloud/ServiceAccountSigner.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import java.util.Objects;
     
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceFactory.java b/gcloud-java-core/src/main/java/com/google/cloud/ServiceFactory.java
    similarity index 97%
    rename from gcloud-java-core/src/main/java/com/google/gcloud/ServiceFactory.java
    rename to gcloud-java-core/src/main/java/com/google/cloud/ServiceFactory.java
    index 1727e9c3976f..bb06127c77c6 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceFactory.java
    +++ b/gcloud-java-core/src/main/java/com/google/cloud/ServiceFactory.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     /**
      * A base interface for all service factories.
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/cloud/ServiceOptions.java
    similarity index 99%
    rename from gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java
    rename to gcloud-java-core/src/main/java/com/google/cloud/ServiceOptions.java
    index 5f47b2cd05aa..e08d0cd9d155 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/ServiceOptions.java
    +++ b/gcloud-java-core/src/main/java/com/google/cloud/ServiceOptions.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import static com.google.common.base.MoreObjects.firstNonNull;
     import static com.google.common.base.Preconditions.checkArgument;
    @@ -28,7 +28,7 @@
     import com.google.auth.http.HttpCredentialsAdapter;
     import com.google.common.collect.Iterables;
     import com.google.common.io.Files;
    -import com.google.gcloud.spi.ServiceRpcFactory;
    +import com.google.cloud.spi.ServiceRpcFactory;
     
     import org.json.JSONException;
     import org.json.JSONObject;
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/WriteChannel.java b/gcloud-java-core/src/main/java/com/google/cloud/WriteChannel.java
    similarity index 98%
    rename from gcloud-java-core/src/main/java/com/google/gcloud/WriteChannel.java
    rename to gcloud-java-core/src/main/java/com/google/cloud/WriteChannel.java
    index e6f06e23dc04..636bc60d0243 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/WriteChannel.java
    +++ b/gcloud-java-core/src/main/java/com/google/cloud/WriteChannel.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import java.io.Closeable;
     import java.nio.channels.WritableByteChannel;
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/package-info.java b/gcloud-java-core/src/main/java/com/google/cloud/package-info.java
    similarity index 96%
    rename from gcloud-java-core/src/main/java/com/google/gcloud/package-info.java
    rename to gcloud-java-core/src/main/java/com/google/cloud/package-info.java
    index d527640c99f9..8b548e3d26e8 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/package-info.java
    +++ b/gcloud-java-core/src/main/java/com/google/cloud/package-info.java
    @@ -17,4 +17,4 @@
     /**
      * Core classes for the {@code gcloud-java} library.
      */
    -package com.google.gcloud;
    +package com.google.cloud;
    diff --git a/gcloud-java-core/src/main/java/com/google/gcloud/spi/ServiceRpcFactory.java b/gcloud-java-core/src/main/java/com/google/cloud/spi/ServiceRpcFactory.java
    similarity index 93%
    rename from gcloud-java-core/src/main/java/com/google/gcloud/spi/ServiceRpcFactory.java
    rename to gcloud-java-core/src/main/java/com/google/cloud/spi/ServiceRpcFactory.java
    index 8ee964ca8f39..21a061f4a5dc 100644
    --- a/gcloud-java-core/src/main/java/com/google/gcloud/spi/ServiceRpcFactory.java
    +++ b/gcloud-java-core/src/main/java/com/google/cloud/spi/ServiceRpcFactory.java
    @@ -14,9 +14,9 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.spi;
    +package com.google.cloud.spi;
     
    -import com.google.gcloud.ServiceOptions;
    +import com.google.cloud.ServiceOptions;
     
     /**
      * A base interface for all service RPC factories. Implementation must provide a public no-arg
    diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/BaseSerializationTest.java b/gcloud-java-core/src/test/java/com/google/cloud/BaseSerializationTest.java
    similarity index 99%
    rename from gcloud-java-core/src/test/java/com/google/gcloud/BaseSerializationTest.java
    rename to gcloud-java-core/src/test/java/com/google/cloud/BaseSerializationTest.java
    index e9ab3d47984b..57603b9026d8 100644
    --- a/gcloud-java-core/src/test/java/com/google/gcloud/BaseSerializationTest.java
    +++ b/gcloud-java-core/src/test/java/com/google/cloud/BaseSerializationTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import static com.google.common.base.MoreObjects.firstNonNull;
     import static org.junit.Assert.assertEquals;
    diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/BaseServiceExceptionTest.java b/gcloud-java-core/src/test/java/com/google/cloud/BaseServiceExceptionTest.java
    similarity index 98%
    rename from gcloud-java-core/src/test/java/com/google/gcloud/BaseServiceExceptionTest.java
    rename to gcloud-java-core/src/test/java/com/google/cloud/BaseServiceExceptionTest.java
    index e3c6abb7d1ee..52bc3b2b51a4 100644
    --- a/gcloud-java-core/src/test/java/com/google/gcloud/BaseServiceExceptionTest.java
    +++ b/gcloud-java-core/src/test/java/com/google/cloud/BaseServiceExceptionTest.java
    @@ -14,9 +14,9 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
    -import static com.google.gcloud.BaseServiceException.UNKNOWN_CODE;
    +import static com.google.cloud.BaseServiceException.UNKNOWN_CODE;
     import static org.easymock.EasyMock.createMock;
     import static org.easymock.EasyMock.expect;
     import static org.easymock.EasyMock.replay;
    diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/BaseWriteChannelTest.java b/gcloud-java-core/src/test/java/com/google/cloud/BaseWriteChannelTest.java
    similarity index 98%
    rename from gcloud-java-core/src/test/java/com/google/gcloud/BaseWriteChannelTest.java
    rename to gcloud-java-core/src/test/java/com/google/cloud/BaseWriteChannelTest.java
    index b44157b6557b..fc476b11ae6e 100644
    --- a/gcloud-java-core/src/test/java/com/google/gcloud/BaseWriteChannelTest.java
    +++ b/gcloud-java-core/src/test/java/com/google/cloud/BaseWriteChannelTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import static junit.framework.TestCase.assertFalse;
     import static junit.framework.TestCase.assertTrue;
    @@ -22,7 +22,7 @@
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertNull;
     
    -import com.google.gcloud.spi.ServiceRpcFactory;
    +import com.google.cloud.spi.ServiceRpcFactory;
     
     import org.junit.Before;
     import org.junit.Rule;
    diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/ExceptionHandlerTest.java b/gcloud-java-core/src/test/java/com/google/cloud/ExceptionHandlerTest.java
    similarity index 97%
    rename from gcloud-java-core/src/test/java/com/google/gcloud/ExceptionHandlerTest.java
    rename to gcloud-java-core/src/test/java/com/google/cloud/ExceptionHandlerTest.java
    index cedc995ddbd0..ddbd2ced841c 100644
    --- a/gcloud-java-core/src/test/java/com/google/gcloud/ExceptionHandlerTest.java
    +++ b/gcloud-java-core/src/test/java/com/google/cloud/ExceptionHandlerTest.java
    @@ -14,14 +14,14 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import static org.junit.Assert.assertFalse;
     import static org.junit.Assert.assertTrue;
     import static org.junit.Assert.fail;
     
    -import com.google.gcloud.ExceptionHandler.Interceptor;
    -import com.google.gcloud.ExceptionHandler.Interceptor.RetryResult;
    +import com.google.cloud.ExceptionHandler.Interceptor;
    +import com.google.cloud.ExceptionHandler.Interceptor.RetryResult;
     
     import org.junit.Rule;
     import org.junit.Test;
    diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/FieldSelectorHelperTest.java b/gcloud-java-core/src/test/java/com/google/cloud/FieldSelectorHelperTest.java
    similarity index 97%
    rename from gcloud-java-core/src/test/java/com/google/gcloud/FieldSelectorHelperTest.java
    rename to gcloud-java-core/src/test/java/com/google/cloud/FieldSelectorHelperTest.java
    index 9871c942180e..6cdc4bdfb924 100644
    --- a/gcloud-java-core/src/test/java/com/google/gcloud/FieldSelectorHelperTest.java
    +++ b/gcloud-java-core/src/test/java/com/google/cloud/FieldSelectorHelperTest.java
    @@ -14,13 +14,13 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertTrue;
     
     import com.google.common.collect.ImmutableList;
    -import com.google.gcloud.FieldSelector.Helper;
    +import com.google.cloud.FieldSelector.Helper;
     
     import org.junit.Test;
     
    diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java b/gcloud-java-core/src/test/java/com/google/cloud/IamPolicyTest.java
    similarity index 99%
    rename from gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java
    rename to gcloud-java-core/src/test/java/com/google/cloud/IamPolicyTest.java
    index 235c2c2b1c85..e79cfd96554c 100644
    --- a/gcloud-java-core/src/test/java/com/google/gcloud/IamPolicyTest.java
    +++ b/gcloud-java-core/src/test/java/com/google/cloud/IamPolicyTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertNotEquals;
    diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/IdentityTest.java b/gcloud-java-core/src/test/java/com/google/cloud/IdentityTest.java
    similarity index 99%
    rename from gcloud-java-core/src/test/java/com/google/gcloud/IdentityTest.java
    rename to gcloud-java-core/src/test/java/com/google/cloud/IdentityTest.java
    index a42bc9db7abd..e720503c547d 100644
    --- a/gcloud-java-core/src/test/java/com/google/gcloud/IdentityTest.java
    +++ b/gcloud-java-core/src/test/java/com/google/cloud/IdentityTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertNull;
    diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/PageImplTest.java b/gcloud-java-core/src/test/java/com/google/cloud/PageImplTest.java
    similarity index 98%
    rename from gcloud-java-core/src/test/java/com/google/gcloud/PageImplTest.java
    rename to gcloud-java-core/src/test/java/com/google/cloud/PageImplTest.java
    index 4389171fb49c..07d979ad857c 100644
    --- a/gcloud-java-core/src/test/java/com/google/gcloud/PageImplTest.java
    +++ b/gcloud-java-core/src/test/java/com/google/cloud/PageImplTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import static org.junit.Assert.assertEquals;
     
    diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/RetryHelperTest.java b/gcloud-java-core/src/test/java/com/google/cloud/RetryHelperTest.java
    similarity index 98%
    rename from gcloud-java-core/src/test/java/com/google/gcloud/RetryHelperTest.java
    rename to gcloud-java-core/src/test/java/com/google/cloud/RetryHelperTest.java
    index 9a7cc2104f4a..7012813be2d0 100644
    --- a/gcloud-java-core/src/test/java/com/google/gcloud/RetryHelperTest.java
    +++ b/gcloud-java-core/src/test/java/com/google/cloud/RetryHelperTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import static java.util.concurrent.Executors.callable;
     import static org.junit.Assert.assertEquals;
    @@ -24,8 +24,8 @@
     
     import com.google.common.base.Stopwatch;
     import com.google.common.base.Ticker;
    -import com.google.gcloud.RetryHelper.NonRetriableException;
    -import com.google.gcloud.RetryHelper.RetriesExhaustedException;
    +import com.google.cloud.RetryHelper.NonRetriableException;
    +import com.google.cloud.RetryHelper.RetriesExhaustedException;
     
     import org.junit.Test;
     
    diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/RetryParamsTest.java b/gcloud-java-core/src/test/java/com/google/cloud/RetryParamsTest.java
    similarity index 87%
    rename from gcloud-java-core/src/test/java/com/google/gcloud/RetryParamsTest.java
    rename to gcloud-java-core/src/test/java/com/google/cloud/RetryParamsTest.java
    index eae44693929b..c3041053110b 100644
    --- a/gcloud-java-core/src/test/java/com/google/gcloud/RetryParamsTest.java
    +++ b/gcloud-java-core/src/test/java/com/google/cloud/RetryParamsTest.java
    @@ -14,18 +14,18 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
    -import static com.google.gcloud.RetryParams.DEFAULT_INITIAL_RETRY_DELAY_MILLIS;
    -import static com.google.gcloud.RetryParams.DEFAULT_MAX_RETRY_DELAY_MILLIS;
    -import static com.google.gcloud.RetryParams.DEFAULT_RETRY_DELAY_BACKOFF_FACTOR;
    -import static com.google.gcloud.RetryParams.DEFAULT_RETRY_MAX_ATTEMPTS;
    -import static com.google.gcloud.RetryParams.DEFAULT_RETRY_MIN_ATTEMPTS;
    -import static com.google.gcloud.RetryParams.DEFAULT_TOTAL_RETRY_PERIOD_MILLIS;
    +import static com.google.cloud.RetryParams.DEFAULT_INITIAL_RETRY_DELAY_MILLIS;
    +import static com.google.cloud.RetryParams.DEFAULT_MAX_RETRY_DELAY_MILLIS;
    +import static com.google.cloud.RetryParams.DEFAULT_RETRY_DELAY_BACKOFF_FACTOR;
    +import static com.google.cloud.RetryParams.DEFAULT_RETRY_MAX_ATTEMPTS;
    +import static com.google.cloud.RetryParams.DEFAULT_RETRY_MIN_ATTEMPTS;
    +import static com.google.cloud.RetryParams.DEFAULT_TOTAL_RETRY_PERIOD_MILLIS;
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.fail;
     
    -import com.google.gcloud.RetryParams.Builder;
    +import com.google.cloud.RetryParams.Builder;
     
     import org.junit.Test;
     import org.junit.runner.RunWith;
    diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java b/gcloud-java-core/src/test/java/com/google/cloud/SerializationTest.java
    similarity index 98%
    rename from gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java
    rename to gcloud-java-core/src/test/java/com/google/cloud/SerializationTest.java
    index 8cf58f554de8..72d622239f3c 100644
    --- a/gcloud-java-core/src/test/java/com/google/gcloud/SerializationTest.java
    +++ b/gcloud-java-core/src/test/java/com/google/cloud/SerializationTest.java
    @@ -14,10 +14,10 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import com.google.common.collect.ImmutableList;
    -import com.google.gcloud.ServiceAccountSigner.SigningException;
    +import com.google.cloud.ServiceAccountSigner.SigningException;
     
     import java.io.ByteArrayInputStream;
     import java.io.IOException;
    diff --git a/gcloud-java-core/src/test/java/com/google/gcloud/ServiceOptionsTest.java b/gcloud-java-core/src/test/java/com/google/cloud/ServiceOptionsTest.java
    similarity index 97%
    rename from gcloud-java-core/src/test/java/com/google/gcloud/ServiceOptionsTest.java
    rename to gcloud-java-core/src/test/java/com/google/cloud/ServiceOptionsTest.java
    index d0e3db2d2a55..b6f7a5453ddc 100644
    --- a/gcloud-java-core/src/test/java/com/google/gcloud/ServiceOptionsTest.java
    +++ b/gcloud-java-core/src/test/java/com/google/cloud/ServiceOptionsTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud;
    +package com.google.cloud;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertNotEquals;
    @@ -22,10 +22,10 @@
     import static org.junit.Assert.assertTrue;
     import static org.junit.Assert.fail;
     
    -import com.google.gcloud.ServiceOptions.Clock;
    -import com.google.gcloud.ServiceOptions.DefaultHttpTransportFactory;
    -import com.google.gcloud.ServiceOptions.HttpTransportFactory;
    -import com.google.gcloud.spi.ServiceRpcFactory;
    +import com.google.cloud.ServiceOptions.Clock;
    +import com.google.cloud.ServiceOptions.DefaultHttpTransportFactory;
    +import com.google.cloud.ServiceOptions.HttpTransportFactory;
    +import com.google.cloud.spi.ServiceRpcFactory;
     
     import org.easymock.EasyMock;
     import org.junit.Test;
    diff --git a/gcloud-java-datastore/README.md b/gcloud-java-datastore/README.md
    index 69cf039472a3..e74349d11e3f 100644
    --- a/gcloud-java-datastore/README.md
    +++ b/gcloud-java-datastore/README.md
    @@ -5,12 +5,12 @@ Java idiomatic client for [Google Cloud Datastore] (https://cloud.google.com/dat
     
     [![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java)
     [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master)
    -[![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-datastore.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-datastore.svg)
    +[![Maven](https://img.shields.io/maven-central/v/com.google.cloud/gcloud-java-datastore.svg)]( https://img.shields.io/maven-central/v/com.google.cloud/gcloud-java-datastore.svg)
     [![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java)
     [![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969)
     
     -  [Homepage] (https://googlecloudplatform.github.io/gcloud-java/)
    --  [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/datastore/package-summary.html)
    +-  [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/datastore/package-summary.html)
     
     > Note: This client is a work-in-progress, and may occasionally
     > make backwards-incompatible changes.
    @@ -20,23 +20,23 @@ Quickstart
     If you are using Maven, add this to your pom.xml file
     ```xml
     
    -  com.google.gcloud
    +  com.google.cloud
       gcloud-java-datastore
       0.1.7
     
     ```
     If you are using Gradle, add this to your dependencies
     ```Groovy
    -compile 'com.google.gcloud:gcloud-java-datastore:0.1.7'
    +compile 'com.google.cloud:gcloud-java-datastore:0.1.7'
     ```
     If you are using SBT, add this to your dependencies
     ```Scala
    -libraryDependencies += "com.google.gcloud" % "gcloud-java-datastore" % "0.1.7"
    +libraryDependencies += "com.google.cloud" % "gcloud-java-datastore" % "0.1.7"
     ```
     
     Example Application
     --------------------
    -[`DatastoreExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/DatastoreExample.java) is a simple command line interface for the Cloud Datastore.  Read more about using the application on the [`DatastoreExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/datastore/DatastoreExample.html).
    +[`DatastoreExample`](../gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/DatastoreExample.java) is a simple command line interface for the Cloud Datastore.  Read more about using the application on the [`DatastoreExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/cloud/examples/datastore/DatastoreExample.html).
     
     Authentication
     --------------
    @@ -70,8 +70,8 @@ You'll need to obtain the `gcloud-java-datastore` library.  See the [Quickstart]
     To make authenticated requests to Google Cloud Datastore, you must create a service object with credentials. You can then make API calls by calling methods on the Datastore service object. The simplest way to authenticate is to use [Application Default Credentials](https://developers.google.com/identity/protocols/application-default-credentials). These credentials are automatically inferred from your environment, so you only need the following code to create your service object:
     
     ```java
    -import com.google.gcloud.datastore.Datastore;
    -import com.google.gcloud.datastore.DatastoreOptions;
    +import com.google.cloud.datastore.Datastore;
    +import com.google.cloud.datastore.DatastoreOptions;
     
     Datastore datastore = DatastoreOptions.defaultInstance().service();
     ```
    @@ -82,9 +82,9 @@ For other authentication options, see the [Authentication](https://github.com/Go
     Objects in Datastore are known as entities. Entities are grouped by "kind" and have keys for easy access. In this code snippet, we will create a new entity representing a person and store that data by the person's email.  First, add the following imports at the top of your file:
     
     ```java
    -import com.google.gcloud.datastore.Entity;
    -import com.google.gcloud.datastore.Key;
    -import com.google.gcloud.datastore.KeyFactory;
    +import com.google.cloud.datastore.Entity;
    +import com.google.cloud.datastore.Key;
    +import com.google.cloud.datastore.KeyFactory;
     ```
     
     Then add the following code to put an entity in Datastore.
    @@ -112,10 +112,10 @@ In addition to retrieving entities by their keys, you can perform queries to ret
     Suppose that you've added more people to Datastore, and now you want to find all people whose favorite food is pizza. Import the following:
     
     ```java
    -import com.google.gcloud.datastore.Query;
    -import com.google.gcloud.datastore.QueryResults;
    -import com.google.gcloud.datastore.StructuredQuery;
    -import com.google.gcloud.datastore.StructuredQuery.PropertyFilter;
    +import com.google.cloud.datastore.Query;
    +import com.google.cloud.datastore.QueryResults;
    +import com.google.cloud.datastore.StructuredQuery;
    +import com.google.cloud.datastore.StructuredQuery.PropertyFilter;
     ```
     
     Then add the following code to your program:
    @@ -137,7 +137,7 @@ Cloud Datastore relies on indexing to run queries. Indexing is turned on by defa
     #### Complete source code
     
     In
    -[AddEntitiesAndRunQuery.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/AddEntitiesAndRunQuery.java)
    +[AddEntitiesAndRunQuery.java](../gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/snippets/AddEntitiesAndRunQuery.java)
     we put together all the code shown above into one program. The program assumes that you are
     running on Compute Engine or from your own desktop. To run the example on App Engine, simply move
     the code from the main method to your application's servlet class and change the print statements to
    @@ -191,4 +191,4 @@ Apache 2.0 - See [LICENSE] for more information.
     [cloud-platform]: https://cloud.google.com/
     [cloud-datastore-docs]: https://cloud.google.com/datastore/docs
     [cloud-datastore-activation]: https://cloud.google.com/datastore/docs/activate
    -[datastore-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/datastore/package-summary.html
    +[datastore-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/datastore/package-summary.html
    diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml
    index 22498ab505f4..43d901aac100 100644
    --- a/gcloud-java-datastore/pom.xml
    +++ b/gcloud-java-datastore/pom.xml
    @@ -8,7 +8,7 @@
         Java idiomatic client for Google Cloud Datastore.
       
       
    -    com.google.gcloud
    +    com.google.cloud
         gcloud-java-pom
         0.1.8-SNAPSHOT
       
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/BaseDatastoreBatchWriter.java
    similarity index 99%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/BaseDatastoreBatchWriter.java
    index 3aa0d38f45f1..8804ef7e8dda 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseDatastoreBatchWriter.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/BaseDatastoreBatchWriter.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import com.google.common.base.Preconditions;
     import com.google.common.collect.Iterables;
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/BaseEntity.java
    similarity index 96%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/BaseEntity.java
    index c7d7219abfb8..c7417faa79f3 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseEntity.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/BaseEntity.java
    @@ -14,19 +14,19 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    -
    -import static com.google.gcloud.datastore.BlobValue.of;
    -import static com.google.gcloud.datastore.BooleanValue.of;
    -import static com.google.gcloud.datastore.DateTimeValue.of;
    -import static com.google.gcloud.datastore.DoubleValue.of;
    -import static com.google.gcloud.datastore.EntityValue.of;
    -import static com.google.gcloud.datastore.KeyValue.of;
    -import static com.google.gcloud.datastore.LatLngValue.of;
    -import static com.google.gcloud.datastore.ListValue.of;
    -import static com.google.gcloud.datastore.LongValue.of;
    -import static com.google.gcloud.datastore.NullValue.of;
    -import static com.google.gcloud.datastore.StringValue.of;
    +package com.google.cloud.datastore;
    +
    +import static com.google.cloud.datastore.BlobValue.of;
    +import static com.google.cloud.datastore.BooleanValue.of;
    +import static com.google.cloud.datastore.DateTimeValue.of;
    +import static com.google.cloud.datastore.DoubleValue.of;
    +import static com.google.cloud.datastore.EntityValue.of;
    +import static com.google.cloud.datastore.KeyValue.of;
    +import static com.google.cloud.datastore.LatLngValue.of;
    +import static com.google.cloud.datastore.ListValue.of;
    +import static com.google.cloud.datastore.LongValue.of;
    +import static com.google.cloud.datastore.NullValue.of;
    +import static com.google.cloud.datastore.StringValue.of;
     
     import com.google.common.collect.ImmutableSortedMap;
     import com.google.common.collect.Maps;
    @@ -43,7 +43,7 @@
      * A base class for entities (key and properties).
      * An entity is a Google Cloud Datastore persistent data object.
      * An entity holds one or more properties, represented by a name (as {@link String})
    - * and a value (as {@link com.google.gcloud.datastore.Value}), and may be associated with a
    + * and a value (as {@link com.google.cloud.datastore.Value}), and may be associated with a
      * key. For a list of possible values see {@link ValueType}.
      *
      * @see Google Cloud Datastore
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/BaseKey.java
    similarity index 95%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/BaseKey.java
    index f2bb87e740d0..73f98562e0e5 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BaseKey.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/BaseKey.java
    @@ -14,11 +14,11 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
    -import static com.google.gcloud.datastore.Validator.validateDatabase;
    -import static com.google.gcloud.datastore.Validator.validateKind;
    -import static com.google.gcloud.datastore.Validator.validateNamespace;
    +import static com.google.cloud.datastore.Validator.validateDatabase;
    +import static com.google.cloud.datastore.Validator.validateKind;
    +import static com.google.cloud.datastore.Validator.validateNamespace;
     
     import com.google.common.base.Preconditions;
     import com.google.common.collect.ImmutableList;
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Batch.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Batch.java
    similarity index 97%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Batch.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Batch.java
    index 5306a685195a..dbe6f86c4b99 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Batch.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Batch.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import java.util.List;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/BatchImpl.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/BatchImpl.java
    index 303e9703f4cc..603e9464c9c1 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BatchImpl.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/BatchImpl.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import java.util.ArrayList;
     import java.util.Iterator;
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Blob.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Blob.java
    similarity index 99%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Blob.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Blob.java
    index b86c4ccb963e..0fd7213d7be3 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Blob.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Blob.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static com.google.common.base.Preconditions.checkNotNull;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BlobValue.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/BlobValue.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BlobValue.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/BlobValue.java
    index 19d545e1790c..d65bb6ee8652 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BlobValue.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/BlobValue.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static com.google.datastore.v1beta3.Value.BLOB_VALUE_FIELD_NUMBER;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BooleanValue.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/BooleanValue.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BooleanValue.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/BooleanValue.java
    index 3e1bdc14e822..c5d7910b5984 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/BooleanValue.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/BooleanValue.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static com.google.datastore.v1beta3.Value.BOOLEAN_VALUE_FIELD_NUMBER;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Cursor.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Cursor.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Cursor.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Cursor.java
    index c4d2b37672da..f9d51638b35b 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Cursor.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Cursor.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static com.google.common.base.Preconditions.checkNotNull;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Datastore.java
    similarity index 97%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Datastore.java
    index c0efaa52b4e8..8b2afcb5ad0c 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Datastore.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Datastore.java
    @@ -14,9 +14,9 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
    -import com.google.gcloud.Service;
    +import com.google.cloud.Service;
     
     import java.util.Iterator;
     import java.util.List;
    @@ -35,7 +35,7 @@ public interface Datastore extends Service, DatastoreReaderWri
     
       /**
        * A callback for running with a transactional
    -   * {@link com.google.gcloud.datastore.DatastoreReaderWriter}.
    +   * {@link com.google.cloud.datastore.DatastoreReaderWriter}.
        * The associated transaction will be committed after a successful return from the {@code run}
        * method. Any propagated exception will cause the transaction to be rolled-back.
        *
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreBatchWriter.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreBatchWriter.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreBatchWriter.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreBatchWriter.java
    index 3a80452349dc..918711aa2822 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreBatchWriter.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreBatchWriter.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import java.util.List;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreException.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreException.java
    similarity index 93%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreException.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreException.java
    index a940fe573f93..c097980aec29 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreException.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreException.java
    @@ -14,12 +14,12 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import com.google.common.collect.ImmutableSet;
    -import com.google.gcloud.BaseServiceException;
    -import com.google.gcloud.RetryHelper.RetryHelperException;
    -import com.google.gcloud.RetryHelper.RetryInterruptedException;
    +import com.google.cloud.BaseServiceException;
    +import com.google.cloud.RetryHelper.RetryHelperException;
    +import com.google.cloud.RetryHelper.RetryInterruptedException;
     
     import java.io.IOException;
     import java.util.Set;
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreFactory.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreFactory.java
    similarity index 90%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreFactory.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreFactory.java
    index b1f5a026a3e5..1a1b49cf71b3 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreFactory.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreFactory.java
    @@ -14,10 +14,10 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     
    -import com.google.gcloud.ServiceFactory;
    +import com.google.cloud.ServiceFactory;
     
     /**
      * An interface for Datastore factories.
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreHelper.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreHelper.java
    index e3cf9c055576..04b3e96c5175 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreHelper.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreHelper.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import com.google.common.collect.Iterators;
     import com.google.common.collect.Maps;
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java
    similarity index 97%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java
    index 4193931ab990..a05c4229f291 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreImpl.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import com.google.common.base.MoreObjects;
     import com.google.common.base.Preconditions;
    @@ -23,12 +23,12 @@
     import com.google.common.collect.Iterables;
     import com.google.common.collect.Sets;
     import com.google.datastore.v1beta3.ReadOptions.ReadConsistency;
    -import com.google.gcloud.BaseService;
    -import com.google.gcloud.RetryHelper;
    -import com.google.gcloud.RetryHelper.RetryHelperException;
    -import com.google.gcloud.RetryParams;
    -import com.google.gcloud.datastore.ReadOption.EventualConsistency;
    -import com.google.gcloud.datastore.spi.DatastoreRpc;
    +import com.google.cloud.BaseService;
    +import com.google.cloud.RetryHelper;
    +import com.google.cloud.RetryHelper.RetryHelperException;
    +import com.google.cloud.RetryParams;
    +import com.google.cloud.datastore.ReadOption.EventualConsistency;
    +import com.google.cloud.datastore.spi.DatastoreRpc;
     import com.google.protobuf.ByteString;
     
     import java.util.ArrayList;
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java
    similarity index 93%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java
    index 8761867f29e0..a9466939060a 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreOptions.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java
    @@ -14,16 +14,16 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
    -import static com.google.gcloud.datastore.Validator.validateNamespace;
    +import static com.google.cloud.datastore.Validator.validateNamespace;
     
     import com.google.common.base.MoreObjects;
     import com.google.common.collect.ImmutableSet;
    -import com.google.gcloud.ServiceOptions;
    -import com.google.gcloud.datastore.spi.DatastoreRpc;
    -import com.google.gcloud.datastore.spi.DatastoreRpcFactory;
    -import com.google.gcloud.datastore.spi.DefaultDatastoreRpc;
    +import com.google.cloud.ServiceOptions;
    +import com.google.cloud.datastore.spi.DatastoreRpc;
    +import com.google.cloud.datastore.spi.DatastoreRpcFactory;
    +import com.google.cloud.datastore.spi.DefaultDatastoreRpc;
     
     import java.lang.reflect.Method;
     import java.util.Objects;
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReader.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreReader.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReader.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreReader.java
    index 3d6e5ec73243..e3989f29ef8b 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReader.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreReader.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import java.util.Iterator;
     import java.util.List;
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReaderWriter.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreReaderWriter.java
    similarity index 95%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReaderWriter.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreReaderWriter.java
    index c64f86a8d0a3..16b6af881929 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreReaderWriter.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreReaderWriter.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     
     /**
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreWriter.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreWriter.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreWriter.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreWriter.java
    index 66ba98aed9e9..2771bb39ea60 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DatastoreWriter.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreWriter.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import java.util.List;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DateTime.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DateTime.java
    index 5e8664395802..fd72edc9806f 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTime.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DateTime.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static com.google.common.base.Preconditions.checkNotNull;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTimeValue.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DateTimeValue.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTimeValue.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DateTimeValue.java
    index e9c42ffabf4c..8ffa98ea5e74 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DateTimeValue.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DateTimeValue.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static com.google.datastore.v1beta3.Value.TIMESTAMP_VALUE_FIELD_NUMBER;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DoubleValue.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DoubleValue.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DoubleValue.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DoubleValue.java
    index d7409d08fe63..51d175bb51c4 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/DoubleValue.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DoubleValue.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static com.google.datastore.v1beta3.Value.DOUBLE_VALUE_FIELD_NUMBER;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Entity.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Entity.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Entity.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Entity.java
    index d012eff14422..3449693fe521 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Entity.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Entity.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static com.google.common.base.Preconditions.checkNotNull;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityQuery.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/EntityQuery.java
    similarity index 97%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityQuery.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/EntityQuery.java
    index 3eda20eed3dc..40249b7ff26b 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityQuery.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/EntityQuery.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     /**
      * An implementation of a Google Cloud Datastore entity query that can be constructed by providing
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/EntityValue.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/EntityValue.java
    index 4a327383afd4..582310e01e78 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/EntityValue.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/EntityValue.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static com.google.datastore.v1beta3.Value.ENTITY_VALUE_FIELD_NUMBER;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/FullEntity.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/FullEntity.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/FullEntity.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/FullEntity.java
    index 25225b853556..aa88a92d3554 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/FullEntity.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/FullEntity.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     /**
      * A full entity is a {@link BaseEntity} that holds all the properties associated with a
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/GqlQuery.java
    similarity index 99%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/GqlQuery.java
    index 342eaf7bd8eb..7a34bf4b1f19 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/GqlQuery.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/GqlQuery.java
    @@ -14,10 +14,10 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static com.google.common.base.Preconditions.checkNotNull;
    -import static com.google.gcloud.datastore.Validator.validateNamespace;
    +import static com.google.cloud.datastore.Validator.validateNamespace;
     
     import com.google.common.base.MoreObjects;
     import com.google.common.collect.ImmutableList;
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/IncompleteKey.java
    similarity index 99%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/IncompleteKey.java
    index 31039b6826f7..18959005596c 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/IncompleteKey.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/IncompleteKey.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import com.google.common.base.Preconditions;
     import com.google.common.collect.ImmutableList;
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Key.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Key.java
    similarity index 99%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Key.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Key.java
    index ccc36ef1f533..7cb70d259e82 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Key.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Key.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static java.nio.charset.StandardCharsets.UTF_8;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/KeyFactory.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/KeyFactory.java
    index 947880111ea4..f7fc17448a6d 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyFactory.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/KeyFactory.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import com.google.common.collect.ImmutableList;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyQuery.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/KeyQuery.java
    similarity index 97%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyQuery.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/KeyQuery.java
    index 4224f2d07ce5..d84dd5b26c20 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyQuery.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/KeyQuery.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     /**
      * An implementation of a Google Cloud Datastore key-only query that can be constructed by providing
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyValue.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/KeyValue.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyValue.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/KeyValue.java
    index fc1823730d12..78d4caebac79 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/KeyValue.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/KeyValue.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static com.google.datastore.v1beta3.Value.KEY_VALUE_FIELD_NUMBER;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LatLng.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/LatLng.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LatLng.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/LatLng.java
    index 7e2b42fac4d3..72f9e9f4f04f 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LatLng.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/LatLng.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static com.google.common.base.Preconditions.checkArgument;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LatLngValue.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/LatLngValue.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LatLngValue.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/LatLngValue.java
    index 91723f710816..80faa427cf28 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LatLngValue.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/LatLngValue.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static com.google.datastore.v1beta3.Value.GEO_POINT_VALUE_FIELD_NUMBER;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ListValue.java
    similarity index 97%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ListValue.java
    index ad73303cd62d..f3692e5395bd 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ListValue.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ListValue.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static com.google.datastore.v1beta3.Value.ARRAY_VALUE_FIELD_NUMBER;
     
    @@ -90,7 +90,7 @@ public Builder addValue(Value first, Value... other) {
         /**
          * Copy the list of values.
          *
    -     * @see com.google.gcloud.datastore.Value.BaseBuilder#set(java.lang.Object)
    +     * @see com.google.cloud.datastore.Value.BaseBuilder#set(java.lang.Object)
          */
         @Override
         public Builder set(List> values) {
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LongValue.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/LongValue.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LongValue.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/LongValue.java
    index 18cdead6280a..ba79af7fb233 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/LongValue.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/LongValue.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static com.google.datastore.v1beta3.Value.INTEGER_VALUE_FIELD_NUMBER;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/NullValue.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/NullValue.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/NullValue.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/NullValue.java
    index ed314200b8bb..8b7ab9bfa49b 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/NullValue.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/NullValue.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static com.google.common.base.Preconditions.checkArgument;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/PathElement.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/PathElement.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/PathElement.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/PathElement.java
    index 1759cc82bcea..413b0786e021 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/PathElement.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/PathElement.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static com.google.common.base.Preconditions.checkArgument;
     import static com.google.common.base.Preconditions.checkNotNull;
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntity.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ProjectionEntity.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntity.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ProjectionEntity.java
    index f8af814245ab..519262a2e9c6 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntity.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ProjectionEntity.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import com.google.protobuf.ByteString;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntityQuery.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ProjectionEntityQuery.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntityQuery.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ProjectionEntityQuery.java
    index d0e9920f3a61..5ccfed549941 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ProjectionEntityQuery.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ProjectionEntityQuery.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     /**
      * An implementation of a Google Cloud Datastore projection entity query that can be constructed by
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Query.java
    similarity index 99%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Query.java
    index dd0ea9f1b798..c37e784d04ee 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Query.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Query.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static com.google.common.base.Preconditions.checkNotNull;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/QueryResults.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/QueryResults.java
    index a6e5971936dd..a907ddcad6b9 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResults.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/QueryResults.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import java.util.Iterator;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/QueryResultsImpl.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/QueryResultsImpl.java
    index ec3a652c6131..b46f9821cc52 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/QueryResultsImpl.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/QueryResultsImpl.java
    @@ -14,12 +14,12 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import com.google.common.base.Preconditions;
     import com.google.common.collect.AbstractIterator;
     import com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType;
    -import com.google.gcloud.datastore.Query.ResultType;
    +import com.google.cloud.datastore.Query.ResultType;
     import com.google.protobuf.ByteString;
     
     import java.util.Iterator;
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/RawValue.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/RawValue.java
    index cd64bcdeff05..81fec851a6dd 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/RawValue.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/RawValue.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     public final class RawValue extends Value {
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ReadOption.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ReadOption.java
    index f0de06d1651d..baadfe4f9bd2 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ReadOption.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ReadOption.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import com.google.common.collect.ImmutableMap;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Serializable.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Serializable.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Serializable.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Serializable.java
    index 89d19bcfd892..2e305935f32e 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Serializable.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Serializable.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import com.google.protobuf.GeneratedMessage;
     import com.google.protobuf.InvalidProtocolBufferException;
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StringValue.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/StringValue.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StringValue.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/StringValue.java
    index 4b2c8e123be7..c47d2d9a61a4 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StringValue.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/StringValue.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static com.google.datastore.v1beta3.Value.STRING_VALUE_FIELD_NUMBER;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/StructuredQuery.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/StructuredQuery.java
    index d91956d6c1db..9028ba6e536f 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/StructuredQuery.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/StructuredQuery.java
    @@ -14,16 +14,16 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static com.google.common.base.Preconditions.checkNotNull;
    -import static com.google.gcloud.datastore.BlobValue.of;
    -import static com.google.gcloud.datastore.BooleanValue.of;
    -import static com.google.gcloud.datastore.DateTimeValue.of;
    -import static com.google.gcloud.datastore.DoubleValue.of;
    -import static com.google.gcloud.datastore.KeyValue.of;
    -import static com.google.gcloud.datastore.LongValue.of;
    -import static com.google.gcloud.datastore.StringValue.of;
    +import static com.google.cloud.datastore.BlobValue.of;
    +import static com.google.cloud.datastore.BooleanValue.of;
    +import static com.google.cloud.datastore.DateTimeValue.of;
    +import static com.google.cloud.datastore.DoubleValue.of;
    +import static com.google.cloud.datastore.KeyValue.of;
    +import static com.google.cloud.datastore.LongValue.of;
    +import static com.google.cloud.datastore.StringValue.of;
     
     import com.google.common.base.MoreObjects;
     import com.google.common.base.MoreObjects.ToStringHelper;
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Transaction.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Transaction.java
    similarity index 99%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Transaction.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Transaction.java
    index 78ee217f31e7..9ecf2c8caeb6 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Transaction.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Transaction.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import java.util.Iterator;
     import java.util.List;
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/TransactionImpl.java
    similarity index 99%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/TransactionImpl.java
    index 469c14e1c78a..9016d561905a 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/TransactionImpl.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/TransactionImpl.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import com.google.protobuf.ByteString;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Validator.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Validator.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Validator.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Validator.java
    index dc7069cebf62..31857af73ddc 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Validator.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Validator.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static com.google.common.base.Preconditions.checkArgument;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Value.java
    similarity index 99%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Value.java
    index 4a87e48fa862..c2c503c8f9db 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/Value.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Value.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static com.google.common.base.Preconditions.checkNotNull;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueBuilder.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ValueBuilder.java
    similarity index 97%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueBuilder.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ValueBuilder.java
    index ee1579c8444d..0328d4a0637b 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueBuilder.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ValueBuilder.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     /**
      * A common interface for Value builders.
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueMarshaller.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ValueMarshaller.java
    similarity index 96%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueMarshaller.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ValueMarshaller.java
    index da4c27b57a8d..89aeede965e5 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueMarshaller.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ValueMarshaller.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     /**
      * A common interface for Value marshallers.
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ValueType.java
    similarity index 98%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ValueType.java
    index ab16126336f5..2b023654742a 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/ValueType.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ValueType.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import com.google.common.collect.ImmutableMap;
     
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/package-info.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/package-info.java
    similarity index 90%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/package-info.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/package-info.java
    index f1ec9b925e7c..f51c9545ecd2 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/package-info.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/package-info.java
    @@ -19,7 +19,7 @@
      *
      * 

    Here's a simple usage example for using gcloud-java from App/Compute Engine. This example * shows how to create a Datastore entity. For the complete source code see - * + * * CreateEntity.java. *

     {@code
      * Datastore datastore = DatastoreOptions.defaultInstance().service();
    @@ -35,7 +35,7 @@
      * 

    * This second example shows how to get and update a Datastore entity if it exists. For the complete * source code see - * + * * UpdateEntity.java. *

     {@code
      * Datastore datastore = DatastoreOptions.defaultInstance().service();
    @@ -57,4 +57,4 @@
      *
      * @see Google Cloud Datastore
      */
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/spi/DatastoreRpc.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/spi/DatastoreRpc.java
    similarity index 96%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/spi/DatastoreRpc.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/spi/DatastoreRpc.java
    index 0aff146835e0..dc3e9ce27249 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/spi/DatastoreRpc.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/spi/DatastoreRpc.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore.spi;
    +package com.google.cloud.datastore.spi;
     
     import com.google.datastore.v1beta3.AllocateIdsRequest;
     import com.google.datastore.v1beta3.AllocateIdsResponse;
    @@ -28,7 +28,7 @@
     import com.google.datastore.v1beta3.RollbackResponse;
     import com.google.datastore.v1beta3.RunQueryRequest;
     import com.google.datastore.v1beta3.RunQueryResponse;
    -import com.google.gcloud.datastore.DatastoreException;
    +import com.google.cloud.datastore.DatastoreException;
     
     /**
      * Provides access to the remote Datastore service.
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/spi/DatastoreRpcFactory.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/spi/DatastoreRpcFactory.java
    similarity index 85%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/spi/DatastoreRpcFactory.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/spi/DatastoreRpcFactory.java
    index 0979b2203037..c16a7ddb0fea 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/spi/DatastoreRpcFactory.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/spi/DatastoreRpcFactory.java
    @@ -14,10 +14,10 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore.spi;
    +package com.google.cloud.datastore.spi;
     
    -import com.google.gcloud.datastore.DatastoreOptions;
    -import com.google.gcloud.spi.ServiceRpcFactory;
    +import com.google.cloud.datastore.DatastoreOptions;
    +import com.google.cloud.spi.ServiceRpcFactory;
     
     /**
      * An interface for Datastore RPC factory.
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/spi/DefaultDatastoreRpc.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/spi/DefaultDatastoreRpc.java
    similarity index 97%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/spi/DefaultDatastoreRpc.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/spi/DefaultDatastoreRpc.java
    index 1fb0fa3a26c6..04d8c4cc8dd4 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/spi/DefaultDatastoreRpc.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/spi/DefaultDatastoreRpc.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore.spi;
    +package com.google.cloud.datastore.spi;
     
     import com.google.datastore.v1beta3.AllocateIdsRequest;
     import com.google.datastore.v1beta3.AllocateIdsResponse;
    @@ -28,8 +28,8 @@
     import com.google.datastore.v1beta3.RollbackResponse;
     import com.google.datastore.v1beta3.RunQueryRequest;
     import com.google.datastore.v1beta3.RunQueryResponse;
    -import com.google.gcloud.datastore.DatastoreException;
    -import com.google.gcloud.datastore.DatastoreOptions;
    +import com.google.cloud.datastore.DatastoreException;
    +import com.google.cloud.datastore.DatastoreOptions;
     
     import java.io.IOException;
     import java.net.InetAddress;
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalDatastoreHelper.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/testing/LocalDatastoreHelper.java
    similarity index 99%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalDatastoreHelper.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/testing/LocalDatastoreHelper.java
    index c37265965337..9d04ddbf930e 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/LocalDatastoreHelper.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/testing/LocalDatastoreHelper.java
    @@ -14,15 +14,15 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore.testing;
    +package com.google.cloud.datastore.testing;
     
     import static com.google.common.base.MoreObjects.firstNonNull;
     import static com.google.common.base.Preconditions.checkArgument;
     
     import com.google.common.base.Strings;
    -import com.google.gcloud.AuthCredentials;
    -import com.google.gcloud.RetryParams;
    -import com.google.gcloud.datastore.DatastoreOptions;
    +import com.google.cloud.AuthCredentials;
    +import com.google.cloud.RetryParams;
    +import com.google.cloud.datastore.DatastoreOptions;
     
     import java.io.BufferedInputStream;
     import java.io.BufferedOutputStream;
    diff --git a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/package-info.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/testing/package-info.java
    similarity index 96%
    rename from gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/package-info.java
    rename to gcloud-java-datastore/src/main/java/com/google/cloud/datastore/testing/package-info.java
    index fae9860275c6..1a00a8c13cf2 100644
    --- a/gcloud-java-datastore/src/main/java/com/google/gcloud/datastore/testing/package-info.java
    +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/testing/package-info.java
    @@ -33,4 +33,4 @@
      * @see 
      *     gcloud-java tools for testing
      */
    -package com.google.gcloud.datastore.testing;
    +package com.google.cloud.datastore.testing;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/BaseDatastoreBatchWriterTest.java
    similarity index 99%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/BaseDatastoreBatchWriterTest.java
    index 7e5938358299..6a30314082b7 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseDatastoreBatchWriterTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/BaseDatastoreBatchWriterTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.easymock.EasyMock.expect;
     import static org.easymock.EasyMock.replay;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/BaseEntityTest.java
    similarity index 99%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/BaseEntityTest.java
    index bd8bdeebc6da..f5100b14dac5 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseEntityTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/BaseEntityTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/BaseKeyTest.java
    similarity index 99%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/BaseKeyTest.java
    index 974231d51c21..abbfbd3a2f16 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BaseKeyTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/BaseKeyTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertTrue;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BlobTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/BlobTest.java
    similarity index 98%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BlobTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/BlobTest.java
    index 1bb7c3fc476e..009c1a31ee1e 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BlobTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/BlobTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertArrayEquals;
     import static org.junit.Assert.assertEquals;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BlobValueTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/BlobValueTest.java
    similarity index 97%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BlobValueTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/BlobValueTest.java
    index 2a4c0dc956e3..3c6586939a54 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BlobValueTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/BlobValueTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BooleanValueTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/BooleanValueTest.java
    similarity index 97%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BooleanValueTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/BooleanValueTest.java
    index bff3d67c9465..2750c70e992b 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/BooleanValueTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/BooleanValueTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/CursorTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/CursorTest.java
    similarity index 97%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/CursorTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/CursorTest.java
    index 72fd3d13cebe..34bdd59bf196 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/CursorTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/CursorTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertNotEquals;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreExceptionTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreExceptionTest.java
    similarity index 96%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreExceptionTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreExceptionTest.java
    index e5bc50eee046..cf086ff25ba0 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreExceptionTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreExceptionTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.easymock.EasyMock.createMock;
     import static org.easymock.EasyMock.expect;
    @@ -26,8 +26,8 @@
     import static org.junit.Assert.assertTrue;
     import static org.junit.Assert.fail;
     
    -import com.google.gcloud.BaseServiceException;
    -import com.google.gcloud.RetryHelper;
    +import com.google.cloud.BaseServiceException;
    +import com.google.cloud.RetryHelper;
     
     import org.junit.Test;
     
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreHelperTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreHelperTest.java
    similarity index 98%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreHelperTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreHelperTest.java
    index 61b266a9abc2..7f32de7b947b 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreHelperTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreHelperTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.easymock.EasyMock.createMock;
     import static org.easymock.EasyMock.createStrictMock;
    @@ -29,7 +29,7 @@
     
     import com.google.common.collect.ImmutableList;
     import com.google.common.collect.Iterators;
    -import com.google.gcloud.datastore.Datastore.TransactionCallable;
    +import com.google.cloud.datastore.Datastore.TransactionCallable;
     
     import org.easymock.EasyMock;
     import org.junit.Test;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreOptionsTest.java
    similarity index 94%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreOptionsTest.java
    index fa74243049de..786f3ea79623 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreOptionsTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreOptionsTest.java
    @@ -14,14 +14,14 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertSame;
     import static org.junit.Assert.assertTrue;
     
    -import com.google.gcloud.datastore.spi.DatastoreRpc;
    -import com.google.gcloud.datastore.spi.DatastoreRpcFactory;
    +import com.google.cloud.datastore.spi.DatastoreRpc;
    +import com.google.cloud.datastore.spi.DatastoreRpcFactory;
     
     import org.easymock.EasyMock;
     import org.junit.Before;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java
    similarity index 98%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java
    index 4f2487916fd8..cd028067ca83 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DatastoreTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
    @@ -37,13 +37,13 @@
     import com.google.datastore.v1beta3.ReadOptions.ReadConsistency;
     import com.google.datastore.v1beta3.RunQueryRequest;
     import com.google.datastore.v1beta3.RunQueryResponse;
    -import com.google.gcloud.RetryParams;
    -import com.google.gcloud.datastore.Query.ResultType;
    -import com.google.gcloud.datastore.StructuredQuery.OrderBy;
    -import com.google.gcloud.datastore.StructuredQuery.PropertyFilter;
    -import com.google.gcloud.datastore.spi.DatastoreRpc;
    -import com.google.gcloud.datastore.spi.DatastoreRpcFactory;
    -import com.google.gcloud.datastore.testing.LocalDatastoreHelper;
    +import com.google.cloud.RetryParams;
    +import com.google.cloud.datastore.Query.ResultType;
    +import com.google.cloud.datastore.StructuredQuery.OrderBy;
    +import com.google.cloud.datastore.StructuredQuery.PropertyFilter;
    +import com.google.cloud.datastore.spi.DatastoreRpc;
    +import com.google.cloud.datastore.spi.DatastoreRpcFactory;
    +import com.google.cloud.datastore.testing.LocalDatastoreHelper;
     import com.google.protobuf.ByteString;
     
     import org.easymock.EasyMock;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DateTimeTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DateTimeTest.java
    similarity index 98%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DateTimeTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DateTimeTest.java
    index 23f3951a5dc3..34c2f7b7e29f 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DateTimeTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DateTimeTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertNotEquals;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DateTimeValueTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DateTimeValueTest.java
    similarity index 97%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DateTimeValueTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DateTimeValueTest.java
    index c90e8c88ba52..8262e97241fa 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DateTimeValueTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DateTimeValueTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DoubleValueTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DoubleValueTest.java
    similarity index 97%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DoubleValueTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DoubleValueTest.java
    index 24d9113ce873..ecc80fd14454 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/DoubleValueTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DoubleValueTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/EntityTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/EntityTest.java
    similarity index 98%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/EntityTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/EntityTest.java
    index 30bdf16d9397..c3aad6f285ff 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/EntityTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/EntityTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertNotEquals;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/EntityValueTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/EntityValueTest.java
    similarity index 97%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/EntityValueTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/EntityValueTest.java
    index e7df91ac0016..07fb3bb0d5cf 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/EntityValueTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/EntityValueTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/FullEntityTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/FullEntityTest.java
    similarity index 98%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/FullEntityTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/FullEntityTest.java
    index 1d62c7a6dfae..c1a47212e422 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/FullEntityTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/FullEntityTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/IncompleteKeyTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/IncompleteKeyTest.java
    similarity index 98%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/IncompleteKeyTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/IncompleteKeyTest.java
    index acd1dfd3c9e3..f4562901d5c6 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/IncompleteKeyTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/IncompleteKeyTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertNull;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyFactoryTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/KeyFactoryTest.java
    similarity index 99%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyFactoryTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/KeyFactoryTest.java
    index dacb348c2172..93f08de11be8 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyFactoryTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/KeyFactoryTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertTrue;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/KeyTest.java
    similarity index 98%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/KeyTest.java
    index 1fdcc5394e7e..398ea22d01e4 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/KeyTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyValueTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/KeyValueTest.java
    similarity index 97%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyValueTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/KeyValueTest.java
    index b2e916983b8a..0d2670b48c88 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/KeyValueTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/KeyValueTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LatLngTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/LatLngTest.java
    similarity index 98%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LatLngTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/LatLngTest.java
    index 1955ec236300..401d8cc0c4c8 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LatLngTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/LatLngTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertNotEquals;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LatLngValueTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/LatLngValueTest.java
    similarity index 97%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LatLngValueTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/LatLngValueTest.java
    index 3a25078237d4..583f89ef6cfe 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LatLngValueTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/LatLngValueTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/ListValueTest.java
    similarity index 98%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/ListValueTest.java
    index 41551939eba4..47acc549d65d 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ListValueTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/ListValueTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LongValueTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/LongValueTest.java
    similarity index 97%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LongValueTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/LongValueTest.java
    index 717c1567bc45..135f5fb8ac6a 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/LongValueTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/LongValueTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/NullValueTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/NullValueTest.java
    similarity index 97%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/NullValueTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/NullValueTest.java
    index 0856fced7992..ffed6e69c4f5 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/NullValueTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/NullValueTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/PathElementTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/PathElementTest.java
    similarity index 98%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/PathElementTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/PathElementTest.java
    index 393521ff08b9..269dddb51d71 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/PathElementTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/PathElementTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ProjectionEntityTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/ProjectionEntityTest.java
    similarity index 98%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ProjectionEntityTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/ProjectionEntityTest.java
    index 43eec2f02001..2b53e6efc04c 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ProjectionEntityTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/ProjectionEntityTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertArrayEquals;
     import static org.junit.Assert.assertEquals;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/RawValueTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/RawValueTest.java
    similarity index 97%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/RawValueTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/RawValueTest.java
    index 1ab1c36538de..1d603888b5d1 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/RawValueTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/RawValueTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/SerializationTest.java
    similarity index 94%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/SerializationTest.java
    index 4bc90315b5d9..ab771f0118a1 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/SerializationTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/SerializationTest.java
    @@ -14,16 +14,16 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static java.nio.charset.StandardCharsets.UTF_8;
     
    -import com.google.gcloud.AuthCredentials;
    -import com.google.gcloud.BaseSerializationTest;
    -import com.google.gcloud.Restorable;
    -import com.google.gcloud.datastore.StructuredQuery.CompositeFilter;
    -import com.google.gcloud.datastore.StructuredQuery.OrderBy;
    -import com.google.gcloud.datastore.StructuredQuery.PropertyFilter;
    +import com.google.cloud.AuthCredentials;
    +import com.google.cloud.BaseSerializationTest;
    +import com.google.cloud.Restorable;
    +import com.google.cloud.datastore.StructuredQuery.CompositeFilter;
    +import com.google.cloud.datastore.StructuredQuery.OrderBy;
    +import com.google.cloud.datastore.StructuredQuery.PropertyFilter;
     
     public class SerializationTest extends BaseSerializationTest {
     
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/StringValueTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/StringValueTest.java
    similarity index 97%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/StringValueTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/StringValueTest.java
    index 4f02568bf924..8dab36015515 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/StringValueTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/StringValueTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/StructuredQueryTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/StructuredQueryTest.java
    similarity index 94%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/StructuredQueryTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/StructuredQueryTest.java
    index cab98ab53837..7f5bbdd74e82 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/StructuredQueryTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/StructuredQueryTest.java
    @@ -14,18 +14,18 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
     import static org.junit.Assert.assertTrue;
     
     import com.google.common.collect.ImmutableList;
    -import com.google.gcloud.datastore.Query.ResultType;
    -import com.google.gcloud.datastore.StructuredQuery.CompositeFilter;
    -import com.google.gcloud.datastore.StructuredQuery.Filter;
    -import com.google.gcloud.datastore.StructuredQuery.OrderBy;
    -import com.google.gcloud.datastore.StructuredQuery.PropertyFilter;
    +import com.google.cloud.datastore.Query.ResultType;
    +import com.google.cloud.datastore.StructuredQuery.CompositeFilter;
    +import com.google.cloud.datastore.StructuredQuery.Filter;
    +import com.google.cloud.datastore.StructuredQuery.OrderBy;
    +import com.google.cloud.datastore.StructuredQuery.PropertyFilter;
     
     import org.junit.Test;
     
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/ValueTest.java
    similarity index 99%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/ValueTest.java
    index fb718dffe1e5..bb039d1a1ac9 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/ValueTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/ValueTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore;
    +package com.google.cloud.datastore;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
    diff --git a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/testing/LocalDatastoreHelperTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/testing/LocalDatastoreHelperTest.java
    similarity index 92%
    rename from gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/testing/LocalDatastoreHelperTest.java
    rename to gcloud-java-datastore/src/test/java/com/google/cloud/datastore/testing/LocalDatastoreHelperTest.java
    index 25ddef1ee4be..73844d2e19b3 100644
    --- a/gcloud-java-datastore/src/test/java/com/google/gcloud/datastore/testing/LocalDatastoreHelperTest.java
    +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/testing/LocalDatastoreHelperTest.java
    @@ -14,13 +14,13 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.datastore.testing;
    +package com.google.cloud.datastore.testing;
     
     import static org.junit.Assert.assertSame;
     import static org.junit.Assert.assertTrue;
     
    -import com.google.gcloud.AuthCredentials;
    -import com.google.gcloud.datastore.DatastoreOptions;
    +import com.google.cloud.AuthCredentials;
    +import com.google.cloud.datastore.DatastoreOptions;
     
     import org.junit.Test;
     import org.junit.runner.RunWith;
    diff --git a/gcloud-java-dns/README.md b/gcloud-java-dns/README.md
    index 0bb9a47635a2..6e095a992890 100644
    --- a/gcloud-java-dns/README.md
    +++ b/gcloud-java-dns/README.md
    @@ -5,12 +5,12 @@ Java idiomatic client for [Google Cloud DNS] (https://cloud.google.com/dns/).
     
     [![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java)
     [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master)
    -[![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-dns.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-dns.svg)
    +[![Maven](https://img.shields.io/maven-central/v/com.google.cloud/gcloud-java-dns.svg)]( https://img.shields.io/maven-central/v/com.google.cloud/gcloud-java-dns.svg)
     [![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java)
     [![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969)
     
     -  [Homepage] (https://googlecloudplatform.github.io/gcloud-java/)
    --  [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/dns/package-summary.html)
    +-  [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/dns/package-summary.html)
     
     > Note: This client is a work-in-progress, and may occasionally
     > make backwards-incompatible changes.
    @@ -20,27 +20,27 @@ Quickstart
     If you are using Maven, add this to your pom.xml file
     ```xml
     
    -  com.google.gcloud
    +  com.google.cloud
       gcloud-java-dns
       0.1.7
     
     ```
     If you are using Gradle, add this to your dependencies
     ```Groovy
    -compile 'com.google.gcloud:gcloud-java-dns:0.1.7'
    +compile 'com.google.cloud:gcloud-java-dns:0.1.7'
     ```
     If you are using SBT, add this to your dependencies
     ```Scala
    -libraryDependencies += "com.google.gcloud" % "gcloud-java-dns" % "0.1.7"
    +libraryDependencies += "com.google.cloud" % "gcloud-java-dns" % "0.1.7"
     ```
     
     Example Application
     -------------------
     
    -[`DnsExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java)
    +[`DnsExample`](../gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/DnsExample.java)
     is a simple command line interface that provides some of Google Cloud DNS's functionality.  Read
     more about using the application on the
    -[`DnsExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/dns/DnsExample.html).
    +[`DnsExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/cloud/examples/dns/DnsExample.html).
     
     Authentication
     --------------
    @@ -83,8 +83,8 @@ These credentials are automatically inferred from your environment, so you only
     code to create your service object:
     
     ```java
    -import com.google.gcloud.dns.Dns;
    -import com.google.gcloud.dns.DnsOptions;
    +import com.google.cloud.dns.Dns;
    +import com.google.cloud.dns.DnsOptions;
     
     Dns dns = DnsOptions.defaultInstance().service();
     ```
    @@ -110,8 +110,8 @@ requires fully qualified domain names which must end with a period.*
     Add the following imports at the top of your file:
     
     ```java
    -import com.google.gcloud.dns.Zone;
    -import com.google.gcloud.dns.ZoneInfo;
    +import com.google.cloud.dns.Zone;
    +import com.google.cloud.dns.ZoneInfo;
     ```
     
     Then add the following code to create a zone.
    @@ -159,8 +159,8 @@ our zone that creates a record set of type A and points URL www.someexampledomai
     IP address 12.13.14.15. Start by adding
     
     ```java
    -import com.google.gcloud.dns.ChangeRequestInfo;
    -import com.google.gcloud.dns.RecordSet;
    +import com.google.cloud.dns.ChangeRequestInfo;
    +import com.google.cloud.dns.RecordSet;
     
     import java.util.concurrent.TimeUnit;
     ```
    @@ -325,11 +325,11 @@ if (result) {
     #### Complete Source Code
     
     We composed some of the aforementioned snippets into complete executable code samples. In
    -[CreateZones.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateZone.java)
    -we create a zone. In [CreateOrUpdateRecordSets.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateRecordSets.java)
    +[CreateZones.java](../gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/snippets/CreateZone.java)
    +we create a zone. In [CreateOrUpdateRecordSets.java](../gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/snippets/CreateOrUpdateRecordSets.java)
     we create a type A record set for a zone, or update an existing type A record set to a new IP address. We
    -demonstrate how to delete a zone in [DeleteZone.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java).
    -Finally, in [ManipulateZonesAndRecordSets.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java)
    +demonstrate how to delete a zone in [DeleteZone.java](../gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/snippets/DeleteZone.java).
    +Finally, in [ManipulateZonesAndRecordSets.java](../gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java)
     we assemble all the code snippets together and create zone, create or update a record set, list zones, list record sets, list changes, and
     delete a zone. The applications assume that they are running on Compute Engine or from your own desktop. To run any of these examples on App
     Engine, simply move the code from the main method to your application's servlet class and change the
    @@ -383,5 +383,5 @@ Apache 2.0 - See [LICENSE] for more information.
     [cloud-platform]: https://cloud.google.com/
     
     [cloud-dns]: https://cloud.google.com/dns/
    -[dns-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/dns/package-summary.html
    +[dns-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/dns/package-summary.html
     [dns-activate]:https://cloud.google.com/dns/getting-started#prerequisites
    diff --git a/gcloud-java-dns/pom.xml b/gcloud-java-dns/pom.xml
    index a4928ccf0397..8e5d7020f365 100644
    --- a/gcloud-java-dns/pom.xml
    +++ b/gcloud-java-dns/pom.xml
    @@ -10,7 +10,7 @@
         Java idiomatic client for Google Cloud DNS.
       
       
    -    com.google.gcloud
    +    com.google.cloud
         gcloud-java-pom
         0.1.8-SNAPSHOT
       
    diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/ChangeRequest.java
    similarity index 99%
    rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java
    rename to gcloud-java-dns/src/main/java/com/google/cloud/dns/ChangeRequest.java
    index b3a2a2170d8b..61864e968ebb 100644
    --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequest.java
    +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/ChangeRequest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.dns;
    +package com.google.cloud.dns;
     
     import static com.google.common.base.Preconditions.checkNotNull;
     
    diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequestInfo.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/ChangeRequestInfo.java
    similarity index 99%
    rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequestInfo.java
    rename to gcloud-java-dns/src/main/java/com/google/cloud/dns/ChangeRequestInfo.java
    index 4a92512996dd..53bce6cf1380 100644
    --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ChangeRequestInfo.java
    +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/ChangeRequestInfo.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.dns;
    +package com.google.cloud.dns;
     
     import static com.google.common.base.Preconditions.checkNotNull;
     
    diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/Dns.java
    similarity index 98%
    rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java
    rename to gcloud-java-dns/src/main/java/com/google/cloud/dns/Dns.java
    index 2216733ca779..f7c1aef0a02c 100644
    --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java
    +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/Dns.java
    @@ -14,14 +14,14 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.dns;
    +package com.google.cloud.dns;
     
     import com.google.common.collect.ImmutableList;
    -import com.google.gcloud.FieldSelector;
    -import com.google.gcloud.FieldSelector.Helper;
    -import com.google.gcloud.Page;
    -import com.google.gcloud.Service;
    -import com.google.gcloud.dns.spi.DnsRpc;
    +import com.google.cloud.FieldSelector;
    +import com.google.cloud.FieldSelector.Helper;
    +import com.google.cloud.Page;
    +import com.google.cloud.Service;
    +import com.google.cloud.dns.spi.DnsRpc;
     
     import java.util.List;
     
    diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsException.java
    similarity index 90%
    rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java
    rename to gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsException.java
    index 1ecb98a3fdc6..8da76625cead 100644
    --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsException.java
    +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsException.java
    @@ -14,12 +14,12 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.dns;
    +package com.google.cloud.dns;
     
     import com.google.common.collect.ImmutableSet;
    -import com.google.gcloud.BaseServiceException;
    -import com.google.gcloud.RetryHelper.RetryHelperException;
    -import com.google.gcloud.RetryHelper.RetryInterruptedException;
    +import com.google.cloud.BaseServiceException;
    +import com.google.cloud.RetryHelper.RetryHelperException;
    +import com.google.cloud.RetryHelper.RetryInterruptedException;
     
     import java.io.IOException;
     import java.util.Set;
    diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsFactory.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsFactory.java
    similarity index 91%
    rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsFactory.java
    rename to gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsFactory.java
    index 734652afb24d..38c4c68de596 100644
    --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsFactory.java
    +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsFactory.java
    @@ -14,9 +14,9 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.dns;
    +package com.google.cloud.dns;
     
    -import com.google.gcloud.ServiceFactory;
    +import com.google.cloud.ServiceFactory;
     
     /**
      * An interface for Dns factories.
    diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsImpl.java
    similarity index 97%
    rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java
    rename to gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsImpl.java
    index 3218daa543b2..785face46173 100644
    --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsImpl.java
    +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsImpl.java
    @@ -14,10 +14,10 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.dns;
    +package com.google.cloud.dns;
     
     import static com.google.common.base.Preconditions.checkArgument;
    -import static com.google.gcloud.RetryHelper.runWithRetries;
    +import static com.google.cloud.RetryHelper.runWithRetries;
     
     import com.google.api.services.dns.model.Change;
     import com.google.api.services.dns.model.ManagedZone;
    @@ -28,11 +28,11 @@
     import com.google.common.collect.ImmutableMap;
     import com.google.common.collect.Iterables;
     import com.google.common.collect.Maps;
    -import com.google.gcloud.BaseService;
    -import com.google.gcloud.Page;
    -import com.google.gcloud.PageImpl;
    -import com.google.gcloud.RetryHelper;
    -import com.google.gcloud.dns.spi.DnsRpc;
    +import com.google.cloud.BaseService;
    +import com.google.cloud.Page;
    +import com.google.cloud.PageImpl;
    +import com.google.cloud.RetryHelper;
    +import com.google.cloud.dns.spi.DnsRpc;
     
     import java.util.Map;
     import java.util.concurrent.Callable;
    diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsOptions.java
    similarity index 93%
    rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java
    rename to gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsOptions.java
    index 9594448579ee..059f7b212044 100644
    --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsOptions.java
    +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsOptions.java
    @@ -14,13 +14,13 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.dns;
    +package com.google.cloud.dns;
     
     import com.google.common.collect.ImmutableSet;
    -import com.google.gcloud.ServiceOptions;
    -import com.google.gcloud.dns.spi.DefaultDnsRpc;
    -import com.google.gcloud.dns.spi.DnsRpc;
    -import com.google.gcloud.dns.spi.DnsRpcFactory;
    +import com.google.cloud.ServiceOptions;
    +import com.google.cloud.dns.spi.DefaultDnsRpc;
    +import com.google.cloud.dns.spi.DnsRpc;
    +import com.google.cloud.dns.spi.DnsRpcFactory;
     
     import java.util.Set;
     
    diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Option.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/Option.java
    similarity index 96%
    rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/Option.java
    rename to gcloud-java-dns/src/main/java/com/google/cloud/dns/Option.java
    index fee99898fb24..b0e23220549c 100644
    --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Option.java
    +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/Option.java
    @@ -14,12 +14,12 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.dns;
    +package com.google.cloud.dns;
     
     import static com.google.common.base.Preconditions.checkNotNull;
     
     import com.google.common.base.MoreObjects;
    -import com.google.gcloud.dns.spi.DnsRpc;
    +import com.google.cloud.dns.spi.DnsRpc;
     
     import java.io.Serializable;
     import java.util.Objects;
    diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/ProjectInfo.java
    similarity index 99%
    rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java
    rename to gcloud-java-dns/src/main/java/com/google/cloud/dns/ProjectInfo.java
    index 52edb25ec902..3d0d4704e6c0 100644
    --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ProjectInfo.java
    +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/ProjectInfo.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.dns;
    +package com.google.cloud.dns;
     
     import static com.google.api.client.repackaged.com.google.common.base.Preconditions.checkNotNull;
     
    diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/RecordSet.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/RecordSet.java
    similarity index 99%
    rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/RecordSet.java
    rename to gcloud-java-dns/src/main/java/com/google/cloud/dns/RecordSet.java
    index 90beedba1d89..a8323041a2fb 100644
    --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/RecordSet.java
    +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/RecordSet.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.dns;
    +package com.google.cloud.dns;
     
     import static com.google.common.base.Preconditions.checkArgument;
     import static com.google.common.base.Preconditions.checkNotNull;
    diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/Zone.java
    similarity index 99%
    rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java
    rename to gcloud-java-dns/src/main/java/com/google/cloud/dns/Zone.java
    index c4250bd206eb..8c21d79a992f 100644
    --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Zone.java
    +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/Zone.java
    @@ -14,12 +14,12 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.dns;
    +package com.google.cloud.dns;
     
     import static com.google.common.base.Preconditions.checkNotNull;
     
     import com.google.api.services.dns.model.ManagedZone;
    -import com.google.gcloud.Page;
    +import com.google.cloud.Page;
     
     import java.io.IOException;
     import java.io.ObjectInputStream;
    diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/ZoneInfo.java
    similarity index 99%
    rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java
    rename to gcloud-java-dns/src/main/java/com/google/cloud/dns/ZoneInfo.java
    index 03c23a6ce3d3..2b8c79e7fe5c 100644
    --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ZoneInfo.java
    +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/ZoneInfo.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.dns;
    +package com.google.cloud.dns;
     
     import static com.google.common.base.Preconditions.checkNotNull;
     
    diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/package-info.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/package-info.java
    similarity index 68%
    rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/package-info.java
    rename to gcloud-java-dns/src/main/java/com/google/cloud/dns/package-info.java
    index 36f41852400c..cdcce0d1ef90 100644
    --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/package-info.java
    +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/package-info.java
    @@ -17,10 +17,12 @@
     /**
      * A client to the Google Cloud DNS.
      *
    - * 

    Here are two simple usage examples from within Compute/App Engine. + *

    + * Here are two simple usage examples from within Compute/App Engine. * * The first snippet shows how to create a zone resource. The complete source code can be found on - * + * * CreateAndListZones.java. Note that you need to replace the {@code domainName} with a domain * name that you own and the ownership of which you verified with Google. * @@ -33,8 +35,10 @@ * Zone createdZone = dns.create(zoneInfo); * }

    * - *

    The second example shows how to create records inside a zone. The complete code can be found - * on + *

    + * The second example shows how to create records inside a zone. The complete code can be found on + * * CreateAndListDnsRecords.java. * *

     {@code
    @@ -50,11 +54,13 @@
      * zone.applyChangeRequest(changeRequest);
      * } 
    * - *

    When using gcloud-java from outside of App/Compute Engine, you have to specify a - * project ID and provide + *

    + * When using gcloud-java from outside of App/Compute Engine, you have to + * specify a + * project ID and + * provide * credentials. * * @see Google Cloud DNS */ -package com.google.gcloud.dns; +package com.google.cloud.dns; diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DefaultDnsRpc.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DefaultDnsRpc.java similarity index 91% rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DefaultDnsRpc.java rename to gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DefaultDnsRpc.java index cbebd19d0d73..05b803513acb 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DefaultDnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DefaultDnsRpc.java @@ -1,13 +1,13 @@ -package com.google.gcloud.dns.spi; - -import static com.google.gcloud.dns.spi.DnsRpc.ListResult.of; -import static com.google.gcloud.dns.spi.DnsRpc.Option.DNS_NAME; -import static com.google.gcloud.dns.spi.DnsRpc.Option.DNS_TYPE; -import static com.google.gcloud.dns.spi.DnsRpc.Option.FIELDS; -import static com.google.gcloud.dns.spi.DnsRpc.Option.NAME; -import static com.google.gcloud.dns.spi.DnsRpc.Option.PAGE_SIZE; -import static com.google.gcloud.dns.spi.DnsRpc.Option.PAGE_TOKEN; -import static com.google.gcloud.dns.spi.DnsRpc.Option.SORTING_ORDER; +package com.google.cloud.dns.spi; + +import static com.google.cloud.dns.spi.DnsRpc.ListResult.of; +import static com.google.cloud.dns.spi.DnsRpc.Option.DNS_NAME; +import static com.google.cloud.dns.spi.DnsRpc.Option.DNS_TYPE; +import static com.google.cloud.dns.spi.DnsRpc.Option.FIELDS; +import static com.google.cloud.dns.spi.DnsRpc.Option.NAME; +import static com.google.cloud.dns.spi.DnsRpc.Option.PAGE_SIZE; +import static com.google.cloud.dns.spi.DnsRpc.Option.PAGE_TOKEN; +import static com.google.cloud.dns.spi.DnsRpc.Option.SORTING_ORDER; import static java.net.HttpURLConnection.HTTP_NOT_FOUND; import com.google.api.client.http.HttpRequestInitializer; @@ -21,8 +21,8 @@ import com.google.api.services.dns.model.Project; import com.google.api.services.dns.model.ResourceRecordSet; import com.google.api.services.dns.model.ResourceRecordSetsListResponse; -import com.google.gcloud.dns.DnsException; -import com.google.gcloud.dns.DnsOptions; +import com.google.cloud.dns.DnsException; +import com.google.cloud.dns.DnsOptions; import java.io.IOException; import java.util.Map; diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DnsRpc.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DnsRpc.java similarity index 98% rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DnsRpc.java rename to gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DnsRpc.java index c7478016db27..57d6b45ba3a5 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DnsRpc.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.google.gcloud.dns.spi; +package com.google.cloud.dns.spi; import com.google.api.services.dns.model.Change; import com.google.api.services.dns.model.ManagedZone; import com.google.api.services.dns.model.Project; import com.google.api.services.dns.model.ResourceRecordSet; import com.google.common.collect.ImmutableList; -import com.google.gcloud.dns.DnsException; +import com.google.cloud.dns.DnsException; import java.util.Map; diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DnsRpcFactory.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DnsRpcFactory.java similarity index 86% rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DnsRpcFactory.java rename to gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DnsRpcFactory.java index ca1b1a0dd018..f54f9d02b41e 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/spi/DnsRpcFactory.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DnsRpcFactory.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package com.google.gcloud.dns.spi; +package com.google.cloud.dns.spi; -import com.google.gcloud.dns.DnsOptions; -import com.google.gcloud.spi.ServiceRpcFactory; +import com.google.cloud.dns.DnsOptions; +import com.google.cloud.spi.ServiceRpcFactory; /** * An interface for DnsRpc factory. Implementation will be loaded via {@link diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/LocalDnsHelper.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/testing/LocalDnsHelper.java similarity index 99% rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/LocalDnsHelper.java rename to gcloud-java-dns/src/main/java/com/google/cloud/dns/testing/LocalDnsHelper.java index 54edcddb5ade..46d116bdf640 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/LocalDnsHelper.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/testing/LocalDnsHelper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.dns.testing; +package com.google.cloud.dns.testing; import static com.google.common.net.InetAddresses.isInetAddress; import static java.net.HttpURLConnection.HTTP_NO_CONTENT; @@ -36,7 +36,7 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.google.common.io.ByteStreams; -import com.google.gcloud.dns.DnsOptions; +import com.google.cloud.dns.DnsOptions; import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.HttpExchange; diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/OptionParsers.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/testing/OptionParsers.java similarity index 99% rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/OptionParsers.java rename to gcloud-java-dns/src/main/java/com/google/cloud/dns/testing/OptionParsers.java index bd773a931ef2..0543c6faab52 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/OptionParsers.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/testing/OptionParsers.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.dns.testing; +package com.google.cloud.dns.testing; import com.google.api.services.dns.model.Change; import com.google.api.services.dns.model.ManagedZone; diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/package-info.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/testing/package-info.java similarity index 96% rename from gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/package-info.java rename to gcloud-java-dns/src/main/java/com/google/cloud/dns/testing/package-info.java index 85c332e56dd8..da431658c712 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/testing/package-info.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/testing/package-info.java @@ -33,4 +33,4 @@ * dnsHelper.stop(); * }

    */ -package com.google.gcloud.dns.testing; +package com.google.cloud.dns.testing; diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestInfoTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/ChangeRequestInfoTest.java similarity index 99% rename from gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestInfoTest.java rename to gcloud-java-dns/src/test/java/com/google/cloud/dns/ChangeRequestInfoTest.java index 136a6e0d56ec..2da7ad75c569 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestInfoTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/ChangeRequestInfoTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.dns; +package com.google.cloud.dns; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/ChangeRequestTest.java similarity index 99% rename from gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java rename to gcloud-java-dns/src/test/java/com/google/cloud/dns/ChangeRequestTest.java index 2c3be337f033..6daa1a0a8cdd 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ChangeRequestTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/ChangeRequestTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.dns; +package com.google.cloud.dns; import static org.easymock.EasyMock.createStrictMock; import static org.easymock.EasyMock.expect; diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsImplTest.java similarity index 98% rename from gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java rename to gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsImplTest.java index c359871b998c..fe3b08f8625b 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsImplTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsImplTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.dns; +package com.google.cloud.dns; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -25,11 +25,11 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; -import com.google.gcloud.Page; -import com.google.gcloud.RetryParams; -import com.google.gcloud.ServiceOptions; -import com.google.gcloud.dns.spi.DnsRpc; -import com.google.gcloud.dns.spi.DnsRpcFactory; +import com.google.cloud.Page; +import com.google.cloud.RetryParams; +import com.google.cloud.ServiceOptions; +import com.google.cloud.dns.spi.DnsRpc; +import com.google.cloud.dns.spi.DnsRpcFactory; import org.easymock.Capture; import org.easymock.EasyMock; diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsTest.java similarity index 98% rename from gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java rename to gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsTest.java index df86d6ebd495..91d46e94262d 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsTest.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.google.gcloud.dns; +package com.google.cloud.dns; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import com.google.gcloud.dns.spi.DnsRpc; +import com.google.cloud.dns.spi.DnsRpc; import org.junit.Test; diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/OptionTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/OptionTest.java similarity index 96% rename from gcloud-java-dns/src/test/java/com/google/gcloud/dns/OptionTest.java rename to gcloud-java-dns/src/test/java/com/google/cloud/dns/OptionTest.java index e9906354f963..1e5be1287ceb 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/OptionTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/OptionTest.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.google.gcloud.dns; +package com.google.cloud.dns; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNull; -import com.google.gcloud.dns.spi.DnsRpc; +import com.google.cloud.dns.spi.DnsRpc; import org.junit.Rule; import org.junit.Test; diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ProjectInfoTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/ProjectInfoTest.java similarity index 99% rename from gcloud-java-dns/src/test/java/com/google/gcloud/dns/ProjectInfoTest.java rename to gcloud-java-dns/src/test/java/com/google/cloud/dns/ProjectInfoTest.java index d959d44d4351..70086250e6dd 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ProjectInfoTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/ProjectInfoTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.dns; +package com.google.cloud.dns; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/RecordSetTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/RecordSetTest.java similarity index 99% rename from gcloud-java-dns/src/test/java/com/google/gcloud/dns/RecordSetTest.java rename to gcloud-java-dns/src/test/java/com/google/cloud/dns/RecordSetTest.java index fc888bf8a697..f5c515b6752d 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/RecordSetTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/RecordSetTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.dns; +package com.google.cloud.dns; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/SerializationTest.java similarity index 96% rename from gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java rename to gcloud-java-dns/src/test/java/com/google/cloud/dns/SerializationTest.java index 7742d4c59a48..32b1bbbd0667 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/SerializationTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/SerializationTest.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.google.gcloud.dns; +package com.google.cloud.dns; import com.google.common.collect.ImmutableList; -import com.google.gcloud.AuthCredentials; -import com.google.gcloud.BaseSerializationTest; -import com.google.gcloud.Restorable; -import com.google.gcloud.RetryParams; +import com.google.cloud.AuthCredentials; +import com.google.cloud.BaseSerializationTest; +import com.google.cloud.Restorable; +import com.google.cloud.RetryParams; import java.io.Serializable; import java.math.BigInteger; diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/ZoneInfoTest.java similarity index 99% rename from gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java rename to gcloud-java-dns/src/test/java/com/google/cloud/dns/ZoneInfoTest.java index b537735c3c4e..215d377f6a67 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneInfoTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/ZoneInfoTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.dns; +package com.google.cloud.dns; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/ZoneTest.java similarity index 99% rename from gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java rename to gcloud-java-dns/src/test/java/com/google/cloud/dns/ZoneTest.java index 5407d4f248b7..fc23316a899b 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ZoneTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/ZoneTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.dns; +package com.google.cloud.dns; import static org.easymock.EasyMock.createStrictMock; import static org.easymock.EasyMock.expect; @@ -31,7 +31,7 @@ import static org.junit.Assert.fail; import com.google.common.collect.ImmutableList; -import com.google.gcloud.Page; +import com.google.cloud.Page; import org.junit.After; import org.junit.Before; diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/it/ITDnsTest.java similarity index 98% rename from gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java rename to gcloud-java-dns/src/test/java/com/google/cloud/dns/it/ITDnsTest.java index e6513451e7f6..2d6ce2e45457 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/it/ITDnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/it/ITDnsTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.dns.it; +package com.google.cloud.dns.it; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -24,16 +24,16 @@ import static org.junit.Assert.fail; import com.google.common.collect.ImmutableList; -import com.google.gcloud.Page; -import com.google.gcloud.dns.ChangeRequest; -import com.google.gcloud.dns.ChangeRequestInfo; -import com.google.gcloud.dns.Dns; -import com.google.gcloud.dns.DnsException; -import com.google.gcloud.dns.DnsOptions; -import com.google.gcloud.dns.ProjectInfo; -import com.google.gcloud.dns.RecordSet; -import com.google.gcloud.dns.Zone; -import com.google.gcloud.dns.ZoneInfo; +import com.google.cloud.Page; +import com.google.cloud.dns.ChangeRequest; +import com.google.cloud.dns.ChangeRequestInfo; +import com.google.cloud.dns.Dns; +import com.google.cloud.dns.DnsException; +import com.google.cloud.dns.DnsOptions; +import com.google.cloud.dns.ProjectInfo; +import com.google.cloud.dns.RecordSet; +import com.google.cloud.dns.Zone; +import com.google.cloud.dns.ZoneInfo; import org.junit.AfterClass; import org.junit.BeforeClass; diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/testing/LocalDnsHelperTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/testing/LocalDnsHelperTest.java similarity index 99% rename from gcloud-java-dns/src/test/java/com/google/gcloud/dns/testing/LocalDnsHelperTest.java rename to gcloud-java-dns/src/test/java/com/google/cloud/dns/testing/LocalDnsHelperTest.java index 315a47c5bb7c..2231d2f08974 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/testing/LocalDnsHelperTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/testing/LocalDnsHelperTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.dns.testing; +package com.google.cloud.dns.testing; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -31,9 +31,9 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; -import com.google.gcloud.dns.DnsException; -import com.google.gcloud.dns.spi.DefaultDnsRpc; -import com.google.gcloud.dns.spi.DnsRpc; +import com.google.cloud.dns.DnsException; +import com.google.cloud.dns.spi.DefaultDnsRpc; +import com.google.cloud.dns.spi.DnsRpc; import org.junit.AfterClass; import org.junit.Before; diff --git a/gcloud-java-examples/README.md b/gcloud-java-examples/README.md index fc6b7c28f636..89cbb3f8d8f7 100644 --- a/gcloud-java-examples/README.md +++ b/gcloud-java-examples/README.md @@ -5,30 +5,30 @@ Examples for gcloud-java (Java idiomatic client for [Google Cloud Platform][clou [![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java) [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) -[![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-examples.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-examples.svg) +[![Maven](https://img.shields.io/maven-central/v/com.google.cloud/gcloud-java-examples.svg)]( https://img.shields.io/maven-central/v/com.google.cloud/gcloud-java-examples.svg) [![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) [![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969) - [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) -- [Examples] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/examples/package-summary.html) +- [Examples] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/examples/package-summary.html) Quickstart ---------- If you are using Maven, add this to your pom.xml file ```xml - com.google.gcloud + com.google.cloud gcloud-java-examples 0.1.7 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-examples:0.1.7' +compile 'com.google.cloud:gcloud-java-examples:0.1.7' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-examples" % "0.1.7" +libraryDependencies += "com.google.cloud" % "gcloud-java-examples" % "0.1.7" ``` To run examples from your command line: @@ -55,20 +55,20 @@ To run examples from your command line: ``` Then you are ready to run the following example: ``` - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.bigquery.BigQueryExample" -Dexec.args="create dataset new_dataset_id" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.bigquery.BigQueryExample" -Dexec.args="create table new_dataset_id new_table_id field_name:string" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.bigquery.BigQueryExample" -Dexec.args="list tables new_dataset_id" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.bigquery.BigQueryExample" -Dexec.args="load new_dataset_id new_table_id CSV gs://my_bucket/my_csv_file" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.bigquery.BigQueryExample" -Dexec.args="query 'select * from new_dataset_id.new_table_id'" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.bigquery.BigQueryExample" -Dexec.args="create dataset new_dataset_id" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.bigquery.BigQueryExample" -Dexec.args="create table new_dataset_id new_table_id field_name:string" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.bigquery.BigQueryExample" -Dexec.args="list tables new_dataset_id" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.bigquery.BigQueryExample" -Dexec.args="load new_dataset_id new_table_id CSV gs://my_bucket/my_csv_file" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.bigquery.BigQueryExample" -Dexec.args="query 'select * from new_dataset_id.new_table_id'" ``` * Here's an example run of `DatastoreExample`. Be sure to change the placeholder project ID "your-project-id" with your own project ID. Also note that you have to enable the Google Cloud Datastore API on the [Google Developers Console][developers-console] before running the following commands. ``` - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.datastore.DatastoreExample" -Dexec.args="your-project-id my_name add my\ comment" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.datastore.DatastoreExample" -Dexec.args="your-project-id my_name display" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.datastore.DatastoreExample" -Dexec.args="your-project-id my_name delete" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.datastore.DatastoreExample" -Dexec.args="your-project-id my_name add my\ comment" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.datastore.DatastoreExample" -Dexec.args="your-project-id my_name display" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.datastore.DatastoreExample" -Dexec.args="your-project-id my_name delete" ``` * Here's an example run of `DnsExample`. @@ -77,33 +77,33 @@ To run examples from your command line: You will need to replace the domain name `elaborateexample.com` with your own domain name with [verified ownership] (https://www.google.com/webmasters/verification/home). Also, note that the example creates and deletes record sets of type A only. Operations with other record types are not implemented in the example. ``` - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.dns.DnsExample" -Dexec.args="create some-sample-zone elaborateexample.com. description" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.dns.DnsExample" -Dexec.args="list" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.dns.DnsExample" -Dexec.args="list some-sample-zone records" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.dns.DnsExample" -Dexec.args="add-record some-sample-zone www.elaborateexample.com. 12.13.14.15 69" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.dns.DnsExample" -Dexec.args="get some-sample-zone" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.dns.DnsExample" -Dexec.args="delete-record some-sample-zone www.elaborateexample.com. 12.13.14.15 69" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.dns.DnsExample" -Dexec.args="list some-sample-zone changes ascending" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.dns.DnsExample" -Dexec.args="delete some-sample-zone" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.dns.DnsExample" -Dexec.args="create some-sample-zone elaborateexample.com. description" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.dns.DnsExample" -Dexec.args="list" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.dns.DnsExample" -Dexec.args="list some-sample-zone records" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.dns.DnsExample" -Dexec.args="add-record some-sample-zone www.elaborateexample.com. 12.13.14.15 69" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.dns.DnsExample" -Dexec.args="get some-sample-zone" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.dns.DnsExample" -Dexec.args="delete-record some-sample-zone www.elaborateexample.com. 12.13.14.15 69" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.dns.DnsExample" -Dexec.args="list some-sample-zone changes ascending" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.dns.DnsExample" -Dexec.args="delete some-sample-zone" ``` * Here's an example run of `ResourceManagerExample`. Be sure to change the placeholder project ID "your-project-id" with your own globally unique project ID. ``` - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.resourcemanager.ResourceManagerExample" -Dexec.args="create your-project-id" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.resourcemanager.ResourceManagerExample" -Dexec.args="list" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.resourcemanager.ResourceManagerExample" -Dexec.args="get your-project-id" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.resourcemanager.ResourceManagerExample" -Dexec.args="create your-project-id" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.resourcemanager.ResourceManagerExample" -Dexec.args="list" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.resourcemanager.ResourceManagerExample" -Dexec.args="get your-project-id" ``` * Here's an example run of `StorageExample`. Before running the example, go to the [Google Developers Console][developers-console] to ensure that "Google Cloud Storage" and "Google Cloud Storage JSON API" are enabled and that you have a bucket. Also ensure that you have a test file (`test.txt` is chosen here) to upload to Cloud Storage stored locally on your machine. ``` - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.storage.StorageExample" -Dexec.args="upload /path/to/test.txt " - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.storage.StorageExample" -Dexec.args="list " - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.storage.StorageExample" -Dexec.args="download test.txt" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.storage.StorageExample" -Dexec.args="delete test.txt" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.storage.StorageExample" -Dexec.args="upload /path/to/test.txt " + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.storage.StorageExample" -Dexec.args="list " + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.storage.StorageExample" -Dexec.args="download test.txt" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.storage.StorageExample" -Dexec.args="delete test.txt" ``` Troubleshooting diff --git a/gcloud-java-examples/pom.xml b/gcloud-java-examples/pom.xml index f5d4cb290118..784323ea44af 100644 --- a/gcloud-java-examples/pom.xml +++ b/gcloud-java-examples/pom.xml @@ -8,7 +8,7 @@ Examples for gcloud-java. - com.google.gcloud + com.google.cloud gcloud-java-pom 0.1.8-SNAPSHOT diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/BigQueryExample.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java similarity index 94% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/BigQueryExample.java rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java index fe27ee3cf63b..b0a7680cf2b9 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/BigQueryExample.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java @@ -14,36 +14,36 @@ * limitations under the License. */ -package com.google.gcloud.examples.bigquery; +package com.google.cloud.examples.bigquery; import com.google.common.collect.ImmutableMap; -import com.google.gcloud.WriteChannel; -import com.google.gcloud.bigquery.BigQuery; -import com.google.gcloud.bigquery.BigQueryError; -import com.google.gcloud.bigquery.BigQueryOptions; -import com.google.gcloud.bigquery.CopyJobConfiguration; -import com.google.gcloud.bigquery.Dataset; -import com.google.gcloud.bigquery.DatasetId; -import com.google.gcloud.bigquery.DatasetInfo; -import com.google.gcloud.bigquery.ExternalTableDefinition; -import com.google.gcloud.bigquery.ExtractJobConfiguration; -import com.google.gcloud.bigquery.Field; -import com.google.gcloud.bigquery.FieldValue; -import com.google.gcloud.bigquery.FormatOptions; -import com.google.gcloud.bigquery.Job; -import com.google.gcloud.bigquery.JobId; -import com.google.gcloud.bigquery.JobInfo; -import com.google.gcloud.bigquery.LoadJobConfiguration; -import com.google.gcloud.bigquery.QueryRequest; -import com.google.gcloud.bigquery.QueryResponse; -import com.google.gcloud.bigquery.Schema; -import com.google.gcloud.bigquery.StandardTableDefinition; -import com.google.gcloud.bigquery.Table; -import com.google.gcloud.bigquery.TableId; -import com.google.gcloud.bigquery.TableInfo; -import com.google.gcloud.bigquery.ViewDefinition; -import com.google.gcloud.bigquery.WriteChannelConfiguration; -import com.google.gcloud.bigquery.spi.BigQueryRpc.Tuple; +import com.google.cloud.WriteChannel; +import com.google.cloud.bigquery.BigQuery; +import com.google.cloud.bigquery.BigQueryError; +import com.google.cloud.bigquery.BigQueryOptions; +import com.google.cloud.bigquery.CopyJobConfiguration; +import com.google.cloud.bigquery.Dataset; +import com.google.cloud.bigquery.DatasetId; +import com.google.cloud.bigquery.DatasetInfo; +import com.google.cloud.bigquery.ExternalTableDefinition; +import com.google.cloud.bigquery.ExtractJobConfiguration; +import com.google.cloud.bigquery.Field; +import com.google.cloud.bigquery.FieldValue; +import com.google.cloud.bigquery.FormatOptions; +import com.google.cloud.bigquery.Job; +import com.google.cloud.bigquery.JobId; +import com.google.cloud.bigquery.JobInfo; +import com.google.cloud.bigquery.LoadJobConfiguration; +import com.google.cloud.bigquery.QueryRequest; +import com.google.cloud.bigquery.QueryResponse; +import com.google.cloud.bigquery.Schema; +import com.google.cloud.bigquery.StandardTableDefinition; +import com.google.cloud.bigquery.Table; +import com.google.cloud.bigquery.TableId; +import com.google.cloud.bigquery.TableInfo; +import com.google.cloud.bigquery.ViewDefinition; +import com.google.cloud.bigquery.WriteChannelConfiguration; +import com.google.cloud.bigquery.spi.BigQueryRpc.Tuple; import java.nio.channels.FileChannel; import java.nio.file.Paths; @@ -63,7 +63,7 @@ *
  • login using gcloud SDK - {@code gcloud auth login}.
  • *
  • compile using maven - {@code mvn compile}
  • *
  • run using maven - - *
    {@code mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.bigquery.BigQueryExample"
    + * 
    {@code mvn exec:java -Dexec.mainClass="com.google.cloud.examples.bigquery.BigQueryExample"
      *  -Dexec.args="[]
      *  list datasets |
      *  list tables  |
    diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/snippets/CreateTableAndLoadData.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/snippets/CreateTableAndLoadData.java
    similarity index 79%
    rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/snippets/CreateTableAndLoadData.java
    rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/snippets/CreateTableAndLoadData.java
    index 857f6b43d013..01290ec8b491 100644
    --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/snippets/CreateTableAndLoadData.java
    +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/snippets/CreateTableAndLoadData.java
    @@ -20,18 +20,18 @@
      * the project's READMEs and package-info.java.
      */
     
    -package com.google.gcloud.examples.bigquery.snippets;
    +package com.google.cloud.examples.bigquery.snippets;
     
    -import com.google.gcloud.bigquery.BigQuery;
    -import com.google.gcloud.bigquery.BigQueryOptions;
    -import com.google.gcloud.bigquery.Field;
    -import com.google.gcloud.bigquery.FormatOptions;
    -import com.google.gcloud.bigquery.Job;
    -import com.google.gcloud.bigquery.Schema;
    -import com.google.gcloud.bigquery.StandardTableDefinition;
    -import com.google.gcloud.bigquery.Table;
    -import com.google.gcloud.bigquery.TableId;
    -import com.google.gcloud.bigquery.TableInfo;
    +import com.google.cloud.bigquery.BigQuery;
    +import com.google.cloud.bigquery.BigQueryOptions;
    +import com.google.cloud.bigquery.Field;
    +import com.google.cloud.bigquery.FormatOptions;
    +import com.google.cloud.bigquery.Job;
    +import com.google.cloud.bigquery.Schema;
    +import com.google.cloud.bigquery.StandardTableDefinition;
    +import com.google.cloud.bigquery.Table;
    +import com.google.cloud.bigquery.TableId;
    +import com.google.cloud.bigquery.TableInfo;
     
     /**
      * A snippet for Google Cloud BigQuery showing how to get a BigQuery table or create it if it does
    diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/snippets/InsertDataAndQueryTable.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/snippets/InsertDataAndQueryTable.java
    similarity index 82%
    rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/snippets/InsertDataAndQueryTable.java
    rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/snippets/InsertDataAndQueryTable.java
    index ba2d1291b229..6fb2a7dce997 100644
    --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/bigquery/snippets/InsertDataAndQueryTable.java
    +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/snippets/InsertDataAndQueryTable.java
    @@ -20,21 +20,21 @@
      * the project's READMEs and package-info.java.
      */
     
    -package com.google.gcloud.examples.bigquery.snippets;
    +package com.google.cloud.examples.bigquery.snippets;
     
    -import com.google.gcloud.bigquery.BigQuery;
    -import com.google.gcloud.bigquery.BigQueryOptions;
    -import com.google.gcloud.bigquery.DatasetInfo;
    -import com.google.gcloud.bigquery.Field;
    -import com.google.gcloud.bigquery.FieldValue;
    -import com.google.gcloud.bigquery.InsertAllRequest;
    -import com.google.gcloud.bigquery.InsertAllResponse;
    -import com.google.gcloud.bigquery.QueryRequest;
    -import com.google.gcloud.bigquery.QueryResponse;
    -import com.google.gcloud.bigquery.Schema;
    -import com.google.gcloud.bigquery.StandardTableDefinition;
    -import com.google.gcloud.bigquery.TableId;
    -import com.google.gcloud.bigquery.TableInfo;
    +import com.google.cloud.bigquery.BigQuery;
    +import com.google.cloud.bigquery.BigQueryOptions;
    +import com.google.cloud.bigquery.DatasetInfo;
    +import com.google.cloud.bigquery.Field;
    +import com.google.cloud.bigquery.FieldValue;
    +import com.google.cloud.bigquery.InsertAllRequest;
    +import com.google.cloud.bigquery.InsertAllResponse;
    +import com.google.cloud.bigquery.QueryRequest;
    +import com.google.cloud.bigquery.QueryResponse;
    +import com.google.cloud.bigquery.Schema;
    +import com.google.cloud.bigquery.StandardTableDefinition;
    +import com.google.cloud.bigquery.TableId;
    +import com.google.cloud.bigquery.TableInfo;
     
     import java.util.HashMap;
     import java.util.Iterator;
    diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/DatastoreExample.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/DatastoreExample.java
    similarity index 90%
    rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/DatastoreExample.java
    rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/DatastoreExample.java
    index 00cfa90325c5..cf0fee504bf8 100644
    --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/DatastoreExample.java
    +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/DatastoreExample.java
    @@ -14,21 +14,21 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.examples.datastore;
    +package com.google.cloud.examples.datastore;
     
    -import com.google.gcloud.datastore.Datastore;
    -import com.google.gcloud.datastore.DatastoreOptions;
    -import com.google.gcloud.datastore.DateTime;
    -import com.google.gcloud.datastore.Entity;
    -import com.google.gcloud.datastore.FullEntity;
    -import com.google.gcloud.datastore.IncompleteKey;
    -import com.google.gcloud.datastore.Key;
    -import com.google.gcloud.datastore.KeyFactory;
    -import com.google.gcloud.datastore.Query;
    -import com.google.gcloud.datastore.QueryResults;
    -import com.google.gcloud.datastore.StructuredQuery;
    -import com.google.gcloud.datastore.StructuredQuery.PropertyFilter;
    -import com.google.gcloud.datastore.Transaction;
    +import com.google.cloud.datastore.Datastore;
    +import com.google.cloud.datastore.DatastoreOptions;
    +import com.google.cloud.datastore.DateTime;
    +import com.google.cloud.datastore.Entity;
    +import com.google.cloud.datastore.FullEntity;
    +import com.google.cloud.datastore.IncompleteKey;
    +import com.google.cloud.datastore.Key;
    +import com.google.cloud.datastore.KeyFactory;
    +import com.google.cloud.datastore.Query;
    +import com.google.cloud.datastore.QueryResults;
    +import com.google.cloud.datastore.StructuredQuery;
    +import com.google.cloud.datastore.StructuredQuery.PropertyFilter;
    +import com.google.cloud.datastore.Transaction;
     
     import java.util.Arrays;
     import java.util.HashMap;
    @@ -44,7 +44,7 @@
      * 
  • login using gcloud SDK - {@code gcloud auth login}.
  • *
  • compile using maven - {@code mvn compile}
  • *
  • run using maven - {@code mvn exec:java - * -Dexec.mainClass="com.google.gcloud.examples.datastore.DatastoreExample" + * -Dexec.mainClass="com.google.cloud.examples.datastore.DatastoreExample" * -Dexec.args="[projectId] [user] [delete|display|add comment]"}
  • * */ diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/AddEntitiesAndRunQuery.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/snippets/AddEntitiesAndRunQuery.java similarity index 85% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/AddEntitiesAndRunQuery.java rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/snippets/AddEntitiesAndRunQuery.java index f1e844c79b24..29b8453ccf28 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/AddEntitiesAndRunQuery.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/snippets/AddEntitiesAndRunQuery.java @@ -20,16 +20,16 @@ * the project's READMEs and package-info.java. */ -package com.google.gcloud.examples.datastore.snippets; +package com.google.cloud.examples.datastore.snippets; -import com.google.gcloud.datastore.Datastore; -import com.google.gcloud.datastore.DatastoreOptions; -import com.google.gcloud.datastore.Entity; -import com.google.gcloud.datastore.Key; -import com.google.gcloud.datastore.KeyFactory; -import com.google.gcloud.datastore.Query; -import com.google.gcloud.datastore.QueryResults; -import com.google.gcloud.datastore.StructuredQuery.PropertyFilter; +import com.google.cloud.datastore.Datastore; +import com.google.cloud.datastore.DatastoreOptions; +import com.google.cloud.datastore.Entity; +import com.google.cloud.datastore.Key; +import com.google.cloud.datastore.KeyFactory; +import com.google.cloud.datastore.Query; +import com.google.cloud.datastore.QueryResults; +import com.google.cloud.datastore.StructuredQuery.PropertyFilter; /** * A snippet for Google Cloud Datastore showing how to create and get entities. The snippet also diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/CreateEntity.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/snippets/CreateEntity.java similarity index 80% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/CreateEntity.java rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/snippets/CreateEntity.java index 3981162a2943..0ed4c5081450 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/CreateEntity.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/snippets/CreateEntity.java @@ -20,14 +20,14 @@ * the project's READMEs and package-info.java. */ -package com.google.gcloud.examples.datastore.snippets; +package com.google.cloud.examples.datastore.snippets; -import com.google.gcloud.datastore.Datastore; -import com.google.gcloud.datastore.DatastoreOptions; -import com.google.gcloud.datastore.DateTime; -import com.google.gcloud.datastore.Entity; -import com.google.gcloud.datastore.Key; -import com.google.gcloud.datastore.KeyFactory; +import com.google.cloud.datastore.Datastore; +import com.google.cloud.datastore.DatastoreOptions; +import com.google.cloud.datastore.DateTime; +import com.google.cloud.datastore.Entity; +import com.google.cloud.datastore.Key; +import com.google.cloud.datastore.KeyFactory; /** * A snippet for Google Cloud Datastore showing how to create an entity. diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/UpdateEntity.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/snippets/UpdateEntity.java similarity index 81% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/UpdateEntity.java rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/snippets/UpdateEntity.java index cbc97f0784dd..79cb6e8b9a5e 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/datastore/snippets/UpdateEntity.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/snippets/UpdateEntity.java @@ -20,14 +20,14 @@ * the project's READMEs and package-info.java. */ -package com.google.gcloud.examples.datastore.snippets; +package com.google.cloud.examples.datastore.snippets; -import com.google.gcloud.datastore.Datastore; -import com.google.gcloud.datastore.DatastoreOptions; -import com.google.gcloud.datastore.DateTime; -import com.google.gcloud.datastore.Entity; -import com.google.gcloud.datastore.Key; -import com.google.gcloud.datastore.KeyFactory; +import com.google.cloud.datastore.Datastore; +import com.google.cloud.datastore.DatastoreOptions; +import com.google.cloud.datastore.DateTime; +import com.google.cloud.datastore.Entity; +import com.google.cloud.datastore.Key; +import com.google.cloud.datastore.KeyFactory; /** * A snippet for Google Cloud Datastore showing how to get an entity and update it if it exists. diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/DnsExample.java similarity index 97% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/DnsExample.java index d0cda485e9f5..44ded7ae0dc0 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/DnsExample.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/DnsExample.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package com.google.gcloud.examples.dns; +package com.google.cloud.examples.dns; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; -import com.google.gcloud.dns.ChangeRequest; -import com.google.gcloud.dns.ChangeRequestInfo; -import com.google.gcloud.dns.Dns; -import com.google.gcloud.dns.DnsOptions; -import com.google.gcloud.dns.ProjectInfo; -import com.google.gcloud.dns.RecordSet; -import com.google.gcloud.dns.Zone; -import com.google.gcloud.dns.ZoneInfo; +import com.google.cloud.dns.ChangeRequest; +import com.google.cloud.dns.ChangeRequestInfo; +import com.google.cloud.dns.Dns; +import com.google.cloud.dns.DnsOptions; +import com.google.cloud.dns.ProjectInfo; +import com.google.cloud.dns.RecordSet; +import com.google.cloud.dns.Zone; +import com.google.cloud.dns.ZoneInfo; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; @@ -47,7 +47,7 @@ *
  • login using gcloud SDK - {@code gcloud auth login}.
  • *
  • compile using maven - {@code mvn compile}
  • *
  • run using maven - {@code mvn exec:java - * -Dexec.mainClass="com.google.gcloud.examples.dns.DnsExample" + * -Dexec.mainClass="com.google.cloud.examples.dns.DnsExample" * -Dexec.args="[] * create | * get | diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateRecordSets.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/snippets/CreateOrUpdateRecordSets.java similarity index 90% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateRecordSets.java rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/snippets/CreateOrUpdateRecordSets.java index e3ddbb10fc0f..b49cdeede5fb 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateOrUpdateRecordSets.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/snippets/CreateOrUpdateRecordSets.java @@ -20,13 +20,13 @@ * the project's README's and package-info.java. */ -package com.google.gcloud.examples.dns.snippets; +package com.google.cloud.examples.dns.snippets; -import com.google.gcloud.dns.ChangeRequestInfo; -import com.google.gcloud.dns.Dns; -import com.google.gcloud.dns.DnsOptions; -import com.google.gcloud.dns.RecordSet; -import com.google.gcloud.dns.Zone; +import com.google.cloud.dns.ChangeRequestInfo; +import com.google.cloud.dns.Dns; +import com.google.cloud.dns.DnsOptions; +import com.google.cloud.dns.RecordSet; +import com.google.cloud.dns.Zone; import java.util.Iterator; import java.util.concurrent.TimeUnit; diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateZone.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/snippets/CreateZone.java similarity index 89% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateZone.java rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/snippets/CreateZone.java index dcf8019319c3..d28ad5cbb2c9 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/CreateZone.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/snippets/CreateZone.java @@ -20,12 +20,12 @@ * the project's README's and package-info.java. */ -package com.google.gcloud.examples.dns.snippets; +package com.google.cloud.examples.dns.snippets; -import com.google.gcloud.dns.Dns; -import com.google.gcloud.dns.DnsOptions; -import com.google.gcloud.dns.Zone; -import com.google.gcloud.dns.ZoneInfo; +import com.google.cloud.dns.Dns; +import com.google.cloud.dns.DnsOptions; +import com.google.cloud.dns.Zone; +import com.google.cloud.dns.ZoneInfo; /** * A snippet for Google Cloud DNS showing how to create a zone. You will need to change the {@code diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/snippets/DeleteZone.java similarity index 91% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/snippets/DeleteZone.java index c791ea8c0992..317daf0c2e7d 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/DeleteZone.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/snippets/DeleteZone.java @@ -20,13 +20,13 @@ * the project's README's and package-info.java. */ -package com.google.gcloud.examples.dns.snippets; +package com.google.cloud.examples.dns.snippets; -import com.google.gcloud.dns.ChangeRequest; -import com.google.gcloud.dns.ChangeRequestInfo; -import com.google.gcloud.dns.Dns; -import com.google.gcloud.dns.DnsOptions; -import com.google.gcloud.dns.RecordSet; +import com.google.cloud.dns.ChangeRequest; +import com.google.cloud.dns.ChangeRequestInfo; +import com.google.cloud.dns.Dns; +import com.google.cloud.dns.DnsOptions; +import com.google.cloud.dns.RecordSet; import java.util.Iterator; diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java similarity index 94% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java index c96c93191c10..53cd77b5ec67 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/snippets/ManipulateZonesAndRecordSets.java @@ -20,15 +20,15 @@ * the project's README's and package-info.java. */ -package com.google.gcloud.examples.dns.snippets; - -import com.google.gcloud.dns.ChangeRequest; -import com.google.gcloud.dns.ChangeRequestInfo; -import com.google.gcloud.dns.Dns; -import com.google.gcloud.dns.DnsOptions; -import com.google.gcloud.dns.RecordSet; -import com.google.gcloud.dns.Zone; -import com.google.gcloud.dns.ZoneInfo; +package com.google.cloud.examples.dns.snippets; + +import com.google.cloud.dns.ChangeRequest; +import com.google.cloud.dns.ChangeRequestInfo; +import com.google.cloud.dns.Dns; +import com.google.cloud.dns.DnsOptions; +import com.google.cloud.dns.RecordSet; +import com.google.cloud.dns.Zone; +import com.google.cloud.dns.ZoneInfo; import java.util.Iterator; import java.util.List; diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/ResourceManagerExample.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/ResourceManagerExample.java similarity index 95% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/ResourceManagerExample.java rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/ResourceManagerExample.java index 349c0eebe73d..9b9e7aaa8ac8 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/ResourceManagerExample.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/ResourceManagerExample.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.google.gcloud.examples.resourcemanager; +package com.google.cloud.examples.resourcemanager; import com.google.common.base.Joiner; -import com.google.gcloud.resourcemanager.Project; -import com.google.gcloud.resourcemanager.ProjectInfo; -import com.google.gcloud.resourcemanager.ResourceManager; -import com.google.gcloud.resourcemanager.ResourceManagerOptions; +import com.google.cloud.resourcemanager.Project; +import com.google.cloud.resourcemanager.ProjectInfo; +import com.google.cloud.resourcemanager.ResourceManager; +import com.google.cloud.resourcemanager.ResourceManagerOptions; import java.util.Arrays; import java.util.HashMap; @@ -36,7 +36,7 @@ *
  • login using gcloud SDK - {@code gcloud auth login}.
  • *
  • compile using maven - {@code mvn compile}
  • *
  • run using maven - {@code mvn exec:java - * -Dexec.mainClass="com.google.gcloud.examples.resourcemanager.ResourceManagerExample" + * -Dexec.mainClass="com.google.cloud.examples.resourcemanager.ResourceManagerExample" * -Dexec.args="[list | [create | delete | get] projectId]"}
  • * */ diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/GetOrCreateProject.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/GetOrCreateProject.java similarity index 84% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/GetOrCreateProject.java rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/GetOrCreateProject.java index 5a298107cc60..796e29bc3b0c 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/GetOrCreateProject.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/GetOrCreateProject.java @@ -20,12 +20,12 @@ * the project's READMEs and package-info.java. */ -package com.google.gcloud.examples.resourcemanager.snippets; +package com.google.cloud.examples.resourcemanager.snippets; -import com.google.gcloud.resourcemanager.Project; -import com.google.gcloud.resourcemanager.ProjectInfo; -import com.google.gcloud.resourcemanager.ResourceManager; -import com.google.gcloud.resourcemanager.ResourceManagerOptions; +import com.google.cloud.resourcemanager.Project; +import com.google.cloud.resourcemanager.ProjectInfo; +import com.google.cloud.resourcemanager.ResourceManager; +import com.google.cloud.resourcemanager.ResourceManagerOptions; /** * A snippet for Google Cloud Resource Manager showing how to create a project if it does not exist. diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/ModifyPolicy.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/ModifyPolicy.java similarity index 83% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/ModifyPolicy.java rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/ModifyPolicy.java index f97adf5b0916..3f12dba0f77f 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/ModifyPolicy.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/ModifyPolicy.java @@ -20,14 +20,14 @@ * the project's READMEs and package-info.java. */ -package com.google.gcloud.examples.resourcemanager.snippets; - -import com.google.gcloud.Identity; -import com.google.gcloud.resourcemanager.Policy; -import com.google.gcloud.resourcemanager.Policy.ProjectRole; -import com.google.gcloud.resourcemanager.Project; -import com.google.gcloud.resourcemanager.ResourceManager; -import com.google.gcloud.resourcemanager.ResourceManagerOptions; +package com.google.cloud.examples.resourcemanager.snippets; + +import com.google.cloud.Identity; +import com.google.cloud.resourcemanager.Policy; +import com.google.cloud.resourcemanager.Policy.ProjectRole; +import com.google.cloud.resourcemanager.Project; +import com.google.cloud.resourcemanager.ResourceManager; +import com.google.cloud.resourcemanager.ResourceManagerOptions; /** * A snippet for Google Cloud Resource Manager showing how to modify a project's IAM policy. diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/UpdateAndListProjects.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/UpdateAndListProjects.java similarity index 89% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/UpdateAndListProjects.java rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/UpdateAndListProjects.java index b194de0815d5..2dba787279f2 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/UpdateAndListProjects.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/UpdateAndListProjects.java @@ -20,11 +20,11 @@ * the project's READMEs and package-info.java. */ -package com.google.gcloud.examples.resourcemanager.snippets; +package com.google.cloud.examples.resourcemanager.snippets; -import com.google.gcloud.resourcemanager.Project; -import com.google.gcloud.resourcemanager.ResourceManager; -import com.google.gcloud.resourcemanager.ResourceManagerOptions; +import com.google.cloud.resourcemanager.Project; +import com.google.cloud.resourcemanager.ResourceManager; +import com.google.cloud.resourcemanager.ResourceManagerOptions; import java.util.Iterator; diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/StorageExample.java similarity index 95% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/StorageExample.java index 29abbff9c30f..01b864e7c8b8 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/StorageExample.java @@ -14,23 +14,23 @@ * limitations under the License. */ -package com.google.gcloud.examples.storage; - -import com.google.gcloud.AuthCredentials; -import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials; -import com.google.gcloud.ReadChannel; -import com.google.gcloud.WriteChannel; -import com.google.gcloud.storage.Blob; -import com.google.gcloud.storage.BlobId; -import com.google.gcloud.storage.BlobInfo; -import com.google.gcloud.storage.Bucket; -import com.google.gcloud.storage.CopyWriter; -import com.google.gcloud.storage.Storage; -import com.google.gcloud.storage.Storage.ComposeRequest; -import com.google.gcloud.storage.Storage.CopyRequest; -import com.google.gcloud.storage.Storage.SignUrlOption; -import com.google.gcloud.storage.StorageOptions; -import com.google.gcloud.storage.spi.StorageRpc.Tuple; +package com.google.cloud.examples.storage; + +import com.google.cloud.AuthCredentials; +import com.google.cloud.AuthCredentials.ServiceAccountAuthCredentials; +import com.google.cloud.ReadChannel; +import com.google.cloud.WriteChannel; +import com.google.cloud.storage.Blob; +import com.google.cloud.storage.BlobId; +import com.google.cloud.storage.BlobInfo; +import com.google.cloud.storage.Bucket; +import com.google.cloud.storage.CopyWriter; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.Storage.ComposeRequest; +import com.google.cloud.storage.Storage.CopyRequest; +import com.google.cloud.storage.Storage.SignUrlOption; +import com.google.cloud.storage.StorageOptions; +import com.google.cloud.storage.spi.StorageRpc.Tuple; import java.io.FileOutputStream; import java.io.IOException; @@ -65,7 +65,7 @@ *
  • login using gcloud SDK - {@code gcloud auth login}.
  • *
  • compile using maven - {@code mvn compile}
  • *
  • run using maven - - *
    {@code mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.storage.StorageExample"
    + * 
    {@code mvn exec:java -Dexec.mainClass="com.google.cloud.examples.storage.StorageExample"
      *  -Dexec.args="[]
      *  list [] |
      *  info [ []] |
    diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/CreateAndListBucketsAndBlobs.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/snippets/CreateAndListBucketsAndBlobs.java
    similarity index 89%
    rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/CreateAndListBucketsAndBlobs.java
    rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/snippets/CreateAndListBucketsAndBlobs.java
    index 435cc90b03d8..922afd7047c3 100644
    --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/CreateAndListBucketsAndBlobs.java
    +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/snippets/CreateAndListBucketsAndBlobs.java
    @@ -20,15 +20,15 @@
      * the project's READMEs and package-info.java.
      */
     
    -package com.google.gcloud.examples.storage.snippets;
    +package com.google.cloud.examples.storage.snippets;
     
     import static java.nio.charset.StandardCharsets.UTF_8;
     
    -import com.google.gcloud.storage.Blob;
    -import com.google.gcloud.storage.Bucket;
    -import com.google.gcloud.storage.BucketInfo;
    -import com.google.gcloud.storage.Storage;
    -import com.google.gcloud.storage.StorageOptions;
    +import com.google.cloud.storage.Blob;
    +import com.google.cloud.storage.Bucket;
    +import com.google.cloud.storage.BucketInfo;
    +import com.google.cloud.storage.Storage;
    +import com.google.cloud.storage.StorageOptions;
     
     import java.util.Iterator;
     
    diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/CreateBlob.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/snippets/CreateBlob.java
    similarity index 82%
    rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/CreateBlob.java
    rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/snippets/CreateBlob.java
    index 2c1304a478ab..afe07b0e5206 100644
    --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/CreateBlob.java
    +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/snippets/CreateBlob.java
    @@ -20,15 +20,15 @@
      * the project's READMEs and package-info.java.
      */
     
    -package com.google.gcloud.examples.storage.snippets;
    +package com.google.cloud.examples.storage.snippets;
     
     import static java.nio.charset.StandardCharsets.UTF_8;
     
    -import com.google.gcloud.storage.Blob;
    -import com.google.gcloud.storage.BlobId;
    -import com.google.gcloud.storage.BlobInfo;
    -import com.google.gcloud.storage.Storage;
    -import com.google.gcloud.storage.StorageOptions;
    +import com.google.cloud.storage.Blob;
    +import com.google.cloud.storage.BlobId;
    +import com.google.cloud.storage.BlobInfo;
    +import com.google.cloud.storage.Storage;
    +import com.google.cloud.storage.StorageOptions;
     
     /**
      * A snippet for Google Cloud Storage showing how to create a blob.
    diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/UpdateBlob.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/snippets/UpdateBlob.java
    similarity index 87%
    rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/UpdateBlob.java
    rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/snippets/UpdateBlob.java
    index 13290b201787..c645ba1e4a54 100644
    --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/UpdateBlob.java
    +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/snippets/UpdateBlob.java
    @@ -20,14 +20,14 @@
      * the project's READMEs and package-info.java.
      */
     
    -package com.google.gcloud.examples.storage.snippets;
    +package com.google.cloud.examples.storage.snippets;
     
     import static java.nio.charset.StandardCharsets.UTF_8;
     
    -import com.google.gcloud.storage.Blob;
    -import com.google.gcloud.storage.BlobId;
    -import com.google.gcloud.storage.Storage;
    -import com.google.gcloud.storage.StorageOptions;
    +import com.google.cloud.storage.Blob;
    +import com.google.cloud.storage.BlobId;
    +import com.google.cloud.storage.Storage;
    +import com.google.cloud.storage.StorageOptions;
     
     import java.io.IOException;
     import java.nio.ByteBuffer;
    diff --git a/gcloud-java-resourcemanager/README.md b/gcloud-java-resourcemanager/README.md
    index 667e9222a402..a59146d0f828 100644
    --- a/gcloud-java-resourcemanager/README.md
    +++ b/gcloud-java-resourcemanager/README.md
    @@ -5,12 +5,12 @@ Java idiomatic client for [Google Cloud Resource Manager] (https://cloud.google.
     
     [![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java)
     [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master)
    -[![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-resourcemanager.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-resourcemanager.svg)
    +[![Maven](https://img.shields.io/maven-central/v/com.google.cloud/gcloud-java-resourcemanager.svg)]( https://img.shields.io/maven-central/v/com.google.cloud/gcloud-java-resourcemanager.svg)
     [![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java)
     [![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969)
     
     -  [Homepage] (https://googlecloudplatform.github.io/gcloud-java/)
    --  [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/resourcemanager/package-summary.html)
    +-  [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/resourcemanager/package-summary.html)
     
     > Note: This client is a work-in-progress, and may occasionally
     > make backwards-incompatible changes.
    @@ -20,23 +20,23 @@ Quickstart
     If you are using Maven, add this to your pom.xml file
     ```xml
     
    -  com.google.gcloud
    +  com.google.cloud
       gcloud-java-resourcemanager
       0.1.7
     
     ```
     If you are using Gradle, add this to your dependencies
     ```Groovy
    -compile 'com.google.gcloud:gcloud-java-resourcemanager:0.1.7'
    +compile 'com.google.cloud:gcloud-java-resourcemanager:0.1.7'
     ```
     If you are using SBT, add this to your dependencies
     ```Scala
    -libraryDependencies += "com.google.gcloud" % "gcloud-java-resourcemanager" % "0.1.7"
    +libraryDependencies += "com.google.cloud" % "gcloud-java-resourcemanager" % "0.1.7"
     ```
     
     Example Application
     --------------------
    -[`ResourceManagerExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/ResourceManagerExample.java) is a simple command line interface for the Cloud Resource Manager.  Read more about using the application on the [`ResourceManagerExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/resourcemanager/ResourceManagerExample.html).
    +[`ResourceManagerExample`](../gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/ResourceManagerExample.java) is a simple command line interface for the Cloud Resource Manager.  Read more about using the application on the [`ResourceManagerExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/cloud/examples/resourcemanager/ResourceManagerExample.html).
     
     Authentication
     --------------
    @@ -80,8 +80,8 @@ These credentials are automatically inferred from your environment, so you only
     code to create your service object:
     
     ```java
    -import com.google.gcloud.resourcemanager.ResourceManager;
    -import com.google.gcloud.resourcemanager.ResourceManagerOptions;
    +import com.google.cloud.resourcemanager.ResourceManager;
    +import com.google.cloud.resourcemanager.ResourceManagerOptions;
     
     ResourceManager resourceManager = ResourceManagerOptions.defaultInstance().service();
     ```
    @@ -91,7 +91,7 @@ You can load a project if you know it's project ID and have read permissions to
     To get a project, add the following import at the top of your file:
     
     ```java
    -import com.google.gcloud.resourcemanager.Project;
    +import com.google.cloud.resourcemanager.Project;
     ```
     
     Then use the following code to get the project:
    @@ -108,8 +108,8 @@ names, and labels [here](https://cloud.google.com/resource-manager/reference/res
     To create a project, add the following imports at the top of your file:
     
     ```java
    -import com.google.gcloud.resourcemanager.Project;
    -import com.google.gcloud.resourcemanager.ProjectInfo;
    +import com.google.cloud.resourcemanager.Project;
    +import com.google.cloud.resourcemanager.ProjectInfo;
     ```
     
     Then add the following code to create a project (be sure to change `projectId` to your own unique
    @@ -171,9 +171,9 @@ locally, and then sending the modified policy for writing, as shown in the snipp
     add these imports:
     
     ```java
    -import com.google.gcloud.Identity;
    -import com.google.gcloud.resourcemanager.Policy;
    -import com.google.gcloud.resourcemanager.Policy.Role;
    +import com.google.cloud.Identity;
    +import com.google.cloud.resourcemanager.Policy;
    +import com.google.cloud.resourcemanager.Policy.Role;
     ```
     
     Assuming you have completed the steps above to create the `ResourceManager` service object and load
    @@ -206,15 +206,15 @@ We put together all the code shown above into three programs. The programs assum
     running from your own desktop and used the Google Cloud SDK to authenticate yourself.
     
     The first program creates a project if it does not exist. Complete source code can be found at
    -[GetOrCreateProject.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/GetOrCreateProject.java).
    +[GetOrCreateProject.java](../gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/GetOrCreateProject.java).
     
     The second program updates a project if it exists and lists all projects the user has permission to
     view. Complete source code can be found at
    -[UpdateAndListProjects.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/UpdateAndListProjects.java).
    +[UpdateAndListProjects.java](../gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/UpdateAndListProjects.java).
     
     The third program modifies the IAM policy associated with a project using the read-modify-write
     pattern.  Complete source code can be found at
    -[ModifyPolicy.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/resourcemanager/snippets/ModifyPolicy.java)
    +[ModifyPolicy.java](../gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/snippets/ModifyPolicy.java)
     
     Java Versions
     -------------
    @@ -255,5 +255,5 @@ Apache 2.0 - See [LICENSE] for more information.
     [TESTING]: https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/TESTING.md#testing-code-that-uses-resource-manager
     [cloud-platform]: https://cloud.google.com/
     [cloud-resourcemanager]: https://cloud.google.com/resource-manager/docs
    -[resourcemanager-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/resourcemanager/package-summary.html
    +[resourcemanager-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/resourcemanager/package-summary.html
     
    diff --git a/gcloud-java-resourcemanager/pom.xml b/gcloud-java-resourcemanager/pom.xml
    index d970bdf883da..007847d4004d 100644
    --- a/gcloud-java-resourcemanager/pom.xml
    +++ b/gcloud-java-resourcemanager/pom.xml
    @@ -8,7 +8,7 @@
         Java idiomatic client for Google Cloud Resource Manager.
       
       
    -    com.google.gcloud
    +    com.google.cloud
         gcloud-java-pom
         0.1.8-SNAPSHOT
       
    diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Option.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Option.java
    similarity index 94%
    rename from gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Option.java
    rename to gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Option.java
    index 3df68468f69f..fb81d77a88ff 100644
    --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Option.java
    +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Option.java
    @@ -14,12 +14,12 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.resourcemanager;
    +package com.google.cloud.resourcemanager;
     
     import static com.google.common.base.Preconditions.checkNotNull;
     
     import com.google.common.base.MoreObjects;
    -import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc;
    +import com.google.cloud.resourcemanager.spi.ResourceManagerRpc;
     
     import java.io.Serializable;
     import java.util.Objects;
    diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Policy.java
    similarity index 97%
    rename from gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java
    rename to gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Policy.java
    index 219d74262319..6f150086a7e3 100644
    --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Policy.java
    +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Policy.java
    @@ -14,14 +14,14 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.resourcemanager;
    +package com.google.cloud.resourcemanager;
     
     import com.google.common.annotations.VisibleForTesting;
     import com.google.common.base.Function;
     import com.google.common.collect.ImmutableSet;
     import com.google.common.collect.Lists;
    -import com.google.gcloud.IamPolicy;
    -import com.google.gcloud.Identity;
    +import com.google.cloud.IamPolicy;
    +import com.google.cloud.Identity;
     
     import java.util.ArrayList;
     import java.util.HashMap;
    diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Project.java
    similarity index 99%
    rename from gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java
    rename to gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Project.java
    index bf9cf0e01a6d..25cda85d1c09 100644
    --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/Project.java
    +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Project.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.resourcemanager;
    +package com.google.cloud.resourcemanager;
     
     import static com.google.common.base.Preconditions.checkNotNull;
     
    diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ProjectInfo.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ProjectInfo.java
    similarity index 99%
    rename from gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ProjectInfo.java
    rename to gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ProjectInfo.java
    index 260e8a8e2f26..355236b653f1 100644
    --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ProjectInfo.java
    +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ProjectInfo.java
    @@ -12,7 +12,7 @@
      * the License.
      */
     
    -package com.google.gcloud.resourcemanager;
    +package com.google.cloud.resourcemanager;
     
     import static com.google.common.base.MoreObjects.firstNonNull;
     import static com.google.common.base.Preconditions.checkNotNull;
    diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManager.java
    similarity index 97%
    rename from gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java
    rename to gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManager.java
    index 92494a5152fe..93425464872f 100644
    --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManager.java
    +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManager.java
    @@ -14,15 +14,15 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.resourcemanager;
    +package com.google.cloud.resourcemanager;
     
     import com.google.common.collect.ImmutableList;
    -import com.google.gcloud.FieldSelector;
    -import com.google.gcloud.FieldSelector.Helper;
    -import com.google.gcloud.IamPolicy;
    -import com.google.gcloud.Page;
    -import com.google.gcloud.Service;
    -import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc;
    +import com.google.cloud.FieldSelector;
    +import com.google.cloud.FieldSelector.Helper;
    +import com.google.cloud.IamPolicy;
    +import com.google.cloud.Page;
    +import com.google.cloud.Service;
    +import com.google.cloud.resourcemanager.spi.ResourceManagerRpc;
     
     import java.util.List;
     
    diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerException.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerException.java
    similarity index 92%
    rename from gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerException.java
    rename to gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerException.java
    index 32a2998791c9..026845d0734c 100644
    --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerException.java
    +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerException.java
    @@ -14,12 +14,12 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.resourcemanager;
    +package com.google.cloud.resourcemanager;
     
     import com.google.common.collect.ImmutableSet;
    -import com.google.gcloud.BaseServiceException;
    -import com.google.gcloud.RetryHelper.RetryHelperException;
    -import com.google.gcloud.RetryHelper.RetryInterruptedException;
    +import com.google.cloud.BaseServiceException;
    +import com.google.cloud.RetryHelper.RetryHelperException;
    +import com.google.cloud.RetryHelper.RetryInterruptedException;
     
     import java.io.IOException;
     import java.util.Set;
    diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerFactory.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerFactory.java
    similarity index 90%
    rename from gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerFactory.java
    rename to gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerFactory.java
    index 256fc321e4e1..7ef607cac23b 100644
    --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerFactory.java
    +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerFactory.java
    @@ -14,9 +14,9 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.resourcemanager;
    +package com.google.cloud.resourcemanager;
     
    -import com.google.gcloud.ServiceFactory;
    +import com.google.cloud.ServiceFactory;
     
     /**
      * An interface for ResourceManager factories.
    diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerImpl.java
    similarity index 95%
    rename from gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java
    rename to gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerImpl.java
    index e4663cb74cb9..2ee4dc4e9e22 100644
    --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerImpl.java
    +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerImpl.java
    @@ -14,23 +14,23 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.resourcemanager;
    +package com.google.cloud.resourcemanager;
     
     import static com.google.common.base.Preconditions.checkArgument;
    -import static com.google.gcloud.RetryHelper.runWithRetries;
    +import static com.google.cloud.RetryHelper.runWithRetries;
     
     import com.google.common.base.Function;
     import com.google.common.collect.ImmutableList;
     import com.google.common.collect.ImmutableMap;
     import com.google.common.collect.Iterables;
     import com.google.common.collect.Maps;
    -import com.google.gcloud.BaseService;
    -import com.google.gcloud.Page;
    -import com.google.gcloud.PageImpl;
    -import com.google.gcloud.PageImpl.NextPageFetcher;
    -import com.google.gcloud.RetryHelper.RetryHelperException;
    -import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc;
    -import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc.Tuple;
    +import com.google.cloud.BaseService;
    +import com.google.cloud.Page;
    +import com.google.cloud.PageImpl;
    +import com.google.cloud.PageImpl.NextPageFetcher;
    +import com.google.cloud.RetryHelper.RetryHelperException;
    +import com.google.cloud.resourcemanager.spi.ResourceManagerRpc;
    +import com.google.cloud.resourcemanager.spi.ResourceManagerRpc.Tuple;
     
     import java.util.List;
     import java.util.Map;
    diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerOptions.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerOptions.java
    similarity index 92%
    rename from gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerOptions.java
    rename to gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerOptions.java
    index 2020be3d2ece..8f5c79e8bc3f 100644
    --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/ResourceManagerOptions.java
    +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerOptions.java
    @@ -14,13 +14,13 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.resourcemanager;
    +package com.google.cloud.resourcemanager;
     
     import com.google.common.collect.ImmutableSet;
    -import com.google.gcloud.ServiceOptions;
    -import com.google.gcloud.resourcemanager.spi.DefaultResourceManagerRpc;
    -import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc;
    -import com.google.gcloud.resourcemanager.spi.ResourceManagerRpcFactory;
    +import com.google.cloud.ServiceOptions;
    +import com.google.cloud.resourcemanager.spi.DefaultResourceManagerRpc;
    +import com.google.cloud.resourcemanager.spi.ResourceManagerRpc;
    +import com.google.cloud.resourcemanager.spi.ResourceManagerRpcFactory;
     
     import java.util.Set;
     
    diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/package-info.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/package-info.java
    similarity index 90%
    rename from gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/package-info.java
    rename to gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/package-info.java
    index d1794447e9fb..0329b0a89b4a 100644
    --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/package-info.java
    +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/package-info.java
    @@ -19,7 +19,7 @@
      *
      * 

    Here's a simple usage example for using gcloud-java from App/Compute Engine. This example * creates a project if it does not exist. For the complete source code see - * + * * GetOrCreateProject.java. *

     {@code
      * ResourceManager resourceManager = ResourceManagerOptions.defaultInstance().service();
    @@ -33,7 +33,7 @@
      * 

    * This second example shows how to update a project if it exists and list all projects the user has * permission to view. For the complete source code see - * + * * UpdateAndListProjects.java. *

     {@code
      * ResourceManager resourceManager = ResourceManagerOptions.defaultInstance().service();
    @@ -58,4 +58,4 @@
      * @see Google Cloud Resource Manager
      */
     
    -package com.google.gcloud.resourcemanager;
    +package com.google.cloud.resourcemanager;
    diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/DefaultResourceManagerRpc.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/spi/DefaultResourceManagerRpc.java
    similarity index 91%
    rename from gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/DefaultResourceManagerRpc.java
    rename to gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/spi/DefaultResourceManagerRpc.java
    index 9f92ff545874..536328b5aa60 100644
    --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/DefaultResourceManagerRpc.java
    +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/spi/DefaultResourceManagerRpc.java
    @@ -1,10 +1,10 @@
    -package com.google.gcloud.resourcemanager.spi;
    +package com.google.cloud.resourcemanager.spi;
     
     import static com.google.common.base.MoreObjects.firstNonNull;
    -import static com.google.gcloud.resourcemanager.spi.ResourceManagerRpc.Option.FIELDS;
    -import static com.google.gcloud.resourcemanager.spi.ResourceManagerRpc.Option.FILTER;
    -import static com.google.gcloud.resourcemanager.spi.ResourceManagerRpc.Option.PAGE_SIZE;
    -import static com.google.gcloud.resourcemanager.spi.ResourceManagerRpc.Option.PAGE_TOKEN;
    +import static com.google.cloud.resourcemanager.spi.ResourceManagerRpc.Option.FIELDS;
    +import static com.google.cloud.resourcemanager.spi.ResourceManagerRpc.Option.FILTER;
    +import static com.google.cloud.resourcemanager.spi.ResourceManagerRpc.Option.PAGE_SIZE;
    +import static com.google.cloud.resourcemanager.spi.ResourceManagerRpc.Option.PAGE_TOKEN;
     import static java.net.HttpURLConnection.HTTP_FORBIDDEN;
     import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
     
    @@ -21,8 +21,8 @@
     import com.google.api.services.cloudresourcemanager.model.TestIamPermissionsResponse;
     import com.google.common.collect.ImmutableList;
     import com.google.common.collect.ImmutableSet;
    -import com.google.gcloud.resourcemanager.ResourceManagerException;
    -import com.google.gcloud.resourcemanager.ResourceManagerOptions;
    +import com.google.cloud.resourcemanager.ResourceManagerException;
    +import com.google.cloud.resourcemanager.ResourceManagerOptions;
     
     import java.io.IOException;
     import java.util.List;
    diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/ResourceManagerRpc.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/spi/ResourceManagerRpc.java
    similarity index 97%
    rename from gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/ResourceManagerRpc.java
    rename to gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/spi/ResourceManagerRpc.java
    index d6ec068a92a3..11e028be93a3 100644
    --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/ResourceManagerRpc.java
    +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/spi/ResourceManagerRpc.java
    @@ -14,11 +14,11 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.resourcemanager.spi;
    +package com.google.cloud.resourcemanager.spi;
     
     import com.google.api.services.cloudresourcemanager.model.Policy;
     import com.google.api.services.cloudresourcemanager.model.Project;
    -import com.google.gcloud.resourcemanager.ResourceManagerException;
    +import com.google.cloud.resourcemanager.ResourceManagerException;
     
     import java.util.List;
     import java.util.Map;
    diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/ResourceManagerRpcFactory.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/spi/ResourceManagerRpcFactory.java
    similarity index 84%
    rename from gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/ResourceManagerRpcFactory.java
    rename to gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/spi/ResourceManagerRpcFactory.java
    index 4dbd1a00d4c7..ef6a96ac4b5e 100644
    --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/spi/ResourceManagerRpcFactory.java
    +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/spi/ResourceManagerRpcFactory.java
    @@ -14,10 +14,10 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.resourcemanager.spi;
    +package com.google.cloud.resourcemanager.spi;
     
    -import com.google.gcloud.resourcemanager.ResourceManagerOptions;
    -import com.google.gcloud.spi.ServiceRpcFactory;
    +import com.google.cloud.resourcemanager.ResourceManagerOptions;
    +import com.google.cloud.spi.ServiceRpcFactory;
     
     /**
      * An interface for Resource Manager RPC factory.
    diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/testing/LocalResourceManagerHelper.java
    similarity index 99%
    rename from gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java
    rename to gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/testing/LocalResourceManagerHelper.java
    index 4d466e55a897..614a7ec63ecf 100644
    --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelper.java
    +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/testing/LocalResourceManagerHelper.java
    @@ -1,4 +1,4 @@
    -package com.google.gcloud.resourcemanager.testing;
    +package com.google.cloud.resourcemanager.testing;
     
     import static com.google.common.base.Preconditions.checkArgument;
     import static com.google.common.base.Preconditions.checkNotNull;
    @@ -17,8 +17,8 @@
     import com.google.common.collect.ImmutableMap;
     import com.google.common.collect.ImmutableSet;
     import com.google.common.io.ByteStreams;
    -import com.google.gcloud.AuthCredentials;
    -import com.google.gcloud.resourcemanager.ResourceManagerOptions;
    +import com.google.cloud.AuthCredentials;
    +import com.google.cloud.resourcemanager.ResourceManagerOptions;
     
     import com.sun.net.httpserver.Headers;
     import com.sun.net.httpserver.HttpExchange;
    diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/package-info.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/testing/package-info.java
    similarity index 95%
    rename from gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/package-info.java
    rename to gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/testing/package-info.java
    index e00b6eda1822..d007d00eaeab 100644
    --- a/gcloud-java-resourcemanager/src/main/java/com/google/gcloud/resourcemanager/testing/package-info.java
    +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/testing/package-info.java
    @@ -30,4 +30,4 @@
      * resourceManagerHelper.stop();
      * }
    */ -package com.google.gcloud.resourcemanager.testing; +package com.google.cloud.resourcemanager.testing; diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/OptionTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/OptionTest.java similarity index 95% rename from gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/OptionTest.java rename to gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/OptionTest.java index 729c7a4b8911..097a5c61c13d 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/OptionTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/OptionTest.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.google.gcloud.resourcemanager; +package com.google.cloud.resourcemanager; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNull; -import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc; +import com.google.cloud.resourcemanager.spi.ResourceManagerRpc; import org.junit.Rule; import org.junit.Test; diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/PolicyTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/PolicyTest.java similarity index 94% rename from gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/PolicyTest.java rename to gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/PolicyTest.java index 04826dd9540f..a99286b119ba 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/PolicyTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/PolicyTest.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.google.gcloud.resourcemanager; +package com.google.cloud.resourcemanager; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; -import com.google.gcloud.Identity; -import com.google.gcloud.resourcemanager.Policy.ProjectRole; +import com.google.cloud.Identity; +import com.google.cloud.resourcemanager.Policy.ProjectRole; import org.junit.Test; diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectInfoTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ProjectInfoTest.java similarity index 99% rename from gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectInfoTest.java rename to gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ProjectInfoTest.java index 3aaef8047322..2b276f485a72 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectInfoTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ProjectInfoTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.resourcemanager; +package com.google.cloud.resourcemanager; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ProjectTest.java similarity index 97% rename from gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectTest.java rename to gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ProjectTest.java index 0f4c205dde17..58920e5fec12 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ProjectTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ProjectTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.resourcemanager; +package com.google.cloud.resourcemanager; import static org.easymock.EasyMock.anyObject; import static org.easymock.EasyMock.createMock; @@ -27,9 +27,9 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.google.gcloud.Identity; -import com.google.gcloud.resourcemanager.Policy.ProjectRole; -import com.google.gcloud.resourcemanager.ProjectInfo.ResourceId; +import com.google.cloud.Identity; +import com.google.cloud.resourcemanager.Policy.ProjectRole; +import com.google.cloud.resourcemanager.ProjectInfo.ResourceId; import org.junit.After; import org.junit.Before; diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerExceptionTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ResourceManagerExceptionTest.java similarity index 95% rename from gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerExceptionTest.java rename to gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ResourceManagerExceptionTest.java index 388f38f31c35..2ac8d1acba7f 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerExceptionTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ResourceManagerExceptionTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.resourcemanager; +package com.google.cloud.resourcemanager; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; @@ -25,8 +25,8 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import com.google.gcloud.BaseServiceException; -import com.google.gcloud.RetryHelper.RetryHelperException; +import com.google.cloud.BaseServiceException; +import com.google.cloud.RetryHelper.RetryHelperException; import org.junit.Test; diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ResourceManagerImplTest.java similarity index 96% rename from gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java rename to gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ResourceManagerImplTest.java index 7d52901aa372..910478af0888 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/ResourceManagerImplTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ResourceManagerImplTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.resourcemanager; +package com.google.cloud.resourcemanager; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -27,16 +27,16 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.google.gcloud.Identity; -import com.google.gcloud.Page; -import com.google.gcloud.resourcemanager.Policy.ProjectRole; -import com.google.gcloud.resourcemanager.ProjectInfo.ResourceId; -import com.google.gcloud.resourcemanager.ResourceManager.ProjectField; -import com.google.gcloud.resourcemanager.ResourceManager.ProjectGetOption; -import com.google.gcloud.resourcemanager.ResourceManager.ProjectListOption; -import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc; -import com.google.gcloud.resourcemanager.spi.ResourceManagerRpcFactory; -import com.google.gcloud.resourcemanager.testing.LocalResourceManagerHelper; +import com.google.cloud.Identity; +import com.google.cloud.Page; +import com.google.cloud.resourcemanager.Policy.ProjectRole; +import com.google.cloud.resourcemanager.ProjectInfo.ResourceId; +import com.google.cloud.resourcemanager.ResourceManager.ProjectField; +import com.google.cloud.resourcemanager.ResourceManager.ProjectGetOption; +import com.google.cloud.resourcemanager.ResourceManager.ProjectListOption; +import com.google.cloud.resourcemanager.spi.ResourceManagerRpc; +import com.google.cloud.resourcemanager.spi.ResourceManagerRpcFactory; +import com.google.cloud.resourcemanager.testing.LocalResourceManagerHelper; import org.easymock.EasyMock; import org.junit.AfterClass; diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/SerializationTest.java similarity index 91% rename from gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java rename to gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/SerializationTest.java index 4bc1bcede195..b09f81b60997 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/SerializationTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/SerializationTest.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.google.gcloud.resourcemanager; +package com.google.cloud.resourcemanager; import com.google.common.collect.ImmutableMap; -import com.google.gcloud.BaseSerializationTest; -import com.google.gcloud.Identity; -import com.google.gcloud.PageImpl; -import com.google.gcloud.Restorable; -import com.google.gcloud.resourcemanager.Policy.ProjectRole; +import com.google.cloud.BaseSerializationTest; +import com.google.cloud.Identity; +import com.google.cloud.PageImpl; +import com.google.cloud.Restorable; +import com.google.cloud.resourcemanager.Policy.ProjectRole; import java.io.Serializable; import java.util.Collections; diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelperTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/testing/LocalResourceManagerHelperTest.java similarity index 98% rename from gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelperTest.java rename to gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/testing/LocalResourceManagerHelperTest.java index 612a4752df6d..7a23383b3d89 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/gcloud/resourcemanager/testing/LocalResourceManagerHelperTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/testing/LocalResourceManagerHelperTest.java @@ -1,4 +1,4 @@ -package com.google.gcloud.resourcemanager.testing; +package com.google.cloud.resourcemanager.testing; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -11,10 +11,10 @@ import com.google.api.services.cloudresourcemanager.model.Binding; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.google.gcloud.resourcemanager.ResourceManagerException; -import com.google.gcloud.resourcemanager.spi.DefaultResourceManagerRpc; -import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc; -import com.google.gcloud.resourcemanager.spi.ResourceManagerRpc.Tuple; +import com.google.cloud.resourcemanager.ResourceManagerException; +import com.google.cloud.resourcemanager.spi.DefaultResourceManagerRpc; +import com.google.cloud.resourcemanager.spi.ResourceManagerRpc; +import com.google.cloud.resourcemanager.spi.ResourceManagerRpc.Tuple; import org.junit.AfterClass; import org.junit.Before; diff --git a/gcloud-java-storage/README.md b/gcloud-java-storage/README.md index 5a8897356db8..8dd56a60c44a 100644 --- a/gcloud-java-storage/README.md +++ b/gcloud-java-storage/README.md @@ -5,12 +5,12 @@ Java idiomatic client for [Google Cloud Storage] (https://cloud.google.com/stora [![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java) [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) -[![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-storage.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java-storage.svg) +[![Maven](https://img.shields.io/maven-central/v/com.google.cloud/gcloud-java-storage.svg)]( https://img.shields.io/maven-central/v/com.google.cloud/gcloud-java-storage.svg) [![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) [![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969) - [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) -- [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/storage/package-summary.html) +- [API Documentation] (http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/storage/package-summary.html) > Note: This client is a work-in-progress, and may occasionally > make backwards-incompatible changes. @@ -20,24 +20,24 @@ Quickstart If you are using Maven, add this to your pom.xml file ```xml - com.google.gcloud + com.google.cloud gcloud-java-storage 0.1.7 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.gcloud:gcloud-java-storage:0.1.7' +compile 'com.google.cloud:gcloud-java-storage:0.1.7' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.gcloud" % "gcloud-java-storage" % "0.1.7" +libraryDependencies += "com.google.cloud" % "gcloud-java-storage" % "0.1.7" ``` Example Application ------------------- -[`StorageExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/StorageExample.java) is a simple command line interface that provides some of Cloud Storage's functionality. Read more about using the application on the [`StorageExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/storage/StorageExample.html). +[`StorageExample`](../gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/StorageExample.java) is a simple command line interface that provides some of Cloud Storage's functionality. Read more about using the application on the [`StorageExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/cloud/examples/storage/StorageExample.html). Authentication -------------- @@ -70,8 +70,8 @@ You'll need to obtain the `gcloud-java-storage` library. See the [Quickstart](# To make authenticated requests to Google Cloud Storage, you must create a service object with credentials. You can then make API calls by calling methods on the Storage service object. The simplest way to authenticate is to use [Application Default Credentials](https://developers.google.com/identity/protocols/application-default-credentials). These credentials are automatically inferred from your environment, so you only need the following code to create your service object: ```java -import com.google.gcloud.storage.Storage; -import com.google.gcloud.storage.StorageOptions; +import com.google.cloud.storage.Storage; +import com.google.cloud.storage.StorageOptions; Storage storage = StorageOptions.defaultInstance().service(); ``` @@ -86,9 +86,9 @@ Add the following imports at the top of your file: ```java import static java.nio.charset.StandardCharsets.UTF_8; -import com.google.gcloud.storage.Blob; -import com.google.gcloud.storage.Bucket; -import com.google.gcloud.storage.BucketInfo; +import com.google.cloud.storage.Blob; +import com.google.cloud.storage.Bucket; +import com.google.cloud.storage.BucketInfo; ``` Then add the following code to create a bucket and upload a simple blob. @@ -143,7 +143,7 @@ while (blobIterator.hasNext()) { #### Complete source code In -[CreateAndListBucketsAndBlobs.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/storage/snippets/CreateAndListBucketsAndBlobs.java) +[CreateAndListBucketsAndBlobs.java](../gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/snippets/CreateAndListBucketsAndBlobs.java) we put together all the code shown above into one program. The program assumes that you are running on Compute Engine or from your own desktop. To run the example on App Engine, simply move the code from the main method to your application's servlet class and change the print statements to @@ -199,5 +199,5 @@ Apache 2.0 - See [LICENSE] for more information. [cloud-storage]: https://cloud.google.com/storage/ [cloud-storage-docs]: https://cloud.google.com/storage/docs/overview [cloud-storage-create-bucket]: https://cloud.google.com/storage/docs/cloud-console#_creatingbuckets -[storage-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/storage/package-summary.html +[storage-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/storage/package-summary.html [cloud-storage-activation]:https://cloud.google.com/storage/docs/signup?hl=en diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml index 2316706850d3..9adab9982493 100644 --- a/gcloud-java-storage/pom.xml +++ b/gcloud-java-storage/pom.xml @@ -8,7 +8,7 @@ Java idiomatic client for Google Cloud Storage. - com.google.gcloud + com.google.cloud gcloud-java-pom 0.1.8-SNAPSHOT diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Acl.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Acl.java similarity index 99% rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/Acl.java rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/Acl.java index 4203d79351b7..1063b24580b8 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Acl.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Acl.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.storage; +package com.google.cloud.storage; import com.google.api.services.storage.model.BucketAccessControl; import com.google.api.services.storage.model.ObjectAccessControl; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BatchRequest.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BatchRequest.java similarity index 94% rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/BatchRequest.java rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/BatchRequest.java index bf77c731754e..f98160b91b18 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BatchRequest.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BatchRequest.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.google.gcloud.storage; +package com.google.cloud.storage; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; -import com.google.gcloud.storage.Storage.BlobGetOption; -import com.google.gcloud.storage.Storage.BlobSourceOption; -import com.google.gcloud.storage.Storage.BlobTargetOption; +import com.google.cloud.storage.Storage.BlobGetOption; +import com.google.cloud.storage.Storage.BlobSourceOption; +import com.google.cloud.storage.Storage.BlobTargetOption; import java.io.Serializable; import java.util.LinkedHashMap; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BatchResponse.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BatchResponse.java similarity index 99% rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/BatchResponse.java rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/BatchResponse.java index fe5f6f5743c8..d07d9dc26c2d 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BatchResponse.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BatchResponse.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.storage; +package com.google.cloud.storage; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Blob.java similarity index 95% rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/Blob.java index 72fcfeff034f..df5ab959ad30 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Blob.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Blob.java @@ -14,27 +14,27 @@ * limitations under the License. */ -package com.google.gcloud.storage; +package com.google.cloud.storage; import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.gcloud.storage.Blob.BlobSourceOption.toGetOptions; -import static com.google.gcloud.storage.Blob.BlobSourceOption.toSourceOptions; +import static com.google.cloud.storage.Blob.BlobSourceOption.toGetOptions; +import static com.google.cloud.storage.Blob.BlobSourceOption.toSourceOptions; import com.google.api.services.storage.model.StorageObject; import com.google.common.base.Function; -import com.google.gcloud.AuthCredentials; -import com.google.gcloud.AuthCredentials.AppEngineAuthCredentials; -import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials; -import com.google.gcloud.ReadChannel; -import com.google.gcloud.ServiceAccountSigner; -import com.google.gcloud.ServiceAccountSigner.SigningException; -import com.google.gcloud.WriteChannel; -import com.google.gcloud.storage.Storage.BlobTargetOption; -import com.google.gcloud.storage.Storage.BlobWriteOption; -import com.google.gcloud.storage.Storage.CopyRequest; -import com.google.gcloud.storage.Storage.SignUrlOption; -import com.google.gcloud.storage.spi.StorageRpc; -import com.google.gcloud.storage.spi.StorageRpc.Tuple; +import com.google.cloud.AuthCredentials; +import com.google.cloud.AuthCredentials.AppEngineAuthCredentials; +import com.google.cloud.AuthCredentials.ServiceAccountAuthCredentials; +import com.google.cloud.ReadChannel; +import com.google.cloud.ServiceAccountSigner; +import com.google.cloud.ServiceAccountSigner.SigningException; +import com.google.cloud.WriteChannel; +import com.google.cloud.storage.Storage.BlobTargetOption; +import com.google.cloud.storage.Storage.BlobWriteOption; +import com.google.cloud.storage.Storage.CopyRequest; +import com.google.cloud.storage.Storage.SignUrlOption; +import com.google.cloud.storage.spi.StorageRpc; +import com.google.cloud.storage.spi.StorageRpc.Tuple; import java.io.IOException; import java.io.ObjectInputStream; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobId.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobId.java similarity index 99% rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobId.java rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobId.java index d30003d632db..52e7fc5f331e 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobId.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.storage; +package com.google.cloud.storage; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobInfo.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobInfo.java similarity index 99% rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobInfo.java rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobInfo.java index 42a2e282b002..dd264fa7f92b 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobInfo.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobInfo.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.storage; +package com.google.cloud.storage; import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobReadChannel.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobReadChannel.java similarity index 96% rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobReadChannel.java rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobReadChannel.java index f9c6f912563d..1c15a9cd4e54 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobReadChannel.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobReadChannel.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package com.google.gcloud.storage; +package com.google.cloud.storage; -import static com.google.gcloud.RetryHelper.runWithRetries; +import static com.google.cloud.RetryHelper.runWithRetries; import com.google.api.services.storage.model.StorageObject; import com.google.common.base.MoreObjects; -import com.google.gcloud.ReadChannel; -import com.google.gcloud.RestorableState; -import com.google.gcloud.RetryHelper; -import com.google.gcloud.storage.spi.StorageRpc; -import com.google.gcloud.storage.spi.StorageRpc.Tuple; +import com.google.cloud.ReadChannel; +import com.google.cloud.RestorableState; +import com.google.cloud.RetryHelper; +import com.google.cloud.storage.spi.StorageRpc; +import com.google.cloud.storage.spi.StorageRpc.Tuple; import java.io.IOException; import java.io.Serializable; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobWriteChannel.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobWriteChannel.java similarity index 89% rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobWriteChannel.java rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobWriteChannel.java index 30b0ec870f51..0076b3cbaac4 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BlobWriteChannel.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobWriteChannel.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package com.google.gcloud.storage; +package com.google.cloud.storage; -import static com.google.gcloud.RetryHelper.runWithRetries; +import static com.google.cloud.RetryHelper.runWithRetries; import static java.util.concurrent.Executors.callable; -import com.google.gcloud.BaseWriteChannel; -import com.google.gcloud.RestorableState; -import com.google.gcloud.RetryHelper; -import com.google.gcloud.WriteChannel; -import com.google.gcloud.storage.spi.StorageRpc; +import com.google.cloud.BaseWriteChannel; +import com.google.cloud.RestorableState; +import com.google.cloud.RetryHelper; +import com.google.cloud.WriteChannel; +import com.google.cloud.storage.spi.StorageRpc; import java.util.Map; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Bucket.java similarity index 97% rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/Bucket.java index cb2058a9e7ab..04337e6a77b1 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Bucket.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Bucket.java @@ -14,20 +14,20 @@ * limitations under the License. */ -package com.google.gcloud.storage; +package com.google.cloud.storage; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.gcloud.storage.Bucket.BucketSourceOption.toGetOptions; -import static com.google.gcloud.storage.Bucket.BucketSourceOption.toSourceOptions; +import static com.google.cloud.storage.Bucket.BucketSourceOption.toGetOptions; +import static com.google.cloud.storage.Bucket.BucketSourceOption.toSourceOptions; import com.google.common.base.Function; import com.google.common.collect.Lists; import com.google.common.collect.Sets; -import com.google.gcloud.Page; -import com.google.gcloud.storage.Storage.BlobGetOption; -import com.google.gcloud.storage.Storage.BucketTargetOption; -import com.google.gcloud.storage.spi.StorageRpc; +import com.google.cloud.Page; +import com.google.cloud.storage.Storage.BlobGetOption; +import com.google.cloud.storage.Storage.BucketTargetOption; +import com.google.cloud.storage.spi.StorageRpc; import java.io.IOException; import java.io.InputStream; @@ -626,7 +626,7 @@ public List get(String blobName1, String blobName2, String... blobNames) { /** * Creates a new blob in this bucket. Direct upload is used to upload {@code content}. - * For large content, {@link Blob#writer(com.google.gcloud.storage.Storage.BlobWriteOption...)} + * For large content, {@link Blob#writer(com.google.cloud.storage.Storage.BlobWriteOption...)} * is recommended as it uses resumable upload. MD5 and CRC32C hashes of {@code content} are * computed and used for validating transferred data. * @@ -646,7 +646,7 @@ public Blob create(String blob, byte[] content, String contentType, BlobTargetOp /** * Creates a new blob in this bucket. Direct upload is used to upload {@code content}. - * For large content, {@link Blob#writer(com.google.gcloud.storage.Storage.BlobWriteOption...)} + * For large content, {@link Blob#writer(com.google.cloud.storage.Storage.BlobWriteOption...)} * is recommended as it uses resumable upload. * * @param blob a blob name @@ -666,7 +666,7 @@ public Blob create(String blob, InputStream content, String contentType, /** * Creates a new blob in this bucket. Direct upload is used to upload {@code content}. - * For large content, {@link Blob#writer(com.google.gcloud.storage.Storage.BlobWriteOption...)} + * For large content, {@link Blob#writer(com.google.cloud.storage.Storage.BlobWriteOption...)} * is recommended as it uses resumable upload. MD5 and CRC32C hashes of {@code content} are * computed and used for validating transferred data. * @@ -685,7 +685,7 @@ public Blob create(String blob, byte[] content, BlobTargetOption... options) { /** * Creates a new blob in this bucket. Direct upload is used to upload {@code content}. - * For large content, {@link Blob#writer(com.google.gcloud.storage.Storage.BlobWriteOption...)} + * For large content, {@link Blob#writer(com.google.cloud.storage.Storage.BlobWriteOption...)} * is recommended as it uses resumable upload. * * @param blob a blob name diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BucketInfo.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BucketInfo.java similarity index 99% rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/BucketInfo.java rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/BucketInfo.java index a893e45c5c86..88ff6095f762 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/BucketInfo.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BucketInfo.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.storage; +package com.google.cloud.storage; import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.Preconditions.checkNotNull; @@ -33,7 +33,7 @@ import com.google.common.base.Function; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; -import com.google.gcloud.storage.Acl.Entity; +import com.google.cloud.storage.Acl.Entity; import java.io.IOException; import java.io.ObjectInputStream; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/CopyWriter.java similarity index 96% rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/CopyWriter.java index 743630b6c4c2..5d3289e71861 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/CopyWriter.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/CopyWriter.java @@ -14,17 +14,17 @@ * limitations under the License. */ -package com.google.gcloud.storage; +package com.google.cloud.storage; -import static com.google.gcloud.RetryHelper.runWithRetries; +import static com.google.cloud.RetryHelper.runWithRetries; import com.google.common.base.MoreObjects; -import com.google.gcloud.Restorable; -import com.google.gcloud.RestorableState; -import com.google.gcloud.RetryHelper; -import com.google.gcloud.storage.spi.StorageRpc; -import com.google.gcloud.storage.spi.StorageRpc.RewriteRequest; -import com.google.gcloud.storage.spi.StorageRpc.RewriteResponse; +import com.google.cloud.Restorable; +import com.google.cloud.RestorableState; +import com.google.cloud.RetryHelper; +import com.google.cloud.storage.spi.StorageRpc; +import com.google.cloud.storage.spi.StorageRpc.RewriteRequest; +import com.google.cloud.storage.spi.StorageRpc.RewriteResponse; import java.io.Serializable; import java.util.Map; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Cors.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Cors.java similarity index 99% rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/Cors.java rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/Cors.java index bcbbd1030dbc..27ff44156712 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Cors.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Cors.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.storage; +package com.google.cloud.storage; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.collect.Iterables.transform; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/HttpMethod.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/HttpMethod.java similarity index 95% rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/HttpMethod.java rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/HttpMethod.java index e2a4563316d3..0d4953b9f316 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/HttpMethod.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/HttpMethod.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.storage; +package com.google.cloud.storage; /** * Http method supported by Storage service. diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Option.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Option.java similarity index 95% rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/Option.java rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/Option.java index 774023eff78b..ca1077d7c595 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Option.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Option.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.google.gcloud.storage; +package com.google.cloud.storage; import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.MoreObjects; -import com.google.gcloud.storage.spi.StorageRpc; +import com.google.cloud.storage.spi.StorageRpc; import java.io.Serializable; import java.util.Objects; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Storage.java similarity index 98% rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/Storage.java index af91905a9f2a..e59e465095d6 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Storage.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.storage; +package com.google.cloud.storage; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; @@ -22,19 +22,19 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; -import com.google.gcloud.AuthCredentials; -import com.google.gcloud.AuthCredentials.AppEngineAuthCredentials; -import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials; -import com.google.gcloud.FieldSelector; -import com.google.gcloud.FieldSelector.Helper; -import com.google.gcloud.Page; -import com.google.gcloud.ReadChannel; -import com.google.gcloud.Service; -import com.google.gcloud.ServiceAccountSigner; -import com.google.gcloud.ServiceAccountSigner.SigningException; -import com.google.gcloud.WriteChannel; -import com.google.gcloud.storage.spi.StorageRpc; -import com.google.gcloud.storage.spi.StorageRpc.Tuple; +import com.google.cloud.AuthCredentials; +import com.google.cloud.AuthCredentials.AppEngineAuthCredentials; +import com.google.cloud.AuthCredentials.ServiceAccountAuthCredentials; +import com.google.cloud.FieldSelector; +import com.google.cloud.FieldSelector.Helper; +import com.google.cloud.Page; +import com.google.cloud.ReadChannel; +import com.google.cloud.Service; +import com.google.cloud.ServiceAccountSigner; +import com.google.cloud.ServiceAccountSigner.SigningException; +import com.google.cloud.WriteChannel; +import com.google.cloud.storage.spi.StorageRpc; +import com.google.cloud.storage.spi.StorageRpc.Tuple; import java.io.InputStream; import java.io.Serializable; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageException.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageException.java similarity index 91% rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageException.java rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageException.java index ee85b80d6e13..2b1aa24e13af 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageException.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageException.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.google.gcloud.storage; +package com.google.cloud.storage; import com.google.api.client.googleapis.json.GoogleJsonError; import com.google.common.collect.ImmutableSet; -import com.google.gcloud.BaseServiceException; -import com.google.gcloud.RetryHelper.RetryHelperException; -import com.google.gcloud.RetryHelper.RetryInterruptedException; +import com.google.cloud.BaseServiceException; +import com.google.cloud.RetryHelper.RetryHelperException; +import com.google.cloud.RetryHelper.RetryInterruptedException; import java.io.IOException; import java.util.Set; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageFactory.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageFactory.java similarity index 90% rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageFactory.java rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageFactory.java index fbce5559464c..0afaa05bcc7c 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageFactory.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageFactory.java @@ -14,10 +14,10 @@ * limitations under the License. */ -package com.google.gcloud.storage; +package com.google.cloud.storage; -import com.google.gcloud.ServiceFactory; +import com.google.cloud.ServiceFactory; /** * An interface for Storage factories. diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageImpl.java similarity index 95% rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageImpl.java index fa56c84e8b92..6d0be9ed01fc 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageImpl.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageImpl.java @@ -14,21 +14,21 @@ * limitations under the License. */ -package com.google.gcloud.storage; +package com.google.cloud.storage; import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkState; -import static com.google.gcloud.RetryHelper.runWithRetries; -import static com.google.gcloud.storage.spi.StorageRpc.Option.DELIMITER; -import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_GENERATION_MATCH; -import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_GENERATION_NOT_MATCH; -import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_METAGENERATION_MATCH; -import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_METAGENERATION_NOT_MATCH; -import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_SOURCE_GENERATION_MATCH; -import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_SOURCE_GENERATION_NOT_MATCH; -import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_MATCH; -import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_NOT_MATCH; +import static com.google.cloud.RetryHelper.runWithRetries; +import static com.google.cloud.storage.spi.StorageRpc.Option.DELIMITER; +import static com.google.cloud.storage.spi.StorageRpc.Option.IF_GENERATION_MATCH; +import static com.google.cloud.storage.spi.StorageRpc.Option.IF_GENERATION_NOT_MATCH; +import static com.google.cloud.storage.spi.StorageRpc.Option.IF_METAGENERATION_MATCH; +import static com.google.cloud.storage.spi.StorageRpc.Option.IF_METAGENERATION_NOT_MATCH; +import static com.google.cloud.storage.spi.StorageRpc.Option.IF_SOURCE_GENERATION_MATCH; +import static com.google.cloud.storage.spi.StorageRpc.Option.IF_SOURCE_GENERATION_NOT_MATCH; +import static com.google.cloud.storage.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_MATCH; +import static com.google.cloud.storage.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_NOT_MATCH; import static java.nio.charset.StandardCharsets.UTF_8; import com.google.api.services.storage.model.StorageObject; @@ -41,16 +41,16 @@ import com.google.common.hash.Hashing; import com.google.common.io.BaseEncoding; import com.google.common.primitives.Ints; -import com.google.gcloud.BaseService; -import com.google.gcloud.Page; -import com.google.gcloud.PageImpl; -import com.google.gcloud.PageImpl.NextPageFetcher; -import com.google.gcloud.ReadChannel; -import com.google.gcloud.RetryHelper.RetryHelperException; -import com.google.gcloud.ServiceAccountSigner; -import com.google.gcloud.storage.spi.StorageRpc; -import com.google.gcloud.storage.spi.StorageRpc.RewriteResponse; -import com.google.gcloud.storage.spi.StorageRpc.Tuple; +import com.google.cloud.BaseService; +import com.google.cloud.Page; +import com.google.cloud.PageImpl; +import com.google.cloud.PageImpl.NextPageFetcher; +import com.google.cloud.ReadChannel; +import com.google.cloud.RetryHelper.RetryHelperException; +import com.google.cloud.ServiceAccountSigner; +import com.google.cloud.storage.spi.StorageRpc; +import com.google.cloud.storage.spi.StorageRpc.RewriteResponse; +import com.google.cloud.storage.spi.StorageRpc.Tuple; import java.io.ByteArrayInputStream; import java.io.InputStream; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageOptions.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageOptions.java similarity index 92% rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageOptions.java rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageOptions.java index df8753efba95..15e5791a6b91 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/StorageOptions.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageOptions.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.google.gcloud.storage; +package com.google.cloud.storage; import com.google.common.collect.ImmutableSet; -import com.google.gcloud.ServiceOptions; -import com.google.gcloud.storage.spi.DefaultStorageRpc; -import com.google.gcloud.storage.spi.StorageRpc; -import com.google.gcloud.storage.spi.StorageRpcFactory; +import com.google.cloud.ServiceOptions; +import com.google.cloud.storage.spi.DefaultStorageRpc; +import com.google.cloud.storage.spi.StorageRpc; +import com.google.cloud.storage.spi.StorageRpcFactory; import java.util.Set; diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/package-info.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/package-info.java similarity index 89% rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/package-info.java rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/package-info.java index 181e63b08d0b..11ab4465f33c 100644 --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/package-info.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/package-info.java @@ -19,7 +19,7 @@ * *

    Here's a simple usage example for using gcloud-java from App/Compute Engine. This example * shows how to create a Storage blob. For the complete source code see - * + * * CreateBlob.java. *

     {@code
      * Storage storage = StorageOptions.defaultInstance().service();
    @@ -30,7 +30,7 @@
      * 

    * This second example shows how to update the blob's content if the blob exists. For the complete * source code see - * + * * UpdateBlob.java. *

     {@code
      * Storage storage = StorageOptions.defaultInstance().service();
    @@ -50,5 +50,5 @@
      * credentials.
      * @see Google Cloud Storage
      */
    -package com.google.gcloud.storage;
    +package com.google.cloud.storage;
     
    diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/DefaultStorageRpc.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/DefaultStorageRpc.java
    similarity index 94%
    rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/DefaultStorageRpc.java
    rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/DefaultStorageRpc.java
    index 8d06832534e2..37c81ff6ff0b 100644
    --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/DefaultStorageRpc.java
    +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/DefaultStorageRpc.java
    @@ -12,25 +12,25 @@
      * the License.
      */
     
    -package com.google.gcloud.storage.spi;
    +package com.google.cloud.storage.spi;
     
     import static com.google.common.base.MoreObjects.firstNonNull;
    -import static com.google.gcloud.storage.spi.StorageRpc.Option.DELIMITER;
    -import static com.google.gcloud.storage.spi.StorageRpc.Option.FIELDS;
    -import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_GENERATION_MATCH;
    -import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_GENERATION_NOT_MATCH;
    -import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_METAGENERATION_MATCH;
    -import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_METAGENERATION_NOT_MATCH;
    -import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_SOURCE_GENERATION_MATCH;
    -import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_SOURCE_GENERATION_NOT_MATCH;
    -import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_MATCH;
    -import static com.google.gcloud.storage.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_NOT_MATCH;
    -import static com.google.gcloud.storage.spi.StorageRpc.Option.MAX_RESULTS;
    -import static com.google.gcloud.storage.spi.StorageRpc.Option.PAGE_TOKEN;
    -import static com.google.gcloud.storage.spi.StorageRpc.Option.PREDEFINED_ACL;
    -import static com.google.gcloud.storage.spi.StorageRpc.Option.PREDEFINED_DEFAULT_OBJECT_ACL;
    -import static com.google.gcloud.storage.spi.StorageRpc.Option.PREFIX;
    -import static com.google.gcloud.storage.spi.StorageRpc.Option.VERSIONS;
    +import static com.google.cloud.storage.spi.StorageRpc.Option.DELIMITER;
    +import static com.google.cloud.storage.spi.StorageRpc.Option.FIELDS;
    +import static com.google.cloud.storage.spi.StorageRpc.Option.IF_GENERATION_MATCH;
    +import static com.google.cloud.storage.spi.StorageRpc.Option.IF_GENERATION_NOT_MATCH;
    +import static com.google.cloud.storage.spi.StorageRpc.Option.IF_METAGENERATION_MATCH;
    +import static com.google.cloud.storage.spi.StorageRpc.Option.IF_METAGENERATION_NOT_MATCH;
    +import static com.google.cloud.storage.spi.StorageRpc.Option.IF_SOURCE_GENERATION_MATCH;
    +import static com.google.cloud.storage.spi.StorageRpc.Option.IF_SOURCE_GENERATION_NOT_MATCH;
    +import static com.google.cloud.storage.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_MATCH;
    +import static com.google.cloud.storage.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_NOT_MATCH;
    +import static com.google.cloud.storage.spi.StorageRpc.Option.MAX_RESULTS;
    +import static com.google.cloud.storage.spi.StorageRpc.Option.PAGE_TOKEN;
    +import static com.google.cloud.storage.spi.StorageRpc.Option.PREDEFINED_ACL;
    +import static com.google.cloud.storage.spi.StorageRpc.Option.PREDEFINED_DEFAULT_OBJECT_ACL;
    +import static com.google.cloud.storage.spi.StorageRpc.Option.PREFIX;
    +import static com.google.cloud.storage.spi.StorageRpc.Option.VERSIONS;
     import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
     import static javax.servlet.http.HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE;
     
    @@ -63,8 +63,8 @@
     import com.google.common.collect.Iterables;
     import com.google.common.collect.Lists;
     import com.google.common.collect.Maps;
    -import com.google.gcloud.storage.StorageException;
    -import com.google.gcloud.storage.StorageOptions;
    +import com.google.cloud.storage.StorageException;
    +import com.google.cloud.storage.StorageOptions;
     
     import java.io.ByteArrayOutputStream;
     import java.io.IOException;
    diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/StorageRpc.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/StorageRpc.java
    similarity index 99%
    rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/StorageRpc.java
    rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/StorageRpc.java
    index 74f8171de87f..2f84f221e13d 100644
    --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/StorageRpc.java
    +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/StorageRpc.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.storage.spi;
    +package com.google.cloud.storage.spi;
     
     import static com.google.common.base.MoreObjects.firstNonNull;
     
    @@ -22,7 +22,7 @@
     import com.google.api.services.storage.model.StorageObject;
     import com.google.common.collect.ImmutableList;
     import com.google.common.collect.ImmutableMap;
    -import com.google.gcloud.storage.StorageException;
    +import com.google.cloud.storage.StorageException;
     
     import java.io.InputStream;
     import java.util.List;
    diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/StorageRpcFactory.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/StorageRpcFactory.java
    similarity index 85%
    rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/StorageRpcFactory.java
    rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/StorageRpcFactory.java
    index 19b98e6273db..f765d3fea98b 100644
    --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/spi/StorageRpcFactory.java
    +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/StorageRpcFactory.java
    @@ -14,10 +14,10 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.storage.spi;
    +package com.google.cloud.storage.spi;
     
    -import com.google.gcloud.spi.ServiceRpcFactory;
    -import com.google.gcloud.storage.StorageOptions;
    +import com.google.cloud.spi.ServiceRpcFactory;
    +import com.google.cloud.storage.StorageOptions;
     
     /**
      * An interface for Storage RPC factory.
    diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/RemoteStorageHelper.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/testing/RemoteStorageHelper.java
    similarity index 94%
    rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/RemoteStorageHelper.java
    rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/testing/RemoteStorageHelper.java
    index b1a836be255a..675c892fcc22 100644
    --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/RemoteStorageHelper.java
    +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/testing/RemoteStorageHelper.java
    @@ -14,15 +14,15 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.storage.testing;
    +package com.google.cloud.storage.testing;
     
    -import com.google.gcloud.AuthCredentials;
    -import com.google.gcloud.RetryParams;
    -import com.google.gcloud.storage.BlobInfo;
    -import com.google.gcloud.storage.Storage;
    -import com.google.gcloud.storage.Storage.BlobListOption;
    -import com.google.gcloud.storage.StorageException;
    -import com.google.gcloud.storage.StorageOptions;
    +import com.google.cloud.AuthCredentials;
    +import com.google.cloud.RetryParams;
    +import com.google.cloud.storage.BlobInfo;
    +import com.google.cloud.storage.Storage;
    +import com.google.cloud.storage.Storage.BlobListOption;
    +import com.google.cloud.storage.StorageException;
    +import com.google.cloud.storage.StorageOptions;
     
     import java.io.IOException;
     import java.io.InputStream;
    @@ -117,7 +117,7 @@ public static String generateBucketName() {
        * @param projectId id of the project to be used for running the tests
        * @param keyStream input stream for a JSON key
        * @return A {@code RemoteStorageHelper} object for the provided options
    -   * @throws com.google.gcloud.storage.testing.RemoteStorageHelper.StorageHelperException if
    +   * @throws com.google.cloud.storage.testing.RemoteStorageHelper.StorageHelperException if
        *     {@code keyStream} is not a valid JSON key stream
        */
       public static RemoteStorageHelper create(String projectId, InputStream keyStream)
    diff --git a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/package-info.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/testing/package-info.java
    similarity index 96%
    rename from gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/package-info.java
    rename to gcloud-java-storage/src/main/java/com/google/cloud/storage/testing/package-info.java
    index 3d30cbb9f37e..a8732b029900 100644
    --- a/gcloud-java-storage/src/main/java/com/google/gcloud/storage/testing/package-info.java
    +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/testing/package-info.java
    @@ -35,4 +35,4 @@
      * @see 
      *     gcloud-java tools for testing
      */
    -package com.google.gcloud.storage.testing;
    +package com.google.cloud.storage.testing;
    diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/AclTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/AclTest.java
    similarity index 84%
    rename from gcloud-java-storage/src/test/java/com/google/gcloud/storage/AclTest.java
    rename to gcloud-java-storage/src/test/java/com/google/cloud/storage/AclTest.java
    index 1c62805b2a1b..26c37f53ba48 100644
    --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/AclTest.java
    +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/AclTest.java
    @@ -14,21 +14,21 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.storage;
    +package com.google.cloud.storage;
     
     import static org.junit.Assert.assertEquals;
     
     import com.google.api.services.storage.model.BucketAccessControl;
     import com.google.api.services.storage.model.ObjectAccessControl;
    -import com.google.gcloud.storage.Acl.Domain;
    -import com.google.gcloud.storage.Acl.Entity;
    -import com.google.gcloud.storage.Acl.Entity.Type;
    -import com.google.gcloud.storage.Acl.Group;
    -import com.google.gcloud.storage.Acl.Project;
    -import com.google.gcloud.storage.Acl.Project.ProjectRole;
    -import com.google.gcloud.storage.Acl.RawEntity;
    -import com.google.gcloud.storage.Acl.Role;
    -import com.google.gcloud.storage.Acl.User;
    +import com.google.cloud.storage.Acl.Domain;
    +import com.google.cloud.storage.Acl.Entity;
    +import com.google.cloud.storage.Acl.Entity.Type;
    +import com.google.cloud.storage.Acl.Group;
    +import com.google.cloud.storage.Acl.Project;
    +import com.google.cloud.storage.Acl.Project.ProjectRole;
    +import com.google.cloud.storage.Acl.RawEntity;
    +import com.google.cloud.storage.Acl.Role;
    +import com.google.cloud.storage.Acl.User;
     
     import org.junit.Test;
     
    diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BatchRequestTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BatchRequestTest.java
    similarity index 95%
    rename from gcloud-java-storage/src/test/java/com/google/gcloud/storage/BatchRequestTest.java
    rename to gcloud-java-storage/src/test/java/com/google/cloud/storage/BatchRequestTest.java
    index 63972ff85dfd..fbea9283ed50 100644
    --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BatchRequestTest.java
    +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BatchRequestTest.java
    @@ -14,18 +14,18 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.storage;
    +package com.google.cloud.storage;
     
    -import static com.google.gcloud.storage.Storage.PredefinedAcl.PUBLIC_READ;
    +import static com.google.cloud.storage.Storage.PredefinedAcl.PUBLIC_READ;
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
     import static org.junit.Assert.assertNotEquals;
     import static org.junit.Assert.assertTrue;
     
     import com.google.common.collect.Iterables;
    -import com.google.gcloud.storage.Storage.BlobGetOption;
    -import com.google.gcloud.storage.Storage.BlobSourceOption;
    -import com.google.gcloud.storage.Storage.BlobTargetOption;
    +import com.google.cloud.storage.Storage.BlobGetOption;
    +import com.google.cloud.storage.Storage.BlobSourceOption;
    +import com.google.cloud.storage.Storage.BlobTargetOption;
     
     import org.junit.Test;
     
    diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BatchResponseTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BatchResponseTest.java
    similarity index 97%
    rename from gcloud-java-storage/src/test/java/com/google/gcloud/storage/BatchResponseTest.java
    rename to gcloud-java-storage/src/test/java/com/google/cloud/storage/BatchResponseTest.java
    index eb45b8b51271..6344d4649fab 100644
    --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BatchResponseTest.java
    +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BatchResponseTest.java
    @@ -14,13 +14,13 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.storage;
    +package com.google.cloud.storage;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertNotEquals;
     
     import com.google.common.collect.ImmutableList;
    -import com.google.gcloud.storage.BatchResponse.Result;
    +import com.google.cloud.storage.BatchResponse.Result;
     
     import org.easymock.EasyMock;
     import org.junit.Before;
    diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobIdTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobIdTest.java
    similarity index 97%
    rename from gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobIdTest.java
    rename to gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobIdTest.java
    index acc1885b9194..989d6ff82f40 100644
    --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobIdTest.java
    +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobIdTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.storage;
    +package com.google.cloud.storage;
     
     import static org.junit.Assert.assertEquals;
     
    diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobInfoTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobInfoTest.java
    similarity index 96%
    rename from gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobInfoTest.java
    rename to gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobInfoTest.java
    index db9dddaa864e..4e2f27265ef9 100644
    --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobInfoTest.java
    +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobInfoTest.java
    @@ -14,11 +14,11 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.storage;
    +package com.google.cloud.storage;
     
    -import static com.google.gcloud.storage.Acl.Project.ProjectRole.VIEWERS;
    -import static com.google.gcloud.storage.Acl.Role.READER;
    -import static com.google.gcloud.storage.Acl.Role.WRITER;
    +import static com.google.cloud.storage.Acl.Project.ProjectRole.VIEWERS;
    +import static com.google.cloud.storage.Acl.Role.READER;
    +import static com.google.cloud.storage.Acl.Role.WRITER;
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
     import static org.junit.Assert.assertNull;
    @@ -27,8 +27,8 @@
     import com.google.api.services.storage.model.StorageObject;
     import com.google.common.collect.ImmutableList;
     import com.google.common.collect.ImmutableMap;
    -import com.google.gcloud.storage.Acl.Project;
    -import com.google.gcloud.storage.Acl.User;
    +import com.google.cloud.storage.Acl.Project;
    +import com.google.cloud.storage.Acl.User;
     
     import org.junit.Test;
     
    diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobReadChannelTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobReadChannelTest.java
    similarity index 97%
    rename from gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobReadChannelTest.java
    rename to gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobReadChannelTest.java
    index 1b0f36a864a2..89f888ec4147 100644
    --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobReadChannelTest.java
    +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobReadChannelTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.storage;
    +package com.google.cloud.storage;
     
     import static org.easymock.EasyMock.anyObject;
     import static org.easymock.EasyMock.createMock;
    @@ -27,11 +27,11 @@
     import static org.junit.Assert.fail;
     
     import com.google.common.collect.ImmutableMap;
    -import com.google.gcloud.ReadChannel;
    -import com.google.gcloud.RestorableState;
    -import com.google.gcloud.RetryParams;
    -import com.google.gcloud.storage.spi.StorageRpc;
    -import com.google.gcloud.storage.spi.StorageRpcFactory;
    +import com.google.cloud.ReadChannel;
    +import com.google.cloud.RestorableState;
    +import com.google.cloud.RetryParams;
    +import com.google.cloud.storage.spi.StorageRpc;
    +import com.google.cloud.storage.spi.StorageRpcFactory;
     
     import org.junit.After;
     import org.junit.Before;
    diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobTest.java
    similarity index 97%
    rename from gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java
    rename to gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobTest.java
    index c8c5fb5d763c..5af12e8d411d 100644
    --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobTest.java
    +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobTest.java
    @@ -14,11 +14,11 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.storage;
    +package com.google.cloud.storage;
     
    -import static com.google.gcloud.storage.Acl.Project.ProjectRole.VIEWERS;
    -import static com.google.gcloud.storage.Acl.Role.READER;
    -import static com.google.gcloud.storage.Acl.Role.WRITER;
    +import static com.google.cloud.storage.Acl.Project.ProjectRole.VIEWERS;
    +import static com.google.cloud.storage.Acl.Role.READER;
    +import static com.google.cloud.storage.Acl.Role.WRITER;
     import static org.easymock.EasyMock.capture;
     import static org.easymock.EasyMock.createMock;
     import static org.easymock.EasyMock.createStrictMock;
    @@ -35,10 +35,10 @@
     
     import com.google.common.collect.ImmutableList;
     import com.google.common.collect.ImmutableMap;
    -import com.google.gcloud.ReadChannel;
    -import com.google.gcloud.storage.Acl.Project;
    -import com.google.gcloud.storage.Acl.User;
    -import com.google.gcloud.storage.Storage.CopyRequest;
    +import com.google.cloud.ReadChannel;
    +import com.google.cloud.storage.Acl.Project;
    +import com.google.cloud.storage.Acl.User;
    +import com.google.cloud.storage.Storage.CopyRequest;
     
     import org.easymock.Capture;
     import org.junit.After;
    diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobWriteChannelTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobWriteChannelTest.java
    similarity index 97%
    rename from gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobWriteChannelTest.java
    rename to gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobWriteChannelTest.java
    index 18ec64a9575f..549211930e3e 100644
    --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BlobWriteChannelTest.java
    +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobWriteChannelTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.storage;
    +package com.google.cloud.storage;
     
     import static org.easymock.EasyMock.anyObject;
     import static org.easymock.EasyMock.capture;
    @@ -31,11 +31,11 @@
     import static org.junit.Assert.fail;
     
     import com.google.common.collect.ImmutableMap;
    -import com.google.gcloud.RestorableState;
    -import com.google.gcloud.RetryParams;
    -import com.google.gcloud.WriteChannel;
    -import com.google.gcloud.storage.spi.StorageRpc;
    -import com.google.gcloud.storage.spi.StorageRpcFactory;
    +import com.google.cloud.RestorableState;
    +import com.google.cloud.RetryParams;
    +import com.google.cloud.WriteChannel;
    +import com.google.cloud.storage.spi.StorageRpc;
    +import com.google.cloud.storage.spi.StorageRpcFactory;
     
     import org.easymock.Capture;
     import org.easymock.CaptureType;
    diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketInfoTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BucketInfoTest.java
    similarity index 90%
    rename from gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketInfoTest.java
    rename to gcloud-java-storage/src/test/java/com/google/cloud/storage/BucketInfoTest.java
    index 6f9fadfdf7cd..59dd2ea632bc 100644
    --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketInfoTest.java
    +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BucketInfoTest.java
    @@ -14,24 +14,24 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.storage;
    +package com.google.cloud.storage;
     
    -import static com.google.gcloud.storage.Acl.Project.ProjectRole.VIEWERS;
    +import static com.google.cloud.storage.Acl.Project.ProjectRole.VIEWERS;
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertTrue;
     
     import com.google.api.services.storage.model.Bucket.Lifecycle.Rule;
     import com.google.common.collect.ImmutableList;
    -import com.google.gcloud.storage.Acl.Project;
    -import com.google.gcloud.storage.Acl.Role;
    -import com.google.gcloud.storage.Acl.User;
    -import com.google.gcloud.storage.BucketInfo.AgeDeleteRule;
    -import com.google.gcloud.storage.BucketInfo.CreatedBeforeDeleteRule;
    -import com.google.gcloud.storage.BucketInfo.DeleteRule;
    -import com.google.gcloud.storage.BucketInfo.DeleteRule.Type;
    -import com.google.gcloud.storage.BucketInfo.IsLiveDeleteRule;
    -import com.google.gcloud.storage.BucketInfo.NumNewerVersionsDeleteRule;
    -import com.google.gcloud.storage.BucketInfo.RawDeleteRule;
    +import com.google.cloud.storage.Acl.Project;
    +import com.google.cloud.storage.Acl.Role;
    +import com.google.cloud.storage.Acl.User;
    +import com.google.cloud.storage.BucketInfo.AgeDeleteRule;
    +import com.google.cloud.storage.BucketInfo.CreatedBeforeDeleteRule;
    +import com.google.cloud.storage.BucketInfo.DeleteRule;
    +import com.google.cloud.storage.BucketInfo.DeleteRule.Type;
    +import com.google.cloud.storage.BucketInfo.IsLiveDeleteRule;
    +import com.google.cloud.storage.BucketInfo.NumNewerVersionsDeleteRule;
    +import com.google.cloud.storage.BucketInfo.RawDeleteRule;
     
     import org.junit.Test;
     
    diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BucketTest.java
    similarity index 97%
    rename from gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java
    rename to gcloud-java-storage/src/test/java/com/google/cloud/storage/BucketTest.java
    index 30b7416531f3..b0f3f7ac9d0c 100644
    --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/BucketTest.java
    +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BucketTest.java
    @@ -14,11 +14,11 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.storage;
    +package com.google.cloud.storage;
     
    -import static com.google.gcloud.storage.Acl.Project.ProjectRole.VIEWERS;
    -import static com.google.gcloud.storage.Acl.Role.READER;
    -import static com.google.gcloud.storage.Acl.Role.WRITER;
    +import static com.google.cloud.storage.Acl.Project.ProjectRole.VIEWERS;
    +import static com.google.cloud.storage.Acl.Role.READER;
    +import static com.google.cloud.storage.Acl.Role.WRITER;
     import static org.easymock.EasyMock.capture;
     import static org.easymock.EasyMock.createMock;
     import static org.easymock.EasyMock.createStrictMock;
    @@ -31,13 +31,13 @@
     import static org.junit.Assert.assertTrue;
     
     import com.google.common.collect.ImmutableList;
    -import com.google.gcloud.Page;
    -import com.google.gcloud.PageImpl;
    -import com.google.gcloud.storage.Acl.Project;
    -import com.google.gcloud.storage.Acl.User;
    -import com.google.gcloud.storage.BatchResponse.Result;
    -import com.google.gcloud.storage.BucketInfo.AgeDeleteRule;
    -import com.google.gcloud.storage.BucketInfo.DeleteRule;
    +import com.google.cloud.Page;
    +import com.google.cloud.PageImpl;
    +import com.google.cloud.storage.Acl.Project;
    +import com.google.cloud.storage.Acl.User;
    +import com.google.cloud.storage.BatchResponse.Result;
    +import com.google.cloud.storage.BucketInfo.AgeDeleteRule;
    +import com.google.cloud.storage.BucketInfo.DeleteRule;
     
     import org.easymock.Capture;
     import org.junit.After;
    diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyRequestTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/CopyRequestTest.java
    similarity index 95%
    rename from gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyRequestTest.java
    rename to gcloud-java-storage/src/test/java/com/google/cloud/storage/CopyRequestTest.java
    index 9f8edfb84162..d3e93d9b8f66 100644
    --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyRequestTest.java
    +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/CopyRequestTest.java
    @@ -14,16 +14,16 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.storage;
    +package com.google.cloud.storage;
     
    -import static com.google.gcloud.storage.Storage.PredefinedAcl.PUBLIC_READ;
    +import static com.google.cloud.storage.Storage.PredefinedAcl.PUBLIC_READ;
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
     import static org.junit.Assert.assertTrue;
     
     import com.google.common.collect.ImmutableList;
    -import com.google.gcloud.storage.Storage.BlobSourceOption;
    -import com.google.gcloud.storage.Storage.BlobTargetOption;
    +import com.google.cloud.storage.Storage.BlobSourceOption;
    +import com.google.cloud.storage.Storage.BlobTargetOption;
     
     import org.junit.Rule;
     import org.junit.Test;
    diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyWriterTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/CopyWriterTest.java
    similarity index 96%
    rename from gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyWriterTest.java
    rename to gcloud-java-storage/src/test/java/com/google/cloud/storage/CopyWriterTest.java
    index 8ccb81688b65..13467283c013 100644
    --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CopyWriterTest.java
    +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/CopyWriterTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.storage;
    +package com.google.cloud.storage;
     
     import static org.easymock.EasyMock.anyObject;
     import static org.easymock.EasyMock.createMock;
    @@ -25,12 +25,12 @@
     import static org.junit.Assert.assertTrue;
     
     import com.google.common.collect.ImmutableMap;
    -import com.google.gcloud.RestorableState;
    -import com.google.gcloud.RetryParams;
    -import com.google.gcloud.storage.spi.StorageRpc;
    -import com.google.gcloud.storage.spi.StorageRpc.RewriteRequest;
    -import com.google.gcloud.storage.spi.StorageRpc.RewriteResponse;
    -import com.google.gcloud.storage.spi.StorageRpcFactory;
    +import com.google.cloud.RestorableState;
    +import com.google.cloud.RetryParams;
    +import com.google.cloud.storage.spi.StorageRpc;
    +import com.google.cloud.storage.spi.StorageRpc.RewriteRequest;
    +import com.google.cloud.storage.spi.StorageRpc.RewriteResponse;
    +import com.google.cloud.storage.spi.StorageRpcFactory;
     
     import org.easymock.EasyMock;
     import org.junit.After;
    diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CorsTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/CorsTest.java
    similarity index 95%
    rename from gcloud-java-storage/src/test/java/com/google/gcloud/storage/CorsTest.java
    rename to gcloud-java-storage/src/test/java/com/google/cloud/storage/CorsTest.java
    index f978cb87f3d1..e16ea98b30b0 100644
    --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/CorsTest.java
    +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/CorsTest.java
    @@ -14,12 +14,12 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.storage;
    +package com.google.cloud.storage;
     
     import static org.junit.Assert.assertEquals;
     
     import com.google.common.collect.ImmutableList;
    -import com.google.gcloud.storage.Cors.Origin;
    +import com.google.cloud.storage.Cors.Origin;
     
     import org.junit.Test;
     
    diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/OptionTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/OptionTest.java
    similarity index 96%
    rename from gcloud-java-storage/src/test/java/com/google/gcloud/storage/OptionTest.java
    rename to gcloud-java-storage/src/test/java/com/google/cloud/storage/OptionTest.java
    index 08a8e79b2c3b..6856745c0c4d 100644
    --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/OptionTest.java
    +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/OptionTest.java
    @@ -14,13 +14,13 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.storage;
    +package com.google.cloud.storage;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertNotEquals;
     import static org.junit.Assert.assertNull;
     
    -import com.google.gcloud.storage.spi.StorageRpc;
    +import com.google.cloud.storage.spi.StorageRpc;
     
     import org.junit.Rule;
     import org.junit.Test;
    diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/SerializationTest.java
    similarity index 93%
    rename from gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java
    rename to gcloud-java-storage/src/test/java/com/google/cloud/storage/SerializationTest.java
    index 613cb81c3549..581a517a1ee6 100644
    --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/SerializationTest.java
    +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/SerializationTest.java
    @@ -14,16 +14,16 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.storage;
    +package com.google.cloud.storage;
     
     import com.google.common.collect.ImmutableMap;
    -import com.google.gcloud.AuthCredentials;
    -import com.google.gcloud.BaseSerializationTest;
    -import com.google.gcloud.PageImpl;
    -import com.google.gcloud.ReadChannel;
    -import com.google.gcloud.Restorable;
    -import com.google.gcloud.storage.Acl.Project.ProjectRole;
    -import com.google.gcloud.storage.spi.StorageRpc;
    +import com.google.cloud.AuthCredentials;
    +import com.google.cloud.BaseSerializationTest;
    +import com.google.cloud.PageImpl;
    +import com.google.cloud.ReadChannel;
    +import com.google.cloud.Restorable;
    +import com.google.cloud.storage.Acl.Project.ProjectRole;
    +import com.google.cloud.storage.spi.StorageRpc;
     
     import java.io.Serializable;
     import java.util.Collections;
    diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageExceptionTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageExceptionTest.java
    similarity index 96%
    rename from gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageExceptionTest.java
    rename to gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageExceptionTest.java
    index cf1d4b394e57..a562ec1194c9 100644
    --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageExceptionTest.java
    +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageExceptionTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.storage;
    +package com.google.cloud.storage;
     
     import static org.easymock.EasyMock.createMock;
     import static org.easymock.EasyMock.expect;
    @@ -26,8 +26,8 @@
     import static org.junit.Assert.assertTrue;
     
     import com.google.api.client.googleapis.json.GoogleJsonError;
    -import com.google.gcloud.BaseServiceException;
    -import com.google.gcloud.RetryHelper.RetryHelperException;
    +import com.google.cloud.BaseServiceException;
    +import com.google.cloud.RetryHelper.RetryHelperException;
     
     import org.junit.Test;
     
    diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java
    similarity index 99%
    rename from gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java
    rename to gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java
    index 3cc99e3bf884..a122383080b8 100644
    --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/StorageImplTest.java
    +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.storage;
    +package com.google.cloud.storage;
     
     import static java.nio.charset.StandardCharsets.UTF_8;
     import static org.junit.Assert.assertArrayEquals;
    @@ -31,16 +31,16 @@
     import com.google.common.collect.Iterables;
     import com.google.common.collect.Maps;
     import com.google.common.io.BaseEncoding;
    -import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials;
    -import com.google.gcloud.Page;
    -import com.google.gcloud.ReadChannel;
    -import com.google.gcloud.RetryParams;
    -import com.google.gcloud.ServiceOptions;
    -import com.google.gcloud.WriteChannel;
    -import com.google.gcloud.storage.Storage.CopyRequest;
    -import com.google.gcloud.storage.spi.StorageRpc;
    -import com.google.gcloud.storage.spi.StorageRpc.Tuple;
    -import com.google.gcloud.storage.spi.StorageRpcFactory;
    +import com.google.cloud.AuthCredentials.ServiceAccountAuthCredentials;
    +import com.google.cloud.Page;
    +import com.google.cloud.ReadChannel;
    +import com.google.cloud.RetryParams;
    +import com.google.cloud.ServiceOptions;
    +import com.google.cloud.WriteChannel;
    +import com.google.cloud.storage.Storage.CopyRequest;
    +import com.google.cloud.storage.spi.StorageRpc;
    +import com.google.cloud.storage.spi.StorageRpc.Tuple;
    +import com.google.cloud.storage.spi.StorageRpcFactory;
     
     import org.easymock.Capture;
     import org.easymock.EasyMock;
    diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java
    similarity index 98%
    rename from gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java
    rename to gcloud-java-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java
    index b6d9b0e46607..a505597b7b21 100644
    --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/it/ITStorageTest.java
    +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.storage.it;
    +package com.google.cloud.storage.it;
     
     import static java.nio.charset.StandardCharsets.UTF_8;
     import static org.junit.Assert.assertArrayEquals;
    @@ -30,24 +30,24 @@
     import com.google.common.collect.ImmutableSet;
     import com.google.common.collect.Iterators;
     import com.google.common.collect.Lists;
    -import com.google.gcloud.Page;
    -import com.google.gcloud.ReadChannel;
    -import com.google.gcloud.RestorableState;
    -import com.google.gcloud.WriteChannel;
    -import com.google.gcloud.storage.BatchRequest;
    -import com.google.gcloud.storage.BatchResponse;
    -import com.google.gcloud.storage.Blob;
    -import com.google.gcloud.storage.BlobId;
    -import com.google.gcloud.storage.BlobInfo;
    -import com.google.gcloud.storage.Bucket;
    -import com.google.gcloud.storage.BucketInfo;
    -import com.google.gcloud.storage.CopyWriter;
    -import com.google.gcloud.storage.HttpMethod;
    -import com.google.gcloud.storage.Storage;
    -import com.google.gcloud.storage.Storage.BlobField;
    -import com.google.gcloud.storage.Storage.BucketField;
    -import com.google.gcloud.storage.StorageException;
    -import com.google.gcloud.storage.testing.RemoteStorageHelper;
    +import com.google.cloud.Page;
    +import com.google.cloud.ReadChannel;
    +import com.google.cloud.RestorableState;
    +import com.google.cloud.WriteChannel;
    +import com.google.cloud.storage.BatchRequest;
    +import com.google.cloud.storage.BatchResponse;
    +import com.google.cloud.storage.Blob;
    +import com.google.cloud.storage.BlobId;
    +import com.google.cloud.storage.BlobInfo;
    +import com.google.cloud.storage.Bucket;
    +import com.google.cloud.storage.BucketInfo;
    +import com.google.cloud.storage.CopyWriter;
    +import com.google.cloud.storage.HttpMethod;
    +import com.google.cloud.storage.Storage;
    +import com.google.cloud.storage.Storage.BlobField;
    +import com.google.cloud.storage.Storage.BucketField;
    +import com.google.cloud.storage.StorageException;
    +import com.google.cloud.storage.testing.RemoteStorageHelper;
     
     import org.junit.AfterClass;
     import org.junit.BeforeClass;
    diff --git a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/testing/RemoteStorageHelperTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/testing/RemoteStorageHelperTest.java
    similarity index 96%
    rename from gcloud-java-storage/src/test/java/com/google/gcloud/storage/testing/RemoteStorageHelperTest.java
    rename to gcloud-java-storage/src/test/java/com/google/cloud/storage/testing/RemoteStorageHelperTest.java
    index 7b8033fc69bb..b817ac2fc101 100644
    --- a/gcloud-java-storage/src/test/java/com/google/gcloud/storage/testing/RemoteStorageHelperTest.java
    +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/testing/RemoteStorageHelperTest.java
    @@ -14,20 +14,20 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.storage.testing;
    +package com.google.cloud.storage.testing;
     
     import static org.junit.Assert.assertEquals;
     import static org.junit.Assert.assertFalse;
     import static org.junit.Assert.assertTrue;
     
     import com.google.common.collect.ImmutableList;
    -import com.google.gcloud.Page;
    -import com.google.gcloud.storage.Blob;
    -import com.google.gcloud.storage.BlobId;
    -import com.google.gcloud.storage.Storage;
    -import com.google.gcloud.storage.Storage.BlobListOption;
    -import com.google.gcloud.storage.StorageException;
    -import com.google.gcloud.storage.StorageOptions;
    +import com.google.cloud.Page;
    +import com.google.cloud.storage.Blob;
    +import com.google.cloud.storage.BlobId;
    +import com.google.cloud.storage.Storage;
    +import com.google.cloud.storage.Storage.BlobListOption;
    +import com.google.cloud.storage.StorageException;
    +import com.google.cloud.storage.StorageOptions;
     
     import org.easymock.EasyMock;
     import org.junit.Before;
    diff --git a/gcloud-java/README.md b/gcloud-java/README.md
    index 36e82fb23a74..ae71ee70a091 100644
    --- a/gcloud-java/README.md
    +++ b/gcloud-java/README.md
    @@ -5,7 +5,7 @@ Java idiomatic client for [Google Cloud Platform][cloud-platform] services.
     
     [![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java)
     [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master)
    -[![Maven](https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java.svg)]( https://img.shields.io/maven-central/v/com.google.gcloud/gcloud-java.svg)
    +[![Maven](https://img.shields.io/maven-central/v/com.google.cloud/gcloud-java.svg)]( https://img.shields.io/maven-central/v/com.google.cloud/gcloud-java.svg)
     [![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java)
     [![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969)
     
    @@ -25,18 +25,18 @@ Quickstart
     If you are using Maven, add this to your pom.xml file
     ```xml
     
    -  com.google.gcloud
    +  com.google.cloud
       gcloud-java
       0.1.7
     
     ```
     If you are using Gradle, add this to your dependencies
     ```Groovy
    -compile 'com.google.gcloud:gcloud-java:0.1.7'
    +compile 'com.google.cloud:gcloud-java:0.1.7'
     ```
     If you are using SBT, add this to your dependencies
     ```Scala
    -libraryDependencies += "com.google.gcloud" % "gcloud-java" % "0.1.7"
    +libraryDependencies += "com.google.cloud" % "gcloud-java" % "0.1.7"
     ```
     
     Troubleshooting
    @@ -80,7 +80,7 @@ Apache 2.0 - See [LICENSE] for more information.
     [cloud-datastore]: https://cloud.google.com/datastore/docs
     [cloud-datastore-docs]: https://cloud.google.com/datastore/docs
     [cloud-datastore-activation]: https://cloud.google.com/datastore/docs/activate
    -[datastore-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/datastore/package-summary.html
    +[datastore-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/datastore/package-summary.html
     
     [cloud-pubsub]: https://cloud.google.com/pubsub/
     [cloud-pubsub-docs]: https://cloud.google.com/pubsub/docs
    @@ -88,4 +88,4 @@ Apache 2.0 - See [LICENSE] for more information.
     [cloud-storage]: https://cloud.google.com/storage/
     [cloud-storage-docs]: https://cloud.google.com/storage/docs/overview
     [cloud-storage-create-bucket]: https://cloud.google.com/storage/docs/cloud-console#_creatingbuckets
    -[storage-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/storage/package-summary.html
    +[storage-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/storage/package-summary.html
    diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml
    index 9b765db419d7..51c8278aba35 100644
    --- a/gcloud-java/pom.xml
    +++ b/gcloud-java/pom.xml
    @@ -8,7 +8,7 @@
         Java idiomatic client for Google Cloud Platform services.
       
       
    -    com.google.gcloud
    +    com.google.cloud
         gcloud-java-pom
         0.1.8-SNAPSHOT
       
    diff --git a/pom.xml b/pom.xml
    index 4f13ff6306d5..8f08cd41536c 100644
    --- a/pom.xml
    +++ b/pom.xml
    @@ -1,7 +1,7 @@
     
     
       4.0.0
    -  com.google.gcloud
    +  com.google.cloud
       gcloud-java-pom
       pom
       0.1.8-SNAPSHOT
    @@ -283,10 +283,10 @@
                 
                   true
                   
    -                com/google/gcloud/**/*.class
    +                com/google/cloud/**/*.class
                   
                   
    -                com/google/gcloud/examples/**/*.class
    +                com/google/cloud/examples/**/*.class
                   
                 
               256m
    @@ -374,19 +374,19 @@
                     
                       
                         API packages
    -                    com.google.gcloud*
    +                    com.google.cloud*
                       
                       
                         Test helpers packages
    -                    com.google.gcloud.bigquery.testing:com.google.gcloud.datastore.testing:com.google.gcloud.dns.testing:com.google.gcloud.resourcemanager.testing:com.google.gcloud.storage.testing
    +                    com.google.cloud.bigquery.testing:com.google.cloud.datastore.testing:com.google.cloud.dns.testing:com.google.cloud.resourcemanager.testing:com.google.cloud.storage.testing
                       
                       
                         Example packages
    -                    com.google.gcloud.examples*
    +                    com.google.cloud.examples*
                       
                       
                         SPI packages
    -                    com.google.gcloud.spi:com.google.gcloud.bigquery.spi:com.google.gcloud.datastore.spi:com.google.gcloud.dns.spi:com.google.gcloud.resourcemanager.spi:com.google.gcloud.storage.spi
    +                    com.google.cloud.spi:com.google.cloud.bigquery.spi:com.google.cloud.datastore.spi:com.google.cloud.dns.spi:com.google.cloud.resourcemanager.spi:com.google.cloud.storage.spi
                       
                     
                   
    diff --git a/src/site/apt/gcloud-java-core/index.apt b/src/site/apt/gcloud-java-core/index.apt
    index 1dbbe002bd1b..e08878b7e65a 100644
    --- a/src/site/apt/gcloud-java-core/index.apt
    +++ b/src/site/apt/gcloud-java-core/index.apt
    @@ -8,5 +8,5 @@ GCloud Java Core: Common functionality for GCloud Java services.
       
        	* {{{https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-core}GitHub repository}}
        	
    -   	* {{{./apidocs/index.html?com/google/gcloud/package-summary.html}Javadocs}}
    +   	* {{{./apidocs/index.html?com/google/cloud/package-summary.html}Javadocs}}
     
    diff --git a/src/site/apt/gcloud-java-datastore/index.apt b/src/site/apt/gcloud-java-datastore/index.apt
    index 193fd958fda1..fca475d6797e 100644
    --- a/src/site/apt/gcloud-java-datastore/index.apt
    +++ b/src/site/apt/gcloud-java-datastore/index.apt
    @@ -12,5 +12,5 @@ GCloud Java Datastore: Idiomatic Java Client for Google Cloud Datastore.
       
        	* {{{https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-datastore}GitHub repository}}
        	
    -   	* {{{./apidocs/index.html?com/google/gcloud/datastore/package-summary.html}Javadocs}}
    +   	* {{{./apidocs/index.html?com/google/cloud/datastore/package-summary.html}Javadocs}}
     
    diff --git a/src/site/apt/gcloud-java-examples/index.apt b/src/site/apt/gcloud-java-examples/index.apt
    index 349b06016d39..c02b42e26bae 100644
    --- a/src/site/apt/gcloud-java-examples/index.apt
    +++ b/src/site/apt/gcloud-java-examples/index.apt
    @@ -7,5 +7,5 @@ GCloud Java Examples: Examples using GCloud Java services
       
        	* {{{https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-examples}GitHub repository}}
        	
    -   	* {{{./apidocs/index.html?com/google/gcloud/examples/package-summary.html}Javadocs}}
    +   	* {{{./apidocs/index.html?com/google/cloud/examples/package-summary.html}Javadocs}}
     
    diff --git a/src/site/apt/gcloud-java-storage/index.apt b/src/site/apt/gcloud-java-storage/index.apt
    index 5af2eb07133e..f00125de2769 100644
    --- a/src/site/apt/gcloud-java-storage/index.apt
    +++ b/src/site/apt/gcloud-java-storage/index.apt
    @@ -12,5 +12,5 @@ GCloud Java Storage: Idiomatic Java Client for Google Cloud Storage.
       
        	* {{{https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-storage}GitHub repository}}
        	
    -   	* {{{./apidocs/index.html?com/google/gcloud/storage/package-summary.html}Javadocs}}
    +   	* {{{./apidocs/index.html?com/google/cloud/storage/package-summary.html}Javadocs}}
     
    diff --git a/src/site/resources/index.html b/src/site/resources/index.html
    index 834d3987a343..bc280acfe1dc 100644
    --- a/src/site/resources/index.html
    +++ b/src/site/resources/index.html
    @@ -60,7 +60,7 @@ 

    gcloud

    Quickstart with Maven: Add gcloud to your pom.xml

    <dependency>
    -  <groupId>com.google.gcloud</groupId>
    +  <groupId>com.google.cloud</groupId>
       <artifactId>gcloud-java</artifactId>
       <version>{{SITE_VERSION}}</version>
     </dependency>
    @@ -135,11 +135,11 @@

    Example: Retrieve Datastore Entries

    -import com.google.gcloud.datastore.Datastore;
    -import com.google.gcloud.datastore.DatastoreOptions;
    -import com.google.gcloud.datastore.Entity;
    -import com.google.gcloud.datastore.Key;
    -import com.google.gcloud.datastore.KeyFactory;
    +import com.google.cloud.datastore.Datastore;
    +import com.google.cloud.datastore.DatastoreOptions;
    +import com.google.cloud.datastore.Entity;
    +import com.google.cloud.datastore.Key;
    +import com.google.cloud.datastore.KeyFactory;
     
     // Authentication is automatic inside Google Compute Engine
     // and Google App Engine.
    @@ -152,12 +152,12 @@ 

    Example: Retrieve Datastore Entries

    -import com.google.gcloud.AuthCredentials;
    -import com.google.gcloud.datastore.Datastore;
    -import com.google.gcloud.datastore.DatastoreOptions;
    -import com.google.gcloud.datastore.Entity;
    -import com.google.gcloud.datastore.Key;
    -import com.google.gcloud.datastore.KeyFactory;
    +import com.google.cloud.AuthCredentials;
    +import com.google.cloud.datastore.Datastore;
    +import com.google.cloud.datastore.DatastoreOptions;
    +import com.google.cloud.datastore.Entity;
    +import com.google.cloud.datastore.Key;
    +import com.google.cloud.datastore.KeyFactory;
     
     DatastoreOptions options = DatastoreOptions.builder()
       .projectId(PROJECT_ID)
    diff --git a/utilities/after_success.sh b/utilities/after_success.sh
    index 352b7dd4dfda..7aeecd2f6bbd 100755
    --- a/utilities/after_success.sh
    +++ b/utilities/after_success.sh
    @@ -19,7 +19,7 @@ if [ "${TRAVIS_JDK_VERSION}" == "oraclejdk7" ]; then
             fi
             if [ "${SITE_VERSION##*-}" != "SNAPSHOT" ]; then
                 # Deploy Maven artifacts (if they don't exist yet) and update artifact version in READMEs.
    -            URL=https://oss.sonatype.org/content/repositories/releases/com/google/gcloud/gcloud-java/$SITE_VERSION/
    +            URL=https://oss.sonatype.org/content/repositories/releases/com/google/cloud/gcloud-java/$SITE_VERSION/
                 if curl --output /dev/null --silent --head --fail "$URL"; then
                     echo "Not deploying artifacts because it seems like they already exist."
                     echo "Existence was checked using the url $URL"
    
    From d947afb542cb8b43fbcbd4f2293d6b62560c7316 Mon Sep 17 00:00:00 2001
    From: Ajay Kannan 
    Date: Tue, 12 Apr 2016 11:28:30 -0700
    Subject: [PATCH 249/375] Release 0.2.0 with repackaging note (#904)
    
    ---
     README.md                           | 3 +++
     gcloud-java-bigquery/pom.xml        | 2 +-
     gcloud-java-contrib/pom.xml         | 2 +-
     gcloud-java-core/pom.xml            | 2 +-
     gcloud-java-datastore/pom.xml       | 2 +-
     gcloud-java-dns/pom.xml             | 2 +-
     gcloud-java-examples/pom.xml        | 2 +-
     gcloud-java-resourcemanager/pom.xml | 2 +-
     gcloud-java-storage/pom.xml         | 2 +-
     gcloud-java/pom.xml                 | 2 +-
     pom.xml                             | 2 +-
     src/site/resources/index.html       | 1 +
     12 files changed, 14 insertions(+), 10 deletions(-)
    
    diff --git a/README.md b/README.md
    index 296a9eabd0b9..ba15d97d6ffa 100644
    --- a/README.md
    +++ b/README.md
    @@ -25,6 +25,9 @@ This client supports the following Google Cloud Platform services:
     
     Quickstart
     ----------
    +
    +> As of April 12th, 2016, `gcloud-java`'s group ID and base package were renamed to `com.google.cloud`. If you haven't already, please update your dependencies.
    +
     If you are using Maven, add this to your pom.xml file
     ```xml
     
    diff --git a/gcloud-java-bigquery/pom.xml b/gcloud-java-bigquery/pom.xml
    index 7d4c02794e45..85278be98ba8 100644
    --- a/gcloud-java-bigquery/pom.xml
    +++ b/gcloud-java-bigquery/pom.xml
    @@ -10,7 +10,7 @@
       
         com.google.cloud
         gcloud-java-pom
    -    0.1.8-SNAPSHOT
    +    0.2.0
       
       
         gcloud-java-bigquery
    diff --git a/gcloud-java-contrib/pom.xml b/gcloud-java-contrib/pom.xml
    index bf9d58e18c9e..79afa4ad523c 100644
    --- a/gcloud-java-contrib/pom.xml
    +++ b/gcloud-java-contrib/pom.xml
    @@ -10,7 +10,7 @@
       
         com.google.cloud
         gcloud-java-pom
    -    0.1.8-SNAPSHOT
    +    0.2.0
       
       
         gcloud-java-contrib
    diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml
    index 2a164ae3288c..2d8eb4e4405c 100644
    --- a/gcloud-java-core/pom.xml
    +++ b/gcloud-java-core/pom.xml
    @@ -10,7 +10,7 @@
       
         com.google.cloud
         gcloud-java-pom
    -    0.1.8-SNAPSHOT
    +    0.2.0
       
       
         gcloud-java-core
    diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml
    index 43d901aac100..2ee811c39267 100644
    --- a/gcloud-java-datastore/pom.xml
    +++ b/gcloud-java-datastore/pom.xml
    @@ -10,7 +10,7 @@
       
         com.google.cloud
         gcloud-java-pom
    -    0.1.8-SNAPSHOT
    +    0.2.0
       
       
         gcloud-java-datastore
    diff --git a/gcloud-java-dns/pom.xml b/gcloud-java-dns/pom.xml
    index 8e5d7020f365..74e5207efdeb 100644
    --- a/gcloud-java-dns/pom.xml
    +++ b/gcloud-java-dns/pom.xml
    @@ -12,7 +12,7 @@
       
         com.google.cloud
         gcloud-java-pom
    -    0.1.8-SNAPSHOT
    +    0.2.0
       
       
         gcloud-java-dns
    diff --git a/gcloud-java-examples/pom.xml b/gcloud-java-examples/pom.xml
    index 784323ea44af..668305ab6081 100644
    --- a/gcloud-java-examples/pom.xml
    +++ b/gcloud-java-examples/pom.xml
    @@ -10,7 +10,7 @@
       
         com.google.cloud
         gcloud-java-pom
    -    0.1.8-SNAPSHOT
    +    0.2.0
       
       
         gcloud-java-examples
    diff --git a/gcloud-java-resourcemanager/pom.xml b/gcloud-java-resourcemanager/pom.xml
    index 007847d4004d..dd0622dc80c7 100644
    --- a/gcloud-java-resourcemanager/pom.xml
    +++ b/gcloud-java-resourcemanager/pom.xml
    @@ -10,7 +10,7 @@
       
         com.google.cloud
         gcloud-java-pom
    -    0.1.8-SNAPSHOT
    +    0.2.0
       
       
         gcloud-java-resourcemanager
    diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml
    index 9adab9982493..ed9f45668014 100644
    --- a/gcloud-java-storage/pom.xml
    +++ b/gcloud-java-storage/pom.xml
    @@ -10,7 +10,7 @@
       
         com.google.cloud
         gcloud-java-pom
    -    0.1.8-SNAPSHOT
    +    0.2.0
       
       
         gcloud-java-storage
    diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml
    index 51c8278aba35..875fa90c5b0b 100644
    --- a/gcloud-java/pom.xml
    +++ b/gcloud-java/pom.xml
    @@ -10,7 +10,7 @@
       
         com.google.cloud
         gcloud-java-pom
    -    0.1.8-SNAPSHOT
    +    0.2.0
       
       
         
    diff --git a/pom.xml b/pom.xml
    index 8f08cd41536c..d2fd35f2c970 100644
    --- a/pom.xml
    +++ b/pom.xml
    @@ -4,7 +4,7 @@
       com.google.cloud
       gcloud-java-pom
       pom
    -  0.1.8-SNAPSHOT
    +  0.2.0
       GCloud Java
       https://github.com/GoogleCloudPlatform/gcloud-java
       
    diff --git a/src/site/resources/index.html b/src/site/resources/index.html
    index bc280acfe1dc..cba3e64a0962 100644
    --- a/src/site/resources/index.html
    +++ b/src/site/resources/index.html
    @@ -64,6 +64,7 @@ 

    Quickstart with Maven: Add gcloud to your pom.xml

    <artifactId>gcloud-java</artifactId> <version>{{SITE_VERSION}}</version> </dependency>
    +

    As of April 12th, 2016, gcloud-java's group ID and base package were renamed to "com.google.cloud". If you haven't already, please update your dependencies.

    From f652533d2c3aa1465409692d443e13faf1044dc9 Mon Sep 17 00:00:00 2001 From: travis-ci Date: Tue, 12 Apr 2016 18:42:18 +0000 Subject: [PATCH 250/375] Updating version in README files. [ci skip] --- README.md | 6 +++--- gcloud-java-bigquery/README.md | 6 +++--- gcloud-java-contrib/README.md | 6 +++--- gcloud-java-core/README.md | 6 +++--- gcloud-java-datastore/README.md | 6 +++--- gcloud-java-dns/README.md | 6 +++--- gcloud-java-examples/README.md | 6 +++--- gcloud-java-resourcemanager/README.md | 6 +++--- gcloud-java-storage/README.md | 6 +++--- gcloud-java/README.md | 6 +++--- 10 files changed, 30 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index ba15d97d6ffa..6bc56bad250a 100644 --- a/README.md +++ b/README.md @@ -33,16 +33,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java - 0.1.7 + 0.2.0 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java:0.1.7' +compile 'com.google.cloud:gcloud-java:0.2.0' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java" % "0.1.7" +libraryDependencies += "com.google.cloud" % "gcloud-java" % "0.2.0" ``` Example Applications diff --git a/gcloud-java-bigquery/README.md b/gcloud-java-bigquery/README.md index 69efc011ee64..92fda2bad050 100644 --- a/gcloud-java-bigquery/README.md +++ b/gcloud-java-bigquery/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-bigquery - 0.1.7 + 0.2.0 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-bigquery:0.1.7' +compile 'com.google.cloud:gcloud-java-bigquery:0.2.0' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-bigquery" % "0.1.7" +libraryDependencies += "com.google.cloud" % "gcloud-java-bigquery" % "0.2.0" ``` Example Application diff --git a/gcloud-java-contrib/README.md b/gcloud-java-contrib/README.md index c83b1f47e7a6..547040449034 100644 --- a/gcloud-java-contrib/README.md +++ b/gcloud-java-contrib/README.md @@ -16,16 +16,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-contrib - 0.1.7 + 0.2.0 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-contrib:0.1.7' +compile 'com.google.cloud:gcloud-java-contrib:0.2.0' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-contrib" % "0.1.7" +libraryDependencies += "com.google.cloud" % "gcloud-java-contrib" % "0.2.0" ``` Java Versions diff --git a/gcloud-java-core/README.md b/gcloud-java-core/README.md index ca34b9789d8a..9a659c0f8cc0 100644 --- a/gcloud-java-core/README.md +++ b/gcloud-java-core/README.md @@ -19,16 +19,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-core - 0.1.7 + 0.2.0 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-core:0.1.7' +compile 'com.google.cloud:gcloud-java-core:0.2.0' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-core" % "0.1.7" +libraryDependencies += "com.google.cloud" % "gcloud-java-core" % "0.2.0" ``` Troubleshooting diff --git a/gcloud-java-datastore/README.md b/gcloud-java-datastore/README.md index e74349d11e3f..86b77c6bf49a 100644 --- a/gcloud-java-datastore/README.md +++ b/gcloud-java-datastore/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-datastore - 0.1.7 + 0.2.0 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-datastore:0.1.7' +compile 'com.google.cloud:gcloud-java-datastore:0.2.0' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-datastore" % "0.1.7" +libraryDependencies += "com.google.cloud" % "gcloud-java-datastore" % "0.2.0" ``` Example Application diff --git a/gcloud-java-dns/README.md b/gcloud-java-dns/README.md index 6e095a992890..994ab5615598 100644 --- a/gcloud-java-dns/README.md +++ b/gcloud-java-dns/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-dns - 0.1.7 + 0.2.0 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-dns:0.1.7' +compile 'com.google.cloud:gcloud-java-dns:0.2.0' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-dns" % "0.1.7" +libraryDependencies += "com.google.cloud" % "gcloud-java-dns" % "0.2.0" ``` Example Application diff --git a/gcloud-java-examples/README.md b/gcloud-java-examples/README.md index 89cbb3f8d8f7..2aab551da6f6 100644 --- a/gcloud-java-examples/README.md +++ b/gcloud-java-examples/README.md @@ -19,16 +19,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-examples - 0.1.7 + 0.2.0 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-examples:0.1.7' +compile 'com.google.cloud:gcloud-java-examples:0.2.0' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-examples" % "0.1.7" +libraryDependencies += "com.google.cloud" % "gcloud-java-examples" % "0.2.0" ``` To run examples from your command line: diff --git a/gcloud-java-resourcemanager/README.md b/gcloud-java-resourcemanager/README.md index a59146d0f828..906ef82710d7 100644 --- a/gcloud-java-resourcemanager/README.md +++ b/gcloud-java-resourcemanager/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-resourcemanager - 0.1.7 + 0.2.0 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-resourcemanager:0.1.7' +compile 'com.google.cloud:gcloud-java-resourcemanager:0.2.0' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-resourcemanager" % "0.1.7" +libraryDependencies += "com.google.cloud" % "gcloud-java-resourcemanager" % "0.2.0" ``` Example Application diff --git a/gcloud-java-storage/README.md b/gcloud-java-storage/README.md index 8dd56a60c44a..bcf7c7068774 100644 --- a/gcloud-java-storage/README.md +++ b/gcloud-java-storage/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-storage - 0.1.7 + 0.2.0 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-storage:0.1.7' +compile 'com.google.cloud:gcloud-java-storage:0.2.0' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-storage" % "0.1.7" +libraryDependencies += "com.google.cloud" % "gcloud-java-storage" % "0.2.0" ``` Example Application diff --git a/gcloud-java/README.md b/gcloud-java/README.md index ae71ee70a091..a01f794be966 100644 --- a/gcloud-java/README.md +++ b/gcloud-java/README.md @@ -27,16 +27,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java - 0.1.7 + 0.2.0 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java:0.1.7' +compile 'com.google.cloud:gcloud-java:0.2.0' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java" % "0.1.7" +libraryDependencies += "com.google.cloud" % "gcloud-java" % "0.2.0" ``` Troubleshooting From 74d6fd94cda62ff48724ad7abcb16087a2889206 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 12 Apr 2016 12:14:00 -0700 Subject: [PATCH 251/375] update version to 0.2.1-SNAPSHOT (#905) --- gcloud-java-bigquery/pom.xml | 2 +- gcloud-java-contrib/pom.xml | 2 +- gcloud-java-core/pom.xml | 2 +- gcloud-java-datastore/pom.xml | 2 +- gcloud-java-dns/pom.xml | 2 +- gcloud-java-examples/pom.xml | 2 +- gcloud-java-resourcemanager/pom.xml | 2 +- gcloud-java-storage/pom.xml | 2 +- gcloud-java/pom.xml | 2 +- pom.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/gcloud-java-bigquery/pom.xml b/gcloud-java-bigquery/pom.xml index 85278be98ba8..9617f762b03d 100644 --- a/gcloud-java-bigquery/pom.xml +++ b/gcloud-java-bigquery/pom.xml @@ -10,7 +10,7 @@ com.google.cloud gcloud-java-pom - 0.2.0 + 0.2.1-SNAPSHOT gcloud-java-bigquery diff --git a/gcloud-java-contrib/pom.xml b/gcloud-java-contrib/pom.xml index 79afa4ad523c..b9b0ee631d43 100644 --- a/gcloud-java-contrib/pom.xml +++ b/gcloud-java-contrib/pom.xml @@ -10,7 +10,7 @@ com.google.cloud gcloud-java-pom - 0.2.0 + 0.2.1-SNAPSHOT gcloud-java-contrib diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml index 2d8eb4e4405c..4e2ecb69a050 100644 --- a/gcloud-java-core/pom.xml +++ b/gcloud-java-core/pom.xml @@ -10,7 +10,7 @@ com.google.cloud gcloud-java-pom - 0.2.0 + 0.2.1-SNAPSHOT gcloud-java-core diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index 2ee811c39267..1cdd009ecee9 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -10,7 +10,7 @@ com.google.cloud gcloud-java-pom - 0.2.0 + 0.2.1-SNAPSHOT gcloud-java-datastore diff --git a/gcloud-java-dns/pom.xml b/gcloud-java-dns/pom.xml index 74e5207efdeb..f94f7514fbf1 100644 --- a/gcloud-java-dns/pom.xml +++ b/gcloud-java-dns/pom.xml @@ -12,7 +12,7 @@ com.google.cloud gcloud-java-pom - 0.2.0 + 0.2.1-SNAPSHOT gcloud-java-dns diff --git a/gcloud-java-examples/pom.xml b/gcloud-java-examples/pom.xml index 668305ab6081..54350ef1ac84 100644 --- a/gcloud-java-examples/pom.xml +++ b/gcloud-java-examples/pom.xml @@ -10,7 +10,7 @@ com.google.cloud gcloud-java-pom - 0.2.0 + 0.2.1-SNAPSHOT gcloud-java-examples diff --git a/gcloud-java-resourcemanager/pom.xml b/gcloud-java-resourcemanager/pom.xml index dd0622dc80c7..727cb970536b 100644 --- a/gcloud-java-resourcemanager/pom.xml +++ b/gcloud-java-resourcemanager/pom.xml @@ -10,7 +10,7 @@ com.google.cloud gcloud-java-pom - 0.2.0 + 0.2.1-SNAPSHOT gcloud-java-resourcemanager diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml index ed9f45668014..3ccd79d9e061 100644 --- a/gcloud-java-storage/pom.xml +++ b/gcloud-java-storage/pom.xml @@ -10,7 +10,7 @@ com.google.cloud gcloud-java-pom - 0.2.0 + 0.2.1-SNAPSHOT gcloud-java-storage diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml index 875fa90c5b0b..fc7489ea72cb 100644 --- a/gcloud-java/pom.xml +++ b/gcloud-java/pom.xml @@ -10,7 +10,7 @@ com.google.cloud gcloud-java-pom - 0.2.0 + 0.2.1-SNAPSHOT diff --git a/pom.xml b/pom.xml index d2fd35f2c970..421ee0a49540 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud gcloud-java-pom pom - 0.2.0 + 0.2.1-SNAPSHOT GCloud Java https://github.com/GoogleCloudPlatform/gcloud-java From 22e5665610176c3d9c435a164b902251c181049f Mon Sep 17 00:00:00 2001 From: garrettjonesgoogle Date: Tue, 12 Apr 2016 13:46:27 -0700 Subject: [PATCH 252/375] Rename com.google.gcloud to com.google.cloud (#907) --- .../google/{gcloud => cloud}/pubsub/spi/v1/PublisherApi.java | 4 ++-- .../com/google/cloud}/pubsub/spi/v1/PublisherSettings.java | 4 ++-- .../google/{gcloud => cloud}/pubsub/spi/v1/SubscriberApi.java | 4 ++-- .../com/google/cloud}/pubsub/spi/v1/SubscriberSettings.java | 4 ++-- .../google/{gcloud => cloud}/pubsub/spi/v1/PublisherApi.java | 4 ++-- .../com/google/cloud}/pubsub/spi/v1/PublisherSettings.java | 4 ++-- .../google/{gcloud => cloud}/pubsub/spi/v1/SubscriberApi.java | 4 ++-- .../com/google/cloud}/pubsub/spi/v1/SubscriberSettings.java | 4 ++-- .../{gcloud => cloud}/pubsub/testing/LocalPubsubHelper.java | 2 +- .../{gcloud => cloud}/pubsub/spi/v1/PublisherApiTest.java | 4 ++-- 10 files changed, 19 insertions(+), 19 deletions(-) rename gcloud-java-pubsub/baseline/src/main/java/com/google/{gcloud => cloud}/pubsub/spi/v1/PublisherApi.java (99%) rename gcloud-java-pubsub/{src/main/java/com/google/gcloud => baseline/src/main/java/com/google/cloud}/pubsub/spi/v1/PublisherSettings.java (99%) rename gcloud-java-pubsub/baseline/src/main/java/com/google/{gcloud => cloud}/pubsub/spi/v1/SubscriberApi.java (99%) rename gcloud-java-pubsub/{src/main/java/com/google/gcloud => baseline/src/main/java/com/google/cloud}/pubsub/spi/v1/SubscriberSettings.java (99%) rename gcloud-java-pubsub/src/main/java/com/google/{gcloud => cloud}/pubsub/spi/v1/PublisherApi.java (99%) rename gcloud-java-pubsub/{baseline/src/main/java/com/google/gcloud => src/main/java/com/google/cloud}/pubsub/spi/v1/PublisherSettings.java (99%) rename gcloud-java-pubsub/src/main/java/com/google/{gcloud => cloud}/pubsub/spi/v1/SubscriberApi.java (99%) rename gcloud-java-pubsub/{baseline/src/main/java/com/google/gcloud => src/main/java/com/google/cloud}/pubsub/spi/v1/SubscriberSettings.java (99%) rename gcloud-java-pubsub/src/main/java/com/google/{gcloud => cloud}/pubsub/testing/LocalPubsubHelper.java (98%) rename gcloud-java-pubsub/src/test/java/com/google/{gcloud => cloud}/pubsub/spi/v1/PublisherApiTest.java (98%) diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java similarity index 99% rename from gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java rename to gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java index 1d8c00c4e910..886945e0504e 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Google Inc. All Rights Reserved. + * Copyright 2016 Google Inc. All Rights Reserved. * * 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 @@ -31,7 +31,7 @@ * Happy editing! */ -package com.google.gcloud.pubsub.spi.v1; +package com.google.cloud.pubsub.spi.v1; import com.google.api.gax.grpc.ApiCallable; import com.google.api.gax.protobuf.PathTemplate; diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherSettings.java similarity index 99% rename from gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java rename to gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherSettings.java index 11c709024144..72d24404d87a 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherSettings.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Google Inc. All Rights Reserved. + * Copyright 2016 Google Inc. All Rights Reserved. * * 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 @@ -31,7 +31,7 @@ * Happy editing! */ -package com.google.gcloud.pubsub.spi.v1; +package com.google.cloud.pubsub.spi.v1; import com.google.api.gax.core.ConnectionSettings; import com.google.api.gax.core.RetrySettings; diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java similarity index 99% rename from gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java rename to gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java index 17c1dfdf0c37..2bfafd62ef0e 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Google Inc. All Rights Reserved. + * Copyright 2016 Google Inc. All Rights Reserved. * * 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 @@ -31,7 +31,7 @@ * Happy editing! */ -package com.google.gcloud.pubsub.spi.v1; +package com.google.cloud.pubsub.spi.v1; import com.google.api.gax.grpc.ApiCallable; import com.google.api.gax.protobuf.PathTemplate; diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberSettings.java similarity index 99% rename from gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java rename to gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberSettings.java index 918ec77e9f04..a46c956ae29d 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberSettings.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Google Inc. All Rights Reserved. + * Copyright 2016 Google Inc. All Rights Reserved. * * 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 @@ -31,7 +31,7 @@ * Happy editing! */ -package com.google.gcloud.pubsub.spi.v1; +package com.google.cloud.pubsub.spi.v1; import com.google.api.gax.core.ConnectionSettings; import com.google.api.gax.core.RetrySettings; diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java similarity index 99% rename from gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java rename to gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java index 1d8c00c4e910..886945e0504e 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherApi.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Google Inc. All Rights Reserved. + * Copyright 2016 Google Inc. All Rights Reserved. * * 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 @@ -31,7 +31,7 @@ * Happy editing! */ -package com.google.gcloud.pubsub.spi.v1; +package com.google.cloud.pubsub.spi.v1; import com.google.api.gax.grpc.ApiCallable; import com.google.api.gax.protobuf.PathTemplate; diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherSettings.java similarity index 99% rename from gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java rename to gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherSettings.java index 11c709024144..72d24404d87a 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/PublisherSettings.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherSettings.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Google Inc. All Rights Reserved. + * Copyright 2016 Google Inc. All Rights Reserved. * * 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 @@ -31,7 +31,7 @@ * Happy editing! */ -package com.google.gcloud.pubsub.spi.v1; +package com.google.cloud.pubsub.spi.v1; import com.google.api.gax.core.ConnectionSettings; import com.google.api.gax.core.RetrySettings; diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java similarity index 99% rename from gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java rename to gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java index 17c1dfdf0c37..2bfafd62ef0e 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberApi.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Google Inc. All Rights Reserved. + * Copyright 2016 Google Inc. All Rights Reserved. * * 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 @@ -31,7 +31,7 @@ * Happy editing! */ -package com.google.gcloud.pubsub.spi.v1; +package com.google.cloud.pubsub.spi.v1; import com.google.api.gax.grpc.ApiCallable; import com.google.api.gax.protobuf.PathTemplate; diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberSettings.java similarity index 99% rename from gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java rename to gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberSettings.java index 918ec77e9f04..a46c956ae29d 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/gcloud/pubsub/spi/v1/SubscriberSettings.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberSettings.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Google Inc. All Rights Reserved. + * Copyright 2016 Google Inc. All Rights Reserved. * * 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 @@ -31,7 +31,7 @@ * Happy editing! */ -package com.google.gcloud.pubsub.spi.v1; +package com.google.cloud.pubsub.spi.v1; import com.google.api.gax.core.ConnectionSettings; import com.google.api.gax.core.RetrySettings; diff --git a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/testing/LocalPubsubHelper.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/testing/LocalPubsubHelper.java similarity index 98% rename from gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/testing/LocalPubsubHelper.java rename to gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/testing/LocalPubsubHelper.java index 76de1a6d3cc7..9b1be716094b 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/gcloud/pubsub/testing/LocalPubsubHelper.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/testing/LocalPubsubHelper.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.pubsub.testing; +package com.google.cloud.pubsub.testing; import com.google.api.gax.testing.DownloadableEmulatorRunner; import com.google.api.gax.testing.GCloudEmulatorRunner; diff --git a/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/v1/PublisherApiTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/spi/v1/PublisherApiTest.java similarity index 98% rename from gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/v1/PublisherApiTest.java rename to gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/spi/v1/PublisherApiTest.java index 109c537c3f4a..0b508efec143 100644 --- a/gcloud-java-pubsub/src/test/java/com/google/gcloud/pubsub/spi/v1/PublisherApiTest.java +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/spi/v1/PublisherApiTest.java @@ -12,10 +12,10 @@ * the License. */ -package com.google.gcloud.pubsub.spi.v1; +package com.google.cloud.pubsub.spi.v1; import com.google.api.gax.grpc.BundlingSettings; -import com.google.gcloud.pubsub.testing.LocalPubsubHelper; +import com.google.cloud.pubsub.testing.LocalPubsubHelper; import com.google.protobuf.ByteString; import com.google.pubsub.v1.PubsubMessage; import com.google.pubsub.v1.PullResponse; From 37a16ae83d9ec2508226e30f38438ca5a38dc989 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 12 Apr 2016 23:50:02 +0200 Subject: [PATCH 253/375] Remove unused apt files and fix homepage URLs (#906) * Remove unused apt files * Fix URLs to homepage for each module --- gcloud-java-bigquery/pom.xml | 1 + gcloud-java-contrib/pom.xml | 1 + gcloud-java-core/pom.xml | 1 + gcloud-java-datastore/pom.xml | 1 + gcloud-java-dns/pom.xml | 1 + gcloud-java-examples/pom.xml | 1 + gcloud-java-resourcemanager/pom.xml | 1 + gcloud-java-storage/pom.xml | 1 + gcloud-java/pom.xml | 1 + src/site/apt/gcloud-java-core/index.apt | 12 ----------- src/site/apt/gcloud-java-datastore/index.apt | 16 --------------- src/site/apt/gcloud-java-examples/index.apt | 11 ---------- src/site/apt/gcloud-java-storage/index.apt | 16 --------------- src/site/apt/index.apt | 21 -------------------- 14 files changed, 9 insertions(+), 76 deletions(-) delete mode 100644 src/site/apt/gcloud-java-core/index.apt delete mode 100644 src/site/apt/gcloud-java-datastore/index.apt delete mode 100644 src/site/apt/gcloud-java-examples/index.apt delete mode 100644 src/site/apt/gcloud-java-storage/index.apt delete mode 100644 src/site/apt/index.apt diff --git a/gcloud-java-bigquery/pom.xml b/gcloud-java-bigquery/pom.xml index 9617f762b03d..4ad6a43b6be3 100644 --- a/gcloud-java-bigquery/pom.xml +++ b/gcloud-java-bigquery/pom.xml @@ -4,6 +4,7 @@ gcloud-java-bigquery jar GCloud Java bigquery + https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-bigquery Java idiomatic client for Google Cloud BigQuery. diff --git a/gcloud-java-contrib/pom.xml b/gcloud-java-contrib/pom.xml index b9b0ee631d43..1220c7c3776e 100644 --- a/gcloud-java-contrib/pom.xml +++ b/gcloud-java-contrib/pom.xml @@ -4,6 +4,7 @@ gcloud-java-contrib jar GCloud Java contributions + https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-contrib Contains packages that provide higher-level abstraction/functionality for common gcloud-java use cases. diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml index 4e2ecb69a050..22648d2e6ffa 100644 --- a/gcloud-java-core/pom.xml +++ b/gcloud-java-core/pom.xml @@ -4,6 +4,7 @@ gcloud-java-core jar GCloud Java core + https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-core Core module for the gcloud-java. diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index 1cdd009ecee9..2e76072b2881 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -4,6 +4,7 @@ gcloud-java-datastore jar GCloud Java datastore + https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-datastore Java idiomatic client for Google Cloud Datastore. diff --git a/gcloud-java-dns/pom.xml b/gcloud-java-dns/pom.xml index f94f7514fbf1..73e949dd5b1e 100644 --- a/gcloud-java-dns/pom.xml +++ b/gcloud-java-dns/pom.xml @@ -6,6 +6,7 @@ gcloud-java-dns jar GCloud Java DNS + https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-dns Java idiomatic client for Google Cloud DNS. diff --git a/gcloud-java-examples/pom.xml b/gcloud-java-examples/pom.xml index 54350ef1ac84..15b4e456494b 100644 --- a/gcloud-java-examples/pom.xml +++ b/gcloud-java-examples/pom.xml @@ -4,6 +4,7 @@ gcloud-java-examples jar GCloud Java examples + https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-examples Examples for gcloud-java. diff --git a/gcloud-java-resourcemanager/pom.xml b/gcloud-java-resourcemanager/pom.xml index 727cb970536b..272c931326d6 100644 --- a/gcloud-java-resourcemanager/pom.xml +++ b/gcloud-java-resourcemanager/pom.xml @@ -4,6 +4,7 @@ gcloud-java-resourcemanager jar GCloud Java resource manager + https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-resourcemanager Java idiomatic client for Google Cloud Resource Manager. diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml index 3ccd79d9e061..1106c7479be7 100644 --- a/gcloud-java-storage/pom.xml +++ b/gcloud-java-storage/pom.xml @@ -4,6 +4,7 @@ gcloud-java-storage jar GCloud Java storage + https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-storage Java idiomatic client for Google Cloud Storage. diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml index fc7489ea72cb..7dbd14e591cc 100644 --- a/gcloud-java/pom.xml +++ b/gcloud-java/pom.xml @@ -4,6 +4,7 @@ gcloud-java jar GCloud Java + https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java Java idiomatic client for Google Cloud Platform services. diff --git a/src/site/apt/gcloud-java-core/index.apt b/src/site/apt/gcloud-java-core/index.apt deleted file mode 100644 index e08878b7e65a..000000000000 --- a/src/site/apt/gcloud-java-core/index.apt +++ /dev/null @@ -1,12 +0,0 @@ -GCloud Java Core: Common functionality for GCloud Java services. - - This module provides common functionality required by service-specific modules of this library. - This library is in a early stage of its development and may occasionally make backwards-incompatible changes, - but it is already usable. - -* Links - - * {{{https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-core}GitHub repository}} - - * {{{./apidocs/index.html?com/google/cloud/package-summary.html}Javadocs}} - diff --git a/src/site/apt/gcloud-java-datastore/index.apt b/src/site/apt/gcloud-java-datastore/index.apt deleted file mode 100644 index fca475d6797e..000000000000 --- a/src/site/apt/gcloud-java-datastore/index.apt +++ /dev/null @@ -1,16 +0,0 @@ -GCloud Java Datastore: Idiomatic Java Client for Google Cloud Datastore. - - This is a Java Client for accessing Google Cloud Datastore. - This library is in a early stage of its development and may occasionally make backwards-incompatible changes, - but it is already usable. - -* Features - - * {{{https://cloud.google.com/datastore/}Google Cloud Datastore}} - -* Links - - * {{{https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-datastore}GitHub repository}} - - * {{{./apidocs/index.html?com/google/cloud/datastore/package-summary.html}Javadocs}} - diff --git a/src/site/apt/gcloud-java-examples/index.apt b/src/site/apt/gcloud-java-examples/index.apt deleted file mode 100644 index c02b42e26bae..000000000000 --- a/src/site/apt/gcloud-java-examples/index.apt +++ /dev/null @@ -1,11 +0,0 @@ -GCloud Java Examples: Examples using GCloud Java services - - This library is in a early stage of its development and may occasionally make backwards-incompatible changes, - but it is already usable. - -* Links - - * {{{https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-examples}GitHub repository}} - - * {{{./apidocs/index.html?com/google/cloud/examples/package-summary.html}Javadocs}} - diff --git a/src/site/apt/gcloud-java-storage/index.apt b/src/site/apt/gcloud-java-storage/index.apt deleted file mode 100644 index f00125de2769..000000000000 --- a/src/site/apt/gcloud-java-storage/index.apt +++ /dev/null @@ -1,16 +0,0 @@ -GCloud Java Storage: Idiomatic Java Client for Google Cloud Storage. - - This is a Java Client for accessing Google Cloud Storage. - This library is in a early stage of its development and may occasionally make backwards-incompatible changes, - but it is already usable. - -* Features - - * {{{https://cloud.google.com/storage/}Google Cloud Storage}} - -* Links - - * {{{https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-storage}GitHub repository}} - - * {{{./apidocs/index.html?com/google/cloud/storage/package-summary.html}Javadocs}} - diff --git a/src/site/apt/index.apt b/src/site/apt/index.apt deleted file mode 100644 index 395bfe7a65e0..000000000000 --- a/src/site/apt/index.apt +++ /dev/null @@ -1,21 +0,0 @@ -GCloud Java: Idiomatic Java Client for Google Cloud Platform services. - - This is a Java Client for accessing Google Cloud Platorm services such as Datastore, Storage, PubSub and others. - This library is in a early stage of its development and may occasionally make backwards-incompatible changes, - but it is already usable. - -* Features - - * {{{https://cloud.google.com/datastore/}Google Cloud Datastore}} - -* Links - - * {{{https://github.com/GoogleCloudPlatform/gcloud-java}GitHub repository}} - - * {{{./apidocs/index.html}Javadocs}} - - * {{{https://travis-ci.org/GoogleCloudPlatform/gcloud-java} Continous Integration System (Travis-CI)}} - - * {{{https://github.com/GoogleCloudPlatform/gcloud-java/issues?page=1&state=open}Issues}} - - * {{{https://coveralls.io/r/GoogleCloudPlatform/gcloud-java/}Coverage}} From 8785cc5c7c23f1ef3c369b0c5423a9e1780f6caa Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 12 Apr 2016 16:31:54 -0700 Subject: [PATCH 254/375] reorder imports --- .../com/google/cloud/bigquery/BigQuery.java | 6 ++--- .../cloud/bigquery/BigQueryException.java | 2 +- .../google/cloud/bigquery/BigQueryImpl.java | 14 +++++------ .../cloud/bigquery/BigQueryOptions.java | 2 +- .../com/google/cloud/bigquery/Option.java | 2 +- .../cloud/bigquery/QueryJobConfiguration.java | 4 ++-- .../google/cloud/bigquery/QueryResult.java | 2 +- .../java/com/google/cloud/bigquery/Table.java | 2 +- .../bigquery/WriteChannelConfiguration.java | 4 ++-- .../bigquery/spi/DefaultBigQueryRpc.java | 5 ++-- .../cloud/bigquery/BigQueryImplTest.java | 10 ++++---- .../bigquery/CopyJobConfigurationTest.java | 2 +- .../google/cloud/bigquery/DatasetTest.java | 4 ++-- .../google/cloud/bigquery/JobInfoTest.java | 4 ++-- .../cloud/bigquery/JobStatisticsTest.java | 2 +- .../bigquery/LoadJobConfigurationTest.java | 2 +- .../bigquery/QueryJobConfigurationTest.java | 4 ++-- .../google/cloud/bigquery/QueryStageTest.java | 2 +- .../cloud/bigquery/SerializationTest.java | 4 ++-- .../com/google/cloud/bigquery/TableTest.java | 6 ++--- .../WriteChannelConfigurationTest.java | 2 +- .../cloud/bigquery/it/ITBigQueryTest.java | 4 ++-- .../com/google/cloud/BaseWriteChannel.java | 1 + .../java/com/google/cloud/ServiceOptions.java | 2 +- .../google/cloud/FieldSelectorHelperTest.java | 2 +- .../com/google/cloud/RetryHelperTest.java | 4 ++-- .../com/google/cloud/SerializationTest.java | 2 +- .../cloud/datastore/DatastoreException.java | 2 +- .../google/cloud/datastore/DatastoreImpl.java | 12 +++++----- .../cloud/datastore/DatastoreOptions.java | 4 ++-- .../com/google/cloud/datastore/GqlQuery.java | 2 +- .../com/google/cloud/datastore/NullValue.java | 1 - .../cloud/datastore/QueryResultsImpl.java | 2 +- .../cloud/datastore/StructuredQuery.java | 2 +- .../cloud/datastore/spi/DatastoreRpc.java | 2 +- .../datastore/spi/DefaultDatastoreRpc.java | 4 ++-- .../testing/LocalDatastoreHelper.java | 2 +- .../cloud/datastore/DatastoreHelperTest.java | 2 +- .../google/cloud/datastore/DatastoreTest.java | 14 +++++------ .../cloud/datastore/StructuredQueryTest.java | 2 +- .../main/java/com/google/cloud/dns/Dns.java | 2 +- .../com/google/cloud/dns/DnsException.java | 2 +- .../java/com/google/cloud/dns/DnsImpl.java | 12 +++++----- .../java/com/google/cloud/dns/DnsOptions.java | 2 +- .../java/com/google/cloud/dns/Option.java | 2 +- .../java/com/google/cloud/dns/spi/DnsRpc.java | 2 +- .../cloud/dns/testing/LocalDnsHelper.java | 2 +- .../com/google/cloud/dns/DnsImplTest.java | 6 ++--- .../google/cloud/dns/SerializationTest.java | 2 +- .../java/com/google/cloud/dns/ZoneTest.java | 2 +- .../com/google/cloud/dns/it/ITDnsTest.java | 2 +- .../cloud/dns/testing/LocalDnsHelperTest.java | 6 ++--- .../examples/bigquery/BigQueryExample.java | 2 +- .../google/cloud/examples/dns/DnsExample.java | 4 ++-- .../ResourceManagerExample.java | 2 +- .../google/cloud/resourcemanager/Option.java | 2 +- .../google/cloud/resourcemanager/Policy.java | 4 ++-- .../resourcemanager/ResourceManager.java | 2 +- .../ResourceManagerException.java | 2 +- .../resourcemanager/ResourceManagerImpl.java | 12 +++++----- .../ResourceManagerOptions.java | 2 +- .../spi/DefaultResourceManagerRpc.java | 6 ++--- .../testing/LocalResourceManagerHelper.java | 4 ++-- .../cloud/resourcemanager/ProjectTest.java | 4 ++-- .../ResourceManagerImplTest.java | 4 ++-- .../resourcemanager/SerializationTest.java | 2 +- .../LocalResourceManagerHelperTest.java | 4 ++-- .../google/cloud/storage/BatchRequest.java | 4 ++-- .../java/com/google/cloud/storage/Blob.java | 4 ++-- .../google/cloud/storage/BlobReadChannel.java | 2 +- .../java/com/google/cloud/storage/Bucket.java | 10 ++++---- .../com/google/cloud/storage/BucketInfo.java | 2 +- .../com/google/cloud/storage/CopyWriter.java | 2 +- .../java/com/google/cloud/storage/Option.java | 2 +- .../com/google/cloud/storage/Storage.java | 6 ++--- .../cloud/storage/StorageException.java | 2 +- .../com/google/cloud/storage/StorageImpl.java | 24 +++++++++---------- .../google/cloud/storage/StorageOptions.java | 2 +- .../cloud/storage/spi/DefaultStorageRpc.java | 6 ++--- .../google/cloud/storage/spi/StorageRpc.java | 2 +- .../cloud/storage/BatchRequestTest.java | 2 +- .../cloud/storage/BatchResponseTest.java | 2 +- .../google/cloud/storage/BlobInfoTest.java | 4 ++-- .../cloud/storage/BlobReadChannelTest.java | 2 +- .../com/google/cloud/storage/BlobTest.java | 4 ++-- .../cloud/storage/BlobWriteChannelTest.java | 2 +- .../google/cloud/storage/BucketInfoTest.java | 2 +- .../com/google/cloud/storage/BucketTest.java | 2 +- .../google/cloud/storage/CopyRequestTest.java | 2 +- .../google/cloud/storage/CopyWriterTest.java | 2 +- .../com/google/cloud/storage/CorsTest.java | 2 +- .../cloud/storage/SerializationTest.java | 2 +- .../google/cloud/storage/StorageImplTest.java | 12 +++++----- .../cloud/storage/it/ITStorageTest.java | 10 ++++---- .../testing/RemoteStorageHelperTest.java | 2 +- 95 files changed, 184 insertions(+), 185 deletions(-) diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQuery.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQuery.java index bbfd45fe999e..90ed343e0e34 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQuery.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQuery.java @@ -18,14 +18,14 @@ import static com.google.common.base.Preconditions.checkArgument; -import com.google.common.base.Function; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; import com.google.cloud.FieldSelector; import com.google.cloud.FieldSelector.Helper; import com.google.cloud.Page; import com.google.cloud.Service; import com.google.cloud.bigquery.spi.BigQueryRpc; +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; import java.util.List; diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryException.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryException.java index 42223c827bcd..7f314a01b088 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryException.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryException.java @@ -16,10 +16,10 @@ package com.google.cloud.bigquery; -import com.google.common.collect.ImmutableSet; import com.google.cloud.BaseServiceException; import com.google.cloud.RetryHelper.RetryHelperException; import com.google.cloud.RetryHelper.RetryInterruptedException; +import com.google.common.collect.ImmutableSet; import java.io.IOException; import java.util.Objects; diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryImpl.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryImpl.java index e269d0599964..62a72647beff 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryImpl.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryImpl.java @@ -16,19 +16,13 @@ package com.google.cloud.bigquery; -import static com.google.common.base.Preconditions.checkArgument; import static com.google.cloud.RetryHelper.runWithRetries; +import static com.google.common.base.Preconditions.checkArgument; import com.google.api.services.bigquery.model.GetQueryResultsResponse; import com.google.api.services.bigquery.model.TableDataInsertAllRequest; import com.google.api.services.bigquery.model.TableDataInsertAllRequest.Rows; import com.google.api.services.bigquery.model.TableRow; -import com.google.common.base.Function; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; import com.google.cloud.BaseService; import com.google.cloud.Page; import com.google.cloud.PageImpl; @@ -36,6 +30,12 @@ import com.google.cloud.RetryHelper; import com.google.cloud.bigquery.InsertAllRequest.RowToInsert; import com.google.cloud.bigquery.spi.BigQueryRpc; +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import java.util.List; import java.util.Map; diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryOptions.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryOptions.java index b0cc56fa0298..1845755bae67 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryOptions.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryOptions.java @@ -16,11 +16,11 @@ package com.google.cloud.bigquery; -import com.google.common.collect.ImmutableSet; import com.google.cloud.ServiceOptions; import com.google.cloud.bigquery.spi.BigQueryRpc; import com.google.cloud.bigquery.spi.BigQueryRpcFactory; import com.google.cloud.bigquery.spi.DefaultBigQueryRpc; +import com.google.common.collect.ImmutableSet; import java.util.Set; diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Option.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Option.java index d2edbbe7b4c5..75108d6dfec5 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Option.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Option.java @@ -18,8 +18,8 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.base.MoreObjects; import com.google.cloud.bigquery.spi.BigQueryRpc; +import com.google.common.base.MoreObjects; import java.io.Serializable; import java.util.Objects; diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryJobConfiguration.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryJobConfiguration.java index 1743b64d0576..4c5034a4a0c8 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryJobConfiguration.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryJobConfiguration.java @@ -19,13 +19,13 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.api.services.bigquery.model.JobConfigurationQuery; +import com.google.cloud.bigquery.JobInfo.CreateDisposition; +import com.google.cloud.bigquery.JobInfo.WriteDisposition; import com.google.common.base.MoreObjects.ToStringHelper; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import com.google.cloud.bigquery.JobInfo.CreateDisposition; -import com.google.cloud.bigquery.JobInfo.WriteDisposition; import java.util.List; import java.util.Map; diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryResult.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryResult.java index fb4b15e8d3f0..74a9e5000b0e 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryResult.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryResult.java @@ -16,9 +16,9 @@ package com.google.cloud.bigquery; +import com.google.cloud.PageImpl; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; -import com.google.cloud.PageImpl; import java.util.List; import java.util.Objects; diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Table.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Table.java index cd151063fca5..8fc83b305458 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Table.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Table.java @@ -18,8 +18,8 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.collect.ImmutableList; import com.google.cloud.Page; +import com.google.common.collect.ImmutableList; import java.io.IOException; import java.io.ObjectInputStream; diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/WriteChannelConfiguration.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/WriteChannelConfiguration.java index bd5c29f830c1..b7bb9db277a3 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/WriteChannelConfiguration.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/WriteChannelConfiguration.java @@ -19,10 +19,10 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.api.services.bigquery.model.JobConfigurationLoad; -import com.google.common.base.MoreObjects; -import com.google.common.collect.ImmutableList; import com.google.cloud.bigquery.JobInfo.CreateDisposition; import com.google.cloud.bigquery.JobInfo.WriteDisposition; +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableList; import java.io.Serializable; import java.util.List; diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/spi/DefaultBigQueryRpc.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/spi/DefaultBigQueryRpc.java index 59cc7730107f..2f02f55c68e7 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/spi/DefaultBigQueryRpc.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/spi/DefaultBigQueryRpc.java @@ -56,13 +56,12 @@ import com.google.api.services.bigquery.model.TableList; import com.google.api.services.bigquery.model.TableReference; import com.google.api.services.bigquery.model.TableRow; +import com.google.cloud.bigquery.BigQueryException; +import com.google.cloud.bigquery.BigQueryOptions; import com.google.common.base.Function; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; -import com.google.cloud.bigquery.BigQueryException; -import com.google.cloud.bigquery.BigQueryOptions; - import java.io.IOException; import java.math.BigInteger; import java.util.List; diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/BigQueryImplTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/BigQueryImplTest.java index 7cb7b162fd10..4a29697a73dc 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/BigQueryImplTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/BigQueryImplTest.java @@ -31,11 +31,6 @@ import com.google.api.services.bigquery.model.TableDataInsertAllRequest; import com.google.api.services.bigquery.model.TableDataInsertAllResponse; import com.google.api.services.bigquery.model.TableRow; -import com.google.common.base.Function; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; import com.google.cloud.Page; import com.google.cloud.RetryParams; import com.google.cloud.WriteChannel; @@ -43,6 +38,11 @@ import com.google.cloud.bigquery.spi.BigQueryRpc; import com.google.cloud.bigquery.spi.BigQueryRpc.Tuple; import com.google.cloud.bigquery.spi.BigQueryRpcFactory; +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; import org.easymock.Capture; import org.easymock.EasyMock; diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/CopyJobConfigurationTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/CopyJobConfigurationTest.java index 54d2370b1c57..7d676a9b1505 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/CopyJobConfigurationTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/CopyJobConfigurationTest.java @@ -20,9 +20,9 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import com.google.common.collect.ImmutableList; import com.google.cloud.bigquery.JobInfo.CreateDisposition; import com.google.cloud.bigquery.JobInfo.WriteDisposition; +import com.google.common.collect.ImmutableList; import org.junit.Test; diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/DatasetTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/DatasetTest.java index 747c8ae4f0dc..7693e9900131 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/DatasetTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/DatasetTest.java @@ -30,10 +30,10 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; import com.google.cloud.Page; import com.google.cloud.PageImpl; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; import org.junit.After; import org.junit.Test; diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobInfoTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobInfoTest.java index 16fe980fe171..e6cd2987fbd7 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobInfoTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobInfoTest.java @@ -21,13 +21,13 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.cloud.bigquery.JobInfo.CreateDisposition; import com.google.cloud.bigquery.JobInfo.WriteDisposition; import com.google.cloud.bigquery.JobStatistics.ExtractStatistics; import com.google.cloud.bigquery.JobStatistics.LoadStatistics; import com.google.cloud.bigquery.JobStatistics.QueryStatistics; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import org.junit.Test; diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobStatisticsTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobStatisticsTest.java index 0dc5fea0b1d7..9fbe43f3903f 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobStatisticsTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobStatisticsTest.java @@ -18,11 +18,11 @@ import static org.junit.Assert.assertEquals; -import com.google.common.collect.ImmutableList; import com.google.cloud.bigquery.JobStatistics.ExtractStatistics; import com.google.cloud.bigquery.JobStatistics.LoadStatistics; import com.google.cloud.bigquery.JobStatistics.QueryStatistics; import com.google.cloud.bigquery.QueryStage.QueryStep; +import com.google.common.collect.ImmutableList; import org.junit.Test; diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/LoadJobConfigurationTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/LoadJobConfigurationTest.java index d811f7d1b569..9980f85426d8 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/LoadJobConfigurationTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/LoadJobConfigurationTest.java @@ -18,9 +18,9 @@ import static org.junit.Assert.assertEquals; -import com.google.common.collect.ImmutableList; import com.google.cloud.bigquery.JobInfo.CreateDisposition; import com.google.cloud.bigquery.JobInfo.WriteDisposition; +import com.google.common.collect.ImmutableList; import org.junit.Test; diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/QueryJobConfigurationTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/QueryJobConfigurationTest.java index 6ad2facb3288..914a6db4d5eb 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/QueryJobConfigurationTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/QueryJobConfigurationTest.java @@ -21,11 +21,11 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.cloud.bigquery.JobInfo.CreateDisposition; import com.google.cloud.bigquery.JobInfo.WriteDisposition; import com.google.cloud.bigquery.QueryJobConfiguration.Priority; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import org.junit.Test; diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/QueryStageTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/QueryStageTest.java index 0270abe7efd1..670143190cf5 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/QueryStageTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/QueryStageTest.java @@ -19,8 +19,8 @@ import static org.junit.Assert.assertEquals; import com.google.api.services.bigquery.model.ExplainQueryStep; -import com.google.common.collect.ImmutableList; import com.google.cloud.bigquery.QueryStage.QueryStep; +import com.google.common.collect.ImmutableList; import org.junit.Test; diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/SerializationTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/SerializationTest.java index 9797a5a5139e..7aabcea120e9 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/SerializationTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/SerializationTest.java @@ -16,12 +16,12 @@ package com.google.cloud.bigquery; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.cloud.AuthCredentials; import com.google.cloud.BaseSerializationTest; import com.google.cloud.Restorable; import com.google.cloud.bigquery.StandardTableDefinition.StreamingBuffer; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import java.io.Serializable; import java.nio.charset.StandardCharsets; diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/TableTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/TableTest.java index 58f187c1cedd..c74fc8e244bc 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/TableTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/TableTest.java @@ -28,12 +28,12 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Iterators; import com.google.cloud.Page; import com.google.cloud.PageImpl; import com.google.cloud.bigquery.InsertAllRequest.RowToInsert; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterators; import org.junit.After; import org.junit.Test; diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/WriteChannelConfigurationTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/WriteChannelConfigurationTest.java index 03ffbcaf38e3..ffe1e58dc19e 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/WriteChannelConfigurationTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/WriteChannelConfigurationTest.java @@ -19,9 +19,9 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -import com.google.common.collect.ImmutableList; import com.google.cloud.bigquery.JobInfo.CreateDisposition; import com.google.cloud.bigquery.JobInfo.WriteDisposition; +import com.google.common.collect.ImmutableList; import org.junit.Test; diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java index 738245bc80f7..9e462a4d5142 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java @@ -23,8 +23,6 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.cloud.Page; import com.google.cloud.WriteChannel; import com.google.cloud.bigquery.BigQuery; @@ -68,6 +66,8 @@ import com.google.cloud.storage.BucketInfo; import com.google.cloud.storage.Storage; import com.google.cloud.storage.testing.RemoteStorageHelper; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import org.junit.AfterClass; import org.junit.BeforeClass; diff --git a/gcloud-java-core/src/main/java/com/google/cloud/BaseWriteChannel.java b/gcloud-java-core/src/main/java/com/google/cloud/BaseWriteChannel.java index f803cd6bbacf..038ef8c362de 100644 --- a/gcloud-java-core/src/main/java/com/google/cloud/BaseWriteChannel.java +++ b/gcloud-java-core/src/main/java/com/google/cloud/BaseWriteChannel.java @@ -16,6 +16,7 @@ package com.google.cloud; +import com.google.cloud.BaseWriteChannel.BaseState; import com.google.common.base.MoreObjects; import java.io.IOException; diff --git a/gcloud-java-core/src/main/java/com/google/cloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/cloud/ServiceOptions.java index e08d0cd9d155..194f61b45c42 100644 --- a/gcloud-java-core/src/main/java/com/google/cloud/ServiceOptions.java +++ b/gcloud-java-core/src/main/java/com/google/cloud/ServiceOptions.java @@ -26,9 +26,9 @@ import com.google.api.client.http.HttpTransport; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.auth.http.HttpCredentialsAdapter; +import com.google.cloud.spi.ServiceRpcFactory; import com.google.common.collect.Iterables; import com.google.common.io.Files; -import com.google.cloud.spi.ServiceRpcFactory; import org.json.JSONException; import org.json.JSONObject; diff --git a/gcloud-java-core/src/test/java/com/google/cloud/FieldSelectorHelperTest.java b/gcloud-java-core/src/test/java/com/google/cloud/FieldSelectorHelperTest.java index 6cdc4bdfb924..9aa892c7b0b0 100644 --- a/gcloud-java-core/src/test/java/com/google/cloud/FieldSelectorHelperTest.java +++ b/gcloud-java-core/src/test/java/com/google/cloud/FieldSelectorHelperTest.java @@ -19,8 +19,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import com.google.common.collect.ImmutableList; import com.google.cloud.FieldSelector.Helper; +import com.google.common.collect.ImmutableList; import org.junit.Test; diff --git a/gcloud-java-core/src/test/java/com/google/cloud/RetryHelperTest.java b/gcloud-java-core/src/test/java/com/google/cloud/RetryHelperTest.java index 7012813be2d0..3887cecd6a83 100644 --- a/gcloud-java-core/src/test/java/com/google/cloud/RetryHelperTest.java +++ b/gcloud-java-core/src/test/java/com/google/cloud/RetryHelperTest.java @@ -22,10 +22,10 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import com.google.common.base.Stopwatch; -import com.google.common.base.Ticker; import com.google.cloud.RetryHelper.NonRetriableException; import com.google.cloud.RetryHelper.RetriesExhaustedException; +import com.google.common.base.Stopwatch; +import com.google.common.base.Ticker; import org.junit.Test; diff --git a/gcloud-java-core/src/test/java/com/google/cloud/SerializationTest.java b/gcloud-java-core/src/test/java/com/google/cloud/SerializationTest.java index 72d622239f3c..75347b250227 100644 --- a/gcloud-java-core/src/test/java/com/google/cloud/SerializationTest.java +++ b/gcloud-java-core/src/test/java/com/google/cloud/SerializationTest.java @@ -16,8 +16,8 @@ package com.google.cloud; -import com.google.common.collect.ImmutableList; import com.google.cloud.ServiceAccountSigner.SigningException; +import com.google.common.collect.ImmutableList; import java.io.ByteArrayInputStream; import java.io.IOException; diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreException.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreException.java index c097980aec29..419cffc7bf3e 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreException.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreException.java @@ -16,10 +16,10 @@ package com.google.cloud.datastore; -import com.google.common.collect.ImmutableSet; import com.google.cloud.BaseServiceException; import com.google.cloud.RetryHelper.RetryHelperException; import com.google.cloud.RetryHelper.RetryInterruptedException; +import com.google.common.collect.ImmutableSet; import java.io.IOException; import java.util.Set; diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java index a05c4229f291..2aa0638bfa7c 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java @@ -16,6 +16,12 @@ package com.google.cloud.datastore; +import com.google.cloud.BaseService; +import com.google.cloud.RetryHelper; +import com.google.cloud.RetryHelper.RetryHelperException; +import com.google.cloud.RetryParams; +import com.google.cloud.datastore.ReadOption.EventualConsistency; +import com.google.cloud.datastore.spi.DatastoreRpc; import com.google.common.base.MoreObjects; import com.google.common.base.Preconditions; import com.google.common.collect.AbstractIterator; @@ -23,12 +29,6 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Sets; import com.google.datastore.v1beta3.ReadOptions.ReadConsistency; -import com.google.cloud.BaseService; -import com.google.cloud.RetryHelper; -import com.google.cloud.RetryHelper.RetryHelperException; -import com.google.cloud.RetryParams; -import com.google.cloud.datastore.ReadOption.EventualConsistency; -import com.google.cloud.datastore.spi.DatastoreRpc; import com.google.protobuf.ByteString; import java.util.ArrayList; diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java index a9466939060a..d456af51bde1 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java @@ -18,12 +18,12 @@ import static com.google.cloud.datastore.Validator.validateNamespace; -import com.google.common.base.MoreObjects; -import com.google.common.collect.ImmutableSet; import com.google.cloud.ServiceOptions; import com.google.cloud.datastore.spi.DatastoreRpc; import com.google.cloud.datastore.spi.DatastoreRpcFactory; import com.google.cloud.datastore.spi.DefaultDatastoreRpc; +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableSet; import java.lang.reflect.Method; import java.util.Objects; diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/GqlQuery.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/GqlQuery.java index 7a34bf4b1f19..2af3559f6899 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/GqlQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/GqlQuery.java @@ -16,8 +16,8 @@ package com.google.cloud.datastore; -import static com.google.common.base.Preconditions.checkNotNull; import static com.google.cloud.datastore.Validator.validateNamespace; +import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/NullValue.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/NullValue.java index 8b7ab9bfa49b..4721e572215f 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/NullValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/NullValue.java @@ -17,7 +17,6 @@ package com.google.cloud.datastore; import static com.google.common.base.Preconditions.checkArgument; - import static com.google.datastore.v1beta3.Value.NULL_VALUE_FIELD_NUMBER; public final class NullValue extends Value { diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/QueryResultsImpl.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/QueryResultsImpl.java index b46f9821cc52..f049ef9edde2 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/QueryResultsImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/QueryResultsImpl.java @@ -16,10 +16,10 @@ package com.google.cloud.datastore; +import com.google.cloud.datastore.Query.ResultType; import com.google.common.base.Preconditions; import com.google.common.collect.AbstractIterator; import com.google.datastore.v1beta3.QueryResultBatch.MoreResultsType; -import com.google.cloud.datastore.Query.ResultType; import com.google.protobuf.ByteString; import java.util.Iterator; diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/StructuredQuery.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/StructuredQuery.java index 9028ba6e536f..442df20c8027 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/StructuredQuery.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/StructuredQuery.java @@ -16,7 +16,6 @@ package com.google.cloud.datastore; -import static com.google.common.base.Preconditions.checkNotNull; import static com.google.cloud.datastore.BlobValue.of; import static com.google.cloud.datastore.BooleanValue.of; import static com.google.cloud.datastore.DateTimeValue.of; @@ -24,6 +23,7 @@ import static com.google.cloud.datastore.KeyValue.of; import static com.google.cloud.datastore.LongValue.of; import static com.google.cloud.datastore.StringValue.of; +import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects.ToStringHelper; diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/spi/DatastoreRpc.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/spi/DatastoreRpc.java index dc3e9ce27249..d7d8aae673ba 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/spi/DatastoreRpc.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/spi/DatastoreRpc.java @@ -16,6 +16,7 @@ package com.google.cloud.datastore.spi; +import com.google.cloud.datastore.DatastoreException; import com.google.datastore.v1beta3.AllocateIdsRequest; import com.google.datastore.v1beta3.AllocateIdsResponse; import com.google.datastore.v1beta3.BeginTransactionRequest; @@ -28,7 +29,6 @@ import com.google.datastore.v1beta3.RollbackResponse; import com.google.datastore.v1beta3.RunQueryRequest; import com.google.datastore.v1beta3.RunQueryResponse; -import com.google.cloud.datastore.DatastoreException; /** * Provides access to the remote Datastore service. diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/spi/DefaultDatastoreRpc.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/spi/DefaultDatastoreRpc.java index 04d8c4cc8dd4..255da4c6e229 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/spi/DefaultDatastoreRpc.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/spi/DefaultDatastoreRpc.java @@ -16,6 +16,8 @@ package com.google.cloud.datastore.spi; +import com.google.cloud.datastore.DatastoreException; +import com.google.cloud.datastore.DatastoreOptions; import com.google.datastore.v1beta3.AllocateIdsRequest; import com.google.datastore.v1beta3.AllocateIdsResponse; import com.google.datastore.v1beta3.BeginTransactionRequest; @@ -28,8 +30,6 @@ import com.google.datastore.v1beta3.RollbackResponse; import com.google.datastore.v1beta3.RunQueryRequest; import com.google.datastore.v1beta3.RunQueryResponse; -import com.google.cloud.datastore.DatastoreException; -import com.google.cloud.datastore.DatastoreOptions; import java.io.IOException; import java.net.InetAddress; diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/testing/LocalDatastoreHelper.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/testing/LocalDatastoreHelper.java index 9d04ddbf930e..4da7e0d27e75 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/testing/LocalDatastoreHelper.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/testing/LocalDatastoreHelper.java @@ -19,10 +19,10 @@ import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.common.base.Preconditions.checkArgument; -import com.google.common.base.Strings; import com.google.cloud.AuthCredentials; import com.google.cloud.RetryParams; import com.google.cloud.datastore.DatastoreOptions; +import com.google.common.base.Strings; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; diff --git a/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreHelperTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreHelperTest.java index 7f32de7b947b..2538a75847bd 100644 --- a/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreHelperTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreHelperTest.java @@ -27,9 +27,9 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.google.cloud.datastore.Datastore.TransactionCallable; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterators; -import com.google.cloud.datastore.Datastore.TransactionCallable; import org.easymock.EasyMock; import org.junit.Test; diff --git a/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java index cd028067ca83..d73d6964e064 100644 --- a/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java @@ -25,6 +25,13 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.google.cloud.RetryParams; +import com.google.cloud.datastore.Query.ResultType; +import com.google.cloud.datastore.StructuredQuery.OrderBy; +import com.google.cloud.datastore.StructuredQuery.PropertyFilter; +import com.google.cloud.datastore.spi.DatastoreRpc; +import com.google.cloud.datastore.spi.DatastoreRpcFactory; +import com.google.cloud.datastore.testing.LocalDatastoreHelper; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterators; import com.google.common.collect.Lists; @@ -37,13 +44,6 @@ import com.google.datastore.v1beta3.ReadOptions.ReadConsistency; import com.google.datastore.v1beta3.RunQueryRequest; import com.google.datastore.v1beta3.RunQueryResponse; -import com.google.cloud.RetryParams; -import com.google.cloud.datastore.Query.ResultType; -import com.google.cloud.datastore.StructuredQuery.OrderBy; -import com.google.cloud.datastore.StructuredQuery.PropertyFilter; -import com.google.cloud.datastore.spi.DatastoreRpc; -import com.google.cloud.datastore.spi.DatastoreRpcFactory; -import com.google.cloud.datastore.testing.LocalDatastoreHelper; import com.google.protobuf.ByteString; import org.easymock.EasyMock; diff --git a/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/StructuredQueryTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/StructuredQueryTest.java index 7f5bbdd74e82..cc2ec78e06a1 100644 --- a/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/StructuredQueryTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/StructuredQueryTest.java @@ -20,12 +20,12 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import com.google.common.collect.ImmutableList; import com.google.cloud.datastore.Query.ResultType; import com.google.cloud.datastore.StructuredQuery.CompositeFilter; import com.google.cloud.datastore.StructuredQuery.Filter; import com.google.cloud.datastore.StructuredQuery.OrderBy; import com.google.cloud.datastore.StructuredQuery.PropertyFilter; +import com.google.common.collect.ImmutableList; import org.junit.Test; diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/Dns.java index f7c1aef0a02c..2aa080fb63d3 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/Dns.java @@ -16,12 +16,12 @@ package com.google.cloud.dns; -import com.google.common.collect.ImmutableList; import com.google.cloud.FieldSelector; import com.google.cloud.FieldSelector.Helper; import com.google.cloud.Page; import com.google.cloud.Service; import com.google.cloud.dns.spi.DnsRpc; +import com.google.common.collect.ImmutableList; import java.util.List; diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsException.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsException.java index 8da76625cead..1e1e34b833a5 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsException.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsException.java @@ -16,10 +16,10 @@ package com.google.cloud.dns; -import com.google.common.collect.ImmutableSet; import com.google.cloud.BaseServiceException; import com.google.cloud.RetryHelper.RetryHelperException; import com.google.cloud.RetryHelper.RetryInterruptedException; +import com.google.common.collect.ImmutableSet; import java.io.IOException; import java.util.Set; diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsImpl.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsImpl.java index 785face46173..cdb311adc823 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsImpl.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsImpl.java @@ -16,23 +16,23 @@ package com.google.cloud.dns; -import static com.google.common.base.Preconditions.checkArgument; import static com.google.cloud.RetryHelper.runWithRetries; +import static com.google.common.base.Preconditions.checkArgument; import com.google.api.services.dns.model.Change; import com.google.api.services.dns.model.ManagedZone; import com.google.api.services.dns.model.Project; import com.google.api.services.dns.model.ResourceRecordSet; -import com.google.common.base.Function; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Iterables; -import com.google.common.collect.Maps; import com.google.cloud.BaseService; import com.google.cloud.Page; import com.google.cloud.PageImpl; import com.google.cloud.RetryHelper; import com.google.cloud.dns.spi.DnsRpc; +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; +import com.google.common.collect.Maps; import java.util.Map; import java.util.concurrent.Callable; diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsOptions.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsOptions.java index 059f7b212044..6d37a7af5694 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsOptions.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsOptions.java @@ -16,11 +16,11 @@ package com.google.cloud.dns; -import com.google.common.collect.ImmutableSet; import com.google.cloud.ServiceOptions; import com.google.cloud.dns.spi.DefaultDnsRpc; import com.google.cloud.dns.spi.DnsRpc; import com.google.cloud.dns.spi.DnsRpcFactory; +import com.google.common.collect.ImmutableSet; import java.util.Set; diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/Option.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/Option.java index b0e23220549c..7a1f9955be05 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/Option.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/Option.java @@ -18,8 +18,8 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.base.MoreObjects; import com.google.cloud.dns.spi.DnsRpc; +import com.google.common.base.MoreObjects; import java.io.Serializable; import java.util.Objects; diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DnsRpc.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DnsRpc.java index 57d6b45ba3a5..ba74f14f0527 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DnsRpc.java @@ -20,8 +20,8 @@ import com.google.api.services.dns.model.ManagedZone; import com.google.api.services.dns.model.Project; import com.google.api.services.dns.model.ResourceRecordSet; -import com.google.common.collect.ImmutableList; import com.google.cloud.dns.DnsException; +import com.google.common.collect.ImmutableList; import java.util.Map; diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/testing/LocalDnsHelper.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/testing/LocalDnsHelper.java index 46d116bdf640..1f35193409ee 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/testing/LocalDnsHelper.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/testing/LocalDnsHelper.java @@ -27,6 +27,7 @@ import com.google.api.services.dns.model.Project; import com.google.api.services.dns.model.Quota; import com.google.api.services.dns.model.ResourceRecordSet; +import com.google.cloud.dns.DnsOptions; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Joiner; import com.google.common.collect.ImmutableList; @@ -36,7 +37,6 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.google.common.io.ByteStreams; -import com.google.cloud.dns.DnsOptions; import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.HttpExchange; diff --git a/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsImplTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsImplTest.java index fe3b08f8625b..457f5ed3adb3 100644 --- a/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsImplTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsImplTest.java @@ -22,14 +22,14 @@ import com.google.api.services.dns.model.Change; import com.google.api.services.dns.model.ManagedZone; import com.google.api.services.dns.model.ResourceRecordSet; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; import com.google.cloud.Page; import com.google.cloud.RetryParams; import com.google.cloud.ServiceOptions; import com.google.cloud.dns.spi.DnsRpc; import com.google.cloud.dns.spi.DnsRpcFactory; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; import org.easymock.Capture; import org.easymock.EasyMock; diff --git a/gcloud-java-dns/src/test/java/com/google/cloud/dns/SerializationTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/SerializationTest.java index 32b1bbbd0667..e510850f62ab 100644 --- a/gcloud-java-dns/src/test/java/com/google/cloud/dns/SerializationTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/SerializationTest.java @@ -16,11 +16,11 @@ package com.google.cloud.dns; -import com.google.common.collect.ImmutableList; import com.google.cloud.AuthCredentials; import com.google.cloud.BaseSerializationTest; import com.google.cloud.Restorable; import com.google.cloud.RetryParams; +import com.google.common.collect.ImmutableList; import java.io.Serializable; import java.math.BigInteger; diff --git a/gcloud-java-dns/src/test/java/com/google/cloud/dns/ZoneTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/ZoneTest.java index fc23316a899b..e1f6c8917647 100644 --- a/gcloud-java-dns/src/test/java/com/google/cloud/dns/ZoneTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/ZoneTest.java @@ -30,8 +30,8 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import com.google.common.collect.ImmutableList; import com.google.cloud.Page; +import com.google.common.collect.ImmutableList; import org.junit.After; import org.junit.Before; diff --git a/gcloud-java-dns/src/test/java/com/google/cloud/dns/it/ITDnsTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/it/ITDnsTest.java index 2d6ce2e45457..dd8eafa775cd 100644 --- a/gcloud-java-dns/src/test/java/com/google/cloud/dns/it/ITDnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/it/ITDnsTest.java @@ -23,7 +23,6 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import com.google.common.collect.ImmutableList; import com.google.cloud.Page; import com.google.cloud.dns.ChangeRequest; import com.google.cloud.dns.ChangeRequestInfo; @@ -34,6 +33,7 @@ import com.google.cloud.dns.RecordSet; import com.google.cloud.dns.Zone; import com.google.cloud.dns.ZoneInfo; +import com.google.common.collect.ImmutableList; import org.junit.AfterClass; import org.junit.BeforeClass; diff --git a/gcloud-java-dns/src/test/java/com/google/cloud/dns/testing/LocalDnsHelperTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/testing/LocalDnsHelperTest.java index 2231d2f08974..fce958d3a126 100644 --- a/gcloud-java-dns/src/test/java/com/google/cloud/dns/testing/LocalDnsHelperTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/testing/LocalDnsHelperTest.java @@ -27,13 +27,13 @@ import com.google.api.services.dns.model.ManagedZone; import com.google.api.services.dns.model.Project; import com.google.api.services.dns.model.ResourceRecordSet; +import com.google.cloud.dns.DnsException; +import com.google.cloud.dns.spi.DefaultDnsRpc; +import com.google.cloud.dns.spi.DnsRpc; import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; -import com.google.cloud.dns.DnsException; -import com.google.cloud.dns.spi.DefaultDnsRpc; -import com.google.cloud.dns.spi.DnsRpc; import org.junit.AfterClass; import org.junit.Before; diff --git a/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java index b0a7680cf2b9..5b15bbd6ec71 100644 --- a/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java @@ -16,7 +16,6 @@ package com.google.cloud.examples.bigquery; -import com.google.common.collect.ImmutableMap; import com.google.cloud.WriteChannel; import com.google.cloud.bigquery.BigQuery; import com.google.cloud.bigquery.BigQueryError; @@ -44,6 +43,7 @@ import com.google.cloud.bigquery.ViewDefinition; import com.google.cloud.bigquery.WriteChannelConfiguration; import com.google.cloud.bigquery.spi.BigQueryRpc.Tuple; +import com.google.common.collect.ImmutableMap; import java.nio.channels.FileChannel; import java.nio.file.Paths; diff --git a/gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/DnsExample.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/DnsExample.java index 44ded7ae0dc0..88b4b984e4c5 100644 --- a/gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/DnsExample.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/DnsExample.java @@ -16,8 +16,6 @@ package com.google.cloud.examples.dns; -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableList; import com.google.cloud.dns.ChangeRequest; import com.google.cloud.dns.ChangeRequestInfo; import com.google.cloud.dns.Dns; @@ -26,6 +24,8 @@ import com.google.cloud.dns.RecordSet; import com.google.cloud.dns.Zone; import com.google.cloud.dns.ZoneInfo; +import com.google.common.base.Joiner; +import com.google.common.collect.ImmutableList; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; diff --git a/gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/ResourceManagerExample.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/ResourceManagerExample.java index 9b9e7aaa8ac8..1d688c414575 100644 --- a/gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/ResourceManagerExample.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/ResourceManagerExample.java @@ -16,11 +16,11 @@ package com.google.cloud.examples.resourcemanager; -import com.google.common.base.Joiner; import com.google.cloud.resourcemanager.Project; import com.google.cloud.resourcemanager.ProjectInfo; import com.google.cloud.resourcemanager.ResourceManager; import com.google.cloud.resourcemanager.ResourceManagerOptions; +import com.google.common.base.Joiner; import java.util.Arrays; import java.util.HashMap; diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Option.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Option.java index fb81d77a88ff..ae53ad7004b4 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Option.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Option.java @@ -18,8 +18,8 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.base.MoreObjects; import com.google.cloud.resourcemanager.spi.ResourceManagerRpc; +import com.google.common.base.MoreObjects; import java.io.Serializable; import java.util.Objects; diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Policy.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Policy.java index 6f150086a7e3..41238fd9b9aa 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Policy.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Policy.java @@ -16,12 +16,12 @@ package com.google.cloud.resourcemanager; +import com.google.cloud.IamPolicy; +import com.google.cloud.Identity; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; -import com.google.cloud.IamPolicy; -import com.google.cloud.Identity; import java.util.ArrayList; import java.util.HashMap; diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManager.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManager.java index 93425464872f..38925278a484 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManager.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManager.java @@ -16,13 +16,13 @@ package com.google.cloud.resourcemanager; -import com.google.common.collect.ImmutableList; import com.google.cloud.FieldSelector; import com.google.cloud.FieldSelector.Helper; import com.google.cloud.IamPolicy; import com.google.cloud.Page; import com.google.cloud.Service; import com.google.cloud.resourcemanager.spi.ResourceManagerRpc; +import com.google.common.collect.ImmutableList; import java.util.List; diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerException.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerException.java index 026845d0734c..1df014e450ee 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerException.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerException.java @@ -16,10 +16,10 @@ package com.google.cloud.resourcemanager; -import com.google.common.collect.ImmutableSet; import com.google.cloud.BaseServiceException; import com.google.cloud.RetryHelper.RetryHelperException; import com.google.cloud.RetryHelper.RetryInterruptedException; +import com.google.common.collect.ImmutableSet; import java.io.IOException; import java.util.Set; diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerImpl.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerImpl.java index 2ee4dc4e9e22..4054a4b2443a 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerImpl.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerImpl.java @@ -16,14 +16,9 @@ package com.google.cloud.resourcemanager; -import static com.google.common.base.Preconditions.checkArgument; import static com.google.cloud.RetryHelper.runWithRetries; +import static com.google.common.base.Preconditions.checkArgument; -import com.google.common.base.Function; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Iterables; -import com.google.common.collect.Maps; import com.google.cloud.BaseService; import com.google.cloud.Page; import com.google.cloud.PageImpl; @@ -31,6 +26,11 @@ import com.google.cloud.RetryHelper.RetryHelperException; import com.google.cloud.resourcemanager.spi.ResourceManagerRpc; import com.google.cloud.resourcemanager.spi.ResourceManagerRpc.Tuple; +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; +import com.google.common.collect.Maps; import java.util.List; import java.util.Map; diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerOptions.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerOptions.java index 8f5c79e8bc3f..d37dfd298aa0 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerOptions.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerOptions.java @@ -16,11 +16,11 @@ package com.google.cloud.resourcemanager; -import com.google.common.collect.ImmutableSet; import com.google.cloud.ServiceOptions; import com.google.cloud.resourcemanager.spi.DefaultResourceManagerRpc; import com.google.cloud.resourcemanager.spi.ResourceManagerRpc; import com.google.cloud.resourcemanager.spi.ResourceManagerRpcFactory; +import com.google.common.collect.ImmutableSet; import java.util.Set; diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/spi/DefaultResourceManagerRpc.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/spi/DefaultResourceManagerRpc.java index 536328b5aa60..427478baef5f 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/spi/DefaultResourceManagerRpc.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/spi/DefaultResourceManagerRpc.java @@ -1,10 +1,10 @@ package com.google.cloud.resourcemanager.spi; -import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.cloud.resourcemanager.spi.ResourceManagerRpc.Option.FIELDS; import static com.google.cloud.resourcemanager.spi.ResourceManagerRpc.Option.FILTER; import static com.google.cloud.resourcemanager.spi.ResourceManagerRpc.Option.PAGE_SIZE; import static com.google.cloud.resourcemanager.spi.ResourceManagerRpc.Option.PAGE_TOKEN; +import static com.google.common.base.MoreObjects.firstNonNull; import static java.net.HttpURLConnection.HTTP_FORBIDDEN; import static java.net.HttpURLConnection.HTTP_NOT_FOUND; @@ -19,10 +19,10 @@ import com.google.api.services.cloudresourcemanager.model.SetIamPolicyRequest; import com.google.api.services.cloudresourcemanager.model.TestIamPermissionsRequest; import com.google.api.services.cloudresourcemanager.model.TestIamPermissionsResponse; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import com.google.cloud.resourcemanager.ResourceManagerException; import com.google.cloud.resourcemanager.ResourceManagerOptions; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import java.io.IOException; import java.util.List; diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/testing/LocalResourceManagerHelper.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/testing/LocalResourceManagerHelper.java index 614a7ec63ecf..6c16372c0424 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/testing/LocalResourceManagerHelper.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/testing/LocalResourceManagerHelper.java @@ -11,14 +11,14 @@ import com.google.api.services.cloudresourcemanager.model.SetIamPolicyRequest; import com.google.api.services.cloudresourcemanager.model.TestIamPermissionsRequest; import com.google.api.services.cloudresourcemanager.model.TestIamPermissionsResponse; +import com.google.cloud.AuthCredentials; +import com.google.cloud.resourcemanager.ResourceManagerOptions; import com.google.common.base.Joiner; import com.google.common.base.Objects; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.io.ByteStreams; -import com.google.cloud.AuthCredentials; -import com.google.cloud.resourcemanager.ResourceManagerOptions; import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.HttpExchange; diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ProjectTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ProjectTest.java index 58920e5fec12..a40336ae665e 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ProjectTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ProjectTest.java @@ -25,11 +25,11 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.cloud.Identity; import com.google.cloud.resourcemanager.Policy.ProjectRole; import com.google.cloud.resourcemanager.ProjectInfo.ResourceId; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import org.junit.After; import org.junit.Before; diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ResourceManagerImplTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ResourceManagerImplTest.java index 910478af0888..92bf6fd96223 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ResourceManagerImplTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ResourceManagerImplTest.java @@ -25,8 +25,6 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.cloud.Identity; import com.google.cloud.Page; import com.google.cloud.resourcemanager.Policy.ProjectRole; @@ -37,6 +35,8 @@ import com.google.cloud.resourcemanager.spi.ResourceManagerRpc; import com.google.cloud.resourcemanager.spi.ResourceManagerRpcFactory; import com.google.cloud.resourcemanager.testing.LocalResourceManagerHelper; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import org.easymock.EasyMock; import org.junit.AfterClass; diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/SerializationTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/SerializationTest.java index b09f81b60997..52d8c9692a88 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/SerializationTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/SerializationTest.java @@ -16,12 +16,12 @@ package com.google.cloud.resourcemanager; -import com.google.common.collect.ImmutableMap; import com.google.cloud.BaseSerializationTest; import com.google.cloud.Identity; import com.google.cloud.PageImpl; import com.google.cloud.Restorable; import com.google.cloud.resourcemanager.Policy.ProjectRole; +import com.google.common.collect.ImmutableMap; import java.io.Serializable; import java.util.Collections; diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/testing/LocalResourceManagerHelperTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/testing/LocalResourceManagerHelperTest.java index 7a23383b3d89..cf65b4981bfc 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/testing/LocalResourceManagerHelperTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/testing/LocalResourceManagerHelperTest.java @@ -9,12 +9,12 @@ import static org.junit.Assert.fail; import com.google.api.services.cloudresourcemanager.model.Binding; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.cloud.resourcemanager.ResourceManagerException; import com.google.cloud.resourcemanager.spi.DefaultResourceManagerRpc; import com.google.cloud.resourcemanager.spi.ResourceManagerRpc; import com.google.cloud.resourcemanager.spi.ResourceManagerRpc.Tuple; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import org.junit.AfterClass; import org.junit.Before; diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BatchRequest.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BatchRequest.java index f98160b91b18..05dfe8e2a1dc 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BatchRequest.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BatchRequest.java @@ -16,11 +16,11 @@ package com.google.cloud.storage; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; import com.google.cloud.storage.Storage.BlobGetOption; import com.google.cloud.storage.Storage.BlobSourceOption; import com.google.cloud.storage.Storage.BlobTargetOption; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; import java.io.Serializable; import java.util.LinkedHashMap; diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/Blob.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Blob.java index df5ab959ad30..1adea4f549bd 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/Blob.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Blob.java @@ -16,12 +16,11 @@ package com.google.cloud.storage; -import static com.google.common.base.Preconditions.checkNotNull; import static com.google.cloud.storage.Blob.BlobSourceOption.toGetOptions; import static com.google.cloud.storage.Blob.BlobSourceOption.toSourceOptions; +import static com.google.common.base.Preconditions.checkNotNull; import com.google.api.services.storage.model.StorageObject; -import com.google.common.base.Function; import com.google.cloud.AuthCredentials; import com.google.cloud.AuthCredentials.AppEngineAuthCredentials; import com.google.cloud.AuthCredentials.ServiceAccountAuthCredentials; @@ -35,6 +34,7 @@ import com.google.cloud.storage.Storage.SignUrlOption; import com.google.cloud.storage.spi.StorageRpc; import com.google.cloud.storage.spi.StorageRpc.Tuple; +import com.google.common.base.Function; import java.io.IOException; import java.io.ObjectInputStream; diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobReadChannel.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobReadChannel.java index 1c15a9cd4e54..49ceb99a5792 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobReadChannel.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobReadChannel.java @@ -19,12 +19,12 @@ import static com.google.cloud.RetryHelper.runWithRetries; import com.google.api.services.storage.model.StorageObject; -import com.google.common.base.MoreObjects; import com.google.cloud.ReadChannel; import com.google.cloud.RestorableState; import com.google.cloud.RetryHelper; import com.google.cloud.storage.spi.StorageRpc; import com.google.cloud.storage.spi.StorageRpc.Tuple; +import com.google.common.base.MoreObjects; import java.io.IOException; import java.io.Serializable; diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/Bucket.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Bucket.java index 04337e6a77b1..989ea87ec9d3 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/Bucket.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Bucket.java @@ -16,18 +16,18 @@ package com.google.cloud.storage; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; import static com.google.cloud.storage.Bucket.BucketSourceOption.toGetOptions; import static com.google.cloud.storage.Bucket.BucketSourceOption.toSourceOptions; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.base.Function; -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; import com.google.cloud.Page; import com.google.cloud.storage.Storage.BlobGetOption; import com.google.cloud.storage.Storage.BucketTargetOption; import com.google.cloud.storage.spi.StorageRpc; +import com.google.common.base.Function; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import java.io.IOException; import java.io.InputStream; diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BucketInfo.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BucketInfo.java index 88ff6095f762..1dcd110808a9 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BucketInfo.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BucketInfo.java @@ -30,10 +30,10 @@ import com.google.api.services.storage.model.Bucket.Website; import com.google.api.services.storage.model.BucketAccessControl; import com.google.api.services.storage.model.ObjectAccessControl; +import com.google.cloud.storage.Acl.Entity; import com.google.common.base.Function; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; -import com.google.cloud.storage.Acl.Entity; import java.io.IOException; import java.io.ObjectInputStream; diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/CopyWriter.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/CopyWriter.java index 5d3289e71861..9e674052f877 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/CopyWriter.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/CopyWriter.java @@ -18,13 +18,13 @@ import static com.google.cloud.RetryHelper.runWithRetries; -import com.google.common.base.MoreObjects; import com.google.cloud.Restorable; import com.google.cloud.RestorableState; import com.google.cloud.RetryHelper; import com.google.cloud.storage.spi.StorageRpc; import com.google.cloud.storage.spi.StorageRpc.RewriteRequest; import com.google.cloud.storage.spi.StorageRpc.RewriteResponse; +import com.google.common.base.MoreObjects; import java.io.Serializable; import java.util.Map; diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/Option.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Option.java index ca1077d7c595..e15d53a2d591 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/Option.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Option.java @@ -18,8 +18,8 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.base.MoreObjects; import com.google.cloud.storage.spi.StorageRpc; +import com.google.common.base.MoreObjects; import java.io.Serializable; import java.util.Objects; diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Storage.java index e59e465095d6..e15a3ad0077c 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Storage.java @@ -19,9 +19,6 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; import com.google.cloud.AuthCredentials; import com.google.cloud.AuthCredentials.AppEngineAuthCredentials; import com.google.cloud.AuthCredentials.ServiceAccountAuthCredentials; @@ -35,6 +32,9 @@ import com.google.cloud.WriteChannel; import com.google.cloud.storage.spi.StorageRpc; import com.google.cloud.storage.spi.StorageRpc.Tuple; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; import java.io.InputStream; import java.io.Serializable; diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageException.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageException.java index 2b1aa24e13af..d6333c5c24e3 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageException.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageException.java @@ -17,10 +17,10 @@ package com.google.cloud.storage; import com.google.api.client.googleapis.json.GoogleJsonError; -import com.google.common.collect.ImmutableSet; import com.google.cloud.BaseServiceException; import com.google.cloud.RetryHelper.RetryHelperException; import com.google.cloud.RetryHelper.RetryInterruptedException; +import com.google.common.collect.ImmutableSet; import java.io.IOException; import java.util.Set; diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageImpl.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageImpl.java index 6d0be9ed01fc..f4769905d8bc 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageImpl.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageImpl.java @@ -16,9 +16,6 @@ package com.google.cloud.storage; -import static com.google.common.base.MoreObjects.firstNonNull; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkState; import static com.google.cloud.RetryHelper.runWithRetries; import static com.google.cloud.storage.spi.StorageRpc.Option.DELIMITER; import static com.google.cloud.storage.spi.StorageRpc.Option.IF_GENERATION_MATCH; @@ -29,18 +26,12 @@ import static com.google.cloud.storage.spi.StorageRpc.Option.IF_SOURCE_GENERATION_NOT_MATCH; import static com.google.cloud.storage.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_MATCH; import static com.google.cloud.storage.spi.StorageRpc.Option.IF_SOURCE_METAGENERATION_NOT_MATCH; +import static com.google.common.base.MoreObjects.firstNonNull; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkState; import static java.nio.charset.StandardCharsets.UTF_8; import com.google.api.services.storage.model.StorageObject; -import com.google.common.base.Function; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.hash.Hashing; -import com.google.common.io.BaseEncoding; -import com.google.common.primitives.Ints; import com.google.cloud.BaseService; import com.google.cloud.Page; import com.google.cloud.PageImpl; @@ -51,6 +42,15 @@ import com.google.cloud.storage.spi.StorageRpc; import com.google.cloud.storage.spi.StorageRpc.RewriteResponse; import com.google.cloud.storage.spi.StorageRpc.Tuple; +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.hash.Hashing; +import com.google.common.io.BaseEncoding; +import com.google.common.primitives.Ints; import java.io.ByteArrayInputStream; import java.io.InputStream; diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageOptions.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageOptions.java index 15e5791a6b91..5eeed5c88a69 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageOptions.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageOptions.java @@ -16,11 +16,11 @@ package com.google.cloud.storage; -import com.google.common.collect.ImmutableSet; import com.google.cloud.ServiceOptions; import com.google.cloud.storage.spi.DefaultStorageRpc; import com.google.cloud.storage.spi.StorageRpc; import com.google.cloud.storage.spi.StorageRpcFactory; +import com.google.common.collect.ImmutableSet; import java.util.Set; diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/DefaultStorageRpc.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/DefaultStorageRpc.java index 37c81ff6ff0b..4ef9afc45e4c 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/DefaultStorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/DefaultStorageRpc.java @@ -14,7 +14,6 @@ package com.google.cloud.storage.spi; -import static com.google.common.base.MoreObjects.firstNonNull; import static com.google.cloud.storage.spi.StorageRpc.Option.DELIMITER; import static com.google.cloud.storage.spi.StorageRpc.Option.FIELDS; import static com.google.cloud.storage.spi.StorageRpc.Option.IF_GENERATION_MATCH; @@ -31,6 +30,7 @@ import static com.google.cloud.storage.spi.StorageRpc.Option.PREDEFINED_DEFAULT_OBJECT_ACL; import static com.google.cloud.storage.spi.StorageRpc.Option.PREFIX; import static com.google.cloud.storage.spi.StorageRpc.Option.VERSIONS; +import static com.google.common.base.MoreObjects.firstNonNull; import static java.net.HttpURLConnection.HTTP_NOT_FOUND; import static javax.servlet.http.HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE; @@ -58,13 +58,13 @@ import com.google.api.services.storage.model.ComposeRequest.SourceObjects.ObjectPreconditions; import com.google.api.services.storage.model.Objects; import com.google.api.services.storage.model.StorageObject; +import com.google.cloud.storage.StorageException; +import com.google.cloud.storage.StorageOptions; import com.google.common.base.Function; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import com.google.cloud.storage.StorageException; -import com.google.cloud.storage.StorageOptions; import java.io.ByteArrayOutputStream; import java.io.IOException; diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/StorageRpc.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/StorageRpc.java index 2f84f221e13d..13dddb7d6737 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/StorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/StorageRpc.java @@ -20,9 +20,9 @@ import com.google.api.services.storage.model.Bucket; import com.google.api.services.storage.model.StorageObject; +import com.google.cloud.storage.StorageException; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.google.cloud.storage.StorageException; import java.io.InputStream; import java.util.List; diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BatchRequestTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BatchRequestTest.java index fbea9283ed50..a47c7c140216 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BatchRequestTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BatchRequestTest.java @@ -22,10 +22,10 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; -import com.google.common.collect.Iterables; import com.google.cloud.storage.Storage.BlobGetOption; import com.google.cloud.storage.Storage.BlobSourceOption; import com.google.cloud.storage.Storage.BlobTargetOption; +import com.google.common.collect.Iterables; import org.junit.Test; diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BatchResponseTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BatchResponseTest.java index 6344d4649fab..a9177489c2fd 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BatchResponseTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BatchResponseTest.java @@ -19,8 +19,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; -import com.google.common.collect.ImmutableList; import com.google.cloud.storage.BatchResponse.Result; +import com.google.common.collect.ImmutableList; import org.easymock.EasyMock; import org.junit.Before; diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobInfoTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobInfoTest.java index 4e2f27265ef9..03d28f8e988e 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobInfoTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobInfoTest.java @@ -25,10 +25,10 @@ import static org.junit.Assert.assertTrue; import com.google.api.services.storage.model.StorageObject; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.cloud.storage.Acl.Project; import com.google.cloud.storage.Acl.User; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import org.junit.Test; diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobReadChannelTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobReadChannelTest.java index 89f888ec4147..a108e5f167ce 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobReadChannelTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobReadChannelTest.java @@ -26,12 +26,12 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import com.google.common.collect.ImmutableMap; import com.google.cloud.ReadChannel; import com.google.cloud.RestorableState; import com.google.cloud.RetryParams; import com.google.cloud.storage.spi.StorageRpc; import com.google.cloud.storage.spi.StorageRpcFactory; +import com.google.common.collect.ImmutableMap; import org.junit.After; import org.junit.Before; diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobTest.java index 5af12e8d411d..14cd6970fa87 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobTest.java @@ -33,12 +33,12 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import com.google.cloud.ReadChannel; import com.google.cloud.storage.Acl.Project; import com.google.cloud.storage.Acl.User; import com.google.cloud.storage.Storage.CopyRequest; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import org.easymock.Capture; import org.junit.After; diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobWriteChannelTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobWriteChannelTest.java index 549211930e3e..27d55d8b686c 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobWriteChannelTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobWriteChannelTest.java @@ -30,12 +30,12 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import com.google.common.collect.ImmutableMap; import com.google.cloud.RestorableState; import com.google.cloud.RetryParams; import com.google.cloud.WriteChannel; import com.google.cloud.storage.spi.StorageRpc; import com.google.cloud.storage.spi.StorageRpcFactory; +import com.google.common.collect.ImmutableMap; import org.easymock.Capture; import org.easymock.CaptureType; diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BucketInfoTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BucketInfoTest.java index 59dd2ea632bc..bcb4259ad564 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BucketInfoTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BucketInfoTest.java @@ -21,7 +21,6 @@ import static org.junit.Assert.assertTrue; import com.google.api.services.storage.model.Bucket.Lifecycle.Rule; -import com.google.common.collect.ImmutableList; import com.google.cloud.storage.Acl.Project; import com.google.cloud.storage.Acl.Role; import com.google.cloud.storage.Acl.User; @@ -32,6 +31,7 @@ import com.google.cloud.storage.BucketInfo.IsLiveDeleteRule; import com.google.cloud.storage.BucketInfo.NumNewerVersionsDeleteRule; import com.google.cloud.storage.BucketInfo.RawDeleteRule; +import com.google.common.collect.ImmutableList; import org.junit.Test; diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BucketTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BucketTest.java index b0f3f7ac9d0c..0494dfcdf506 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BucketTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BucketTest.java @@ -30,7 +30,6 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import com.google.common.collect.ImmutableList; import com.google.cloud.Page; import com.google.cloud.PageImpl; import com.google.cloud.storage.Acl.Project; @@ -38,6 +37,7 @@ import com.google.cloud.storage.BatchResponse.Result; import com.google.cloud.storage.BucketInfo.AgeDeleteRule; import com.google.cloud.storage.BucketInfo.DeleteRule; +import com.google.common.collect.ImmutableList; import org.easymock.Capture; import org.junit.After; diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/CopyRequestTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/CopyRequestTest.java index d3e93d9b8f66..0649566864a1 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/CopyRequestTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/CopyRequestTest.java @@ -21,9 +21,9 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import com.google.common.collect.ImmutableList; import com.google.cloud.storage.Storage.BlobSourceOption; import com.google.cloud.storage.Storage.BlobTargetOption; +import com.google.common.collect.ImmutableList; import org.junit.Rule; import org.junit.Test; diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/CopyWriterTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/CopyWriterTest.java index 13467283c013..5f5b9102c195 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/CopyWriterTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/CopyWriterTest.java @@ -24,13 +24,13 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import com.google.common.collect.ImmutableMap; import com.google.cloud.RestorableState; import com.google.cloud.RetryParams; import com.google.cloud.storage.spi.StorageRpc; import com.google.cloud.storage.spi.StorageRpc.RewriteRequest; import com.google.cloud.storage.spi.StorageRpc.RewriteResponse; import com.google.cloud.storage.spi.StorageRpcFactory; +import com.google.common.collect.ImmutableMap; import org.easymock.EasyMock; import org.junit.After; diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/CorsTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/CorsTest.java index e16ea98b30b0..b22547a34e54 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/CorsTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/CorsTest.java @@ -18,8 +18,8 @@ import static org.junit.Assert.assertEquals; -import com.google.common.collect.ImmutableList; import com.google.cloud.storage.Cors.Origin; +import com.google.common.collect.ImmutableList; import org.junit.Test; diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/SerializationTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/SerializationTest.java index 581a517a1ee6..a8d399e1b1e4 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/SerializationTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/SerializationTest.java @@ -16,7 +16,6 @@ package com.google.cloud.storage; -import com.google.common.collect.ImmutableMap; import com.google.cloud.AuthCredentials; import com.google.cloud.BaseSerializationTest; import com.google.cloud.PageImpl; @@ -24,6 +23,7 @@ import com.google.cloud.Restorable; import com.google.cloud.storage.Acl.Project.ProjectRole; import com.google.cloud.storage.spi.StorageRpc; +import com.google.common.collect.ImmutableMap; import java.io.Serializable; import java.util.Collections; diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java index a122383080b8..208988a74668 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java @@ -25,12 +25,6 @@ import static org.junit.Assert.assertTrue; import com.google.api.services.storage.model.StorageObject; -import com.google.common.base.Function; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Iterables; -import com.google.common.collect.Maps; -import com.google.common.io.BaseEncoding; import com.google.cloud.AuthCredentials.ServiceAccountAuthCredentials; import com.google.cloud.Page; import com.google.cloud.ReadChannel; @@ -41,6 +35,12 @@ import com.google.cloud.storage.spi.StorageRpc; import com.google.cloud.storage.spi.StorageRpc.Tuple; import com.google.cloud.storage.spi.StorageRpcFactory; +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; +import com.google.common.collect.Maps; +import com.google.common.io.BaseEncoding; import org.easymock.Capture; import org.easymock.EasyMock; diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java index a505597b7b21..684653390d1b 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java @@ -25,11 +25,6 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterators; -import com.google.common.collect.Lists; import com.google.cloud.Page; import com.google.cloud.ReadChannel; import com.google.cloud.RestorableState; @@ -48,6 +43,11 @@ import com.google.cloud.storage.Storage.BucketField; import com.google.cloud.storage.StorageException; import com.google.cloud.storage.testing.RemoteStorageHelper; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterators; +import com.google.common.collect.Lists; import org.junit.AfterClass; import org.junit.BeforeClass; diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/testing/RemoteStorageHelperTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/testing/RemoteStorageHelperTest.java index b817ac2fc101..3c29ca223c23 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/testing/RemoteStorageHelperTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/testing/RemoteStorageHelperTest.java @@ -20,7 +20,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import com.google.common.collect.ImmutableList; import com.google.cloud.Page; import com.google.cloud.storage.Blob; import com.google.cloud.storage.BlobId; @@ -28,6 +27,7 @@ import com.google.cloud.storage.Storage.BlobListOption; import com.google.cloud.storage.StorageException; import com.google.cloud.storage.StorageOptions; +import com.google.common.collect.ImmutableList; import org.easymock.EasyMock; import org.junit.Before; From 81278d68431a33f65a973e108f7914b3511fd097 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Tue, 12 Apr 2016 16:34:46 -0700 Subject: [PATCH 255/375] fix remaining checkstyle issues --- .../src/main/java/com/google/cloud/bigquery/QueryStage.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryStage.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryStage.java index c88175279a3d..b9cfb804b1ac 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryStage.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryStage.java @@ -373,8 +373,9 @@ public String toString() { @Override public int hashCode() { - return Objects.hash(computeRatioAvg, computeRatioMax, generatedId, name, readRatioAvg, readRatioMax, - recordsRead, recordsWritten, steps, waitRatioAvg, waitRatioMax, writeRatioAvg); + return Objects.hash(computeRatioAvg, computeRatioMax, generatedId, name, readRatioAvg, + readRatioMax, recordsRead, recordsWritten, steps, waitRatioAvg, waitRatioMax, + writeRatioAvg); } @Override From 613f19df83140533c87c9c168db29453399af78a Mon Sep 17 00:00:00 2001 From: Arie Ozarov Date: Tue, 12 Apr 2016 18:02:00 -0700 Subject: [PATCH 256/375] update pubsub pom --- gcloud-java-pubsub/pom.xml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/gcloud-java-pubsub/pom.xml b/gcloud-java-pubsub/pom.xml index 16a82879b9f4..cae94315abf9 100644 --- a/gcloud-java-pubsub/pom.xml +++ b/gcloud-java-pubsub/pom.xml @@ -1,8 +1,6 @@ 4.0.0 - com.google.gcloud - 0.1.5 gcloud-java-pubsub jar GCloud Java Pub/Sub @@ -10,9 +8,9 @@ Java idiomatic client for Google Cloud Pub/Sub. - com.google.gcloud + com.google.cloud gcloud-java-pom - 0.1.5 + 0.2.1-SNAPSHOT gcloud-java-pubsub From fd740ead7276b35128a0ba01fe08ff0bc6e55896 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Thu, 14 Apr 2016 18:07:13 -0400 Subject: [PATCH 257/375] Marked exceptions for create and deletes in DNS as non-idempotent. (#883) Add the notion of "rejected" to BaseServiceException to indicate that the service rejected the request and it should be safe to retry it even if request is not idempotent. --- .../google/cloud/BaseServiceException.java | 60 ++++++++++--------- .../com/google/cloud/dns/DnsException.java | 16 ++--- .../google/cloud/dns/spi/DefaultDnsRpc.java | 23 +++---- 3 files changed, 52 insertions(+), 47 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/cloud/BaseServiceException.java b/gcloud-java-core/src/main/java/com/google/cloud/BaseServiceException.java index 6dc87f4abb3e..ad2d6bf07144 100644 --- a/gcloud-java-core/src/main/java/com/google/cloud/BaseServiceException.java +++ b/gcloud-java-core/src/main/java/com/google/cloud/BaseServiceException.java @@ -48,10 +48,16 @@ protected static final class Error implements Serializable { private final Integer code; private final String reason; + private final boolean rejected; public Error(Integer code, String reason) { + this(code, reason, false); + } + + public Error(Integer code, String reason, boolean rejected) { this.code = code; this.reason = reason; + this.rejected = rejected; } /** @@ -61,6 +67,15 @@ public Integer code() { return code; } + /** + * Returns true if the error indicates that the API call was certainly not accepted by the + * server. For instance, if the server returns a rate limit exceeded error, it certainly did not + * process the request and this method will return {@code true}. + */ + public boolean rejected() { + return rejected; + } + /** * Returns the reason that caused the exception. */ @@ -68,11 +83,11 @@ public String reason() { return reason; } - boolean isRetryable(Set retryableErrors) { + boolean isRetryable(boolean idempotent, Set retryableErrors) { for (Error retryableError : retryableErrors) { if ((retryableError.code() == null || retryableError.code().equals(this.code())) && (retryableError.reason() == null || retryableError.reason().equals(this.reason()))) { - return true; + return idempotent || retryableError.rejected(); } } return false; @@ -95,12 +110,14 @@ public BaseServiceException(IOException exception, boolean idempotent) { String reason = null; String location = null; String debugInfo = null; + Boolean retryable = null; if (exception instanceof GoogleJsonResponseException) { GoogleJsonError jsonError = ((GoogleJsonResponseException) exception).getDetails(); if (jsonError != null) { - Error error = error(jsonError); + Error error = new Error(jsonError.getCode(), reason(jsonError)); code = error.code; reason = error.reason; + retryable = isRetryable(idempotent, error); if (reason != null) { GoogleJsonError.ErrorInfo errorInfo = jsonError.getErrors().get(0); location = errorInfo.getLocation(); @@ -110,8 +127,8 @@ public BaseServiceException(IOException exception, boolean idempotent) { code = ((GoogleJsonResponseException) exception).getStatusCode(); } } + this.retryable = MoreObjects.firstNonNull(retryable, isRetryable(idempotent, exception)); this.code = code; - this.retryable = idempotent && isRetryable(exception); this.reason = reason; this.idempotent = idempotent; this.location = location; @@ -119,13 +136,7 @@ public BaseServiceException(IOException exception, boolean idempotent) { } public BaseServiceException(GoogleJsonError error, boolean idempotent) { - super(error.getMessage()); - this.code = error.getCode(); - this.reason = reason(error); - this.idempotent = idempotent; - this.retryable = idempotent && isRetryable(error); - this.location = null; - this.debugInfo = null; + this(error.getCode(), error.getMessage(), reason(error), idempotent); } public BaseServiceException(int code, String message, String reason, boolean idempotent) { @@ -138,7 +149,7 @@ public BaseServiceException(int code, String message, String reason, boolean ide this.code = code; this.reason = reason; this.idempotent = idempotent; - this.retryable = idempotent && new Error(code, reason).isRetryable(retryableErrors()); + this.retryable = isRetryable(idempotent, new Error(code, reason)); this.location = null; this.debugInfo = null; } @@ -147,15 +158,12 @@ protected Set retryableErrors() { return Collections.emptySet(); } - protected boolean isRetryable(GoogleJsonError error) { - return error != null && error(error).isRetryable(retryableErrors()); + protected boolean isRetryable(boolean idempotent, Error error) { + return error.isRetryable(idempotent, retryableErrors()); } - protected boolean isRetryable(IOException exception) { - if (exception instanceof GoogleJsonResponseException) { - return isRetryable(((GoogleJsonResponseException) exception).getDetails()); - } - return exception instanceof SocketTimeoutException; + protected boolean isRetryable(boolean idempotent, IOException exception) { + return idempotent && exception instanceof SocketTimeoutException; } /** @@ -187,8 +195,8 @@ public boolean idempotent() { } /** - * Returns the service location where the error causing the exception occurred. Returns - * {@code null} if not set. + * Returns the service location where the error causing the exception occurred. Returns {@code + * null} if not available. */ public String location() { return location; @@ -223,18 +231,14 @@ public int hashCode() { debugInfo); } - protected static String reason(GoogleJsonError error) { - if (error.getErrors() != null && !error.getErrors().isEmpty()) { + private static String reason(GoogleJsonError error) { + if (error.getErrors() != null && !error.getErrors().isEmpty()) { return error.getErrors().get(0).getReason(); } return null; } - protected static Error error(GoogleJsonError error) { - return new Error(error.getCode(), reason(error)); - } - - protected static String message(IOException exception) { + private static String message(IOException exception) { if (exception instanceof GoogleJsonResponseException) { GoogleJsonError details = ((GoogleJsonResponseException) exception).getDetails(); if (details != null) { diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsException.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsException.java index 1e1e34b833a5..f725984b6661 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsException.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsException.java @@ -31,16 +31,16 @@ public class DnsException extends BaseServiceException { // see: https://cloud.google.com/dns/troubleshooting private static final Set RETRYABLE_ERRORS = ImmutableSet.of( - new Error(429, null), - new Error(500, null), - new Error(502, null), - new Error(503, null), - new Error(null, "userRateLimitExceeded"), - new Error(null, "rateLimitExceeded")); + new Error(429, null, true), + new Error(500, null, false), + new Error(502, null, false), + new Error(503, null, false), + new Error(null, "userRateLimitExceeded", true), + new Error(null, "rateLimitExceeded", true)); private static final long serialVersionUID = 490302380416260252L; - public DnsException(IOException exception) { - super(exception, true); + public DnsException(IOException exception, boolean idempotent) { + super(exception, idempotent); } private DnsException(int code, String message) { diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DefaultDnsRpc.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DefaultDnsRpc.java index 05b803513acb..08f14a0ba254 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DefaultDnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DefaultDnsRpc.java @@ -36,8 +36,8 @@ public class DefaultDnsRpc implements DnsRpc { private final Dns dns; private final DnsOptions options; - private static DnsException translate(IOException exception) { - return new DnsException(exception); + private static DnsException translate(IOException exception, boolean idempotent) { + return new DnsException(exception, idempotent); } /** @@ -61,7 +61,8 @@ public ManagedZone create(ManagedZone zone, Map options) throws DnsEx .setFields(FIELDS.getString(options)) .execute(); } catch (IOException ex) { - throw translate(ex); + // todo this can cause misleading report of a failure, intended to be fixed within #924 + throw translate(ex, true); } } @@ -73,7 +74,7 @@ public ManagedZone getZone(String zoneName, Map options) throws DnsEx .setFields(FIELDS.getString(options)) .execute(); } catch (IOException ex) { - DnsException serviceException = translate(ex); + DnsException serviceException = translate(ex, true); if (serviceException.code() == HTTP_NOT_FOUND) { return null; } @@ -93,7 +94,7 @@ public ListResult listZones(Map options) throws DnsExcep .execute(); return of(zoneList.getNextPageToken(), zoneList.getManagedZones()); } catch (IOException ex) { - throw translate(ex); + throw translate(ex, true); } } @@ -103,7 +104,7 @@ public boolean deleteZone(String zoneName) throws DnsException { dns.managedZones().delete(this.options.projectId(), zoneName).execute(); return true; } catch (IOException ex) { - DnsException serviceException = translate(ex); + DnsException serviceException = translate(ex, false); if (serviceException.code() == HTTP_NOT_FOUND) { return false; } @@ -126,7 +127,7 @@ public ListResult listRecordSets(String zoneName, Map options) throws DnsException { return dns.projects().get(this.options.projectId()) .setFields(FIELDS.getString(options)).execute(); } catch (IOException ex) { - throw translate(ex); + throw translate(ex, true); } } @@ -148,7 +149,7 @@ public Change applyChangeRequest(String zoneName, Change changeRequest, Map listChangeRequests(String zoneName, Map opt ChangesListResponse response = request.execute(); return of(response.getNextPageToken(), response.getChanges()); } catch (IOException ex) { - throw translate(ex); + throw translate(ex, true); } } } From 7d7b799c4ab14b6c0fd90520bc1060533607a1fe Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 15 Apr 2016 00:19:58 +0200 Subject: [PATCH 258/375] Enable mocking of functional classes and configurations (#892) * Enable mocking of functional classes and configurations * Refactor classes to be either final or have final equals/hashCode * Make job configuration classes final --- .../google/cloud/bigquery/BigQueryError.java | 6 +- .../cloud/bigquery/CopyJobConfiguration.java | 4 +- .../com/google/cloud/bigquery/CsvOptions.java | 6 +- .../com/google/cloud/bigquery/Dataset.java | 18 ++- .../com/google/cloud/bigquery/DatasetId.java | 6 +- .../google/cloud/bigquery/DatasetInfo.java | 3 +- .../bigquery/ExternalTableDefinition.java | 9 +- .../bigquery/ExtractJobConfiguration.java | 4 +- .../java/com/google/cloud/bigquery/Field.java | 20 ++-- .../com/google/cloud/bigquery/FieldValue.java | 9 +- .../google/cloud/bigquery/FormatOptions.java | 5 +- .../cloud/bigquery/InsertAllRequest.java | 5 +- .../cloud/bigquery/InsertAllResponse.java | 8 +- .../java/com/google/cloud/bigquery/Job.java | 18 ++- .../java/com/google/cloud/bigquery/JobId.java | 6 +- .../com/google/cloud/bigquery/JobInfo.java | 3 +- .../google/cloud/bigquery/JobStatistics.java | 107 +++++++++++++----- .../com/google/cloud/bigquery/JobStatus.java | 9 +- .../cloud/bigquery/LoadJobConfiguration.java | 4 +- .../cloud/bigquery/QueryJobConfiguration.java | 30 ++--- .../google/cloud/bigquery/QueryRequest.java | 6 +- .../google/cloud/bigquery/QueryResponse.java | 8 +- .../google/cloud/bigquery/QueryResult.java | 8 +- .../com/google/cloud/bigquery/QueryStage.java | 9 +- .../com/google/cloud/bigquery/Schema.java | 6 +- .../bigquery/StandardTableDefinition.java | 9 +- .../java/com/google/cloud/bigquery/Table.java | 18 ++- .../com/google/cloud/bigquery/TableId.java | 6 +- .../com/google/cloud/bigquery/TableInfo.java | 3 +- .../google/cloud/bigquery/ViewDefinition.java | 11 +- .../bigquery/WriteChannelConfiguration.java | 5 +- .../google/cloud/bigquery/JobInfoTest.java | 3 +- .../cloud/bigquery/JobStatisticsTest.java | 21 ++-- .../com/google/cloud/bigquery/JobTest.java | 4 +- .../cloud/bigquery/SerializationTest.java | 13 ++- .../main/java/com/google/cloud/IamPolicy.java | 5 +- .../com/google/cloud/dns/ChangeRequest.java | 16 +-- .../google/cloud/dns/ChangeRequestInfo.java | 8 +- .../com/google/cloud/dns/ProjectInfo.java | 9 +- .../java/com/google/cloud/dns/RecordSet.java | 6 +- .../main/java/com/google/cloud/dns/Zone.java | 15 ++- .../java/com/google/cloud/dns/ZoneInfo.java | 4 +- .../google/cloud/resourcemanager/Policy.java | 2 +- .../google/cloud/resourcemanager/Project.java | 15 ++- .../cloud/resourcemanager/ProjectInfo.java | 4 +- .../google/cloud/storage/BatchResponse.java | 11 +- .../java/com/google/cloud/storage/Blob.java | 13 ++- .../java/com/google/cloud/storage/BlobId.java | 13 ++- .../com/google/cloud/storage/BlobInfo.java | 4 +- .../java/com/google/cloud/storage/Bucket.java | 17 ++- .../com/google/cloud/storage/BucketInfo.java | 4 +- 51 files changed, 367 insertions(+), 189 deletions(-) diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryError.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryError.java index a5e94ae8b70c..121ca578c0d3 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryError.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryError.java @@ -17,7 +17,7 @@ * {@link BigQueryException} is thrown the BigQuery Error that caused it, if any, can be accessed * with {@link BigQueryException#error()}. */ -public class BigQueryError implements Serializable { +public final class BigQueryError implements Serializable { static final Function FROM_PB_FUNCTION = new Function() { @@ -98,7 +98,9 @@ public String toString() { @Override public boolean equals(Object obj) { - return obj instanceof BigQueryError && Objects.equals(toPb(), ((BigQueryError) obj).toPb()); + return obj == this + || obj instanceof BigQueryError + && Objects.equals(toPb(), ((BigQueryError) obj).toPb()); } ErrorProto toPb() { diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/CopyJobConfiguration.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/CopyJobConfiguration.java index 3717ff039c7b..e455416bea7b 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/CopyJobConfiguration.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/CopyJobConfiguration.java @@ -181,7 +181,9 @@ ToStringHelper toStringHelper() { @Override public boolean equals(Object obj) { - return obj instanceof CopyJobConfiguration && baseEquals((CopyJobConfiguration) obj); + return obj == this + || obj instanceof CopyJobConfiguration + && baseEquals((CopyJobConfiguration) obj); } @Override diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/CsvOptions.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/CsvOptions.java index e07347f2b873..b621ed2cc6bc 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/CsvOptions.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/CsvOptions.java @@ -25,7 +25,7 @@ * Google BigQuery options for CSV format. This class wraps some properties of CSV files used by * BigQuery to parse external data. */ -public class CsvOptions extends FormatOptions { +public final class CsvOptions extends FormatOptions { private static final long serialVersionUID = 2193570529308612708L; @@ -224,7 +224,9 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof CsvOptions && Objects.equals(toPb(), ((CsvOptions) obj).toPb()); + return obj == this + || obj instanceof CsvOptions + && Objects.equals(toPb(), ((CsvOptions) obj).toPb()); } com.google.api.services.bigquery.model.CsvOptions toPb() { diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Dataset.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Dataset.java index 31dee897aada..5cc7a260f00f 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Dataset.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Dataset.java @@ -34,7 +34,7 @@ * {@link DatasetInfo}. *

    */ -public final class Dataset extends DatasetInfo { +public class Dataset extends DatasetInfo { private static final long serialVersionUID = -4272921483363065593L; @@ -230,14 +230,20 @@ public Builder toBuilder() { } @Override - public boolean equals(Object obj) { - return obj instanceof Dataset - && Objects.equals(toPb(), ((Dataset) obj).toPb()) - && Objects.equals(options, ((Dataset) obj).options); + public final boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null || !obj.getClass().equals(Dataset.class)) { + return false; + } + Dataset other = (Dataset) obj; + return Objects.equals(toPb(), other.toPb()) + && Objects.equals(options, other.options); } @Override - public int hashCode() { + public final int hashCode() { return Objects.hash(super.hashCode(), options); } diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/DatasetId.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/DatasetId.java index 634327f2189d..a6f2762da9cd 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/DatasetId.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/DatasetId.java @@ -26,7 +26,7 @@ /** * Google BigQuery Dataset identity. */ -public class DatasetId implements Serializable { +public final class DatasetId implements Serializable { private static final long serialVersionUID = -6186254820908152300L; @@ -68,7 +68,9 @@ public static DatasetId of(String dataset) { @Override public boolean equals(Object obj) { - return obj instanceof DatasetId && Objects.equals(toPb(), ((DatasetId) obj).toPb()); + return obj == this + || obj instanceof DatasetId + && Objects.equals(toPb(), ((DatasetId) obj).toPb()); } @Override diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/DatasetInfo.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/DatasetInfo.java index 284cf5aebeac..3e7da7cc6c87 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/DatasetInfo.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/DatasetInfo.java @@ -395,7 +395,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj != null + return obj == this + || obj != null && obj.getClass().equals(DatasetInfo.class) && Objects.equals(toPb(), ((DatasetInfo) obj).toPb()); } diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/ExternalTableDefinition.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/ExternalTableDefinition.java index 0b191d3af761..af17c281f7f1 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/ExternalTableDefinition.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/ExternalTableDefinition.java @@ -255,12 +255,15 @@ ToStringHelper toStringHelper() { } @Override - public boolean equals(Object obj) { - return obj instanceof ExternalTableDefinition && baseEquals((ExternalTableDefinition) obj); + public final boolean equals(Object obj) { + return obj == this + || obj != null + && obj.getClass().equals(ExternalTableDefinition.class) + && baseEquals((ExternalTableDefinition) obj); } @Override - public int hashCode() { + public final int hashCode() { return Objects.hash(baseHashCode(), compression, ignoreUnknownValues, maxBadRecords, formatOptions, sourceUris); } diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/ExtractJobConfiguration.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/ExtractJobConfiguration.java index 6c31e2781d9e..3dccddcae764 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/ExtractJobConfiguration.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/ExtractJobConfiguration.java @@ -211,7 +211,9 @@ ToStringHelper toStringHelper() { @Override public boolean equals(Object obj) { - return obj instanceof ExtractJobConfiguration && baseEquals((ExtractJobConfiguration) obj); + return obj == this + || obj instanceof ExtractJobConfiguration + && baseEquals((ExtractJobConfiguration) obj); } @Override diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Field.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Field.java index c1342ead8f2a..dc805e12c2a2 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Field.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Field.java @@ -32,12 +32,12 @@ import java.util.Objects; /** - * Google BigQuery Table field. A table field has a name, a value, a mode and possibly a - * description. Supported types are: {@link Type#integer()}, {@link Type#bool()}, - * {@link Type#string()}, {@link Type#floatingPoint()}, {@link Type#timestamp()} and - * {@link Type#record(Field...)}. One or more fields form a table's schema. + * Google BigQuery Table field. A table field has a name, a type, a mode and possibly a description. + * Supported types are: {@link Type#integer()}, {@link Type#bool()}, {@link Type#string()}, + * {@link Type#floatingPoint()}, {@link Type#timestamp()} and {@link Type#record(Field...)}. One or + * more fields form a table's schema. */ -public class Field implements Serializable { +public final class Field implements Serializable { static final Function FROM_PB_FUNCTION = new Function() { @@ -56,6 +56,11 @@ public TableFieldSchema apply(Field field) { private static final long serialVersionUID = -8154262932305199256L; + private final String name; + private final Type type; + private final String mode; + private final String description; + /** * Data Types for a BigQuery Table field. This class provides factory methods for all BigQuery * field types. To instantiate a RECORD value the list of sub-fields must be provided. @@ -185,11 +190,6 @@ public enum Mode { NULLABLE, REQUIRED, REPEATED } - private final String name; - private final Type type; - private final String mode; - private final String description; - public static final class Builder { private String name; diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/FieldValue.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/FieldValue.java index 0bd15da9d908..1c06b87d639d 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/FieldValue.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/FieldValue.java @@ -216,13 +216,16 @@ public String toString() { } @Override - public int hashCode() { + public final int hashCode() { return Objects.hash(attribute, value); } @Override - public boolean equals(Object obj) { - if (!(obj instanceof FieldValue)) { + public final boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null || !obj.getClass().equals(FieldValue.class)) { return false; } FieldValue other = (FieldValue) obj; diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/FormatOptions.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/FormatOptions.java index 98e199f6b644..4267d5384147 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/FormatOptions.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/FormatOptions.java @@ -59,7 +59,10 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof FormatOptions && Objects.equals(type, ((FormatOptions) obj).type()); + return obj == this + || obj != null + && obj.getClass().equals(FormatOptions.class) + && Objects.equals(type, ((FormatOptions) obj).type()); } /** diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/InsertAllRequest.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/InsertAllRequest.java index 6907abaaae33..b46257833b78 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/InsertAllRequest.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/InsertAllRequest.java @@ -37,7 +37,7 @@ * @see Streaming Data into * BigQuery */ -public class InsertAllRequest implements Serializable { +public final class InsertAllRequest implements Serializable { private static final long serialVersionUID = 211200307773853078L; @@ -443,6 +443,9 @@ public int hashCode() { @Override public boolean equals(Object obj) { + if (obj == this) { + return true; + } if (!(obj instanceof InsertAllRequest)) { return false; } diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/InsertAllResponse.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/InsertAllResponse.java index 1b998947f068..a145d1037bf7 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/InsertAllResponse.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/InsertAllResponse.java @@ -74,13 +74,15 @@ public boolean hasErrors() { } @Override - public int hashCode() { + public final int hashCode() { return Objects.hash(insertErrors); } @Override - public boolean equals(Object obj) { - return obj instanceof InsertAllResponse + public final boolean equals(Object obj) { + return obj == this + || obj != null + && obj.getClass().equals(InsertAllResponse.class) && Objects.equals(insertErrors, ((InsertAllResponse) obj).insertErrors); } diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Job.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Job.java index 17b58426afc4..bfcca5b5388a 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Job.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Job.java @@ -30,7 +30,7 @@ * {@link JobInfo}. *

    */ -public final class Job extends JobInfo { +public class Job extends JobInfo { private static final long serialVersionUID = -4324100991693024704L; @@ -178,14 +178,20 @@ public Builder toBuilder() { } @Override - public boolean equals(Object obj) { - return obj instanceof Job - && Objects.equals(toPb(), ((Job) obj).toPb()) - && Objects.equals(options, ((Job) obj).options); + public final boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null || !obj.getClass().equals(Job.class)) { + return false; + } + Job other = (Job) obj; + return Objects.equals(toPb(), other.toPb()) + && Objects.equals(options, other.options); } @Override - public int hashCode() { + public final int hashCode() { return Objects.hash(super.hashCode(), options); } diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobId.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobId.java index bc81fe11f700..d2981151481f 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobId.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobId.java @@ -26,7 +26,7 @@ /** * Google BigQuery Job identity. */ -public class JobId implements Serializable { +public final class JobId implements Serializable { private static final long serialVersionUID = 1225914835379688976L; @@ -68,7 +68,9 @@ public static JobId of(String job) { @Override public boolean equals(Object obj) { - return obj instanceof JobId && Objects.equals(toPb(), ((JobId) obj).toPb()); + return obj == this + || obj instanceof JobId + && Objects.equals(toPb(), ((JobId) obj).toPb()); } @Override diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobInfo.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobInfo.java index 500eaabcaf17..13addc9d6e7a 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobInfo.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobInfo.java @@ -319,7 +319,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj != null + return obj == this + || obj != null && obj.getClass().equals(JobInfo.class) && Objects.equals(toPb(), ((JobInfo) obj).toPb()); } diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobStatistics.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobStatistics.java index 58ae9045e7cc..90ad164a7ce5 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobStatistics.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobStatistics.java @@ -14,7 +14,7 @@ /** * A Google BigQuery Job statistics. */ -public class JobStatistics implements Serializable { +public abstract class JobStatistics implements Serializable { private static final long serialVersionUID = 1433024714741660399L; @@ -22,6 +22,55 @@ public class JobStatistics implements Serializable { private final Long endTime; private final Long startTime; + /** + * A Google BigQuery Copy Job statistics. + */ + public static class CopyStatistics extends JobStatistics { + + private static final long serialVersionUID = 8218325588441660938L; + + static final class Builder extends JobStatistics.Builder { + + private Builder() {} + + private Builder(com.google.api.services.bigquery.model.JobStatistics statisticsPb) { + super(statisticsPb); + } + + @Override + CopyStatistics build() { + return new CopyStatistics(this); + } + } + + private CopyStatistics(Builder builder) { + super(builder); + } + + @Override + public final boolean equals(Object obj) { + return obj == this + || obj != null + && obj.getClass().equals(CopyStatistics.class) + && baseEquals((CopyStatistics) obj); + } + + @Override + public final int hashCode() { + return baseHashCode(); + } + + static Builder builder() { + return new Builder(); + } + + @SuppressWarnings("unchecked") + static CopyStatistics fromPb( + com.google.api.services.bigquery.model.JobStatistics statisticPb) { + return new Builder(statisticPb).build(); + } + } + /** * A Google BigQuery Extract Job statistics. */ @@ -73,14 +122,16 @@ ToStringHelper toStringHelper() { } @Override - public boolean equals(Object obj) { - return obj instanceof ExtractStatistics - && Objects.equals(toPb(), ((ExtractStatistics) obj).toPb()); + public final boolean equals(Object obj) { + return obj == this + || obj != null + && obj.getClass().equals(ExtractStatistics.class) + && baseEquals((ExtractStatistics) obj); } @Override - public int hashCode() { - return Objects.hash(super.hashCode(), destinationUriFileCounts); + public final int hashCode() { + return Objects.hash(baseHashCode(), destinationUriFileCounts); } @Override @@ -203,13 +254,16 @@ ToStringHelper toStringHelper() { } @Override - public boolean equals(Object obj) { - return obj instanceof LoadStatistics && Objects.equals(toPb(), ((LoadStatistics) obj).toPb()); + public final boolean equals(Object obj) { + return obj == this + || obj != null + && obj.getClass().equals(LoadStatistics.class) + && baseEquals((LoadStatistics) obj); } @Override - public int hashCode() { - return Objects.hash(super.hashCode(), inputBytes, inputFiles, outputBytes, outputRows); + public final int hashCode() { + return Objects.hash(baseHashCode(), inputBytes, inputFiles, outputBytes, outputRows); } @Override @@ -361,14 +415,16 @@ ToStringHelper toStringHelper() { } @Override - public boolean equals(Object obj) { - return obj instanceof QueryStatistics - && Objects.equals(toPb(), ((QueryStatistics) obj).toPb()); + public final boolean equals(Object obj) { + return obj == this + || obj != null + && obj.getClass().equals(QueryStatistics.class) + && baseEquals((QueryStatistics) obj); } @Override - public int hashCode() { - return Objects.hash(super.hashCode(), billingTier, cacheHit, totalBytesBilled, + public final int hashCode() { + return Objects.hash(baseHashCode(), billingTier, cacheHit, totalBytesBilled, totalBytesProcessed, queryPlan); } @@ -396,7 +452,7 @@ static QueryStatistics fromPb( } } - static class Builder> { + abstract static class Builder> { private Long creationTime; private Long endTime; @@ -430,10 +486,7 @@ B startTime(Long startTime) { return self(); } - @SuppressWarnings("unchecked") - T build() { - return (T) new JobStatistics(this); - } + abstract T build(); } protected JobStatistics(Builder builder) { @@ -477,14 +530,12 @@ public String toString() { return toStringHelper().toString(); } - @Override - public int hashCode() { + final int baseHashCode() { return Objects.hash(creationTime, endTime, startTime); } - @Override - public boolean equals(Object obj) { - return obj instanceof JobStatistics && Objects.equals(toPb(), ((JobStatistics) obj).toPb()); + final boolean baseEquals(JobStatistics jobStatistics) { + return Objects.equals(toPb(), jobStatistics.toPb()); } com.google.api.services.bigquery.model.JobStatistics toPb() { @@ -496,10 +547,6 @@ com.google.api.services.bigquery.model.JobStatistics toPb() { return statistics; } - static Builder builder() { - return new Builder(); - } - @SuppressWarnings("unchecked") static T fromPb( com.google.api.services.bigquery.model.JobStatistics statisticPb) { @@ -510,7 +557,7 @@ static T fromPb( } else if (statisticPb.getQuery() != null) { return (T) QueryStatistics.fromPb(statisticPb); } else { - return (T) new Builder(statisticPb).build(); + return (T) CopyStatistics.fromPb(statisticPb); } } } diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobStatus.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobStatus.java index 8d8da43e00de..7c948e6373f9 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobStatus.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/JobStatus.java @@ -94,13 +94,16 @@ public String toString() { } @Override - public int hashCode() { + public final int hashCode() { return Objects.hash(state, error, executionErrors); } @Override - public boolean equals(Object obj) { - return obj instanceof JobStatus && Objects.equals(toPb(), ((JobStatus) obj).toPb()); + public final boolean equals(Object obj) { + return obj == this + || obj != null + && obj.getClass().equals(JobStatus.class) + && Objects.equals(toPb(), ((JobStatus) obj).toPb()); } com.google.api.services.bigquery.model.JobStatus toPb() { diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/LoadJobConfiguration.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/LoadJobConfiguration.java index a4abbce89137..03e2d7fea05e 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/LoadJobConfiguration.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/LoadJobConfiguration.java @@ -269,7 +269,9 @@ ToStringHelper toStringHelper() { @Override public boolean equals(Object obj) { - return obj instanceof LoadJobConfiguration && baseEquals((LoadJobConfiguration) obj); + return obj == this + || obj instanceof LoadJobConfiguration + && baseEquals((LoadJobConfiguration) obj); } @Override diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryJobConfiguration.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryJobConfiguration.java index 4c5034a4a0c8..73b1403245c7 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryJobConfiguration.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryJobConfiguration.java @@ -39,6 +39,19 @@ public final class QueryJobConfiguration extends JobConfiguration { private static final long serialVersionUID = -1108948249081804890L; + private final String query; + private final TableId destinationTable; + private final Map tableDefinitions; + private final List userDefinedFunctions; + private final CreateDisposition createDisposition; + private final WriteDisposition writeDisposition; + private final DatasetId defaultDataset; + private final Priority priority; + private final Boolean allowLargeResults; + private final Boolean useQueryCache; + private final Boolean flattenResults; + private final Boolean dryRun; + /** * Priority levels for a query. If not specified the priority is assumed to be * {@link Priority#INTERACTIVE}. @@ -59,19 +72,6 @@ public enum Priority { BATCH } - private final String query; - private final TableId destinationTable; - private final Map tableDefinitions; - private final List userDefinedFunctions; - private final CreateDisposition createDisposition; - private final WriteDisposition writeDisposition; - private final DatasetId defaultDataset; - private final Priority priority; - private final Boolean allowLargeResults; - private final Boolean useQueryCache; - private final Boolean flattenResults; - private final Boolean dryRun; - public static final class Builder extends JobConfiguration.Builder { @@ -450,7 +450,9 @@ ToStringHelper toStringHelper() { @Override public boolean equals(Object obj) { - return obj instanceof QueryJobConfiguration && baseEquals((QueryJobConfiguration) obj); + return obj == this + || obj instanceof QueryJobConfiguration + && baseEquals((QueryJobConfiguration) obj); } @Override diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryRequest.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryRequest.java index 8cd3530f9227..166e0db9a18d 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryRequest.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryRequest.java @@ -60,7 +60,7 @@ * @see Query * @see Query Reference */ -public class QueryRequest implements Serializable { +public final class QueryRequest implements Serializable { private static final long serialVersionUID = -8727328332415880852L; @@ -250,7 +250,9 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof QueryRequest && Objects.equals(toPb(), ((QueryRequest) obj).toPb()); + return obj == this + || obj instanceof QueryRequest + && Objects.equals(toPb(), ((QueryRequest) obj).toPb()); } QueryRequest setProjectId(String projectId) { diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryResponse.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryResponse.java index ceb1099d4faf..57a8966b0301 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryResponse.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryResponse.java @@ -170,16 +170,16 @@ public String toString() { } @Override - public int hashCode() { + public final int hashCode() { return Objects.hash(jobId); } @Override - public boolean equals(Object obj) { - if (this == obj) { + public final boolean equals(Object obj) { + if (obj == this) { return true; } - if (obj == null || getClass() != obj.getClass()) { + if (obj == null || !obj.getClass().equals(QueryResponse.class)) { return false; } QueryResponse response = (QueryResponse) obj; diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryResult.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryResult.java index 74a9e5000b0e..ba036187307c 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryResult.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryResult.java @@ -149,16 +149,16 @@ public String toString() { } @Override - public int hashCode() { + public final int hashCode() { return Objects.hash(super.hashCode(), cacheHit, schema, totalBytesProcessed, totalRows); } @Override - public boolean equals(Object obj) { - if (this == obj) { + public final boolean equals(Object obj) { + if (obj == this) { return true; } - if (obj == null || getClass() != obj.getClass()) { + if (obj == null || !obj.getClass().equals(QueryResult.class)) { return false; } QueryResult response = (QueryResult) obj; diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryStage.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryStage.java index b9cfb804b1ac..7276a86e7eeb 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryStage.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/QueryStage.java @@ -372,15 +372,18 @@ public String toString() { } @Override - public int hashCode() { + public final int hashCode() { return Objects.hash(computeRatioAvg, computeRatioMax, generatedId, name, readRatioAvg, readRatioMax, recordsRead, recordsWritten, steps, waitRatioAvg, waitRatioMax, writeRatioAvg); } @Override - public boolean equals(Object obj) { - if (!(obj instanceof QueryStage)) { + public final boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null || !obj.getClass().equals(QueryStage.class)) { return false; } QueryStage other = (QueryStage) obj; diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Schema.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Schema.java index 88114d47ae6c..218c2a214e50 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Schema.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Schema.java @@ -31,7 +31,7 @@ /** * This class represents the schema for a Google BigQuery Table or data source. */ -public class Schema implements Serializable { +public final class Schema implements Serializable { static final Function FROM_PB_FUNCTION = new Function */ -public final class Table extends TableInfo { +public class Table extends TableInfo { private static final long serialVersionUID = 5744556727066570096L; @@ -322,14 +322,20 @@ public Builder toBuilder() { } @Override - public boolean equals(Object obj) { - return obj instanceof Table - && Objects.equals(toPb(), ((Table) obj).toPb()) - && Objects.equals(options, ((Table) obj).options); + public final boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null || !obj.getClass().equals(Table.class)) { + return false; + } + Table other = (Table) obj; + return Objects.equals(toPb(), other.toPb()) + && Objects.equals(options, other.options); } @Override - public int hashCode() { + public final int hashCode() { return Objects.hash(super.hashCode(), options); } diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableId.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableId.java index cee20332db9e..95768a59b5d2 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableId.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableId.java @@ -27,7 +27,7 @@ /** * Google BigQuery Table identity. */ -public class TableId implements Serializable { +public final class TableId implements Serializable { static final Function FROM_PB_FUNCTION = new Function() { @@ -92,7 +92,9 @@ public static TableId of(String dataset, String table) { @Override public boolean equals(Object obj) { - return obj instanceof TableId && Objects.equals(toPb(), ((TableId) obj).toPb()); + return obj == this + || obj instanceof TableId + && Objects.equals(toPb(), ((TableId) obj).toPb()); } @Override diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableInfo.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableInfo.java index 2c6083eaea75..c27b0dfdf1e5 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableInfo.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableInfo.java @@ -339,7 +339,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj != null + return obj == this + || obj != null && obj.getClass().equals(TableInfo.class) && Objects.equals(toPb(), ((TableInfo) obj).toPb()); } diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/ViewDefinition.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/ViewDefinition.java index 89ca9674508e..1d3a97ba616d 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/ViewDefinition.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/ViewDefinition.java @@ -33,7 +33,7 @@ * * @see Views */ -public final class ViewDefinition extends TableDefinition { +public class ViewDefinition extends TableDefinition { private static final long serialVersionUID = -8789311196910794545L; @@ -146,12 +146,15 @@ ToStringHelper toStringHelper() { } @Override - public boolean equals(Object obj) { - return obj instanceof ViewDefinition && baseEquals((ViewDefinition) obj); + public final boolean equals(Object obj) { + return obj == this + || obj != null + && obj.getClass().equals(ViewDefinition.class) + && baseEquals((ViewDefinition) obj); } @Override - public int hashCode() { + public final int hashCode() { return Objects.hash(baseHashCode(), query, userDefinedFunctions); } diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/WriteChannelConfiguration.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/WriteChannelConfiguration.java index b7bb9db277a3..898063e7e0ed 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/WriteChannelConfiguration.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/WriteChannelConfiguration.java @@ -33,7 +33,7 @@ * into a table with a {@link com.google.cloud.WriteChannel} * ({@link BigQuery#writer(WriteChannelConfiguration)}). */ -public class WriteChannelConfiguration implements LoadConfiguration, Serializable { +public final class WriteChannelConfiguration implements LoadConfiguration, Serializable { private static final long serialVersionUID = 470267591917413578L; @@ -241,7 +241,8 @@ public String toString() { @Override public boolean equals(Object obj) { - return obj instanceof WriteChannelConfiguration + return obj == this + || obj instanceof WriteChannelConfiguration && Objects.equals(toPb(), ((WriteChannelConfiguration) obj).toPb()); } diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobInfoTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobInfoTest.java index e6cd2987fbd7..d7fde0957a2f 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobInfoTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobInfoTest.java @@ -23,6 +23,7 @@ import com.google.cloud.bigquery.JobInfo.CreateDisposition; import com.google.cloud.bigquery.JobInfo.WriteDisposition; +import com.google.cloud.bigquery.JobStatistics.CopyStatistics; import com.google.cloud.bigquery.JobStatistics.ExtractStatistics; import com.google.cloud.bigquery.JobStatistics.LoadStatistics; import com.google.cloud.bigquery.JobStatistics.QueryStatistics; @@ -42,7 +43,7 @@ public class JobInfoTest { private static final String EMAIL = "email"; private static final JobId JOB_ID = JobId.of("job"); private static final JobStatus JOB_STATUS = new JobStatus(JobStatus.State.DONE); - private static final JobStatistics COPY_JOB_STATISTICS = JobStatistics.builder() + private static final CopyStatistics COPY_JOB_STATISTICS = CopyStatistics.builder() .creationTime(1L) .endTime(3L) .startTime(2L) diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobStatisticsTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobStatisticsTest.java index 9fbe43f3903f..c4c8c5ae6f4b 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobStatisticsTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobStatisticsTest.java @@ -18,11 +18,12 @@ import static org.junit.Assert.assertEquals; +import com.google.common.collect.ImmutableList; +import com.google.cloud.bigquery.JobStatistics.CopyStatistics; import com.google.cloud.bigquery.JobStatistics.ExtractStatistics; import com.google.cloud.bigquery.JobStatistics.LoadStatistics; import com.google.cloud.bigquery.JobStatistics.QueryStatistics; import com.google.cloud.bigquery.QueryStage.QueryStep; -import com.google.common.collect.ImmutableList; import org.junit.Test; @@ -42,6 +43,11 @@ public class JobStatisticsTest { private static final Long CREATION_TIME = 10L; private static final Long END_TIME = 20L; private static final Long START_TIME = 15L; + private static final CopyStatistics COPY_STATISTICS = CopyStatistics.builder() + .creationTime(CREATION_TIME) + .endTime(END_TIME) + .startTime(START_TIME) + .build(); private static final ExtractStatistics EXTRACT_STATISTICS = ExtractStatistics.builder() .creationTime(CREATION_TIME) .endTime(END_TIME) @@ -101,17 +107,12 @@ public class JobStatisticsTest { .billingTier(BILLING_TIER) .cacheHit(CACHE_HIT) .build(); - private static final JobStatistics STATISTICS = JobStatistics.builder() - .creationTime(CREATION_TIME) - .endTime(END_TIME) - .startTime(START_TIME) - .build(); @Test public void testBuilder() { - assertEquals(CREATION_TIME, STATISTICS.creationTime()); - assertEquals(START_TIME, STATISTICS.startTime()); - assertEquals(END_TIME, STATISTICS.endTime()); + assertEquals(CREATION_TIME, COPY_STATISTICS.creationTime()); + assertEquals(START_TIME, COPY_STATISTICS.startTime()); + assertEquals(END_TIME, COPY_STATISTICS.endTime()); assertEquals(CREATION_TIME, EXTRACT_STATISTICS.creationTime()); assertEquals(START_TIME, EXTRACT_STATISTICS.startTime()); @@ -160,7 +161,7 @@ public void testToPbAndFromPb() { ExtractStatistics.fromPb(EXTRACT_STATISTICS.toPb())); compareLoadStatistics(LOAD_STATISTICS, LoadStatistics.fromPb(LOAD_STATISTICS.toPb())); compareQueryStatistics(QUERY_STATISTICS, QueryStatistics.fromPb(QUERY_STATISTICS.toPb())); - compareStatistics(STATISTICS, JobStatistics.fromPb(STATISTICS.toPb())); + compareStatistics(COPY_STATISTICS, JobStatistics.fromPb(COPY_STATISTICS.toPb())); compareLoadStatistics(LOAD_STATISTICS_INCOMPLETE, LoadStatistics.fromPb(LOAD_STATISTICS_INCOMPLETE.toPb())); diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobTest.java index b2a2461f1267..44e5e201e95c 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobTest.java @@ -27,6 +27,8 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import com.google.cloud.bigquery.JobStatistics.CopyStatistics; + import org.junit.After; import org.junit.Test; @@ -40,7 +42,7 @@ public class JobTest { private static final String SELF_LINK = "selfLink"; private static final String EMAIL = "email"; private static final JobStatus JOB_STATUS = new JobStatus(JobStatus.State.DONE); - private static final JobStatistics COPY_JOB_STATISTICS = JobStatistics.builder() + private static final JobStatistics COPY_JOB_STATISTICS = CopyStatistics.builder() .creationTime(1L) .endTime(3L) .startTime(2L) diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/SerializationTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/SerializationTest.java index 7aabcea120e9..30b1b9e067ec 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/SerializationTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/SerializationTest.java @@ -122,11 +122,12 @@ public class SerializationTest extends BaseSerializationTest { .etag(ETAG) .generatedId(GENERATED_ID) .build(); - private static final JobStatistics JOB_STATISTICS = JobStatistics.builder() - .creationTime(1L) - .endTime(3L) - .startTime(2L) - .build(); + private static final JobStatistics.CopyStatistics COPY_STATISTICS = + JobStatistics.CopyStatistics.builder() + .creationTime(1L) + .endTime(3L) + .startTime(2L) + .build(); private static final JobStatistics.ExtractStatistics EXTRACT_STATISTICS = JobStatistics.ExtractStatistics.builder() .creationTime(1L) @@ -235,7 +236,7 @@ protected Serializable[] serializableObjects() { return new Serializable[]{DOMAIN_ACCESS, GROUP_ACCESS, USER_ACCESS, VIEW_ACCESS, DATASET_ID, DATASET_INFO, TABLE_ID, CSV_OPTIONS, STREAMING_BUFFER, TABLE_DEFINITION, EXTERNAL_TABLE_DEFINITION, VIEW_DEFINITION, TABLE_SCHEMA, TABLE_INFO, VIEW_INFO, - EXTERNAL_TABLE_INFO, INLINE_FUNCTION, URI_FUNCTION, JOB_STATISTICS, EXTRACT_STATISTICS, + EXTERNAL_TABLE_INFO, INLINE_FUNCTION, URI_FUNCTION, COPY_STATISTICS, EXTRACT_STATISTICS, LOAD_STATISTICS, QUERY_STATISTICS, BIGQUERY_ERROR, JOB_STATUS, JOB_ID, COPY_JOB_CONFIGURATION, EXTRACT_JOB_CONFIGURATION, LOAD_CONFIGURATION, LOAD_JOB_CONFIGURATION, QUERY_JOB_CONFIGURATION, JOB_INFO, INSERT_ALL_REQUEST, diff --git a/gcloud-java-core/src/main/java/com/google/cloud/IamPolicy.java b/gcloud-java-core/src/main/java/com/google/cloud/IamPolicy.java index 1f214e1b0f71..2d15d9907687 100644 --- a/gcloud-java-core/src/main/java/com/google/cloud/IamPolicy.java +++ b/gcloud-java-core/src/main/java/com/google/cloud/IamPolicy.java @@ -219,7 +219,10 @@ public final int hashCode() { @Override public final boolean equals(Object obj) { - if (obj == null || !getClass().equals(obj.getClass())) { + if (obj == this) { + return true; + } + if (obj == null || !obj.getClass().equals(getClass())) { return false; } @SuppressWarnings("rawtypes") diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/ChangeRequest.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/ChangeRequest.java index 61864e968ebb..3538a5c411e9 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/ChangeRequest.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/ChangeRequest.java @@ -192,19 +192,21 @@ public Builder toBuilder() { } @Override - public boolean equals(Object obj) { + public final boolean equals(Object obj) { + if (obj == this) { + return true; + } if (obj == null || !obj.getClass().equals(ChangeRequest.class)) { return false; - } else { - ChangeRequest other = (ChangeRequest) obj; - return Objects.equals(options, other.options) - && Objects.equals(zone, other.zone) - && Objects.equals(toPb(), other.toPb()); } + ChangeRequest other = (ChangeRequest) obj; + return Objects.equals(toPb(), other.toPb()) + && Objects.equals(options, other.options) + && Objects.equals(zone, other.zone); } @Override - public int hashCode() { + public final int hashCode() { return Objects.hash(super.hashCode(), options, zone); } diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/ChangeRequestInfo.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/ChangeRequestInfo.java index 53bce6cf1380..8ed68765a163 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/ChangeRequestInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/ChangeRequestInfo.java @@ -335,9 +335,11 @@ static ChangeRequestInfo fromPb(Change pb) { } @Override - public boolean equals(Object other) { - return other != null && other.getClass().equals(ChangeRequestInfo.class) - && other instanceof ChangeRequestInfo && toPb().equals(((ChangeRequestInfo) other).toPb()); + public boolean equals(Object obj) { + return obj == this + || obj != null + && obj.getClass().equals(ChangeRequestInfo.class) + && toPb().equals(((ChangeRequestInfo) obj).toPb()); } @Override diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/ProjectInfo.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/ProjectInfo.java index 3d0d4704e6c0..bc35bacc317d 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/ProjectInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/ProjectInfo.java @@ -268,12 +268,15 @@ static ProjectInfo fromPb(Project pb) { } @Override - public boolean equals(Object other) { - return (other instanceof ProjectInfo) && toPb().equals(((ProjectInfo) other).toPb()); + public final boolean equals(Object obj) { + return obj == this + || obj != null + && obj.getClass().equals(ProjectInfo.class) + && toPb().equals(((ProjectInfo) obj).toPb()); } @Override - public int hashCode() { + public final int hashCode() { return Objects.hash(id, number, quota); } diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/RecordSet.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/RecordSet.java index a8323041a2fb..5e061b5164e8 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/RecordSet.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/RecordSet.java @@ -43,7 +43,7 @@ * @see Google Cloud DNS * documentation */ -public class RecordSet implements Serializable { +public final class RecordSet implements Serializable { static final Function FROM_PB_FUNCTION = new Function() { @@ -282,7 +282,9 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof RecordSet && Objects.equals(this.toPb(), ((RecordSet) obj).toPb()); + return obj == this + || obj instanceof RecordSet + && Objects.equals(this.toPb(), ((RecordSet) obj).toPb()); } ResourceRecordSet toPb() { diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/Zone.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/Zone.java index 8c21d79a992f..a01f7212d28e 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/Zone.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/Zone.java @@ -196,13 +196,20 @@ public Dns dns() { } @Override - public boolean equals(Object obj) { - return obj instanceof Zone && Objects.equals(toPb(), ((Zone) obj).toPb()) - && Objects.equals(options, ((Zone) obj).options); + public final boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null || !obj.getClass().equals(Zone.class)) { + return false; + } + Zone other = (Zone) obj; + return Objects.equals(toPb(), other.toPb()) + && Objects.equals(options, other.options); } @Override - public int hashCode() { + public final int hashCode() { return Objects.hash(super.hashCode(), options); } diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/ZoneInfo.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/ZoneInfo.java index 2b8c79e7fe5c..d6178479b68b 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/ZoneInfo.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/ZoneInfo.java @@ -293,7 +293,9 @@ static ZoneInfo fromPb(ManagedZone pb) { @Override public boolean equals(Object obj) { - return obj != null && obj.getClass().equals(ZoneInfo.class) + return obj == this + || obj != null + && obj.getClass().equals(ZoneInfo.class) && Objects.equals(toPb(), ((ZoneInfo) obj).toPb()); } diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Policy.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Policy.java index 41238fd9b9aa..f22b13e96268 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Policy.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Policy.java @@ -40,7 +40,7 @@ * * @see Policy */ -public class Policy extends IamPolicy { +public final class Policy extends IamPolicy { private static final long serialVersionUID = -5573557282693961850L; diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Project.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Project.java index 25cda85d1c09..d728ec3ea4df 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Project.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Project.java @@ -257,13 +257,20 @@ public Builder toBuilder() { } @Override - public boolean equals(Object obj) { - return obj instanceof Project && Objects.equals(toPb(), ((Project) obj).toPb()) - && Objects.equals(options, ((Project) obj).options); + public final boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null || !obj.getClass().equals(Project.class)) { + return false; + } + Project other = (Project) obj; + return Objects.equals(toPb(), other.toPb()) + && Objects.equals(options, other.options); } @Override - public int hashCode() { + public final int hashCode() { return Objects.hash(super.hashCode(), options); } diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ProjectInfo.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ProjectInfo.java index 355236b653f1..762ad3db050f 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ProjectInfo.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ProjectInfo.java @@ -336,7 +336,9 @@ public Long createTimeMillis() { @Override public boolean equals(Object obj) { - return obj != null && obj.getClass().equals(ProjectInfo.class) + return obj == this + || obj != null + && obj.getClass().equals(ProjectInfo.class) && Objects.equals(toPb(), ((ProjectInfo) obj).toPb()); } diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BatchResponse.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BatchResponse.java index d07d9dc26c2d..d1e56758b9d2 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BatchResponse.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BatchResponse.java @@ -26,7 +26,7 @@ /** * Google Storage batch response. */ -public final class BatchResponse implements Serializable { +public class BatchResponse implements Serializable { private static final long serialVersionUID = 1057416839397037706L; @@ -121,13 +121,16 @@ static Result empty() { } @Override - public int hashCode() { + public final int hashCode() { return Objects.hash(deleteResult, updateResult, getResult); } @Override - public boolean equals(Object obj) { - if (!(obj instanceof BatchResponse)) { + public final boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null || !obj.getClass().equals(BatchResponse.class)) { return false; } BatchResponse other = (BatchResponse) obj; diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/Blob.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Blob.java index 1adea4f549bd..9b74b686d8f9 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/Blob.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Blob.java @@ -526,10 +526,15 @@ public Builder toBuilder() { @Override public final boolean equals(Object obj) { - return this == obj - || obj instanceof Blob - && Objects.equals(toPb(), ((Blob) obj).toPb()) - && Objects.equals(options, ((Blob) obj).options); + if (obj == this) { + return true; + } + if (obj == null || !obj.getClass().equals(Blob.class)) { + return false; + } + Blob other = (Blob) obj; + return Objects.equals(toPb(), other.toPb()) + && Objects.equals(options, other.options); } @Override diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobId.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobId.java index 52e7fc5f331e..88664e191f84 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobId.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobId.java @@ -79,9 +79,16 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof BlobId && Objects.equals(bucket, ((BlobId) obj).bucket) - && Objects.equals(name, ((BlobId) obj).name) - && Objects.equals(generation, ((BlobId) obj).generation); + if (obj == this) { + return true; + } + if (obj == null || !obj.getClass().equals(BlobId.class)) { + return false; + } + BlobId other = (BlobId) obj; + return Objects.equals(bucket, other.bucket) + && Objects.equals(name, other.name) + && Objects.equals(generation, other.generation); } StorageObject toPb() { diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobInfo.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobInfo.java index dd264fa7f92b..f7d21b09a8ee 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobInfo.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobInfo.java @@ -638,7 +638,9 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj != null && obj.getClass().equals(BlobInfo.class) + return obj == this + || obj != null + && obj.getClass().equals(BlobInfo.class) && Objects.equals(toPb(), ((BlobInfo) obj).toPb()); } diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/Bucket.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Bucket.java index 989ea87ec9d3..9f5a2e2499a0 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/Bucket.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Bucket.java @@ -49,7 +49,7 @@ * {@link BucketInfo}. *

    */ -public final class Bucket extends BucketInfo { +public class Bucket extends BucketInfo { private static final long serialVersionUID = 8574601739542252586L; @@ -714,13 +714,20 @@ public Builder toBuilder() { } @Override - public boolean equals(Object obj) { - return obj instanceof Bucket && Objects.equals(toPb(), ((Bucket) obj).toPb()) - && Objects.equals(options, ((Bucket) obj).options); + public final boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj != null && !obj.getClass().equals(Bucket.class)) { + return false; + } + Bucket other = (Bucket) obj; + return Objects.equals(toPb(), other.toPb()) + && Objects.equals(options, other.options); } @Override - public int hashCode() { + public final int hashCode() { return Objects.hash(super.hashCode(), options); } diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BucketInfo.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BucketInfo.java index 1dcd110808a9..36e0ed54ffa0 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BucketInfo.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BucketInfo.java @@ -719,7 +719,9 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj != null && obj.getClass().equals(BucketInfo.class) + return obj == this + || obj != null + && obj.getClass().equals(BucketInfo.class) && Objects.equals(toPb(), ((BucketInfo) obj).toPb()); } From 527c656bcb783a8d05dbfbd4f36d743dc8e7cc14 Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Thu, 14 Apr 2016 19:39:22 -0400 Subject: [PATCH 259/375] Added DNS helper to testing documentation. (#926) Added DNS to testing documentation. --- TESTING.md | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/TESTING.md b/TESTING.md index aecd6140b79f..7ae34db4c4f1 100644 --- a/TESTING.md +++ b/TESTING.md @@ -54,6 +54,40 @@ We recommend that you start the emulator on the remote machine using the [Google gcloud beta emulators datastore start --host-port : ``` +### Testing code that uses DNS + +#### On your machine + +You can test against an in-memory local DNS by following these steps: + +1. Before running your testing code, start the DNS emulator `LocalDnsHelper`. This can be done as follows: + + ```java + long delay = 0; + LocalDnsHelper helper = LocalDnsHelper.create(delay); + helper.start(); + ``` + + This will spawn a server thread that listens to `localhost` at an ephemeral port for DNS requests. + The `delay` parameter determines if change requests should be processed synchronously + (value `0`) or in a separate thread with a minimum of delay of `delay` milliseconds. + +2. In your program, create the DNS service by using the helper's `options()` method. For example: + + ```java + Dns dns = LocalDnsHelper.options().service(); + ``` + +3. Run your tests. + +4. Stop the DNS emulator. + + ```java + helper.stop(); + ``` + + This method will block until the server thread has been terminated. + ### Testing code that uses Storage Currently, there isn't an emulator for Google Cloud Storage, so an alternative is to create a test project. `RemoteStorageHelper` contains convenience methods to make setting up and cleaning up the test project easier. To use this class, follow the steps below: @@ -84,7 +118,7 @@ Here is an example that clears the bucket created in Step 3 with a timeout of 5 #### On your machine -You can test against a temporary local Resource Manager by following these steps: +You can test against an in-memory local Resource Manager by following these steps: 1. Before running your testing code, start the Resource Manager emulator `LocalResourceManagerHelper`. This can be done as follows: From 8b766e6241587467387957d59ff4ec0bd64116fe Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Fri, 15 Apr 2016 15:07:34 -0700 Subject: [PATCH 260/375] Documentation on supporting new services (#923) Documentation on how to add a new client library --- CONTRIBUTING.md | 9 ++- SUPPORTING_NEW_SERVICES.md | 114 +++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 3 deletions(-) create mode 100644 SUPPORTING_NEW_SERVICES.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3d93f2d032c7..3ed827deb5af 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,9 +2,9 @@ Contributing ============ 1. **Please sign one of the contributor license agreements below.** -1. Fork the repo, develop and test your code changes, add docs. -1. Make sure that your commit messages clearly describe the changes. -1. Send a pull request. +2. Fork the repo, develop and test your code changes, add docs. +3. Make sure that your commit messages clearly describe the changes. +4. Send a pull request. Here are some guidelines for hacking on gcloud-java. @@ -43,6 +43,9 @@ The feature must work fully on Java 7 and above. The feature must not add unnecessary dependencies (where "unnecessary" is of course subjective, but new dependencies should be discussed). +Adding Support for a New Service +-------------------------------- +See [SUPPORTING_NEW_SERVICES](./SUPPORTING_NEW_SERVICES.md) for guidelines on how to add support for a new Google Cloud service to `gcloud-java`. Coding Style ------------ diff --git a/SUPPORTING_NEW_SERVICES.md b/SUPPORTING_NEW_SERVICES.md new file mode 100644 index 000000000000..7eba222336de --- /dev/null +++ b/SUPPORTING_NEW_SERVICES.md @@ -0,0 +1,114 @@ +## Supporting New Services + +### Overview + +This document outlines how to add support for a new service in `gcloud-java`. New services should be submodules located in a folder within the main repository, built using Maven. A new service should contain the following items: + +* An API layer, with which users will interact. This includes model objects and a service class. +* An SPI layer, which translates gcloud-java API calls into RPCs using an autogenerated client library. In almost all use cases, the user will not directly interact with this code. Separating this code from the API layer provides two benefits. First, it allows the API layer to remain stable despite changes to the autogenerated libraries used. Second, it makes testing easier, since the RPC implementation can be substituted with a mock. +* A test helper class, which allows users to easily interact with a local service emulator (if possible). If there is no emulator available and the service is too complex to create a mock, then a remote test helper should be provided to separate test data from other user data and enable easy cleanup. +* Tests, including unit tests and integration tests. +* A command line example application. +* Documentation, which is comprised of READMEs, Javadoc, and code snippets. + +### Components of a new service + +#### API layer + +Before starting work on the API layer, write a design document and provide sample API code. Sample API code should either be included in the design document or as a pull request tagged with the "don't merge" label. As part of the design process, be sure to examine the Google Cloud service API and any implementations provided in other gcloud-* language libraries. Solicit feedback from other contributors to the repository. `gcloud-java` services should be low-level while minimizing boilerplate code needed by API users. They should also be flexible enough to be used by higher-level libraries. For example, [Objectify](https://github.com/objectify/objectify) should be able to use `gcloud-java-datastore`. + +The library should contain: +* A subclass of the [`ServiceOptions`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-core/src/main/java/com/google/cloud/ServiceOptions.java) class. The `ServiceOptions` class contains important information for communicating with the Google Cloud service, such as the project ID, authentication, and retry handling. Subclasses should add/override relevant methods as necessary. Example: [`DatastoreOptions`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java). +* An interface extending the [`Service`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-core/src/main/java/com/google/cloud/Service.java) interface (example: [`Datastore`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Datastore.java)) and an implentation of that interface (example: [`DatastoreImpl`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java)). +* An interface extending the [`ServiceFactory`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-core/src/main/java/com/google/cloud/ServiceFactory.java) interface. Example: [`DatastoreFactory`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreFactory.java) +* A runtime exception class that extends [`BaseServiceException`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-core/src/main/java/com/google/cloud/BaseServiceException.java), which is used to wrap service-related exceptions. Example: [`DatastoreException`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreException.java) +* Classes representing model objects and request-related options. Model objects that correspond to service resources should have a subclass that provides functions related to that resource. For example, see [`BlobInfo`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobInfo.java) (the metadata class) and [`Blob`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-storage/src/main/java/com/google/cloud/storage/Blob.java) (the functional class). The builders for both objects should implement a common interface or abstract class, and the functional subclass builder should delegate to the metadata class builder. +* Request-related options classes. Operations should accept these options as varargs when appropriate. Supplying options as varargs allows for supporting more advanced use cases without affecting the method signature. The options classes should provide static methods to create instances with specific options settings. A common option is to request that only specific fields of a model object should be included in a response. Typically such an option is created via a `fields(...)` method which accepts a vararg of type `Field` enum. The enum should implement the [FieldSelector](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-core/src/main/java/com/google/cloud/FieldSelector.java) interface. + +In general, make classes immutable whenever possible, providing builders as necessary. Make model object classes `java.util.Serializable`. Prefer making classes final, with the following exceptions: (1) functional objects and (2) classes in which the user cannot set all attributes. If a class cannot be made final, then `hashCode` or `equals` overrides should be made final if possible. + +`gcloud-java-core` provides functionality for code patterns used across `gcloud-java` libraries. The following are some important core concepts: +* Paging: Google Cloud services often expose page-based listing using page tokens. The [`Page`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-core/src/main/java/com/google/cloud/Page.java) interface should be used for page-based listing. A `Page` contains an iterator over results in that page, as well as methods to get the next page and all results in future pages. `Page` requires a `NextPageFetcher` implementation (see the `NextPageFetcher` interface in [`PageImpl`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-core/src/main/java/com/google/cloud/PageImpl.java)). This implementation should delegate constructing request options to the `nextRequestOptions` method in `PageImpl`. + +* Exception handling: we have the notion of retryable versus non-retryable operations. These are encapsulated by `BaseServiceException`. Retryable error codes should be listed in the service's subclass of `BaseServiceException`. An operation should be considered retryable if it makes sense to retry (e.g. if there was a transient service error, not a fundamentally invalid request) and if the operation that triggered the exception is idempotent. Exceptions also contain information regarding whether the service rejected the request, meaning the operation was not applied. The `BaseServiceException` subclass should also provide methods to translate the exceptions given by the underlying autogeneraged client library. The [`ExceptionHandler`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-core/src/main/java/com/google/cloud/ExceptionHandler.java) class intercepts and retries RPC calls when retryable exceptions are encountered. Note that some exceptions are masked in the SPI layer. For example, `get` and `delete` operations often return "404 Not Found" if the resource doesn't exist. Instead of throwing an exception in these cases, we often return `null` for `get` and `false` for `delete`. + +* Batching: The [`BatchResult`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/dns-alpha-batch/gcloud-java-core/src/main/java/com/google/cloud/BatchResult.java) class provides a simple way for users to combine RPC calls for performance enhancement. APIs for services that support batching should implement a batch class that contains methods similar to the methods in the `Service.java` subclass. A batch operation's return type should be a subclass of `BatchResult`. Also provide an SPI-layer class to collect batch requests and submit the batch. A batch instance should be created by the service API, preferably via a method called `batch()`. The batch should be submitted using the batch instance itself, preferably using a method named `submit()`. + +* IAM Policies: If the Google Cloud service supports [IAM](https://cloud.google.com/iam/docs/), you should provide a subclass of [`IamPolicy`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-core/src/main/java/com/google/cloud/IamPolicy.java) in your API. [`Policy`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/Policy.java) can be used to set default access control lists on Google Cloud projects as a whole. However, if users want to set policies on specific resources within a project, they will need to use the subclass you provide in your API. + +Notes/reminders: +* API layer classes should be located in the package `com.google.cloud.servicename`, where "servicename" corresponds to the name of the Google Cloud service. +* Override the `ServiceOptions.defaultRetryParams()` method in your service's options class to align with the Service Level Agreement (SLA) given by the underlying service. See #857 and #860 for context. +* Override the `ServiceOptions.projectIdRequired()` method to return false when the service does not require requests to be associated with a specific project. +* See conventions about overriding the `equals` and `hashCode` methods in the discussion of #892. +* While not all fields for model objects need to be exposed to the user, `gcloud-java` services should get and set all relevant fields when making RPC calls to the Google Cloud service's API. For example, since the `parent` field of Cloud Resource Manager Project objects is in alpha (at the time this was written) and not available to most users, `gcloud-java-resourcemanager` gets and sets the parent when interacting with the Cloud Resource Manager, but does not expose the parent to users. As a result, the user won't accidentally unset the parent when updating a project. +* Be aware of differences in "update" behavior and name update/replace methods accordingly in your API. See #321 for context. +* Do not expose third party libraries in the API. This has been a design choice from the beginning of the project, and all existing `gcloud-java` services adhere to this convention. +* Member variable getters and builder setters should not use the JavaBean get/set prefix style. +* Any service-generated IDs for model objects should be named `generatedId()`. + +#### SPI layer + +The SPI layer classes should be located in the package `com.google.cloud.servicename.spi`. In most cases, the SPI layer should contain at least three classes: +* An RPC factory interface (allows for the implementation to be loaded via the `java.util.ServiceLoader`). +* An RPC interface that contains all RPC methods. +* A default RPC implementation. + +#### Test helpers + +Test helper classes should be located in the package `com.google.cloud.servicename.testing`. The naming convention for test helpers is `[Local|Remote][Service]Helper.java`. For example, the local test helper for `gcloud-java-datastore` is named `LocalDatastoreHelper` and the remote test helper for `gcloud-java-storage` is named `RemoteStorageHelper`. All test helpers should contain public `create` and `options` methods, and local helpers should contain `start` and `stop` methods. See existing test helpers for information on what each of those methods should do. + +There are three types of test helpers: +* When a local emulator is already available, your test helper should launch that emulator and return service options to connect to that local emulator. This enables both users and our own library to run unit tests easily. An example of this type of helper is `LocalDatastoreHelper`. Google Cloud Datastore provides a script that launches a local datastore, so `LocalDatastoreHelper` launches that script in a separate process when the user calls `start()`. + +* When there is no local emulator but the service is simple enough to write an emulator, you should do so. The emulator should listen to a port for requests, process those requests, and send responses back, being as true to the actual service as possible. Dependencies in this mock should be as lightweight as possible. Be sure to document differences between your emulator and the actual service. Examples of this type of test helper are `LocalResourceManagerHelper` and `LocalDnsHelper`. + +* When there is no local emulator and the service is too complex to write a solid emulator, the test helper should contain methods to get options and to help isolate test data from production data. `RemoteStorageHelper` is an example of this type of test helper, since there is no local emulator for Google Cloud Storage (at the time that this was written) and because the Google Cloud Storage API is complex. `RemoteStorageHelper` has methods to: + * Get service options settings. + * Create a test bucket with a sufficiently obscure name (to separate the bucket from any of the users other data). + * Clean up data left over from tests in that test bucket. + +#### Tests + +API-level functionality should be well-covered by unit tests. Coders and reviewers should examine test coverage to ensure that important code paths are not being left untested. As of now, `gcloud-java` relies on integration tests to test the SPI layer. Unit tests for the API layer should be located in the package `com.google.cloud.servicename`. Integration tests should be placed in a separate package, `com.google.cloud.servicename.it`, which enables us to catch method access bugs. Unit tests for the test helper should be placed in the package `com.google.cloud.servicename.testing`. All unit tests run for pull requests, but integration tests are only run upon merging the pull request. We only run integration tests upon merging pull requests to avoid decrypting and exposing credentials to anybody who can create a pull request from a fork. Prefix integration test file names with "IT" (e.g. `ITDnsTest`) to separate them from regular unit tests. + +Simple service-related tests should be added to [GoogleCloudPlatform/gcloud-java-examples](https://github.com/GoogleCloudPlatform/gcloud-java-examples/tree/master/test-apps). To test releases and platform-specific bugs, it's valuable to deploy the apps in that repository on App Engine, Compute Engine, and from your own desktop. + +#### Example application + +The example application should be a simple command line interface for the service. It should use common library usage patterns so that users can have good examples of how to use the service. Be sure to keep the examples up to date if/when there are updates that make the API cleaner and more concise. See examples of applications under the `gcloud-java-examples` folder. The example application should be in the package `com.google.cloud.examples.servicename`. + +#### Documentation + +* Include a summary of the service and code snippets on the main repository's README. These snippets should be simple and cover a few common usage patterns. The README snippets should also be added to `gcloud-java-examples` in the package `com.google.cloud.examples.servicename.snippets`. Placing snippet code in the repository ensures that the snippet code builds when Travis CI is run. For this purpose, README snippets and the snippet code in `gcloud-java-examples` should be kept in sync. Issue #753 suggests autogenerating READMEs, which would be useful for keeping snippet code in sync. As of yet, we do not have unit tests for snippets, so the snippets should be tested periodically, especially after any relevant library updates. +* Create a README in the service's folder. This README should mimic the structure of other services' READMEs. In particular, you should create a step-by-step "Getting Started" guide. See [`gcloud-java-datastore`'s README](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-datastore/README.md) for reference. All code in that step-by-step guide should also be included in the `gcloud-java-examples` snippets package. +* The API and test helper packages should have `package-info.java` files. These files should contain descriptions of the packages as well as simple example code and/or links to code snippets. +* Public methods, classes, and builders should contain meaningful Javadoc. When possible, copy docs from the service's `cloud.google.com` API documentation and provide `@see` links to relevant Google Cloud web pages. Document both unchecked and checked exceptions. +* Update [`TESTING`](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/TESTING.md) with how to run tests using the test helper. +* Update the [`gcloud-java-examples` README](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/gcloud-java-examples/README.md) with instructions on how to run your example application. + +Notes/reminders: +* Clearly document which APIs must be enabled in the Developers Console's API Manager. +* Versioning in documentation is automatically updated by the script `utilities/update_docs_version.sh`. Be sure to examine that script to make sure any version-dependent documentation will be updated properly upon release. + +### Workflow + +New services should be created in a branch based on `master`. The branch name should include the suffix "-alpha". For example, while developing `gcloud-java-pubsub`, all Pub/Sub related work should be done in `pubsub-alpha`. All code should be submitted through pull requests from a branch on a forked repository. Limiting pull request size is very helpful for reviewers. All code that is merged into the branch should be standalone and well-tested. Any todo comments in the code should have an associated Github issue number for tracking purposes. You should periodically pull updates from the master branch, especially if there are project-wide updates or if relevant changes have been made to the core utilities library, `gcloud-java-core`. This PR should only contain commits related to the merge to ease code review. + +Create at least two milestones (stable and future) for your service and an issue tag with the service name. Create issues for any to-do items and tag them appropriately. This keeps an up-to-date short-term to-do list and also allows for longer term roadmaps. + +Be sure you've configured the base folder's `pom.xml` correctly. + * Add your module to the base directory's `pom.xml` file under the list of modules (in alphabetical order). + * Add your module to the javadoc packaging settings. See PR #802 for an example. + + + +When your service is complete, contact the service owners to get a review. The primary purpose of this review is to make sure that the gcloud-java service interacts with the Google Cloud service properly. Present the reviewers with a link to the Github repository, as well as your (updated) design document that details the API. + +### Closing remarks + +* Efforts should be made to maintain the current style of the repository and a consistent style between gcloud-java services. + * We anticipate that people will sometimes use multiple `gcloud-java` services, so we don't want differences in conventions from one service API to another. Look at existing `gcloud-java` services to see coding and naming conventions. + * Codacy is configured to report on pull requests about style issues. Whenever possible, those comments should be addressed. Coders and reviewers should also run a linter on pull requests, because the Codacy tool may not catch all style errors. There is a [Checkstyle configuration](https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/checkstyle.xml) provided in the repository. +* When weighing which services to add, consider that a hand-crafted `gcloud-java` service API is especially useful if it can simplify the usability of the autogenerated client. From 9de36edd828e03a8ad7d93ef5292851da1857e0f Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Sat, 16 Apr 2016 01:31:16 +0200 Subject: [PATCH 261/375] Add prefixes field to field selector when listing blobs (#933) --- .../java/com/google/cloud/FieldSelector.java | 40 ++++++++++++++----- .../google/cloud/FieldSelectorHelperTest.java | 17 ++++++++ .../com/google/cloud/storage/Storage.java | 3 +- .../google/cloud/storage/StorageImplTest.java | 22 ++++++---- 4 files changed, 62 insertions(+), 20 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/cloud/FieldSelector.java b/gcloud-java-core/src/main/java/com/google/cloud/FieldSelector.java index a2b92d752eaf..5a46d058648d 100644 --- a/gcloud-java-core/src/main/java/com/google/cloud/FieldSelector.java +++ b/gcloud-java-core/src/main/java/com/google/cloud/FieldSelector.java @@ -43,6 +43,8 @@ public interface FieldSelector { */ class Helper { + private static final String[] EMPTY_FIELDS = {}; + private Helper() {} private static final Function FIELD_TO_STRING_FUNCTION = @@ -63,18 +65,18 @@ private static String selector(List required, FieldSele } /** - * Returns a composite selector given a number of fields. The string selector returned by this - * method can be used for field selection in API calls that return a single resource. This - * method is not supposed to be used directly by users. + * Returns a composite selector given a number of resource fields. The string selector returned + * by this method can be used for field selection in API calls that return a single resource. + * This method is not supposed to be used directly by users. */ public static String selector(List required, FieldSelector... others) { return selector(required, others, new String[]{}); } /** - * Returns a composite selector given a number of fields and a container name. The string - * selector returned by this method can be used for field selection in API calls that return a - * list of resources. This method is not supposed to be used directly by users. + * Returns a composite selector given a number of resource fields and a container name. The + * string selector returned by this method can be used for field selection in API calls that + * return a list of resources. This method is not supposed to be used directly by users. */ public static String listSelector(String containerName, List required, FieldSelector... others) { @@ -82,14 +84,30 @@ public static String listSelector(String containerName, List required, FieldSelector[] others, String... extraResourceFields) { - return "nextPageToken," + containerName + '(' + return listSelector(EMPTY_FIELDS, containerName, required, others, extraResourceFields); + } + + /** + * Returns a composite selector given a number of top level fields as strings, a number of + * resource fields and a container name. This method also takes an {@code extraResourceFields} + * parameter to specify some extra resource fields as strings. The string selector returned by + * this method can be used for field selection in API calls that return a list of resources. + * This method is not supposed to be used directly by users. + */ + public static String listSelector(String[] topLevelFields, String containerName, + List required, FieldSelector[] others, + String... extraResourceFields) { + Set topLevelStrings = Sets.newHashSetWithExpectedSize(topLevelFields.length + 1); + topLevelStrings.addAll(Lists.asList("nextPageToken", topLevelFields)); + return Joiner.on(',').join(topLevelStrings) + "," + containerName + '(' + selector(required, others, extraResourceFields) + ')'; } } diff --git a/gcloud-java-core/src/test/java/com/google/cloud/FieldSelectorHelperTest.java b/gcloud-java-core/src/test/java/com/google/cloud/FieldSelectorHelperTest.java index 9aa892c7b0b0..02d5847946e0 100644 --- a/gcloud-java-core/src/test/java/com/google/cloud/FieldSelectorHelperTest.java +++ b/gcloud-java-core/src/test/java/com/google/cloud/FieldSelectorHelperTest.java @@ -46,6 +46,7 @@ public String selector() { return "field3"; } }; + private static final String[] FIRST_LEVEL_FIELDS = {"firstLevel1", "firstLevel2"}; private static final List REQUIRED_FIELDS = ImmutableList.of(FIELD1, FIELD2); private static final String CONTAINER = "container"; @@ -81,4 +82,20 @@ public void testListSelectorWithExtraFields() { assertTrue(selector.endsWith(")")); assertEquals(52, selector.length()); } + + @Test + public void testListSelectorWithFirstLevelFields() { + String selector = Helper.listSelector(FIRST_LEVEL_FIELDS, CONTAINER, REQUIRED_FIELDS, + new FieldSelector[]{FIELD3}, "field4"); + assertTrue(selector.contains("firstLevel1")); + assertTrue(selector.contains("firstLevel2")); + assertTrue(selector.contains("nextPageToken")); + assertTrue(selector.contains("container(")); + assertTrue(selector.contains("field1")); + assertTrue(selector.contains("field2")); + assertTrue(selector.contains("field3")); + assertTrue(selector.contains("field4")); + assertTrue(selector.endsWith(")")); + assertEquals(76, selector.length()); + } } diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Storage.java index e15a3ad0077c..4c32aea1a428 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Storage.java @@ -654,6 +654,7 @@ public static BucketListOption fields(BucketField... fields) { */ class BlobListOption extends Option { + private static final String[] TOP_LEVEL_FIELDS = {"prefixes"}; private static final long serialVersionUID = 9083383524788661294L; private BlobListOption(StorageRpc.Option option, Object value) { @@ -713,7 +714,7 @@ public static BlobListOption versions(boolean versions) { */ public static BlobListOption fields(BlobField... fields) { return new BlobListOption(StorageRpc.Option.FIELDS, - Helper.listSelector("items", BlobField.REQUIRED_FIELDS, fields)); + Helper.listSelector(TOP_LEVEL_FIELDS, "items", BlobField.REQUIRED_FIELDS, fields)); } } diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java index 208988a74668..47f776458876 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java @@ -584,12 +584,13 @@ public void testListBucketsWithSelectedFields() { initializeService(); ImmutableList bucketList = ImmutableList.of(expectedBucket1, expectedBucket2); Page page = storage.list(BUCKET_LIST_FIELDS); - String selector = (String) capturedOptions.getValue().get(BLOB_LIST_FIELDS.rpcOption()); - assertTrue(selector.contains("items")); + String selector = (String) capturedOptions.getValue().get(BUCKET_LIST_FIELDS.rpcOption()); + assertTrue(selector.contains("items(")); assertTrue(selector.contains("name")); assertTrue(selector.contains("acl")); assertTrue(selector.contains("location")); assertTrue(selector.contains("nextPageToken")); + assertTrue(selector.endsWith(")")); assertEquals(38, selector.length()); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(bucketList.toArray(), Iterables.toArray(page.values(), Bucket.class)); @@ -607,10 +608,11 @@ public void testListBucketsWithEmptyFields() { initializeService(); ImmutableList bucketList = ImmutableList.of(expectedBucket1, expectedBucket2); Page page = storage.list(BUCKET_LIST_EMPTY_FIELDS); - String selector = (String) capturedOptions.getValue().get(BLOB_LIST_FIELDS.rpcOption()); - assertTrue(selector.contains("items")); + String selector = (String) capturedOptions.getValue().get(BUCKET_LIST_EMPTY_FIELDS.rpcOption()); + assertTrue(selector.contains("items(")); assertTrue(selector.contains("name")); assertTrue(selector.contains("nextPageToken")); + assertTrue(selector.endsWith(")")); assertEquals(25, selector.length()); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(bucketList.toArray(), Iterables.toArray(page.values(), Bucket.class)); @@ -679,13 +681,15 @@ public void testListBlobsWithSelectedFields() { assertEquals(BLOB_LIST_PREFIX.value(), capturedOptions.getValue().get(BLOB_LIST_PREFIX.rpcOption())); String selector = (String) capturedOptions.getValue().get(BLOB_LIST_FIELDS.rpcOption()); - assertTrue(selector.contains("items")); + assertTrue(selector.contains("prefixes")); + assertTrue(selector.contains("items(")); assertTrue(selector.contains("bucket")); assertTrue(selector.contains("name")); assertTrue(selector.contains("contentType")); assertTrue(selector.contains("md5Hash")); assertTrue(selector.contains("nextPageToken")); - assertEquals(52, selector.length()); + assertTrue(selector.endsWith(")")); + assertEquals(61, selector.length()); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(blobList.toArray(), Iterables.toArray(page.values(), Blob.class)); } @@ -710,11 +714,13 @@ public void testListBlobsWithEmptyFields() { assertEquals(BLOB_LIST_PREFIX.value(), capturedOptions.getValue().get(BLOB_LIST_PREFIX.rpcOption())); String selector = (String) capturedOptions.getValue().get(BLOB_LIST_EMPTY_FIELDS.rpcOption()); - assertTrue(selector.contains("items")); + assertTrue(selector.contains("prefixes")); + assertTrue(selector.contains("items(")); assertTrue(selector.contains("bucket")); assertTrue(selector.contains("name")); assertTrue(selector.contains("nextPageToken")); - assertEquals(32, selector.length()); + assertTrue(selector.endsWith(")")); + assertEquals(41, selector.length()); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(blobList.toArray(), Iterables.toArray(page.values(), Blob.class)); } From 996aa476a830616b023864ed4c91e375d8265506 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 18 Apr 2016 10:59:30 +0200 Subject: [PATCH 262/375] ListValue: add static methods and builder setters for specific types --- .../com/google/cloud/datastore/ListValue.java | 186 +++++++++++++++++- .../google/cloud/datastore/ListValueTest.java | 133 +++++++++++++ 2 files changed, 318 insertions(+), 1 deletion(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ListValue.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ListValue.java index f3692e5395bd..d43b78053df7 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ListValue.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/ListValue.java @@ -24,6 +24,9 @@ import java.util.ArrayList; import java.util.List; +/** + * A Google Cloud Datastore list value. A list value is a list of {@link Value} objects. + */ public final class ListValue extends Value>> { private static final long serialVersionUID = -5461475706792576395L; @@ -79,6 +82,9 @@ private void addValueHelper(Value value) { listBuilder.add(value); } + /** + * Adds the provided values to the {@code ListValue} builder. + */ public Builder addValue(Value first, Value... other) { addValueHelper(first); for (Value value : other) { @@ -88,7 +94,107 @@ public Builder addValue(Value first, Value... other) { } /** - * Copy the list of values. + * Adds the provided string values to the {@code ListValue} builder. + */ + public Builder addValue(String first, String... other) { + listBuilder.add(StringValue.of(first)); + for (String value : other) { + listBuilder.add(StringValue.of(value)); + } + return this; + } + + /** + * Adds the provided long values to the {@code ListValue} builder. + */ + public Builder addValue(long first, long... other) { + listBuilder.add(LongValue.of(first)); + for (long value : other) { + listBuilder.add(LongValue.of(value)); + } + return this; + } + + /** + * Adds the provided double values to the {@code ListValue} builder. + */ + public Builder addValue(double first, double... other) { + listBuilder.add(DoubleValue.of(first)); + for (double value : other) { + listBuilder.add(DoubleValue.of(value)); + } + return this; + } + + /** + * Adds the provided boolean values to the {@code ListValue} builder. + */ + public Builder addValue(boolean first, boolean... other) { + listBuilder.add(BooleanValue.of(first)); + for (boolean value : other) { + listBuilder.add(BooleanValue.of(value)); + } + return this; + } + + /** + * Adds the provided {@code DateTime} values to the {@code ListValue} builder. + */ + public Builder addValue(DateTime first, DateTime... other) { + listBuilder.add(DateTimeValue.of(first)); + for (DateTime value : other) { + listBuilder.add(DateTimeValue.of(value)); + } + return this; + } + + /** + * Adds the provided {@code LatLng} values to the {@code ListValue} builder. + */ + public Builder addValue(LatLng first, LatLng... other) { + listBuilder.add(LatLngValue.of(first)); + for (LatLng value : other) { + listBuilder.add(LatLngValue.of(value)); + } + return this; + } + + /** + * Adds the provided {@code Key} values to the {@code ListValue} builder. + */ + public Builder addValue(Key first, Key... other) { + listBuilder.add(KeyValue.of(first)); + for (Key value : other) { + listBuilder.add(KeyValue.of(value)); + } + return this; + } + + /** + * Adds the provided {@code FullEntity} values to the {@code ListValue} builder. + */ + public Builder addValue(FullEntity first, FullEntity... other) { + listBuilder.add(EntityValue.of(first)); + for (FullEntity value : other) { + listBuilder.add(EntityValue.of(value)); + } + return this; + } + + /** + * Adds the provided {@code Blob} values to the {@code ListValue} builder. + */ + public Builder addValue(Blob first, Blob... other) { + listBuilder.add(BlobValue.of(first)); + for (Blob value : other) { + listBuilder.add(BlobValue.of(value)); + } + return this; + } + + /** + * Sets the list of values of this {@code ListValue} builder to {@code values}. The provided + * list is copied. * * @see com.google.cloud.datastore.Value.BaseBuilder#set(java.lang.Object) */ @@ -106,6 +212,9 @@ public List> get() { return listBuilder.build(); } + /** + * Creates a {@code ListValue} object. + */ @Override public ListValue build() { return new ListValue(this); @@ -124,19 +233,94 @@ private ListValue(Builder builder) { super(builder); } + /** + * Returns a builder for the list value object. + */ @Override public Builder toBuilder() { return new Builder().mergeFrom(this); } + /** + * Creates a {@code ListValue} object given a list of {@code Value} objects. + */ public static ListValue of(List> values) { return new ListValue(values); } + /** + * Creates a {@code ListValue} object given a number of {@code Value} objects. + */ public static ListValue of(Value first, Value... other) { return new ListValue(first, other); } + /** + * Creates a {@code ListValue} object given a number of string values. + */ + public static ListValue of(String first, String... other) { + return builder().addValue(first, other).build(); + } + + /** + * Creates a {@code ListValue} object given a number of long values. + */ + public static ListValue of(long first, long... other) { + return builder().addValue(first, other).build(); + } + + /** + * Creates a {@code ListValue} object given a number of double values. + */ + public static ListValue of(double first, double... other) { + return builder().addValue(first, other).build(); + } + + /** + * Creates a {@code ListValue} object given a number of boolean values. + */ + public static ListValue of(boolean first, boolean... other) { + return builder().addValue(first, other).build(); + } + + /** + * Creates a {@code ListValue} object given a number of {@code DateTime} values. + */ + public static ListValue of(DateTime first, DateTime... other) { + return builder().addValue(first, other).build(); + } + + /** + * Creates a {@code ListValue} object given a number of {@code LatLng} values. + */ + public static ListValue of(LatLng first, LatLng... other) { + return builder().addValue(first, other).build(); + } + + /** + * Creates a {@code ListValue} object given a number of {@code Key} values. + */ + public static ListValue of(Key first, Key... other) { + return builder().addValue(first, other).build(); + } + + /** + * Creates a {@code ListValue} object given a number of {@code FullEntity} values. + */ + public static ListValue of(FullEntity first, FullEntity... other) { + return builder().addValue(first, other).build(); + } + + /** + * Creates a {@code ListValue} object given a number of {@code Blob} values. + */ + public static ListValue of(Blob first, Blob... other) { + return builder().addValue(first, other).build(); + } + + /** + * Returns a builder for {@code ListValue} objects. + */ public static Builder builder() { return new Builder(); } diff --git a/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/ListValueTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/ListValueTest.java index 47acc549d65d..567f2778dc38 100644 --- a/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/ListValueTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/ListValueTest.java @@ -31,6 +31,24 @@ public class ListValueTest { private static final List> CONTENT = ImmutableList.of(NullValue.of(), StringValue.of("foo")); + private static final String STRING1 = "string1"; + private static final String STRING2 = "string2"; + private static final long LONG1 = 1L; + private static final long LONG2 = 2L; + private static final double DOUBLE1 = 1.0; + private static final double DOUBLE2 = 2.0; + private static final boolean BOOLEAN1 = true; + private static final boolean BOOLEAN2 = false; + private static final DateTime DATETIME1 = new DateTime(1); + private static final DateTime DATETIME2 = new DateTime(2); + private static final LatLng LATLNG1 = LatLng.of(DOUBLE1, DOUBLE2); + private static final LatLng LATLNG2 = LatLng.of(DOUBLE2, DOUBLE1); + private static final Key KEY1 = Key.builder("project", "kind", "name1").build(); + private static final Key KEY2 = Key.builder("project", "kind", "name2").build(); + private static final FullEntity ENTITY1 = FullEntity.builder(KEY1).build(); + private static final FullEntity ENTITY2 = FullEntity.builder(KEY2).build(); + private static final Blob BLOB1 = Blob.copyFrom(new byte[]{0xD, 0xE, 0xA, 0xD}); + private static final Blob BLOB2 = Blob.copyFrom(new byte[]{0xB, 0x0, 0x0, 0x0}); @Test public void testToBuilder() throws Exception { @@ -46,6 +64,44 @@ public void testOf() throws Exception { value = ListValue.of(Collections.>emptyList()); assertEquals(Collections.>emptyList(), value.get()); assertFalse(value.excludeFromIndexes()); + value = ListValue.of(STRING1); + assertEquals(ImmutableList.of(StringValue.of(STRING1)), value.get()); + value = ListValue.of(STRING1, STRING2); + assertEquals(ImmutableList.of(StringValue.of(STRING1), StringValue.of(STRING2)), value.get()); + value = ListValue.of(LONG1); + assertEquals(ImmutableList.of(LongValue.of(LONG1)), value.get()); + value = ListValue.of(LONG1, LONG2); + assertEquals(ImmutableList.of(LongValue.of(LONG1), LongValue.of(LONG2)), value.get()); + value = ListValue.of(DOUBLE1); + assertEquals(ImmutableList.of(DoubleValue.of(DOUBLE1)), value.get()); + value = ListValue.of(DOUBLE1, DOUBLE2); + assertEquals(ImmutableList.of(DoubleValue.of(DOUBLE1), DoubleValue.of(DOUBLE2)), value.get()); + value = ListValue.of(BOOLEAN1); + assertEquals(ImmutableList.of(BooleanValue.of(BOOLEAN1)), value.get()); + value = ListValue.of(BOOLEAN1, BOOLEAN2); + assertEquals(ImmutableList.of(BooleanValue.of(BOOLEAN1), BooleanValue.of(BOOLEAN2)), + value.get()); + value = ListValue.of(DATETIME1); + assertEquals(ImmutableList.of(DateTimeValue.of(DATETIME1)), value.get()); + value = ListValue.of(DATETIME1, DATETIME2); + assertEquals(ImmutableList.of(DateTimeValue.of(DATETIME1), DateTimeValue.of(DATETIME2)), + value.get()); + value = ListValue.of(LATLNG1); + assertEquals(ImmutableList.of(LatLngValue.of(LATLNG1)), value.get()); + value = ListValue.of(LATLNG1, LATLNG2); + assertEquals(ImmutableList.of(LatLngValue.of(LATLNG1), LatLngValue.of(LATLNG2)), value.get()); + value = ListValue.of(KEY1); + assertEquals(ImmutableList.of(KeyValue.of(KEY1)), value.get()); + value = ListValue.of(KEY1, KEY2); + assertEquals(ImmutableList.of(KeyValue.of(KEY1), KeyValue.of(KEY2)), value.get()); + value = ListValue.of(ENTITY1); + assertEquals(ImmutableList.of(EntityValue.of(ENTITY1)), value.get()); + value = ListValue.of(ENTITY1, ENTITY2); + assertEquals(ImmutableList.of(EntityValue.of(ENTITY1), EntityValue.of(ENTITY2)), value.get()); + value = ListValue.of(BLOB1); + assertEquals(ImmutableList.of(BlobValue.of(BLOB1)), value.get()); + value = ListValue.of(BLOB1, BLOB2); + assertEquals(ImmutableList.of(BlobValue.of(BLOB1), BlobValue.of(BLOB2)), value.get()); } @SuppressWarnings("deprecation") @@ -65,5 +121,82 @@ public void testBuilder() throws Exception { builder = builder.set(Collections.>emptyList()); assertEquals(Collections.>emptyList(), builder.build().get()); + + builder = builder.addValue(STRING1); + assertEquals(ImmutableList.of(StringValue.of(STRING1)), builder.build().get()); + builder = builder.set(Collections.>emptyList()); + + builder = builder.addValue(STRING1, STRING2); + assertEquals(ImmutableList.of(StringValue.of(STRING1), StringValue.of(STRING2)), + builder.build().get()); + builder = builder.set(Collections.>emptyList()); + + builder = builder.addValue(LONG1); + assertEquals(ImmutableList.of(LongValue.of(LONG1)), builder.build().get()); + builder = builder.set(Collections.>emptyList()); + + builder = builder.addValue(LONG1, LONG2); + assertEquals(ImmutableList.of(LongValue.of(LONG1), LongValue.of(LONG2)), builder.build().get()); + builder = builder.set(Collections.>emptyList()); + + builder = builder.addValue(DOUBLE1); + assertEquals(ImmutableList.of(DoubleValue.of(DOUBLE1)), builder.build().get()); + builder = builder.set(Collections.>emptyList()); + + builder = builder.addValue(DOUBLE1, DOUBLE2); + assertEquals(ImmutableList.of(DoubleValue.of(DOUBLE1), DoubleValue.of(DOUBLE2)), + builder.build().get()); + builder = builder.set(Collections.>emptyList()); + + builder = builder.addValue(BOOLEAN1); + assertEquals(ImmutableList.of(BooleanValue.of(BOOLEAN1)), builder.build().get()); + builder = builder.set(Collections.>emptyList()); + + builder = builder.addValue(BOOLEAN1, BOOLEAN2); + assertEquals(ImmutableList.of(BooleanValue.of(BOOLEAN1), BooleanValue.of(BOOLEAN2)), + builder.build().get()); + builder = builder.set(Collections.>emptyList()); + + builder = builder.addValue(DATETIME1); + assertEquals(ImmutableList.of(DateTimeValue.of(DATETIME1)), builder.build().get()); + builder = builder.set(Collections.>emptyList()); + + builder = builder.addValue(DATETIME1, DATETIME2); + assertEquals(ImmutableList.of(DateTimeValue.of(DATETIME1), DateTimeValue.of(DATETIME2)), + builder.build().get()); + builder = builder.set(Collections.>emptyList()); + + builder = builder.addValue(LATLNG1); + assertEquals(ImmutableList.of(LatLngValue.of(LATLNG1)), builder.build().get()); + builder = builder.set(Collections.>emptyList()); + + builder = builder.addValue(LATLNG1, LATLNG2); + assertEquals(ImmutableList.of(LatLngValue.of(LATLNG1), LatLngValue.of(LATLNG2)), + builder.build().get()); + builder = builder.set(Collections.>emptyList()); + + builder = builder.addValue(KEY1); + assertEquals(ImmutableList.of(KeyValue.of(KEY1)), builder.build().get()); + builder = builder.set(Collections.>emptyList()); + + builder = builder.addValue(KEY1, KEY2); + assertEquals(ImmutableList.of(KeyValue.of(KEY1), KeyValue.of(KEY2)), builder.build().get()); + builder = builder.set(Collections.>emptyList()); + + builder = builder.addValue(ENTITY1); + assertEquals(ImmutableList.of(EntityValue.of(ENTITY1)), builder.build().get()); + builder = builder.set(Collections.>emptyList()); + + builder = builder.addValue(ENTITY1, ENTITY2); + assertEquals(ImmutableList.of(EntityValue.of(ENTITY1), EntityValue.of(ENTITY2)), + builder.build().get()); + builder = builder.set(Collections.>emptyList()); + + builder = builder.addValue(BLOB1); + assertEquals(ImmutableList.of(BlobValue.of(BLOB1)), builder.build().get()); + builder = builder.set(Collections.>emptyList()); + + builder = builder.addValue(BLOB1, BLOB2); + assertEquals(ImmutableList.of(BlobValue.of(BLOB1), BlobValue.of(BLOB2)), builder.build().get()); } } From 5e0de55a546770228b07fe82029b7d822efe91b7 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 18 Apr 2016 18:40:21 +0200 Subject: [PATCH 263/375] Add options(namespace) method to LocalDatastoreHelper (#936) Add options(namespace) method to LocalDatastoreHelper --- .../cloud/datastore/DatastoreOptions.java | 6 +++++ .../testing/LocalDatastoreHelper.java | 23 ++++++++++++++----- .../testing/LocalDatastoreHelperTest.java | 7 ++++++ 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java index d456af51bde1..77e716474e41 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java @@ -75,6 +75,9 @@ public DatastoreOptions build() { return new DatastoreOptions(this); } + /** + * Sets the default namespace to be used by the datastore service. + */ public Builder namespace(String namespace) { this.namespace = validateNamespace(namespace); return this; @@ -112,6 +115,9 @@ protected DatastoreRpcFactory defaultRpcFactory() { return DefaultDatastoreRpcFactory.INSTANCE; } + /** + * Returns the default namespace to be used by the datastore service. + */ public String namespace() { return namespace; } diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/testing/LocalDatastoreHelper.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/testing/LocalDatastoreHelper.java index 4da7e0d27e75..906e3ccb300e 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/testing/LocalDatastoreHelper.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/testing/LocalDatastoreHelper.java @@ -556,17 +556,28 @@ private static int findAvailablePort() { } } + private DatastoreOptions.Builder optionsBuilder() { + return DatastoreOptions.builder() + .projectId(projectId) + .host("localhost:" + Integer.toString(port)) + .authCredentials(AuthCredentials.noAuth()) + .retryParams(RetryParams.noRetries()); + } + /** * Returns a {@link DatastoreOptions} instance that sets the host to use the Datastore emulator on * localhost. */ public DatastoreOptions options() { - return DatastoreOptions.builder() - .projectId(projectId) - .host("localhost:" + Integer.toString(port)) - .authCredentials(AuthCredentials.noAuth()) - .retryParams(RetryParams.noRetries()) - .build(); + return optionsBuilder().build(); + } + + /** + * Returns a {@link DatastoreOptions} instance that sets the host to use the Datastore emulator on + * localhost. The default namespace is set to {@code namespace}. + */ + public DatastoreOptions options(String namespace) { + return optionsBuilder().namespace(namespace).build(); } /** diff --git a/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/testing/LocalDatastoreHelperTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/testing/LocalDatastoreHelperTest.java index 73844d2e19b3..a5a49e472ae3 100644 --- a/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/testing/LocalDatastoreHelperTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/testing/LocalDatastoreHelperTest.java @@ -16,6 +16,7 @@ package com.google.cloud.datastore.testing; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; @@ -31,6 +32,7 @@ public class LocalDatastoreHelperTest { private static final double TOLERANCE = 0.00001; private static final String PROJECT_ID_PREFIX = "test-project-"; + private static final String NAMESPACE = "namespace"; @Test public void testCreate() { @@ -49,5 +51,10 @@ public void testOptions() { assertTrue(options.projectId().startsWith(PROJECT_ID_PREFIX)); assertTrue(options.host().startsWith("localhost:")); assertSame(AuthCredentials.noAuth(), options.authCredentials()); + options = helper.options(NAMESPACE); + assertTrue(options.projectId().startsWith(PROJECT_ID_PREFIX)); + assertTrue(options.host().startsWith("localhost:")); + assertSame(AuthCredentials.noAuth(), options.authCredentials()); + assertEquals(NAMESPACE, options.namespace()); } } From e213176f7f4f201969a4d301711f60def3943d5f Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 20 Apr 2016 13:46:55 +0200 Subject: [PATCH 264/375] Add support for batches to DNS (#940) --- .../java/com/google/cloud/BatchResult.java | 108 ++ .../com/google/cloud/BatchResultTest.java | 113 ++ gcloud-java-dns/pom.xml | 5 + .../com/google/cloud/dns/ChangeRequest.java | 4 +- .../main/java/com/google/cloud/dns/Dns.java | 5 + .../java/com/google/cloud/dns/DnsBatch.java | 354 ++++++ .../com/google/cloud/dns/DnsBatchResult.java | 38 + .../com/google/cloud/dns/DnsException.java | 5 + .../java/com/google/cloud/dns/DnsImpl.java | 38 +- .../java/com/google/cloud/dns/RecordSet.java | 2 +- .../google/cloud/dns/spi/DefaultDnsRpc.java | 268 +++- .../java/com/google/cloud/dns/spi/DnsRpc.java | 5 + .../com/google/cloud/dns/spi/RpcBatch.java | 117 ++ .../cloud/dns/testing/LocalDnsHelper.java | 126 +- .../google/cloud/dns/DnsBatchResultTest.java | 109 ++ .../com/google/cloud/dns/DnsBatchTest.java | 632 ++++++++++ .../com/google/cloud/dns/DnsImplTest.java | 22 +- .../google/cloud/dns/SerializationTest.java | 2 + .../com/google/cloud/dns/it/ITDnsTest.java | 1068 ++++++++++++++-- .../cloud/dns/testing/LocalDnsHelperTest.java | 1074 ++++++++++++++++- 20 files changed, 3942 insertions(+), 153 deletions(-) create mode 100644 gcloud-java-core/src/main/java/com/google/cloud/BatchResult.java create mode 100644 gcloud-java-core/src/test/java/com/google/cloud/BatchResultTest.java create mode 100644 gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsBatch.java create mode 100644 gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsBatchResult.java create mode 100644 gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/RpcBatch.java create mode 100644 gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsBatchResultTest.java create mode 100644 gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsBatchTest.java diff --git a/gcloud-java-core/src/main/java/com/google/cloud/BatchResult.java b/gcloud-java-core/src/main/java/com/google/cloud/BatchResult.java new file mode 100644 index 000000000000..fb78409ea31e --- /dev/null +++ b/gcloud-java-core/src/main/java/com/google/cloud/BatchResult.java @@ -0,0 +1,108 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + +import java.util.LinkedList; +import java.util.List; + +/** + * This class holds a single result of a batch call. The class is not thread-safe. + * + * @param the type of the result + * @param the type of the service-dependent exception thrown when a processing error occurs + * + */ +public abstract class BatchResult { + + private T result; + private boolean completed = false; + private E error; + private final List> toBeNotified = new LinkedList<>(); + + /** + * Returns {@code true} if the batch has been completed and the result is available; {@code false} + * otherwise. + */ + public boolean completed() { + return completed; + } + + /** + * Returns the result of this call. + * + * @throws IllegalStateException if the batch has not been completed yet + * @throws E if an error occurred when processing the batch request + */ + public T get() throws E { + checkState(completed(), "Batch has not been completed yet"); + if (error != null) { + throw error; + } + return result; + } + + /** + * Adds a callback for the batch operation. + * + * @throws IllegalStateException if the batch has been completed already + */ + public void notify(Callback callback) { + checkState(!completed, "The batch has been completed. All the calls to the notify()" + + " method should be done prior to submitting the batch."); + toBeNotified.add(callback); + } + + /** + * Sets an error and status as completed. Notifies all callbacks. + */ + protected void error(E error) { + this.error = checkNotNull(error); + this.completed = true; + for (Callback callback : toBeNotified) { + callback.error(error); + } + } + + /** + * Sets a result and status as completed. Notifies all callbacks. + */ + protected void success(T result) { + this.result = result; + this.completed = true; + for (Callback callback : toBeNotified) { + callback.success(result); + } + } + + /** + * An interface for the batch callbacks. + */ + public interface Callback { + /** + * The method to be called when the batched operation succeeds. + */ + void success(T result); + + /** + * The method to be called when the batched operation fails. + */ + void error(E exception); + } +} diff --git a/gcloud-java-core/src/test/java/com/google/cloud/BatchResultTest.java b/gcloud-java-core/src/test/java/com/google/cloud/BatchResultTest.java new file mode 100644 index 000000000000..8fb26bc8ce36 --- /dev/null +++ b/gcloud-java-core/src/test/java/com/google/cloud/BatchResultTest.java @@ -0,0 +1,113 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import org.easymock.EasyMock; +import org.junit.Before; +import org.junit.Test; + +public class BatchResultTest { + + private BatchResult result; + + @Before + public void setUp() { + result = new BatchResult() {}; + } + + @Test + public void testSuccess() { + assertFalse(result.completed()); + try { + result.get(); + fail("This was not completed yet."); + } catch (IllegalStateException ex) { + // expected + } + result.success(true); + assertTrue(result.get()); + // test that null is allowed + result.success(null); + } + + @Test + public void testError() { + assertFalse(result.completed()); + try { + result.get(); + fail("This was not completed yet."); + } catch (IllegalStateException ex) { + // expected + } + try { + result.error(null); + fail(); + } catch (NullPointerException exc) { + // expected + } + BaseServiceException ex = new BaseServiceException(0, "message", "reason", false); + result.error(ex); + try { + result.get(); + fail("This is a failed operation and should have thrown a DnsException."); + } catch (BaseServiceException real) { + assertSame(ex, real); + } + } + + @Test + public void testNotifyError() { + final BaseServiceException ex = new BaseServiceException(0, "message", "reason", false); + assertFalse(result.completed()); + BatchResult.Callback callback = + EasyMock.createStrictMock(BatchResult.Callback.class); + callback.error(ex); + EasyMock.replay(callback); + result.notify(callback); + result.error(ex); + try { + result.notify(callback); + fail("The batch has been completed."); + } catch (IllegalStateException exception) { + // expected + } + EasyMock.verify(callback); + } + + @Test + public void testNotifySuccess() { + assertFalse(result.completed()); + BatchResult.Callback callback = + EasyMock.createStrictMock(BatchResult.Callback.class); + callback.success(true); + EasyMock.replay(callback); + result.notify(callback); + result.success(true); + try { + result.notify(callback); + fail("The batch has been completed."); + } catch (IllegalStateException exception) { + // expected + } + EasyMock.verify(callback); + } +} diff --git a/gcloud-java-dns/pom.xml b/gcloud-java-dns/pom.xml index 73e949dd5b1e..8acd6abee783 100644 --- a/gcloud-java-dns/pom.xml +++ b/gcloud-java-dns/pom.xml @@ -40,6 +40,11 @@
    + + commons-fileupload + commons-fileupload + 1.3.1 + ${project.groupId} gcloud-java-core diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/ChangeRequest.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/ChangeRequest.java index 3538a5c411e9..267acf199b87 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/ChangeRequest.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/ChangeRequest.java @@ -173,8 +173,8 @@ public ChangeRequest reload(Dns.ChangeRequestOption... options) { /** * Returns {@code true} if the change request has been completed. If the status is not {@link - * Status#DONE} already, the method makes an API call to Google Cloud DNS to update the change - * request first. + * ChangeRequestInfo.Status#DONE} already, the method makes an API call to Google Cloud DNS to + * update the change request first. * * @throws DnsException upon failure of the API call or if the associated zone was not found */ diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/Dns.java index 2aa080fb63d3..38faad7854e7 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/Dns.java @@ -503,4 +503,9 @@ ChangeRequest getChangeRequest(String zoneName, String changeRequestId, * @see Cloud DNS Chages: list */ Page listChangeRequests(String zoneName, ChangeRequestListOption... options); + + /** + * Creates a new empty batch for grouping multiple service calls in one underlying RPC call. + */ + DnsBatch batch(); } diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsBatch.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsBatch.java new file mode 100644 index 000000000000..d81fc27f3a1a --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsBatch.java @@ -0,0 +1,354 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.dns; + +import static java.net.HttpURLConnection.HTTP_NOT_FOUND; + +import com.google.api.client.googleapis.json.GoogleJsonError; +import com.google.api.services.dns.model.Change; +import com.google.api.services.dns.model.ChangesListResponse; +import com.google.api.services.dns.model.ManagedZone; +import com.google.api.services.dns.model.ManagedZonesListResponse; +import com.google.api.services.dns.model.Project; +import com.google.api.services.dns.model.ResourceRecordSet; +import com.google.api.services.dns.model.ResourceRecordSetsListResponse; +import com.google.cloud.Page; +import com.google.cloud.PageImpl; +import com.google.cloud.dns.spi.DnsRpc; +import com.google.cloud.dns.spi.RpcBatch; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; + +import java.util.List; +import java.util.Map; + +/** + * A batch of operations to be submitted to Google Cloud DNS using a single RPC request. + */ +public class DnsBatch { + + private final RpcBatch batch; + private final DnsRpc dnsRpc; + private final DnsOptions options; + + DnsBatch(DnsOptions options) { + this.options = options; + this.dnsRpc = options.rpc(); + this.batch = dnsRpc.createBatch(); + } + + @VisibleForTesting + Object batch() { + return batch; + } + + @VisibleForTesting + DnsRpc dnsRpc() { + return dnsRpc; + } + + @VisibleForTesting + DnsOptions options() { + return options; + } + + /** + * Adds a request representing the "list zones" operation to this batch. The {@code options} can + * be used to restrict the fields returned or provide page size limits in the same way as for + * {@link Dns#listZones(Dns.ZoneListOption...)}. Calling {@link DnsBatchResult#get()} on the + * return value yields a page of zones if successful and throws a {@link DnsException} otherwise. + */ + public DnsBatchResult> listZones(Dns.ZoneListOption... options) { + DnsBatchResult> result = new DnsBatchResult<>(); + Map optionMap = DnsImpl.optionMap(options); + RpcBatch.Callback callback = + createListZonesCallback(result, optionMap); + batch.addListZones(callback, optionMap); + return result; + } + + /** + * Adds a request representing the "create zone" operation to this batch. The {@code options} can + * be used to restrict the fields returned in the same way as for {@link Dns#create(ZoneInfo, + * Dns.ZoneOption...)}. Calling {@link DnsBatchResult#get()} on the return value yields the + * created {@link Zone} if successful and throws a {@link DnsException} otherwise. + */ + public DnsBatchResult createZone(ZoneInfo zone, Dns.ZoneOption... options) { + DnsBatchResult result = new DnsBatchResult<>(); + // todo this can cause misleading report of a failure, intended to be fixed within #924 + RpcBatch.Callback callback = createZoneCallback(this.options, result, true); + Map optionMap = DnsImpl.optionMap(options); + batch.addCreateZone(zone.toPb(), callback, optionMap); + return result; + } + + /** + * Adds a request representing the "delete zone" operation to this batch. Calling {@link + * DnsBatchResult#get()} on the return value yields {@code true} upon successful deletion, {@code + * false} if the zone was not found, or throws a {@link DnsException} if the operation failed. + */ + public DnsBatchResult deleteZone(String zoneName) { + DnsBatchResult result = new DnsBatchResult<>(); + RpcBatch.Callback callback = createDeleteZoneCallback(result); + batch.addDeleteZone(zoneName, callback); + return result; + } + + /** + * Adds a request representing the "get zone" operation to this batch. The {@code options} can be + * used to restrict the fields returned in the same way as for {@link Dns#getZone(String, + * Dns.ZoneOption...)}. Calling {@link DnsBatchResult#get()} on the return value yields the + * requested {@link Zone} if successful, {@code null} if no such zone exists, or throws a + * {@link DnsException} if the operation failed. + */ + public DnsBatchResult getZone(String zoneName, Dns.ZoneOption... options) { + DnsBatchResult result = new DnsBatchResult<>(); + RpcBatch.Callback callback = createZoneCallback(this.options, result, true); + Map optionMap = DnsImpl.optionMap(options); + batch.addGetZone(zoneName, callback, optionMap); + return result; + } + + /** + * Adds a request representing the "get project" operation to this batch. The {@code options} can + * be used to restrict the fields returned in the same way as for {@link + * Dns#getProject(Dns.ProjectOption...)}. Calling {@link DnsBatchResult#get()} on the return value + * yields the created {@link ProjectInfo} if successful and throws a {@link DnsException} if the + * operation failed. + */ + public DnsBatchResult getProject(Dns.ProjectOption... options) { + DnsBatchResult result = new DnsBatchResult<>(); + RpcBatch.Callback callback = createProjectCallback(result); + Map optionMap = DnsImpl.optionMap(options); + batch.addGetProject(callback, optionMap); + return result; + } + + /** + * Adds a request representing the "list record sets" operation in the zone specified by {@code + * zoneName} to this batch. The {@code options} can be used to restrict the fields returned or + * provide page size limits in the same way as for {@link Dns#listRecordSets(String, + * Dns.RecordSetListOption...)}. Calling {@link DnsBatchResult#get()} on the return value yields a + * page of record sets if successful and throws a {@link DnsException} if the operation failed or + * the zone does not exist. + */ + public DnsBatchResult> listRecordSets(String zoneName, + Dns.RecordSetListOption... options) { + DnsBatchResult> result = new DnsBatchResult<>(); + Map optionMap = DnsImpl.optionMap(options); + RpcBatch.Callback callback = + createListRecordSetsCallback(zoneName, result, optionMap); + batch.addListRecordSets(zoneName, callback, optionMap); + return result; + } + + /** + * Adds a request representing the "list change requests" operation in the zone specified by + * {@code zoneName} to this batch. The {@code options} can be used to restrict the fields returned + * or provide page size limits in the same way as for {@link Dns#listChangeRequests(String, + * Dns.ChangeRequestListOption...)}. Calling {@link DnsBatchResult#get()} on the return value + * yields a page of change requests if successful and throws a {@link DnsException} if the + * operation failed or the zone does not exist. + */ + public DnsBatchResult> listChangeRequests(String zoneName, + Dns.ChangeRequestListOption... options) { + DnsBatchResult> result = new DnsBatchResult<>(); + Map optionMap = DnsImpl.optionMap(options); + RpcBatch.Callback callback = + createListChangeRequestsCallback(zoneName, result, optionMap); + batch.addListChangeRequests(zoneName, callback, optionMap); + return result; + } + + /** + * Adds a request representing the "get change request" operation for the zone specified by {@code + * zoneName} to this batch. The {@code options} can be used to restrict the fields returned in the + * same way as for {@link Dns#getChangeRequest(String, String, Dns.ChangeRequestOption...)}. + * Calling {@link DnsBatchResult#get()} on the return value yields the requested {@link + * ChangeRequest} if successful, {@code null} if the change request does not exist, or throws a + * {@link DnsException} if the operation failed or the zone does not exist. + */ + public DnsBatchResult getChangeRequest(String zoneName, String changeRequestId, + Dns.ChangeRequestOption... options) { + DnsBatchResult result = new DnsBatchResult<>(); + RpcBatch.Callback callback = createChangeRequestCallback(zoneName, result, true); + Map optionMap = DnsImpl.optionMap(options); + batch.addGetChangeRequest(zoneName, changeRequestId, callback, optionMap); + return result; + } + + /** + * Adds a request representing the "apply change request" operation to the zone specified by + * {@code zoneName} to this batch. The {@code options} can be used to restrict the fields returned + * in the same way as for {@link Dns#applyChangeRequest(String, ChangeRequestInfo, + * Dns.ChangeRequestOption...)}. Calling {@link DnsBatchResult#get()} on the return value yields + * the created {@link ChangeRequest} if successful, {@code null} if the change request does not + * exist, or throws a {@link DnsException} if the operation failed or the zone does not exist. + */ + public DnsBatchResult applyChangeRequest(String zoneName, + ChangeRequestInfo changeRequest, Dns.ChangeRequestOption... options) { + DnsBatchResult result = new DnsBatchResult<>(); + RpcBatch.Callback callback = createChangeRequestCallback(zoneName, result, false); + Map optionMap = DnsImpl.optionMap(options); + batch.addApplyChangeRequest(zoneName, changeRequest.toPb(), callback, optionMap); + return result; + } + + /** + * Submits this batch for processing using a single HTTP request. + */ + public void submit() { + batch.submit(); + } + + private RpcBatch.Callback createListZonesCallback( + final DnsBatchResult> result, final Map optionMap) { + return new RpcBatch.Callback() { + @Override + public void onSuccess(ManagedZonesListResponse response) { + List zones = response.getManagedZones(); + Page zonePage = new PageImpl<>( + new DnsImpl.ZonePageFetcher(options, response.getNextPageToken(), optionMap), + response.getNextPageToken(), zones == null ? ImmutableList.of() + : Iterables.transform(zones, DnsImpl.zoneFromPb(options))); + result.success(zonePage); + } + + @Override + public void onFailure(GoogleJsonError googleJsonError) { + result.error(new DnsException(googleJsonError, true)); + } + }; + } + + private RpcBatch.Callback createDeleteZoneCallback(final DnsBatchResult result) { + return new RpcBatch.Callback() { + @Override + public void onSuccess(Void response) { + result.success(true); + } + + @Override + public void onFailure(GoogleJsonError googleJsonError) { + DnsException serviceException = new DnsException(googleJsonError, false); + if (serviceException.code() == HTTP_NOT_FOUND) { + result.success(false); + } else { + result.error(serviceException); + } + } + }; + } + + /** + * A joint callback for both "get zone" and "create zone" operations. + */ + private RpcBatch.Callback createZoneCallback(final DnsOptions serviceOptions, + final DnsBatchResult result, final boolean idempotent) { + return new RpcBatch.Callback() { + @Override + public void onSuccess(ManagedZone response) { + result.success(response == null ? null : Zone.fromPb(serviceOptions.service(), response)); + } + + @Override + public void onFailure(GoogleJsonError googleJsonError) { + result.error(new DnsException(googleJsonError, idempotent)); + } + }; + } + + private RpcBatch.Callback createProjectCallback( + final DnsBatchResult result) { + return new RpcBatch.Callback() { + @Override + public void onSuccess(Project response) { + result.success(response == null ? null : ProjectInfo.fromPb(response)); + } + + @Override + public void onFailure(GoogleJsonError googleJsonError) { + result.error(new DnsException(googleJsonError, true)); + } + }; + } + + private RpcBatch.Callback createListRecordSetsCallback( + final String zoneName, final DnsBatchResult> result, + final Map optionMap) { + return new RpcBatch.Callback() { + @Override + public void onSuccess(ResourceRecordSetsListResponse response) { + List recordSets = response.getRrsets(); + Page page = new PageImpl<>( + new DnsImpl.RecordSetPageFetcher(zoneName, options, response.getNextPageToken(), + optionMap), + response.getNextPageToken(), recordSets == null ? ImmutableList.of() + : Iterables.transform(recordSets, RecordSet.FROM_PB_FUNCTION)); + result.success(page); + } + + @Override + public void onFailure(GoogleJsonError googleJsonError) { + result.error(new DnsException(googleJsonError, true)); + } + }; + } + + private RpcBatch.Callback createListChangeRequestsCallback( + final String zoneName, final DnsBatchResult> result, + final Map optionMap) { + return new RpcBatch.Callback() { + @Override + public void onSuccess(ChangesListResponse response) { + List changes = response.getChanges(); + Page page = new PageImpl<>( + new DnsImpl.ChangeRequestPageFetcher(zoneName, options, response.getNextPageToken(), + optionMap), + response.getNextPageToken(), changes == null ? ImmutableList.of() + : Iterables.transform(changes, ChangeRequest.fromPbFunction(options.service(), + zoneName))); + result.success(page); + } + + @Override + public void onFailure(GoogleJsonError googleJsonError) { + result.error(new DnsException(googleJsonError, true)); + } + }; + } + + /** + * A joint callback for both "get change request" and "create change request" operations. + */ + private RpcBatch.Callback createChangeRequestCallback(final String zoneName, + final DnsBatchResult result, final boolean idempotent) { + return new RpcBatch.Callback() { + @Override + public void onSuccess(Change response) { + result.success(response == null ? null : ChangeRequest.fromPb(options.service(), + zoneName, response)); + } + + @Override + public void onFailure(GoogleJsonError googleJsonError) { + result.error(new DnsException(googleJsonError, idempotent)); + } + }; + } +} diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsBatchResult.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsBatchResult.java new file mode 100644 index 000000000000..41c217ddc60e --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsBatchResult.java @@ -0,0 +1,38 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.dns; + +import com.google.cloud.BatchResult; + +/** + * This class holds a single result of a batch call to the Cloud DNS. + */ +public class DnsBatchResult extends BatchResult { + + DnsBatchResult() { + } + + @Override + protected void error(DnsException error) { + super.error(error); + } + + @Override + protected void success(T result) { + super.success(result); + } +} diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsException.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsException.java index f725984b6661..274ff91b3bd0 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsException.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsException.java @@ -16,6 +16,7 @@ package com.google.cloud.dns; +import com.google.api.client.googleapis.json.GoogleJsonError; import com.google.cloud.BaseServiceException; import com.google.cloud.RetryHelper.RetryHelperException; import com.google.cloud.RetryHelper.RetryInterruptedException; @@ -43,6 +44,10 @@ public DnsException(IOException exception, boolean idempotent) { super(exception, idempotent); } + public DnsException(GoogleJsonError error, boolean idempotent) { + super(error, idempotent); + } + private DnsException(int code, String message) { super(code, message, null, true); } diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsImpl.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsImpl.java index cdb311adc823..be0e8621cf41 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsImpl.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsImpl.java @@ -44,7 +44,7 @@ final class DnsImpl extends BaseService implements Dns { private final DnsRpc dnsRpc; - private static class ZonePageFetcher implements PageImpl.NextPageFetcher { + static class ZonePageFetcher implements PageImpl.NextPageFetcher { private static final long serialVersionUID = 2158209410430566961L; private final Map requestOptions; @@ -63,7 +63,7 @@ public Page nextPage() { } } - private static class ChangeRequestPageFetcher implements PageImpl.NextPageFetcher { + static class ChangeRequestPageFetcher implements PageImpl.NextPageFetcher { private static final long serialVersionUID = 4473265130673029139L; private final String zoneName; @@ -84,14 +84,14 @@ public Page nextPage() { } } - private static class DnsRecordPageFetcher implements PageImpl.NextPageFetcher { + static class RecordSetPageFetcher implements PageImpl.NextPageFetcher { private static final long serialVersionUID = -6039369212511530846L; private final Map requestOptions; private final DnsOptions serviceOptions; private final String zoneName; - DnsRecordPageFetcher(String zoneName, DnsOptions serviceOptions, String cursor, + RecordSetPageFetcher(String zoneName, DnsOptions serviceOptions, String cursor, Map optionMap) { this.zoneName = zoneName; this.requestOptions = @@ -110,6 +110,15 @@ public Page nextPage() { dnsRpc = options.rpc(); } + static Function zoneFromPb(final DnsOptions options) { + return new Function() { + @Override + public Zone apply(ManagedZone zonePb) { + return Zone.fromPb(options.service(), zonePb); + } + }; + } + @Override public Page listZones(ZoneListOption... options) { return listZones(options(), optionMap(options)); @@ -117,14 +126,6 @@ public Page listZones(ZoneListOption... options) { private static Page listZones(final DnsOptions serviceOptions, final Map optionsMap) { - // define transformation function - // this differs from the other list operations since zone is functional and requires dns service - Function pbToZoneFunction = new Function() { - @Override - public Zone apply(ManagedZone zonePb) { - return Zone.fromPb(serviceOptions.service(), zonePb); - } - }; try { // get a list of managed zones final DnsRpc rpc = serviceOptions.rpc(); @@ -137,8 +138,8 @@ public DnsRpc.ListResult call() { }, serviceOptions.retryParams(), EXCEPTION_HANDLER); String cursor = result.pageToken(); // transform that list into zone objects - Iterable zones = result.results() == null - ? ImmutableList.of() : Iterables.transform(result.results(), pbToZoneFunction); + Iterable zones = result.results() == null ? ImmutableList.of() + : Iterables.transform(result.results(), zoneFromPb(serviceOptions)); return new PageImpl<>(new ZonePageFetcher(serviceOptions, cursor, optionsMap), cursor, zones); } catch (RetryHelper.RetryHelperException e) { @@ -198,7 +199,7 @@ public DnsRpc.ListResult call() { Iterable recordSets = result.results() == null ? ImmutableList.of() : Iterables.transform(result.results(), RecordSet.FROM_PB_FUNCTION); - return new PageImpl<>(new DnsRecordPageFetcher(zoneName, serviceOptions, cursor, optionsMap), + return new PageImpl<>(new RecordSetPageFetcher(zoneName, serviceOptions, cursor, optionsMap), cursor, recordSets); } catch (RetryHelper.RetryHelperException e) { throw DnsException.translateAndThrow(e); @@ -306,7 +307,12 @@ public Change call() { } } - private Map optionMap(Option... options) { + @Override + public DnsBatch batch() { + return new DnsBatch(this.options()); + } + + static Map optionMap(Option... options) { Map temp = Maps.newEnumMap(DnsRpc.Option.class); for (Option option : options) { Object prev = temp.put(option.rpcOption(), option.value()); diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/RecordSet.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/RecordSet.java index 5e061b5164e8..e9d2e1b2527e 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/RecordSet.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/RecordSet.java @@ -154,7 +154,7 @@ private Builder(RecordSet record) { * RFC 1034 (section 3.6.1). Examples of records are available in Google DNS documentation. * * @see Google - * DNS documentation . + * DNS documentation */ public Builder addRecord(String record) { this.rrdatas.add(checkNotNull(record)); diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DefaultDnsRpc.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DefaultDnsRpc.java index 08f14a0ba254..4ee117cc7ea1 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DefaultDnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DefaultDnsRpc.java @@ -1,3 +1,19 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.dns.spi; import static com.google.cloud.dns.spi.DnsRpc.ListResult.of; @@ -10,6 +26,10 @@ import static com.google.cloud.dns.spi.DnsRpc.Option.SORTING_ORDER; import static java.net.HttpURLConnection.HTTP_NOT_FOUND; +import com.google.api.client.googleapis.batch.BatchRequest; +import com.google.api.client.googleapis.batch.json.JsonBatchCallback; +import com.google.api.client.googleapis.json.GoogleJsonError; +import com.google.api.client.http.HttpHeaders; import com.google.api.client.http.HttpRequestInitializer; import com.google.api.client.http.HttpTransport; import com.google.api.client.json.jackson.JacksonFactory; @@ -36,6 +56,129 @@ public class DefaultDnsRpc implements DnsRpc { private final Dns dns; private final DnsOptions options; + private class DefaultRpcBatch implements RpcBatch { + + private final BatchRequest batch; + + private DefaultRpcBatch(BatchRequest batch) { + this.batch = batch; + } + + @Override + public void addListZones(RpcBatch.Callback callback, + Map options) { + try { + listZonesCall(options).queue(batch, toJsonCallback(callback)); + } catch (IOException ex) { + throw translate(ex, false); + } + } + + @Override + public void addCreateZone(ManagedZone zone, RpcBatch.Callback callback, + Map options) { + try { + createZoneCall(zone, options).queue(batch, toJsonCallback(callback)); + } catch (IOException ex) { + throw translate(ex, false); + } + } + + @Override + public void addGetZone(String zoneName, RpcBatch.Callback callback, + Map options) { + try { + getZoneCall(zoneName, options).queue(batch, toJsonCallback(callback)); + } catch (IOException ex) { + throw translate(ex, false); + } + } + + @Override + public void addDeleteZone(String zoneName, RpcBatch.Callback callback) { + try { + deleteZoneCall(zoneName).queue(batch, toJsonCallback(callback)); + } catch (IOException ex) { + throw translate(ex, false); + } + } + + @Override + public void addGetProject(RpcBatch.Callback callback, + Map options) { + try { + getProjectCall(options).queue(batch, toJsonCallback(callback)); + } catch (IOException ex) { + throw translate(ex, false); + } + } + + @Override + public void addListRecordSets(String zoneName, + RpcBatch.Callback callback, Map options) { + try { + listRecordSetsCall(zoneName, options).queue(batch, toJsonCallback(callback)); + } catch (IOException ex) { + throw translate(ex, false); + } + } + + @Override + public void addListChangeRequests(String zoneName, + RpcBatch.Callback callback, Map options) { + try { + listChangeRequestsCall(zoneName, options).queue(batch, toJsonCallback(callback)); + } catch (IOException ex) { + throw translate(ex, false); + } + } + + @Override + public void addGetChangeRequest(String zoneName, String changeRequestId, + RpcBatch.Callback callback, Map options) { + try { + getChangeRequestCall(zoneName, changeRequestId, options).queue(batch, + toJsonCallback(callback)); + } catch (IOException ex) { + throw translate(ex, false); + } + } + + @Override + public void addApplyChangeRequest(String zoneName, Change change, + RpcBatch.Callback callback, Map options) { + try { + applyChangeRequestCall(zoneName, change, options).queue(batch, toJsonCallback(callback)); + } catch (IOException ex) { + throw translate(ex, false); + } + } + + @Override + public void submit() { + try { + batch.execute(); + } catch (IOException ex) { + throw translate(ex, false); + } + } + } + + private static JsonBatchCallback toJsonCallback(final RpcBatch.Callback callback) { + return new JsonBatchCallback() { + @Override + public void onSuccess(T response, HttpHeaders httpHeaders) throws IOException { + callback.onSuccess(response); + } + + @Override + public void onFailure(GoogleJsonError googleJsonError, HttpHeaders httpHeaders) + throws IOException { + callback.onFailure(googleJsonError); + } + }; + } + private static DnsException translate(IOException exception, boolean idempotent) { return new DnsException(exception, idempotent); } @@ -56,23 +199,25 @@ public DefaultDnsRpc(DnsOptions options) { @Override public ManagedZone create(ManagedZone zone, Map options) throws DnsException { try { - return dns.managedZones() - .create(this.options.projectId(), zone) - .setFields(FIELDS.getString(options)) - .execute(); + return createZoneCall(zone, options).execute(); } catch (IOException ex) { // todo this can cause misleading report of a failure, intended to be fixed within #924 throw translate(ex, true); } } + private Dns.ManagedZones.Create createZoneCall(ManagedZone zone, Map options) + throws IOException { + return dns.managedZones() + .create(this.options.projectId(), zone) + .setFields(FIELDS.getString(options)); + } + @Override public ManagedZone getZone(String zoneName, Map options) throws DnsException { // just fields option try { - return dns.managedZones().get(this.options.projectId(), zoneName) - .setFields(FIELDS.getString(options)) - .execute(); + return getZoneCall(zoneName, options).execute(); } catch (IOException ex) { DnsException serviceException = translate(ex, true); if (serviceException.code() == HTTP_NOT_FOUND) { @@ -82,26 +227,36 @@ public ManagedZone getZone(String zoneName, Map options) throws DnsEx } } + private Dns.ManagedZones.Get getZoneCall(String zoneName, Map options) + throws IOException { + return dns.managedZones() + .get(this.options.projectId(), zoneName) + .setFields(FIELDS.getString(options)); + } + @Override public ListResult listZones(Map options) throws DnsException { // fields, page token, page size try { - ManagedZonesListResponse zoneList = dns.managedZones().list(this.options.projectId()) - .setFields(FIELDS.getString(options)) - .setMaxResults(PAGE_SIZE.getInt(options)) - .setDnsName(DNS_NAME.getString(options)) - .setPageToken(PAGE_TOKEN.getString(options)) - .execute(); + ManagedZonesListResponse zoneList = listZonesCall(options).execute(); return of(zoneList.getNextPageToken(), zoneList.getManagedZones()); } catch (IOException ex) { throw translate(ex, true); } } + private Dns.ManagedZones.List listZonesCall(Map options) throws IOException { + return dns.managedZones().list(this.options.projectId()) + .setFields(FIELDS.getString(options)) + .setMaxResults(PAGE_SIZE.getInt(options)) + .setDnsName(DNS_NAME.getString(options)) + .setPageToken(PAGE_TOKEN.getString(options)); + } + @Override public boolean deleteZone(String zoneName) throws DnsException { try { - dns.managedZones().delete(this.options.projectId(), zoneName).execute(); + deleteZoneCall(zoneName).execute(); return true; } catch (IOException ex) { DnsException serviceException = translate(ex, false); @@ -112,54 +267,68 @@ public boolean deleteZone(String zoneName) throws DnsException { } } + private Dns.ManagedZones.Delete deleteZoneCall(String zoneName) throws IOException { + return dns.managedZones().delete(this.options.projectId(), zoneName); + } + @Override public ListResult listRecordSets(String zoneName, Map options) throws DnsException { - // options are fields, page token, dns name, type try { - ResourceRecordSetsListResponse response = dns.resourceRecordSets() - .list(this.options.projectId(), zoneName) - .setFields(FIELDS.getString(options)) - .setPageToken(PAGE_TOKEN.getString(options)) - .setMaxResults(PAGE_SIZE.getInt(options)) - .setName(NAME.getString(options)) - .setType(DNS_TYPE.getString(options)) - .execute(); + ResourceRecordSetsListResponse response = listRecordSetsCall(zoneName, options).execute(); return of(response.getNextPageToken(), response.getRrsets()); } catch (IOException ex) { throw translate(ex, true); } } + private Dns.ResourceRecordSets.List listRecordSetsCall(String zoneName, Map options) + throws IOException { + // options are fields, page token, dns name, type + return dns.resourceRecordSets() + .list(this.options.projectId(), zoneName) + .setFields(FIELDS.getString(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + .setMaxResults(PAGE_SIZE.getInt(options)) + .setName(NAME.getString(options)) + .setType(DNS_TYPE.getString(options)); + } + @Override public Project getProject(Map options) throws DnsException { try { - return dns.projects().get(this.options.projectId()) - .setFields(FIELDS.getString(options)).execute(); + return getProjectCall(options).execute(); } catch (IOException ex) { throw translate(ex, true); } } + private Dns.Projects.Get getProjectCall(Map options) throws IOException { + return dns.projects().get(this.options.projectId()).setFields(FIELDS.getString(options)); + } + @Override public Change applyChangeRequest(String zoneName, Change changeRequest, Map options) throws DnsException { try { - return dns.changes().create(this.options.projectId(), zoneName, changeRequest) - .setFields(FIELDS.getString(options)) - .execute(); + return applyChangeRequestCall(zoneName, changeRequest, options).execute(); } catch (IOException ex) { throw translate(ex, false); } } + private Dns.Changes.Create applyChangeRequestCall(String zoneName, Change changeRequest, + Map options) throws IOException { + return dns.changes() + .create(this.options.projectId(), zoneName, changeRequest) + .setFields(FIELDS.getString(options)); + } + @Override public Change getChangeRequest(String zoneName, String changeRequestId, Map options) throws DnsException { try { - return dns.changes().get(this.options.projectId(), zoneName, changeRequestId) - .setFields(FIELDS.getString(options)) - .execute(); + return getChangeRequestCall(zoneName, changeRequestId, options).execute(); } catch (IOException ex) { DnsException serviceException = translate(ex, true); if (serviceException.code() == HTTP_NOT_FOUND) { @@ -175,23 +344,40 @@ public Change getChangeRequest(String zoneName, String changeRequestId, Map options) throws IOException { + return dns.changes() + .get(this.options.projectId(), zoneName, changeRequestId) + .setFields(FIELDS.getString(options)); + } + @Override public ListResult listChangeRequests(String zoneName, Map options) throws DnsException { - // options are fields, page token, page size, sort order try { - Dns.Changes.List request = dns.changes().list(this.options.projectId(), zoneName) - .setFields(FIELDS.getString(options)) - .setMaxResults(PAGE_SIZE.getInt(options)) - .setPageToken(PAGE_TOKEN.getString(options)); - if (SORTING_ORDER.getString(options) != null) { - // todo check and change if more sorting options are implemented, issue #604 - request = request.setSortBy(SORT_BY).setSortOrder(SORTING_ORDER.getString(options)); - } - ChangesListResponse response = request.execute(); + ChangesListResponse response = listChangeRequestsCall(zoneName, options).execute(); return of(response.getNextPageToken(), response.getChanges()); } catch (IOException ex) { throw translate(ex, true); } } + + private Dns.Changes.List listChangeRequestsCall(String zoneName, Map options) + throws IOException { + // options are fields, page token, page size, sort order + Dns.Changes.List request = dns.changes().list(this.options.projectId(), zoneName) + .setFields(FIELDS.getString(options)) + .setMaxResults(PAGE_SIZE.getInt(options)) + .setPageToken(PAGE_TOKEN.getString(options)); + if (SORTING_ORDER.getString(options) != null) { + // todo check and change if more sorting options are implemented, issue #604 + request = request.setSortBy(SORT_BY).setSortOrder(SORTING_ORDER.getString(options)); + } + return request; + } + + @Override + public RpcBatch createBatch() { + return new DefaultRpcBatch(dns.batch()); + } } diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DnsRpc.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DnsRpc.java index ba74f14f0527..5d0054d86379 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/DnsRpc.java @@ -171,4 +171,9 @@ Change getChangeRequest(String zoneName, String changeRequestId, Map */ ListResult listChangeRequests(String zoneName, Map options) throws DnsException; + + /** + * Creates an empty batch. + */ + RpcBatch createBatch(); } diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/RpcBatch.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/RpcBatch.java new file mode 100644 index 000000000000..154ffa4a3c99 --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/RpcBatch.java @@ -0,0 +1,117 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.dns.spi; + +import com.google.api.client.googleapis.json.GoogleJsonError; +import com.google.api.services.dns.model.Change; +import com.google.api.services.dns.model.ChangesListResponse; +import com.google.api.services.dns.model.ManagedZone; +import com.google.api.services.dns.model.ManagedZonesListResponse; +import com.google.api.services.dns.model.Project; +import com.google.api.services.dns.model.ResourceRecordSetsListResponse; + +import java.util.Map; + +/** + * An interface for the collection of batch operations. + */ +public interface RpcBatch { + + /** + * An interface for batch callbacks. + */ + interface Callback { + + /** + * This method will be called upon success of the batch operation. + */ + void onSuccess(T response); + + /** + * This method will be called upon failure of the batch operation. + */ + void onFailure(GoogleJsonError googleJsonError); + } + + /** + * Adds a call to "list zones" to the batch with the provided {@code callback} and {@code + * options}. + */ + void addListZones(Callback callback, Map options); + + /** + * Adds a call to "create zone" to the batch with the provided {@code callback} and {@code + * options}. + */ + void addCreateZone(ManagedZone zone, Callback callback, + Map options); + + /** + * Adds a call to "get zone" to the batch with the provided {@code callback} and {@code options}. + * The zone to be retrieved is identified by {@code zoneName}. + */ + void addGetZone(String zoneName, Callback callback, Map options); + + /** + * Adds a call to "get project" to the batch with the provided {@code callback} and {@code + * options}. + */ + void addGetProject(Callback callback, Map options); + + /** + * Adds a call to "delete zone" to the batch with the provided {@code callback}. The zone to be + * deleted is identified by {@code zoneName}. + */ + void addDeleteZone(String zoneName, Callback callback); + + /** + * Adds a call to "list record sets" to the batch with the provided {@code callback} and {@code + * options}. The zone whose record sets are to be listed is identified by {@code zoneName}. + */ + void addListRecordSets(String zoneName, Callback callback, + Map options); + + /** + * Adds a call to "list change requests" to the batch with the provided {@code callback} and + * {@code options}. The zone whose change requests are to be listed is identified by {@code + * zoneName}. + */ + void addListChangeRequests(String zoneName, Callback callback, + Map options); + + /** + * Adds a call to "get change request" to the batch with the provided {@code callback} and {@code + * options}. The change request to be retrieved is identified by {@code changeRequestId}. The zone + * to which the change request was applied is identified by {@code zoneName}. + */ + void addGetChangeRequest(String zoneName, String changeRequestId, Callback callback, + Map options); + + /** + * Adds a call to "apply change request" to the batch with the provided {@code callback} and + * {@code options}. The parameter {@code change} is the change request to be applied. The zone to + * which the change request should be applied is identified by {@code zoneName}. + */ + void addApplyChangeRequest(String zoneName, Change change, Callback callback, + Map options); + + /** + * Submits a batch of requests for processing using a single HTTP request to Cloud DNS. + */ + void submit(); +} + diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/testing/LocalDnsHelper.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/testing/LocalDnsHelper.java index 1f35193409ee..774bc566a458 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/testing/LocalDnsHelper.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/testing/LocalDnsHelper.java @@ -20,6 +20,7 @@ import static java.net.HttpURLConnection.HTTP_NO_CONTENT; import static java.net.HttpURLConnection.HTTP_OK; +import com.google.api.client.http.HttpMediaType; import com.google.api.client.json.JsonFactory; import com.google.api.client.json.jackson.JacksonFactory; import com.google.api.services.dns.model.Change; @@ -27,6 +28,7 @@ import com.google.api.services.dns.model.Project; import com.google.api.services.dns.model.Quota; import com.google.api.services.dns.model.ResourceRecordSet; +import com.google.cloud.AuthCredentials; import com.google.cloud.dns.DnsOptions; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Joiner; @@ -37,19 +39,21 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.google.common.io.ByteStreams; - import com.sun.net.httpserver.Headers; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; +import org.apache.commons.fileupload.MultipartStream; import org.joda.time.format.ISODateTimeFormat; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.net.InetSocketAddress; +import java.net.Socket; import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; @@ -62,6 +66,7 @@ import java.util.NavigableMap; import java.util.NavigableSet; import java.util.Random; +import java.util.Scanner; import java.util.Set; import java.util.SortedMap; import java.util.TreeMap; @@ -112,6 +117,9 @@ public class LocalDnsHelper { private static final ScheduledExecutorService EXECUTORS = Executors.newScheduledThreadPool(2, Executors.defaultThreadFactory()); private static final String PROJECT_ID = "dummyprojectid"; + private static final String RESPONSE_BOUNDARY = "____THIS_IS_HELPERS_BOUNDARY____"; + private static final String RESPONSE_SEPARATOR = "--" + RESPONSE_BOUNDARY + "\r\n"; + private static final String RESPONSE_END = "--" + RESPONSE_BOUNDARY + "--\r\n\r\n"; static { try { @@ -138,7 +146,8 @@ private enum CallRegex { ZONE_GET("GET", CONTEXT + "/[^/]+/managedZones/[^/]+"), ZONE_LIST("GET", CONTEXT + "/[^/]+/managedZones"), PROJECT_GET("GET", CONTEXT + "/[^/]+"), - RECORD_LIST("GET", CONTEXT + "/[^/]+/managedZones/[^/]+/rrsets"); + RECORD_LIST("GET", CONTEXT + "/[^/]+/managedZones/[^/]+/rrsets"), + BATCH("POST", "/batch"); private final String method; private final String pathRegex; @@ -307,6 +316,12 @@ private Response pickHandler(HttpExchange exchange, CallRegex regex) { } catch (IOException ex) { return Error.BAD_REQUEST.response(ex.getMessage()); } + case BATCH: + try { + return handleBatch(exchange); + } catch (IOException | URISyntaxException ex) { + return Error.BAD_REQUEST.response(ex.getMessage()); + } default: return Error.INTERNAL_ERROR.response("Operation without a handler."); } @@ -319,7 +334,11 @@ public void handle(HttpExchange exchange) throws IOException { for (CallRegex regex : CallRegex.values()) { if (requestMethod.equals(regex.method) && rawPath.matches(regex.pathRegex)) { Response response = pickHandler(exchange, regex); - writeResponse(exchange, response); + if (response != null) { + /* null response is returned by batch request, because it handles writing + the response on its own */ + writeResponse(exchange, response); + } return; } } @@ -328,6 +347,84 @@ public void handle(HttpExchange exchange) throws IOException { requestMethod, exchange.getRequestURI()))); } + private Response handleBatch(final HttpExchange exchange) throws IOException, + URISyntaxException { + String contentType = exchange.getRequestHeaders().getFirst("Content-type"); + if (contentType != null) { + HttpMediaType httpMediaType = new HttpMediaType(contentType); + String boundary = httpMediaType.getParameter("boundary"); + MultipartStream multipartStream = + new MultipartStream(exchange.getRequestBody(), boundary.getBytes(), 1024, null); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + byte[] bytes = new byte[1024]; + boolean nextPart = multipartStream.skipPreamble(); + while (nextPart) { + String line; + String contentId = null; + String headers = multipartStream.readHeaders(); + Scanner scanner = new Scanner(headers); + while (scanner.hasNextLine()) { + line = scanner.nextLine(); + if (line.toLowerCase().startsWith("content-id")) { + contentId = line.split(":")[1].trim(); + } + } + // TODO: remove and write directly to socket once api client provides a complete + // location line (e.g. GET /aaa/bbb HTTP/1.0) + // and uses a request path for location instead of a complete URL. + ByteArrayOutputStream bouts = new ByteArrayOutputStream(); + multipartStream.readBodyData(bouts); + byte[] contentBytes = bouts.toByteArray(); + int indexOfCr = -1; + for (int i = 0; i < contentBytes.length; i++) { + if (contentBytes[i] == '\r') { + indexOfCr = i; + break; + } + } + Socket socket = new Socket("127.0.0.1", server.getAddress().getPort()); + OutputStream socketOutput = socket.getOutputStream(); + InputStream socketInput = socket.getInputStream(); + //multipartStream.readBodyData(socketOutput); + if (indexOfCr < 0) { + socketOutput.write(contentBytes); + } else { + String[] requestLine = + new String(contentBytes, 0, indexOfCr, StandardCharsets.UTF_8).split(" "); + socketOutput.write(requestLine[0].getBytes()); + socketOutput.write(' '); + URI uri = new URI(requestLine[1]); + socketOutput.write(uri.getRawPath().getBytes()); + if (uri.getRawQuery() != null) { + socketOutput.write('?'); + socketOutput.write(uri.getRawQuery().getBytes()); + } + if (uri.getRawFragment() != null) { + socketOutput.write('#'); + socketOutput.write(uri.getRawFragment().getBytes()); + } + socketOutput.write(" HTTP/1.0".getBytes()); + socketOutput.write(contentBytes, indexOfCr, contentBytes.length - indexOfCr); + } + socketOutput.flush(); + out.write(RESPONSE_SEPARATOR.getBytes()); + out.write("Content-Type: application/http\r\n".getBytes()); + out.write(("Content-ID: " + contentId + "\r\n\r\n").getBytes()); + int length; + while ((length = socketInput.read(bytes)) != -1) { + out.write(bytes, 0, length); + } + socket.close(); + nextPart = multipartStream.skipPreamble(); + } + out.write(RESPONSE_END.getBytes()); + writeBatchResponse(exchange, out); + } else { + return Error.BAD_REQUEST.response("Content-type header was not provided for batch."); + } + return null; + } + /** * @throws IOException if the request cannot be parsed. */ @@ -368,7 +465,8 @@ private LocalDnsHelper(long delay) { try { server = HttpServer.create(new InetSocketAddress(0), 0); port = server.getAddress().getPort(); - server.createContext(CONTEXT, new RequestHandler()); + server.setExecutor(Executors.newCachedThreadPool()); + server.createContext("/", new RequestHandler()); } catch (IOException e) { throw new RuntimeException("Could not bind the mock DNS server.", e); } @@ -397,7 +495,11 @@ public static LocalDnsHelper create(Long delay) { * Returns a {@link DnsOptions} instance that sets the host to use the mock server. */ public DnsOptions options() { - return DnsOptions.builder().projectId(PROJECT_ID).host("http://localhost:" + port).build(); + return DnsOptions.builder() + .projectId(PROJECT_ID) + .host("http://localhost:" + port) + .authCredentials(AuthCredentials.noAuth()) + .build(); } /** @@ -430,6 +532,20 @@ private static void writeResponse(HttpExchange exchange, Response response) { } } + private static void writeBatchResponse(HttpExchange exchange, ByteArrayOutputStream output) { + exchange.getResponseHeaders().set( + "Content-type", "multipart/mixed; boundary=" + RESPONSE_BOUNDARY); + try { + exchange.getResponseHeaders().add("Connection", "close"); + exchange.sendResponseHeaders(200, output.toByteArray().length); + OutputStream responseBody = exchange.getResponseBody(); + output.writeTo(responseBody); + responseBody.close(); + } catch (IOException e) { + log.log(Level.WARNING, "IOException encountered when sending response.", e); + } + } + private static String decodeContent(Headers headers, InputStream inputStream) throws IOException { List contentEncoding = headers.get("Content-encoding"); InputStream input = inputStream; diff --git a/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsBatchResultTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsBatchResultTest.java new file mode 100644 index 000000000000..96ca99cc9e3e --- /dev/null +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsBatchResultTest.java @@ -0,0 +1,109 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.dns; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.google.cloud.BatchResult; + +import org.easymock.EasyMock; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; + +public class DnsBatchResultTest { + + private DnsBatchResult result; + + @Before + public void setUp() { + result = new DnsBatchResult<>(); + } + + @Test + public void testSuccess() { + assertFalse(result.completed()); + try { + result.get(); + fail("This was not completed yet."); + } catch (IllegalStateException ex) { + // expected + } + result.success(true); + assertTrue(result.get()); + } + + @Test + public void testError() { + assertFalse(result.completed()); + try { + result.get(); + fail("This was not completed yet."); + } catch (IllegalStateException ex) { + // expected + } + DnsException ex = new DnsException(new IOException("some error"), true); + result.error(ex); + try { + result.get(); + fail("This is a failed operation and should have thrown a DnsException."); + } catch (DnsException real) { + assertSame(ex, real); + } + } + + @Test + public void testNotifyError() { + DnsException ex = new DnsException(new IOException("some error"), false); + assertFalse(result.completed()); + BatchResult.Callback callback = + EasyMock.createStrictMock(BatchResult.Callback.class); + callback.error(ex); + EasyMock.replay(callback); + result.notify(callback); + result.error(ex); + try { + result.notify(callback); + fail("The batch has been completed."); + } catch (IllegalStateException exception) { + // expected + } + EasyMock.verify(callback); + } + + @Test + public void testNotifySuccess() { + assertFalse(result.completed()); + BatchResult.Callback callback = + EasyMock.createStrictMock(BatchResult.Callback.class); + callback.success(true); + EasyMock.replay(callback); + result.notify(callback); + result.success(true); + try { + result.notify(callback); + fail("The batch has been completed."); + } catch (IllegalStateException exception) { + // expected + } + EasyMock.verify(callback); + } +} diff --git a/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsBatchTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsBatchTest.java new file mode 100644 index 000000000000..bd743a3babb6 --- /dev/null +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsBatchTest.java @@ -0,0 +1,632 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.dns; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.google.api.client.googleapis.json.GoogleJsonError; +import com.google.api.services.dns.model.Change; +import com.google.api.services.dns.model.ChangesListResponse; +import com.google.api.services.dns.model.ManagedZone; +import com.google.api.services.dns.model.ManagedZonesListResponse; +import com.google.api.services.dns.model.Project; +import com.google.api.services.dns.model.ResourceRecordSet; +import com.google.api.services.dns.model.ResourceRecordSetsListResponse; +import com.google.cloud.Page; +import com.google.cloud.dns.spi.DnsRpc; +import com.google.cloud.dns.spi.RpcBatch; +import com.google.common.collect.ImmutableList; + +import org.easymock.Capture; +import org.easymock.EasyMock; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +public class DnsBatchTest { + + private static final String ZONE_NAME = "somezonename"; + private static final String DNS_NAME = "example.com."; + private static final String DESCRIPTION = "desc"; + private static final Integer MAX_SIZE = 20; + private static final String PAGE_TOKEN = "some token"; + + private static final ZoneInfo ZONE_INFO = ZoneInfo.of(ZONE_NAME, DNS_NAME, DESCRIPTION); + private static final Dns.ZoneOption ZONE_FIELDS = + Dns.ZoneOption.fields(Dns.ZoneField.CREATION_TIME); + private static final Dns.ProjectOption PROJECT_FIELDS = + Dns.ProjectOption.fields(Dns.ProjectField.QUOTA); + private static final Dns.ZoneListOption[] ZONE_LIST_OPTIONS = { + Dns.ZoneListOption.pageSize(MAX_SIZE), Dns.ZoneListOption.pageToken(PAGE_TOKEN), + Dns.ZoneListOption.fields(Dns.ZoneField.DESCRIPTION), + Dns.ZoneListOption.dnsName(DNS_NAME)}; + private static final ProjectInfo PROJECT_INFO = ProjectInfo.builder().build(); + private static final Dns.RecordSetListOption[] RECORD_SET_LIST_OPTIONS = { + Dns.RecordSetListOption.pageSize(MAX_SIZE), + Dns.RecordSetListOption.pageToken(PAGE_TOKEN), + Dns.RecordSetListOption.fields(Dns.RecordSetField.TTL), + Dns.RecordSetListOption.dnsName(DNS_NAME), + Dns.RecordSetListOption.type(RecordSet.Type.AAAA)}; + private static final RecordSet RECORD_SET = + RecordSet.builder("Something", RecordSet.Type.AAAA).build(); + private static final ChangeRequestInfo CHANGE_REQUEST_PARTIAL = ChangeRequestInfo.builder() + .add(RECORD_SET) + .build(); + private static final String CHANGE_ID = "some change id"; + private static final ChangeRequestInfo CHANGE_REQUEST_COMPLETE = ChangeRequestInfo.builder() + .add(RECORD_SET) + .startTimeMillis(123L) + .status(ChangeRequest.Status.PENDING) + .generatedId(CHANGE_ID) + .build(); + private static final Dns.ChangeRequestListOption[] CHANGE_LIST_OPTIONS = { + Dns.ChangeRequestListOption.pageSize(MAX_SIZE), + Dns.ChangeRequestListOption.pageToken(PAGE_TOKEN), + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.STATUS), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING)}; + private static final Dns.ChangeRequestOption CHANGE_GET_FIELDS = + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS); + private static final List RECORD_SET_LIST = ImmutableList.of( + RECORD_SET.toPb(), RECORD_SET.toPb(), RECORD_SET.toPb(), RECORD_SET.toPb()); + private static final List CHANGE_LIST = ImmutableList.of(CHANGE_REQUEST_COMPLETE.toPb(), + CHANGE_REQUEST_COMPLETE.toPb(), CHANGE_REQUEST_COMPLETE.toPb()); + private static final List ZONE_LIST = ImmutableList.of(ZONE_INFO.toPb(), + ZONE_INFO.toPb()); + private static final GoogleJsonError GOOGLE_JSON_ERROR = new GoogleJsonError(); + + private DnsOptions optionsMock; + private DnsRpc dnsRpcMock; + private RpcBatch batchMock; + private DnsBatch dnsBatch; + private final Dns dns = EasyMock.createStrictMock(Dns.class); + + @Before + public void setUp() { + optionsMock = EasyMock.createMock(DnsOptions.class); + dnsRpcMock = EasyMock.createMock(DnsRpc.class); + batchMock = EasyMock.createMock(RpcBatch.class); + EasyMock.expect(optionsMock.rpc()).andReturn(dnsRpcMock); + EasyMock.expect(dnsRpcMock.createBatch()).andReturn(batchMock); + EasyMock.replay(optionsMock, dnsRpcMock, batchMock, dns); + dnsBatch = new DnsBatch(optionsMock); + } + + @After + public void tearDown() { + EasyMock.verify(batchMock, dnsRpcMock, optionsMock, dns); + } + + @Test + public void testConstructor() { + assertSame(batchMock, dnsBatch.batch()); + assertSame(optionsMock, dnsBatch.options()); + assertSame(dnsRpcMock, dnsBatch.dnsRpc()); + } + + @Test + public void testListZones() { + EasyMock.reset(batchMock); + Capture> callback = Capture.newInstance(); + Capture> capturedOptions = Capture.newInstance(); + batchMock.addListZones(EasyMock.capture(callback), EasyMock.capture(capturedOptions)); + EasyMock.replay(batchMock); + DnsBatchResult> batchResult = dnsBatch.listZones(); + assertEquals(0, capturedOptions.getValue().size()); + assertNotNull(callback.getValue()); + try { + batchResult.get(); + fail("No result available yet."); + } catch (IllegalStateException ex) { + // expected + } + RpcBatch.Callback capturedCallback = callback.getValue(); + capturedCallback.onFailure(GOOGLE_JSON_ERROR); + try { + batchResult.get(); + fail("Should throw a DnsException on error."); + } catch (DnsException ex) { + // expected + assertTrue(ex.idempotent()); + } + } + + @Test + public void testListZonesWithOptions() { + EasyMock.reset(batchMock); + Capture> callback = Capture.newInstance(); + Capture> capturedOptions = Capture.newInstance(); + batchMock.addListZones(EasyMock.capture(callback), EasyMock.capture(capturedOptions)); + EasyMock.replay(batchMock); + DnsBatchResult> batchResult = dnsBatch.listZones(ZONE_LIST_OPTIONS); + assertNotNull(callback.getValue()); + Integer size = (Integer) capturedOptions.getValue().get(ZONE_LIST_OPTIONS[0].rpcOption()); + assertEquals(MAX_SIZE, size); + String selector = (String) capturedOptions.getValue().get(ZONE_LIST_OPTIONS[1].rpcOption()); + assertEquals(PAGE_TOKEN, selector); + selector = (String) capturedOptions.getValue().get(ZONE_LIST_OPTIONS[2].rpcOption()); + assertTrue(selector.contains(Dns.ZoneField.DESCRIPTION.selector())); + assertTrue(selector.contains(Dns.ZoneField.NAME.selector())); + selector = (String) capturedOptions.getValue().get(ZONE_LIST_OPTIONS[3].rpcOption()); + assertEquals(DNS_NAME, selector); + // check the callback + ManagedZonesListResponse response = new ManagedZonesListResponse() + .setManagedZones(ZONE_LIST) + .setNextPageToken(PAGE_TOKEN); + RpcBatch.Callback capturedCallback = callback.getValue(); + EasyMock.verify(optionsMock); + EasyMock.reset(optionsMock); + EasyMock.expect(optionsMock.service()).andReturn(dns).times(ZONE_LIST.size()); + EasyMock.replay(optionsMock); + capturedCallback.onSuccess(response); + Page page = batchResult.get(); + assertEquals(PAGE_TOKEN, page.nextPageCursor()); + Iterator iterator = page.values().iterator(); + int resultSize = 0; + EasyMock.verify(dns); + EasyMock.reset(dns); + EasyMock.expect(dns.options()).andReturn(optionsMock).times(ZONE_LIST.size() + 1); + EasyMock.replay(dns); + Zone zoneInfoFunctional = new Zone(dns, new ZoneInfo.BuilderImpl(ZONE_INFO)); + while (iterator.hasNext()) { + assertEquals(zoneInfoFunctional, iterator.next()); + resultSize++; + } + assertEquals(ZONE_LIST.size(), resultSize); + } + + @Test + public void testCreateZone() { + EasyMock.reset(batchMock); + Capture> callback = Capture.newInstance(); + Capture> capturedOptions = Capture.newInstance(); + Capture capturedZone = Capture.newInstance(); + batchMock.addCreateZone(EasyMock.capture(capturedZone), EasyMock.capture(callback), + EasyMock.capture(capturedOptions)); + EasyMock.replay(batchMock); + DnsBatchResult batchResult = dnsBatch.createZone(ZONE_INFO); + assertEquals(0, capturedOptions.getValue().size()); + assertEquals(ZONE_INFO.toPb(), capturedZone.getValue()); + assertNotNull(callback.getValue()); + try { + batchResult.get(); + fail("No result available yet."); + } catch (IllegalStateException ex) { + // expected + } + // testing error here, success is tested with options + RpcBatch.Callback capturedCallback = callback.getValue(); + capturedCallback.onFailure(GOOGLE_JSON_ERROR); + try { + batchResult.get(); + fail("Should throw a DnsException on error."); + } catch (DnsException ex) { + // expected + assertTrue(ex.idempotent()); + } + } + + @Test + public void testCreateZoneWithOptions() { + EasyMock.reset(dns, batchMock, optionsMock); + EasyMock.expect(dns.options()).andReturn(optionsMock); + EasyMock.expect(optionsMock.service()).andReturn(dns); + Capture> callback = Capture.newInstance(); + Capture> capturedOptions = Capture.newInstance(); + Capture capturedZone = Capture.newInstance(); + batchMock.addCreateZone(EasyMock.capture(capturedZone), EasyMock.capture(callback), + EasyMock.capture(capturedOptions)); + EasyMock.replay(dns, batchMock, optionsMock); + DnsBatchResult batchResult = dnsBatch.createZone(ZONE_INFO, ZONE_FIELDS); + assertEquals(ZONE_INFO.toPb(), capturedZone.getValue()); + assertNotNull(callback.getValue()); + String selector = (String) capturedOptions.getValue().get(ZONE_FIELDS.rpcOption()); + assertTrue(selector.contains(Dns.ZoneField.CREATION_TIME.selector())); + assertTrue(selector.contains(Dns.ZoneField.NAME.selector())); + RpcBatch.Callback capturedCallback = callback.getValue(); + capturedCallback.onSuccess(ZONE_INFO.toPb()); + assertEquals(ZONE_INFO.toPb(), batchResult.get().toPb()); + } + + @Test + public void testGetZone() { + EasyMock.reset(batchMock); + Capture> callback = Capture.newInstance(); + Capture> capturedOptions = Capture.newInstance(); + batchMock.addGetZone(EasyMock.eq(ZONE_NAME), EasyMock.capture(callback), + EasyMock.capture(capturedOptions)); + EasyMock.replay(batchMock); + DnsBatchResult batchResult = dnsBatch.getZone(ZONE_NAME); + assertEquals(0, capturedOptions.getValue().size()); + assertNotNull(callback.getValue()); + try { + batchResult.get(); + fail("No result available yet."); + } catch (IllegalStateException ex) { + // expected + } + // testing error here, success is tested with options + RpcBatch.Callback capturedCallback = callback.getValue(); + capturedCallback.onFailure(GOOGLE_JSON_ERROR); + try { + batchResult.get(); + fail("Should throw a DnsException on error."); + } catch (DnsException ex) { + // expected + assertTrue(ex.idempotent()); + } + } + + @Test + public void testGetZoneWithOptions() { + EasyMock.reset(dns, batchMock, optionsMock); + EasyMock.expect(dns.options()).andReturn(optionsMock); + Capture> callback = Capture.newInstance(); + Capture> capturedOptions = Capture.newInstance(); + batchMock.addGetZone(EasyMock.eq(ZONE_NAME), EasyMock.capture(callback), + EasyMock.capture(capturedOptions)); + EasyMock.expect(optionsMock.service()).andReturn(dns); + EasyMock.replay(dns, batchMock, optionsMock); + DnsBatchResult batchResult = dnsBatch.getZone(ZONE_NAME, ZONE_FIELDS); + assertNotNull(callback.getValue()); + String selector = (String) capturedOptions.getValue().get(ZONE_FIELDS.rpcOption()); + assertTrue(selector.contains(Dns.ZoneField.CREATION_TIME.selector())); + assertTrue(selector.contains(Dns.ZoneField.NAME.selector())); + RpcBatch.Callback capturedCallback = callback.getValue(); + capturedCallback.onSuccess(ZONE_INFO.toPb()); + assertEquals(ZONE_INFO.toPb(), batchResult.get().toPb()); + } + + @Test + public void testDeleteZone() { + EasyMock.reset(batchMock); + Capture> callback = Capture.newInstance(); + batchMock.addDeleteZone(EasyMock.eq(ZONE_NAME), EasyMock.capture(callback)); + EasyMock.replay(batchMock); + DnsBatchResult batchResult = dnsBatch.deleteZone(ZONE_NAME); + assertNotNull(callback.getValue()); + try { + batchResult.get(); + fail("No result available yet."); + } catch (IllegalStateException ex) { + // expected + } + // testing error here, success is tested with options + RpcBatch.Callback capturedCallback = callback.getValue(); + capturedCallback.onFailure(GOOGLE_JSON_ERROR); + try { + batchResult.get(); + fail("Should throw a DnsException on error."); + } catch (DnsException ex) { + // expected + assertFalse(ex.idempotent()); + } + } + + @Test + public void testDeleteZoneOnSuccess() { + EasyMock.reset(batchMock); + Capture> callback = Capture.newInstance(); + batchMock.addDeleteZone(EasyMock.eq(ZONE_NAME), EasyMock.capture(callback)); + EasyMock.replay(batchMock); + DnsBatchResult batchResult = dnsBatch.deleteZone(ZONE_NAME); + assertNotNull(callback.getValue()); + RpcBatch.Callback capturedCallback = callback.getValue(); + Void result = null; + capturedCallback.onSuccess(result); + assertTrue(batchResult.get()); + } + + @Test + public void testGetProject() { + EasyMock.reset(batchMock); + Capture> callback = Capture.newInstance(); + Capture> capturedOptions = Capture.newInstance(); + batchMock.addGetProject(EasyMock.capture(callback), EasyMock.capture(capturedOptions)); + EasyMock.replay(batchMock); + DnsBatchResult batchResult = dnsBatch.getProject(); + assertEquals(0, capturedOptions.getValue().size()); + assertNotNull(callback.getValue()); + try { + batchResult.get(); + fail("No result available yet."); + } catch (IllegalStateException ex) { + // expected + } + // testing error here, success is tested with options + RpcBatch.Callback capturedCallback = callback.getValue(); + capturedCallback.onFailure(GOOGLE_JSON_ERROR); + try { + batchResult.get(); + fail("Should throw a DnsException on error."); + } catch (DnsException ex) { + // expected + assertTrue(ex.idempotent()); + } + } + + @Test + public void testGetProjectWithOptions() { + EasyMock.reset(batchMock); + Capture> callback = Capture.newInstance(); + Capture> capturedOptions = Capture.newInstance(); + batchMock.addGetProject(EasyMock.capture(callback), EasyMock.capture(capturedOptions)); + EasyMock.replay(batchMock); + DnsBatchResult batchResult = dnsBatch.getProject(PROJECT_FIELDS); + assertNotNull(callback.getValue()); + String selector = (String) capturedOptions.getValue().get(PROJECT_FIELDS.rpcOption()); + assertTrue(selector.contains(Dns.ProjectField.QUOTA.selector())); + assertTrue(selector.contains(Dns.ProjectField.PROJECT_ID.selector())); + RpcBatch.Callback capturedCallback = callback.getValue(); + capturedCallback.onSuccess(PROJECT_INFO.toPb()); + assertEquals(PROJECT_INFO, batchResult.get()); + } + + @Test + public void testListRecordSets() { + EasyMock.reset(batchMock); + Capture> callback = Capture.newInstance(); + Capture> capturedOptions = Capture.newInstance(); + batchMock.addListRecordSets(EasyMock.eq(ZONE_NAME), EasyMock.capture(callback), + EasyMock.capture(capturedOptions)); + EasyMock.replay(batchMock); + DnsBatchResult> batchResult = dnsBatch.listRecordSets(ZONE_NAME); + assertEquals(0, capturedOptions.getValue().size()); + assertNotNull(callback.getValue()); + try { + batchResult.get(); + fail("No result available yet."); + } catch (IllegalStateException ex) { + // expected + } + RpcBatch.Callback capturedCallback = callback.getValue(); + capturedCallback.onFailure(GOOGLE_JSON_ERROR); + try { + batchResult.get(); + fail("Should throw a DnsException on error."); + } catch (DnsException ex) { + // expected + assertTrue(ex.idempotent()); + } + } + + @Test + public void testListRecordSetsWithOptions() { + EasyMock.reset(batchMock); + Capture> callback = Capture.newInstance(); + Capture> capturedOptions = Capture.newInstance(); + batchMock.addListRecordSets(EasyMock.eq(ZONE_NAME), EasyMock.capture(callback), + EasyMock.capture(capturedOptions)); + EasyMock.replay(batchMock); + DnsBatchResult> batchResult = + dnsBatch.listRecordSets(ZONE_NAME, RECORD_SET_LIST_OPTIONS); + assertNotNull(callback.getValue()); + Integer size = (Integer) capturedOptions.getValue().get(RECORD_SET_LIST_OPTIONS[0].rpcOption()); + assertEquals(MAX_SIZE, size); + String selector = (String) capturedOptions.getValue() + .get(RECORD_SET_LIST_OPTIONS[1].rpcOption()); + assertEquals(PAGE_TOKEN, selector); + selector = (String) capturedOptions.getValue().get(RECORD_SET_LIST_OPTIONS[2].rpcOption()); + assertTrue(selector.contains(Dns.RecordSetField.NAME.selector())); + assertTrue(selector.contains(Dns.RecordSetField.TTL.selector())); + selector = (String) capturedOptions.getValue().get(RECORD_SET_LIST_OPTIONS[3].rpcOption()); + assertEquals(RECORD_SET_LIST_OPTIONS[3].value(), selector); + String type = (String) capturedOptions.getValue().get(RECORD_SET_LIST_OPTIONS[4] + .rpcOption()); + assertEquals(RECORD_SET_LIST_OPTIONS[4].value(), type); + RpcBatch.Callback capturedCallback = callback.getValue(); + ResourceRecordSetsListResponse response = new ResourceRecordSetsListResponse() + .setRrsets(RECORD_SET_LIST) + .setNextPageToken(PAGE_TOKEN); + capturedCallback.onSuccess(response); + Page page = batchResult.get(); + assertEquals(PAGE_TOKEN, page.nextPageCursor()); + Iterator iterator = page.values().iterator(); + int resultSize = 0; + while (iterator.hasNext()) { + assertEquals(RECORD_SET, iterator.next()); + resultSize++; + } + assertEquals(RECORD_SET_LIST.size(), resultSize); + } + + @Test + public void testListChangeRequests() { + EasyMock.reset(batchMock); + Capture> callback = Capture.newInstance(); + Capture> capturedOptions = Capture.newInstance(); + batchMock.addListChangeRequests(EasyMock.eq(ZONE_NAME), EasyMock.capture(callback), + EasyMock.capture(capturedOptions)); + EasyMock.replay(batchMock); + DnsBatchResult> batchResult = dnsBatch.listChangeRequests(ZONE_NAME); + assertNotNull(callback.getValue()); + assertEquals(0, capturedOptions.getValue().size()); + try { + batchResult.get(); + fail("No result available yet."); + } catch (IllegalStateException ex) { + // expected + } + RpcBatch.Callback capturedCallback = callback.getValue(); + capturedCallback.onFailure(GOOGLE_JSON_ERROR); + try { + batchResult.get(); + fail("Should throw a DnsException on error."); + } catch (DnsException ex) { + // expected + assertTrue(ex.idempotent()); + } + } + + @Test + public void testListChangeRequestsWithOptions() { + EasyMock.reset(batchMock); + Capture> callback = Capture.newInstance(); + Capture> capturedOptions = Capture.newInstance(); + batchMock.addListChangeRequests(EasyMock.eq(ZONE_NAME), EasyMock.capture(callback), + EasyMock.capture(capturedOptions)); + EasyMock.replay(batchMock); + DnsBatchResult> batchResult = + dnsBatch.listChangeRequests(ZONE_NAME, CHANGE_LIST_OPTIONS); + assertNotNull(callback.getValue()); + Integer size = (Integer) capturedOptions.getValue().get(CHANGE_LIST_OPTIONS[0].rpcOption()); + assertEquals(MAX_SIZE, size); + String selector = (String) capturedOptions.getValue().get(CHANGE_LIST_OPTIONS[1].rpcOption()); + assertEquals(PAGE_TOKEN, selector); + selector = (String) capturedOptions.getValue().get(CHANGE_LIST_OPTIONS[2].rpcOption()); + assertTrue(selector.contains(Dns.ChangeRequestField.STATUS.selector())); + assertTrue(selector.contains(Dns.ChangeRequestField.ID.selector())); + selector = (String) capturedOptions.getValue().get(CHANGE_LIST_OPTIONS[3].rpcOption()); + assertTrue(selector.contains(Dns.SortingOrder.ASCENDING.selector())); + // check the callback + ChangesListResponse response = new ChangesListResponse() + .setChanges(CHANGE_LIST) + .setNextPageToken(PAGE_TOKEN); + RpcBatch.Callback capturedCallback = callback.getValue(); + EasyMock.verify(optionsMock); + EasyMock.reset(optionsMock); + EasyMock.expect(optionsMock.service()).andReturn(dns); + EasyMock.replay(optionsMock); + capturedCallback.onSuccess(response); + Page page = batchResult.get(); + assertEquals(PAGE_TOKEN, page.nextPageCursor()); + Iterator iterator = page.values().iterator(); + int resultSize = 0; + EasyMock.verify(dns); + EasyMock.reset(dns); + EasyMock.expect(dns.options()).andReturn(optionsMock).times(CHANGE_LIST.size()); + EasyMock.replay(dns); + while (iterator.hasNext()) { + assertEquals(CHANGE_REQUEST_COMPLETE.toPb(), iterator.next().toPb()); + resultSize++; + } + assertEquals(CHANGE_LIST.size(), resultSize); + } + + @Test + public void testGetChangeRequest() { + EasyMock.reset(batchMock); + Capture> callback = Capture.newInstance(); + Capture> capturedOptions = Capture.newInstance(); + batchMock.addGetChangeRequest(EasyMock.eq(ZONE_NAME), + EasyMock.eq(CHANGE_REQUEST_COMPLETE.generatedId()), EasyMock.capture(callback), + EasyMock.capture(capturedOptions)); + EasyMock.replay(batchMock); + DnsBatchResult batchResult = dnsBatch.getChangeRequest(ZONE_NAME, + CHANGE_REQUEST_COMPLETE.generatedId()); + assertEquals(0, capturedOptions.getValue().size()); + assertNotNull(callback.getValue()); + try { + batchResult.get(); + fail("No result available yet."); + } catch (IllegalStateException ex) { + // expected + } + // testing error here, success is tested with options + RpcBatch.Callback capturedCallback = callback.getValue(); + capturedCallback.onFailure(GOOGLE_JSON_ERROR); + try { + batchResult.get(); + fail("Should throw a DnsException on error."); + } catch (DnsException ex) { + // expected + assertTrue(ex.idempotent()); + } + } + + @Test + public void testGetChangeRequestWithOptions() { + EasyMock.reset(dns, batchMock, optionsMock); + EasyMock.expect(dns.options()).andReturn(optionsMock); + EasyMock.expect(optionsMock.service()).andReturn(dns); + Capture> callback = Capture.newInstance(); + Capture> capturedOptions = Capture.newInstance(); + batchMock.addGetChangeRequest(EasyMock.eq(ZONE_NAME), + EasyMock.eq(CHANGE_REQUEST_COMPLETE.generatedId()), EasyMock.capture(callback), + EasyMock.capture(capturedOptions)); + EasyMock.replay(dns, batchMock, optionsMock); + DnsBatchResult batchResult = dnsBatch.getChangeRequest(ZONE_NAME, + CHANGE_REQUEST_COMPLETE.generatedId(), CHANGE_GET_FIELDS); + assertNotNull(callback.getValue()); + String selector = (String) capturedOptions.getValue().get(CHANGE_GET_FIELDS.rpcOption()); + assertTrue(selector.contains(Dns.ChangeRequestField.STATUS.selector())); + assertTrue(selector.contains(Dns.ChangeRequestField.ID.selector())); + RpcBatch.Callback capturedCallback = callback.getValue(); + capturedCallback.onSuccess(CHANGE_REQUEST_COMPLETE.toPb()); + assertEquals(CHANGE_REQUEST_COMPLETE.toPb(), batchResult.get().toPb()); + } + + @Test + public void testApplyChangeRequest() { + EasyMock.reset(batchMock); + Capture> callback = Capture.newInstance(); + Capture> capturedOptions = Capture.newInstance(); + batchMock.addApplyChangeRequest(EasyMock.eq(ZONE_NAME), + EasyMock.eq(CHANGE_REQUEST_PARTIAL.toPb()), EasyMock.capture(callback), + EasyMock.capture(capturedOptions)); + EasyMock.replay(batchMock); + DnsBatchResult batchResult = dnsBatch.applyChangeRequest(ZONE_INFO.name(), + CHANGE_REQUEST_PARTIAL); + assertEquals(0, capturedOptions.getValue().size()); + assertNotNull(callback.getValue()); + try { + batchResult.get(); + fail("No result available yet."); + } catch (IllegalStateException ex) { + // expected + } + // testing error here, success is tested with options + RpcBatch.Callback capturedCallback = callback.getValue(); + capturedCallback.onFailure(GOOGLE_JSON_ERROR); + try { + batchResult.get(); + fail("Should throw a DnsException on error."); + } catch (DnsException ex) { + // expected + assertFalse(ex.idempotent()); + } + } + + @Test + public void testApplyChangeRequestWithOptions() { + EasyMock.reset(dns, batchMock, optionsMock); + EasyMock.expect(dns.options()).andReturn(optionsMock); + Capture> callback = Capture.newInstance(); + Capture> capturedOptions = Capture.newInstance(); + batchMock.addApplyChangeRequest(EasyMock.eq(ZONE_NAME), + EasyMock.eq(CHANGE_REQUEST_PARTIAL.toPb()), EasyMock.capture(callback), + EasyMock.capture(capturedOptions)); + EasyMock.expect(optionsMock.service()).andReturn(dns); + EasyMock.replay(dns, batchMock, optionsMock); + DnsBatchResult batchResult = dnsBatch.applyChangeRequest(ZONE_INFO.name(), + CHANGE_REQUEST_PARTIAL, CHANGE_GET_FIELDS); + String selector = (String) capturedOptions.getValue().get(CHANGE_GET_FIELDS.rpcOption()); + assertTrue(selector.contains(Dns.ChangeRequestField.STATUS.selector())); + assertTrue(selector.contains(Dns.ChangeRequestField.ID.selector())); + RpcBatch.Callback capturedCallback = callback.getValue(); + capturedCallback.onSuccess(CHANGE_REQUEST_COMPLETE.toPb()); + assertEquals(CHANGE_REQUEST_COMPLETE.toPb(), batchResult.get().toPb()); + } +} diff --git a/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsImplTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsImplTest.java index 457f5ed3adb3..d34cb340e6e3 100644 --- a/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsImplTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsImplTest.java @@ -91,7 +91,7 @@ public class DnsImplTest { Dns.ChangeRequestListOption.pageToken(PAGE_TOKEN), Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.STATUS), Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING)}; - private static final Dns.RecordSetListOption[] DNS_RECORD_LIST_OPTIONS = { + private static final Dns.RecordSetListOption[] RECORD_SET_LIST_OPTIONS = { Dns.RecordSetListOption.pageSize(MAX_SIZE), Dns.RecordSetListOption.pageToken(PAGE_TOKEN), Dns.RecordSetListOption.fields(Dns.RecordSetField.TTL), @@ -350,7 +350,7 @@ public void testListZonesWithOptions() { } @Test - public void testListDnsRecords() { + public void testListRecordSets() { EasyMock.expect(dnsRpcMock.listRecordSets(ZONE_INFO.name(), EMPTY_RPC_OPTIONS)) .andReturn(LIST_OF_PB_DNS_RECORDS); EasyMock.replay(dnsRpcMock); @@ -362,28 +362,28 @@ public void testListDnsRecords() { } @Test - public void testListDnsRecordsWithOptions() { + public void testListRecordSetsWithOptions() { Capture> capturedOptions = Capture.newInstance(); EasyMock.expect(dnsRpcMock.listRecordSets(EasyMock.eq(ZONE_NAME), EasyMock.capture(capturedOptions))).andReturn(LIST_OF_PB_DNS_RECORDS); EasyMock.replay(dnsRpcMock); dns = options.service(); // creates DnsImpl - Page dnsPage = dns.listRecordSets(ZONE_NAME, DNS_RECORD_LIST_OPTIONS); + Page dnsPage = dns.listRecordSets(ZONE_NAME, RECORD_SET_LIST_OPTIONS); assertEquals(2, Lists.newArrayList(dnsPage.values()).size()); assertTrue(Lists.newArrayList(dnsPage.values()).contains(DNS_RECORD1)); assertTrue(Lists.newArrayList(dnsPage.values()).contains(DNS_RECORD2)); - Integer size = (Integer) capturedOptions.getValue().get(DNS_RECORD_LIST_OPTIONS[0].rpcOption()); + Integer size = (Integer) capturedOptions.getValue().get(RECORD_SET_LIST_OPTIONS[0].rpcOption()); assertEquals(MAX_SIZE, size); String selector = (String) capturedOptions.getValue() - .get(DNS_RECORD_LIST_OPTIONS[1].rpcOption()); + .get(RECORD_SET_LIST_OPTIONS[1].rpcOption()); assertEquals(PAGE_TOKEN, selector); - selector = (String) capturedOptions.getValue().get(DNS_RECORD_LIST_OPTIONS[2].rpcOption()); + selector = (String) capturedOptions.getValue().get(RECORD_SET_LIST_OPTIONS[2].rpcOption()); assertTrue(selector.contains(Dns.RecordSetField.NAME.selector())); assertTrue(selector.contains(Dns.RecordSetField.TTL.selector())); - selector = (String) capturedOptions.getValue().get(DNS_RECORD_LIST_OPTIONS[3].rpcOption()); - assertEquals(DNS_RECORD_LIST_OPTIONS[3].value(), selector); - String type = (String) capturedOptions.getValue().get(DNS_RECORD_LIST_OPTIONS[4] + selector = (String) capturedOptions.getValue().get(RECORD_SET_LIST_OPTIONS[3].rpcOption()); + assertEquals(RECORD_SET_LIST_OPTIONS[3].value(), selector); + String type = (String) capturedOptions.getValue().get(RECORD_SET_LIST_OPTIONS[4] .rpcOption()); - assertEquals(DNS_RECORD_LIST_OPTIONS[4].value(), type); + assertEquals(RECORD_SET_LIST_OPTIONS[4].value(), type); } } diff --git a/gcloud-java-dns/src/test/java/com/google/cloud/dns/SerializationTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/SerializationTest.java index e510850f62ab..2115c9dd98bf 100644 --- a/gcloud-java-dns/src/test/java/com/google/cloud/dns/SerializationTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/SerializationTest.java @@ -22,6 +22,8 @@ import com.google.cloud.RetryParams; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableList; + import java.io.Serializable; import java.math.BigInteger; import java.util.concurrent.TimeUnit; diff --git a/gcloud-java-dns/src/test/java/com/google/cloud/dns/it/ITDnsTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/it/ITDnsTest.java index dd8eafa775cd..5a27af8e28ae 100644 --- a/gcloud-java-dns/src/test/java/com/google/cloud/dns/it/ITDnsTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/it/ITDnsTest.java @@ -27,6 +27,12 @@ import com.google.cloud.dns.ChangeRequest; import com.google.cloud.dns.ChangeRequestInfo; import com.google.cloud.dns.Dns; +import com.google.cloud.dns.Dns.ChangeRequestField; +import com.google.cloud.dns.Dns.ProjectField; +import com.google.cloud.dns.Dns.RecordSetField; +import com.google.cloud.dns.Dns.ZoneField; +import com.google.cloud.dns.DnsBatch; +import com.google.cloud.dns.DnsBatchResult; import com.google.cloud.dns.DnsException; import com.google.cloud.dns.DnsOptions; import com.google.cloud.dns.ProjectInfo; @@ -34,6 +40,7 @@ import com.google.cloud.dns.Zone; import com.google.cloud.dns.ZoneInfo; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -87,7 +94,7 @@ public class ITDnsTest { .build(); private static final List ZONE_NAMES = ImmutableList.of(ZONE_NAME1, ZONE_NAME_EMPTY_DESCRIPTION); - + @Rule public Timeout globalTimeout = Timeout.seconds(300); @@ -106,8 +113,7 @@ private static void clear() { List toDelete = new LinkedList<>(); while (recordSetIterator.hasNext()) { RecordSet recordSet = recordSetIterator.next(); - if (!ImmutableList.of(RecordSet.Type.NS, RecordSet.Type.SOA) - .contains(recordSet.type())) { + if (!ImmutableList.of(RecordSet.Type.NS, RecordSet.Type.SOA).contains(recordSet.type())) { toDelete.add(recordSet); } } @@ -151,7 +157,7 @@ private static void assertEqChangesIgnoreStatus(ChangeRequest expected, ChangeRe private static void waitForChangeToComplete(String zoneName, String changeId) { ChangeRequest changeRequest = DNS.getChangeRequest(zoneName, changeId, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); + Dns.ChangeRequestOption.fields(ChangeRequestField.STATUS)); waitForChangeToComplete(changeRequest); } @@ -220,7 +226,7 @@ public void testCreateZoneWithErrors() { @Test public void testCreateZoneWithOptions() { try { - Zone created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.CREATION_TIME)); + Zone created = DNS.create(ZONE1, Dns.ZoneOption.fields(ZoneField.CREATION_TIME)); assertEquals(ZONE1.name(), created.name()); // always returned assertNotNull(created.creationTimeMillis()); assertNull(created.description()); @@ -229,7 +235,7 @@ public void testCreateZoneWithOptions() { assertNull(created.nameServerSet()); assertNull(created.generatedId()); created.delete(); - created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.DESCRIPTION)); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(ZoneField.DESCRIPTION)); assertEquals(ZONE1.name(), created.name()); // always returned assertNull(created.creationTimeMillis()); assertEquals(ZONE1.description(), created.description()); @@ -238,7 +244,7 @@ public void testCreateZoneWithOptions() { assertNull(created.nameServerSet()); assertNull(created.generatedId()); created.delete(); - created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.DNS_NAME)); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(ZoneField.DNS_NAME)); assertEquals(ZONE1.name(), created.name()); // always returned assertNull(created.creationTimeMillis()); assertEquals(ZONE1.dnsName(), created.dnsName()); @@ -247,7 +253,7 @@ public void testCreateZoneWithOptions() { assertNull(created.nameServerSet()); assertNull(created.generatedId()); created.delete(); - created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(ZoneField.NAME)); assertEquals(ZONE1.name(), created.name()); // always returned assertNull(created.creationTimeMillis()); assertNull(created.dnsName()); @@ -256,7 +262,7 @@ public void testCreateZoneWithOptions() { assertNull(created.nameServerSet()); assertNull(created.generatedId()); created.delete(); - created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVER_SET)); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(ZoneField.NAME_SERVER_SET)); assertEquals(ZONE1.name(), created.name()); // always returned assertNull(created.creationTimeMillis()); assertNull(created.dnsName()); @@ -265,7 +271,7 @@ public void testCreateZoneWithOptions() { assertNull(created.nameServerSet()); // we did not set it assertNull(created.generatedId()); created.delete(); - created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVERS)); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(ZoneField.NAME_SERVERS)); assertEquals(ZONE1.name(), created.name()); // always returned assertNull(created.creationTimeMillis()); assertNull(created.dnsName()); @@ -274,7 +280,7 @@ public void testCreateZoneWithOptions() { assertNull(created.nameServerSet()); assertNull(created.generatedId()); created.delete(); - created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID)); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(ZoneField.ZONE_ID)); assertEquals(ZONE1.name(), created.name()); // always returned assertNull(created.creationTimeMillis()); assertNull(created.dnsName()); @@ -284,8 +290,8 @@ public void testCreateZoneWithOptions() { assertNotNull(created.generatedId()); created.delete(); // combination of multiple things - created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID, - Dns.ZoneField.NAME_SERVERS, Dns.ZoneField.NAME_SERVER_SET, Dns.ZoneField.DESCRIPTION)); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(ZoneField.ZONE_ID, + ZoneField.NAME_SERVERS, ZoneField.NAME_SERVER_SET, ZoneField.DESCRIPTION)); assertEquals(ZONE1.name(), created.name()); // always returned assertNull(created.creationTimeMillis()); assertNull(created.dnsName()); @@ -301,8 +307,8 @@ public void testCreateZoneWithOptions() { @Test public void testGetZone() { try { - DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); - Zone created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.CREATION_TIME)); + DNS.create(ZONE1, Dns.ZoneOption.fields(ZoneField.NAME)); + Zone created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(ZoneField.CREATION_TIME)); assertEquals(ZONE1.name(), created.name()); // always returned assertNotNull(created.creationTimeMillis()); assertNull(created.description()); @@ -310,7 +316,7 @@ public void testGetZone() { assertTrue(created.nameServers().isEmpty()); // never returns null assertNull(created.nameServerSet()); assertNull(created.generatedId()); - created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.DESCRIPTION)); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(ZoneField.DESCRIPTION)); assertEquals(ZONE1.name(), created.name()); // always returned assertNull(created.creationTimeMillis()); assertEquals(ZONE1.description(), created.description()); @@ -318,7 +324,7 @@ public void testGetZone() { assertTrue(created.nameServers().isEmpty()); // never returns null assertNull(created.nameServerSet()); assertNull(created.generatedId()); - created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.DNS_NAME)); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(ZoneField.DNS_NAME)); assertEquals(ZONE1.name(), created.name()); // always returned assertNull(created.creationTimeMillis()); assertEquals(ZONE1.dnsName(), created.dnsName()); @@ -326,7 +332,7 @@ public void testGetZone() { assertTrue(created.nameServers().isEmpty()); // never returns null assertNull(created.nameServerSet()); assertNull(created.generatedId()); - created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.NAME)); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(ZoneField.NAME)); assertEquals(ZONE1.name(), created.name()); // always returned assertNull(created.creationTimeMillis()); assertNull(created.dnsName()); @@ -334,7 +340,7 @@ public void testGetZone() { assertTrue(created.nameServers().isEmpty()); // never returns null assertNull(created.nameServerSet()); assertNull(created.generatedId()); - created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVER_SET)); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(ZoneField.NAME_SERVER_SET)); assertEquals(ZONE1.name(), created.name()); // always returned assertNull(created.creationTimeMillis()); assertNull(created.dnsName()); @@ -342,7 +348,7 @@ public void testGetZone() { assertTrue(created.nameServers().isEmpty()); // never returns null assertNull(created.nameServerSet()); // we did not set it assertNull(created.generatedId()); - created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVERS)); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(ZoneField.NAME_SERVERS)); assertEquals(ZONE1.name(), created.name()); // always returned assertNull(created.creationTimeMillis()); assertNull(created.dnsName()); @@ -350,7 +356,7 @@ public void testGetZone() { assertFalse(created.nameServers().isEmpty()); assertNull(created.nameServerSet()); assertNull(created.generatedId()); - created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID)); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(ZoneField.ZONE_ID)); assertEquals(ZONE1.name(), created.name()); // always returned assertNull(created.creationTimeMillis()); assertNull(created.dnsName()); @@ -359,8 +365,8 @@ public void testGetZone() { assertTrue(created.nameServers().isEmpty()); // never returns null assertNotNull(created.generatedId()); // combination of multiple things - created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID, - Dns.ZoneField.NAME_SERVERS, Dns.ZoneField.NAME_SERVER_SET, Dns.ZoneField.DESCRIPTION)); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(ZoneField.ZONE_ID, + ZoneField.NAME_SERVERS, ZoneField.NAME_SERVER_SET, ZoneField.DESCRIPTION)); assertEquals(ZONE1.name(), created.name()); // always returned assertNull(created.creationTimeMillis()); assertNull(created.dnsName()); @@ -421,7 +427,7 @@ public void testListZones() { assertEquals(1, zones.size()); // field options Iterator zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), - Dns.ZoneListOption.fields(Dns.ZoneField.ZONE_ID)).iterateAll(); + Dns.ZoneListOption.fields(ZoneField.ZONE_ID)).iterateAll(); Zone zone = zoneIterator.next(); assertNull(zone.creationTimeMillis()); assertNotNull(zone.name()); @@ -432,7 +438,7 @@ public void testListZones() { assertNotNull(zone.generatedId()); assertFalse(zoneIterator.hasNext()); zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), - Dns.ZoneListOption.fields(Dns.ZoneField.CREATION_TIME)).iterateAll(); + Dns.ZoneListOption.fields(ZoneField.CREATION_TIME)).iterateAll(); zone = zoneIterator.next(); assertNotNull(zone.creationTimeMillis()); assertNotNull(zone.name()); @@ -443,7 +449,7 @@ public void testListZones() { assertNull(zone.generatedId()); assertFalse(zoneIterator.hasNext()); zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), - Dns.ZoneListOption.fields(Dns.ZoneField.DNS_NAME)).iterateAll(); + Dns.ZoneListOption.fields(ZoneField.DNS_NAME)).iterateAll(); zone = zoneIterator.next(); assertNull(zone.creationTimeMillis()); assertNotNull(zone.name()); @@ -454,7 +460,7 @@ public void testListZones() { assertNull(zone.generatedId()); assertFalse(zoneIterator.hasNext()); zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), - Dns.ZoneListOption.fields(Dns.ZoneField.DESCRIPTION)).iterateAll(); + Dns.ZoneListOption.fields(ZoneField.DESCRIPTION)).iterateAll(); zone = zoneIterator.next(); assertNull(zone.creationTimeMillis()); assertNotNull(zone.name()); @@ -465,7 +471,7 @@ public void testListZones() { assertNull(zone.generatedId()); assertFalse(zoneIterator.hasNext()); zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), - Dns.ZoneListOption.fields(Dns.ZoneField.NAME_SERVERS)).iterateAll(); + Dns.ZoneListOption.fields(ZoneField.NAME_SERVERS)).iterateAll(); zone = zoneIterator.next(); assertNull(zone.creationTimeMillis()); assertNotNull(zone.name()); @@ -476,7 +482,7 @@ public void testListZones() { assertNull(zone.generatedId()); assertFalse(zoneIterator.hasNext()); zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), - Dns.ZoneListOption.fields(Dns.ZoneField.NAME_SERVER_SET)).iterateAll(); + Dns.ZoneListOption.fields(ZoneField.NAME_SERVER_SET)).iterateAll(); zone = zoneIterator.next(); assertNull(zone.creationTimeMillis()); assertNotNull(zone.name()); @@ -487,8 +493,8 @@ public void testListZones() { assertNull(zone.generatedId()); assertFalse(zoneIterator.hasNext()); // several combined - zones = filter(DNS.listZones(Dns.ZoneListOption.fields(Dns.ZoneField.ZONE_ID, - Dns.ZoneField.DESCRIPTION), + zones = filter(DNS.listZones(Dns.ZoneListOption.fields(ZoneField.ZONE_ID, + ZoneField.DESCRIPTION), Dns.ZoneListOption.pageSize(1)).iterateAll()); assertEquals(2, zones.size()); for (Zone current : zones) { @@ -521,12 +527,12 @@ public void testDeleteZone() { @Test public void testCreateChange() { try { - DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); + DNS.create(ZONE1, Dns.ZoneOption.fields(ZoneField.NAME)); ChangeRequest created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); assertEquals(CHANGE_ADD_ZONE1.additions(), created.additions()); assertNotNull(created.startTimeMillis()); assertTrue(created.deletions().isEmpty()); - assertEquals("1", created.generatedId()); + assertNotNull(created.generatedId()); assertTrue(ImmutableList.of(ChangeRequest.Status.PENDING, ChangeRequest.Status.DONE) .contains(created.status())); assertEqChangesIgnoreStatus(created, DNS.getChangeRequest(ZONE1.name(), "1")); @@ -535,51 +541,51 @@ public void testCreateChange() { waitForChangeToComplete(created); // with options created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); + Dns.ChangeRequestOption.fields(ChangeRequestField.ID)); assertTrue(created.additions().isEmpty()); assertNull(created.startTimeMillis()); assertTrue(created.deletions().isEmpty()); - assertEquals("3", created.generatedId()); + assertNotNull(created.generatedId()); assertNull(created.status()); waitForChangeToComplete(created); created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); waitForChangeToComplete(created); created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); + Dns.ChangeRequestOption.fields(ChangeRequestField.STATUS)); assertTrue(created.additions().isEmpty()); assertNull(created.startTimeMillis()); assertTrue(created.deletions().isEmpty()); - assertEquals("5", created.generatedId()); + assertNotNull(created.generatedId()); assertNotNull(created.status()); waitForChangeToComplete(created); created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); waitForChangeToComplete(created); created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); + Dns.ChangeRequestOption.fields(ChangeRequestField.START_TIME)); assertTrue(created.additions().isEmpty()); assertNotNull(created.startTimeMillis()); assertTrue(created.deletions().isEmpty()); - assertEquals("7", created.generatedId()); + assertNotNull(created.generatedId()); assertNull(created.status()); waitForChangeToComplete(created); created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); waitForChangeToComplete(created); created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); + Dns.ChangeRequestOption.fields(ChangeRequestField.ADDITIONS)); assertEquals(CHANGE_ADD_ZONE1.additions(), created.additions()); assertNull(created.startTimeMillis()); assertTrue(created.deletions().isEmpty()); - assertEquals("9", created.generatedId()); + assertNotNull(created.generatedId()); assertNull(created.status()); // finishes with delete otherwise we cannot delete the zone waitForChangeToComplete(created); created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); + Dns.ChangeRequestOption.fields(ChangeRequestField.DELETIONS)); waitForChangeToComplete(created); assertEquals(CHANGE_DELETE_ZONE1.deletions(), created.deletions()); assertNull(created.startTimeMillis()); assertTrue(created.additions().isEmpty()); - assertEquals("10", created.generatedId()); + assertNotNull(created.generatedId()); assertNull(created.status()); waitForChangeToComplete(created); } finally { @@ -721,47 +727,47 @@ public void testListChanges() { // field options changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), - Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.ADDITIONS)).iterateAll()); + Dns.ChangeRequestListOption.fields(ChangeRequestField.ADDITIONS)).iterateAll()); change = changes.get(1); assertEquals(CHANGE_ADD_ZONE1.additions(), change.additions()); assertTrue(change.deletions().isEmpty()); - assertEquals("1", change.generatedId()); + assertNotNull(change.generatedId()); assertNull(change.startTimeMillis()); assertNull(change.status()); changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), - Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.DELETIONS)).iterateAll()); + Dns.ChangeRequestListOption.fields(ChangeRequestField.DELETIONS)).iterateAll()); change = changes.get(2); assertTrue(change.additions().isEmpty()); assertNotNull(change.deletions()); - assertEquals("2", change.generatedId()); + assertNotNull(change.generatedId()); assertNull(change.startTimeMillis()); assertNull(change.status()); changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), - Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.ID)).iterateAll()); + Dns.ChangeRequestListOption.fields(ChangeRequestField.ID)).iterateAll()); change = changes.get(1); assertTrue(change.additions().isEmpty()); assertTrue(change.deletions().isEmpty()); - assertEquals("1", change.generatedId()); + assertNotNull(change.generatedId()); assertNull(change.startTimeMillis()); assertNull(change.status()); changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), - Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.START_TIME)).iterateAll()); + Dns.ChangeRequestListOption.fields(ChangeRequestField.START_TIME)).iterateAll()); change = changes.get(1); assertTrue(change.additions().isEmpty()); assertTrue(change.deletions().isEmpty()); - assertEquals("1", change.generatedId()); + assertNotNull(change.generatedId()); assertNotNull(change.startTimeMillis()); assertNull(change.status()); changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), - Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.STATUS)).iterateAll()); + Dns.ChangeRequestListOption.fields(ChangeRequestField.STATUS)).iterateAll()); change = changes.get(1); assertTrue(change.additions().isEmpty()); assertTrue(change.deletions().isEmpty()); - assertEquals("1", change.generatedId()); + assertNotNull(change.generatedId()); assertNull(change.startTimeMillis()); assertEquals(ChangeRequest.Status.DONE, change.status()); } finally { @@ -772,7 +778,7 @@ public void testListChanges() { @Test public void testGetChange() { try { - Zone zone = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); + Zone zone = DNS.create(ZONE1, Dns.ZoneOption.fields(ZoneField.NAME)); ChangeRequest created = zone.applyChangeRequest(CHANGE_ADD_ZONE1); ChangeRequest retrieved = DNS.getChangeRequest(zone.name(), created.generatedId()); assertEqChangesIgnoreStatus(created, retrieved); @@ -780,37 +786,37 @@ public void testGetChange() { zone.applyChangeRequest(CHANGE_DELETE_ZONE1); // with options created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); + Dns.ChangeRequestOption.fields(ChangeRequestField.ID)); retrieved = DNS.getChangeRequest(zone.name(), created.generatedId(), - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); + Dns.ChangeRequestOption.fields(ChangeRequestField.ID)); assertEqChangesIgnoreStatus(created, retrieved); waitForChangeToComplete(zone.name(), created.generatedId()); zone.applyChangeRequest(CHANGE_DELETE_ZONE1); created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); + Dns.ChangeRequestOption.fields(ChangeRequestField.STATUS)); retrieved = DNS.getChangeRequest(zone.name(), created.generatedId(), - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); + Dns.ChangeRequestOption.fields(ChangeRequestField.STATUS)); assertEqChangesIgnoreStatus(created, retrieved); waitForChangeToComplete(zone.name(), created.generatedId()); zone.applyChangeRequest(CHANGE_DELETE_ZONE1); created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); + Dns.ChangeRequestOption.fields(ChangeRequestField.START_TIME)); retrieved = DNS.getChangeRequest(zone.name(), created.generatedId(), - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); + Dns.ChangeRequestOption.fields(ChangeRequestField.START_TIME)); assertEqChangesIgnoreStatus(created, retrieved); waitForChangeToComplete(zone.name(), created.generatedId()); zone.applyChangeRequest(CHANGE_DELETE_ZONE1); created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); + Dns.ChangeRequestOption.fields(ChangeRequestField.ADDITIONS)); retrieved = DNS.getChangeRequest(zone.name(), created.generatedId(), - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); + Dns.ChangeRequestOption.fields(ChangeRequestField.ADDITIONS)); assertEqChangesIgnoreStatus(created, retrieved); waitForChangeToComplete(zone.name(), created.generatedId()); // finishes with delete otherwise we cannot delete the zone created = zone.applyChangeRequest(CHANGE_DELETE_ZONE1, - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); + Dns.ChangeRequestOption.fields(ChangeRequestField.DELETIONS)); retrieved = DNS.getChangeRequest(zone.name(), created.generatedId(), - Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); + Dns.ChangeRequestOption.fields(ChangeRequestField.DELETIONS)); assertEqChangesIgnoreStatus(created, retrieved); waitForChangeToComplete(zone.name(), created.generatedId()); } finally { @@ -824,14 +830,14 @@ public void testGetProject() { ProjectInfo project = DNS.getProject(); assertNotNull(project.quota()); // options - project = DNS.getProject(Dns.ProjectOption.fields(Dns.ProjectField.QUOTA)); + project = DNS.getProject(Dns.ProjectOption.fields(ProjectField.QUOTA)); assertNotNull(project.quota()); - project = DNS.getProject(Dns.ProjectOption.fields(Dns.ProjectField.PROJECT_ID)); + project = DNS.getProject(Dns.ProjectOption.fields(ProjectField.PROJECT_ID)); assertNull(project.quota()); - project = DNS.getProject(Dns.ProjectOption.fields(Dns.ProjectField.PROJECT_NUMBER)); + project = DNS.getProject(Dns.ProjectOption.fields(ProjectField.PROJECT_NUMBER)); assertNull(project.quota()); - project = DNS.getProject(Dns.ProjectOption.fields(Dns.ProjectField.PROJECT_NUMBER, - Dns.ProjectField.QUOTA, Dns.ProjectField.PROJECT_ID)); + project = DNS.getProject(Dns.ProjectOption.fields(ProjectField.PROJECT_NUMBER, + ProjectField.QUOTA, ProjectField.PROJECT_ID)); assertNotNull(project.quota()); } @@ -849,7 +855,7 @@ public void testListDnsRecords() { } // field options Iterator recordSetIterator = DNS.listRecordSets(zone.name(), - Dns.RecordSetListOption.fields(Dns.RecordSetField.TTL)).iterateAll(); + Dns.RecordSetListOption.fields(RecordSetField.TTL)).iterateAll(); int counter = 0; while (recordSetIterator.hasNext()) { RecordSet recordSet = recordSetIterator.next(); @@ -861,7 +867,7 @@ public void testListDnsRecords() { } assertEquals(2, counter); recordSetIterator = DNS.listRecordSets(zone.name(), - Dns.RecordSetListOption.fields(Dns.RecordSetField.NAME)).iterateAll(); + Dns.RecordSetListOption.fields(RecordSetField.NAME)).iterateAll(); counter = 0; while (recordSetIterator.hasNext()) { RecordSet recordSet = recordSetIterator.next(); @@ -873,7 +879,7 @@ public void testListDnsRecords() { } assertEquals(2, counter); recordSetIterator = DNS.listRecordSets(zone.name(), - Dns.RecordSetListOption.fields(Dns.RecordSetField.DNS_RECORDS)) + Dns.RecordSetListOption.fields(RecordSetField.DNS_RECORDS)) .iterateAll(); counter = 0; while (recordSetIterator.hasNext()) { @@ -886,7 +892,7 @@ public void testListDnsRecords() { } assertEquals(2, counter); recordSetIterator = DNS.listRecordSets(zone.name(), - Dns.RecordSetListOption.fields(Dns.RecordSetField.TYPE), + Dns.RecordSetListOption.fields(RecordSetField.TYPE), Dns.RecordSetListOption.pageSize(1)).iterateAll(); // also test paging counter = 0; while (recordSetIterator.hasNext()) { @@ -900,7 +906,7 @@ public void testListDnsRecords() { assertEquals(2, counter); // test page size Page recordSetPage = DNS.listRecordSets(zone.name(), - Dns.RecordSetListOption.fields(Dns.RecordSetField.TYPE), + Dns.RecordSetListOption.fields(RecordSetField.TYPE), Dns.RecordSetListOption.pageSize(1)); assertEquals(1, ImmutableList.copyOf(recordSetPage.values().iterator()).size()); // test name filter @@ -920,8 +926,7 @@ public void testListDnsRecords() { waitForChangeToComplete(ZONE1.name(), change.generatedId()); recordSetIterator = DNS.listRecordSets(ZONE1.name(), Dns.RecordSetListOption.dnsName(A_RECORD_ZONE1.name()), - Dns.RecordSetListOption.type(A_RECORD_ZONE1.type())) - .iterateAll(); + Dns.RecordSetListOption.type(A_RECORD_ZONE1.type())).iterateAll(); counter = 0; while (recordSetIterator.hasNext()) { RecordSet recordSet = recordSetIterator.next(); @@ -962,4 +967,915 @@ public void testListDnsRecords() { clear(); } } + + @Test + public void testListZonesBatch() { + try { + DnsBatch batch = DNS.batch(); + DnsBatchResult> result = batch.listZones(); + batch.submit(); + List zones = filter(result.get().iterateAll()); + assertEquals(0, zones.size()); + // some zones exists + Zone firstZone = DNS.create(ZONE1); + batch = DNS.batch(); + result = batch.listZones(); + batch.submit(); + zones = filter(result.get().iterateAll()); + assertEquals(1, zones.size()); + assertEquals(firstZone, zones.get(0)); + Zone created = DNS.create(ZONE_EMPTY_DESCRIPTION); + batch = DNS.batch(); + result = batch.listZones(); + DnsBatchResult> zeroSizeError = + batch.listZones(Dns.ZoneListOption.pageSize(0)); + DnsBatchResult> negativeSizeError = + batch.listZones(Dns.ZoneListOption.pageSize(-1)); + DnsBatchResult> okSize = batch.listZones(Dns.ZoneListOption.pageSize(1)); + DnsBatchResult> nameError = batch.listZones(Dns.ZoneListOption.dnsName("aaaaa")); + DnsBatchResult> okName = + batch.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName())); + DnsBatchResult> idResult = + batch.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(ZoneField.ZONE_ID)); + DnsBatchResult> timeResult = + batch.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(ZoneField.CREATION_TIME)); + DnsBatchResult> dnsNameResult = + batch.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(ZoneField.DNS_NAME)); + DnsBatchResult> descriptionResult = + batch.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(ZoneField.DESCRIPTION)); + DnsBatchResult> nameServersResult = + batch.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(ZoneField.NAME_SERVERS)); + DnsBatchResult> nameServerSetResult = + batch.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(ZoneField.NAME_SERVER_SET)); + DnsBatchResult> combinationResult = + batch.listZones(Dns.ZoneListOption.fields(ZoneField.ZONE_ID, ZoneField.DESCRIPTION), + Dns.ZoneListOption.pageSize(1)); + batch.submit(); + zones = filter(result.get().iterateAll()); + assertEquals(2, zones.size()); + assertTrue(zones.contains(firstZone)); + assertTrue(zones.contains(created)); + // error in options + try { + zeroSizeError.get(); + fail(); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + assertFalse(ex.retryable()); + } + try { + negativeSizeError.get(); + fail(); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + assertFalse(ex.retryable()); + } + // ok size + assertEquals(1, Iterables.size(okSize.get().values())); + // dns name problems + try { + nameError.get(); + fail(); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + assertFalse(ex.retryable()); + } + // ok name + zones = filter(okName.get().iterateAll()); + assertEquals(1, zones.size()); + // field options + Iterator zoneIterator = idResult.get().iterateAll(); + Zone zone = zoneIterator.next(); + assertNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNull(zone.dnsName()); + assertNull(zone.description()); + assertNull(zone.nameServerSet()); + assertTrue(zone.nameServers().isEmpty()); + assertNotNull(zone.generatedId()); + assertFalse(zoneIterator.hasNext()); + zoneIterator = timeResult.get().iterateAll(); + zone = zoneIterator.next(); + assertNotNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNull(zone.dnsName()); + assertNull(zone.description()); + assertNull(zone.nameServerSet()); + assertTrue(zone.nameServers().isEmpty()); + assertNull(zone.generatedId()); + assertFalse(zoneIterator.hasNext()); + zoneIterator = dnsNameResult.get().iterateAll(); + zone = zoneIterator.next(); + assertNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNotNull(zone.dnsName()); + assertNull(zone.description()); + assertNull(zone.nameServerSet()); + assertTrue(zone.nameServers().isEmpty()); + assertNull(zone.generatedId()); + assertFalse(zoneIterator.hasNext()); + zoneIterator = descriptionResult.get().iterateAll(); + zone = zoneIterator.next(); + assertNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNull(zone.dnsName()); + assertNotNull(zone.description()); + assertNull(zone.nameServerSet()); + assertTrue(zone.nameServers().isEmpty()); + assertNull(zone.generatedId()); + assertFalse(zoneIterator.hasNext()); + zoneIterator = nameServersResult.get().iterateAll(); + zone = zoneIterator.next(); + assertNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNull(zone.dnsName()); + assertNull(zone.description()); + assertNull(zone.nameServerSet()); + assertFalse(zone.nameServers().isEmpty()); + assertNull(zone.generatedId()); + assertFalse(zoneIterator.hasNext()); + zoneIterator = nameServerSetResult.get().iterateAll(); + zone = zoneIterator.next(); + assertNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNull(zone.dnsName()); + assertNull(zone.description()); + assertNull(zone.nameServerSet()); // we cannot set it using gcloud java + assertTrue(zone.nameServers().isEmpty()); + assertNull(zone.generatedId()); + assertFalse(zoneIterator.hasNext()); + // several combined + zones = filter(combinationResult.get().iterateAll()); + assertEquals(2, zones.size()); + for (Zone current : zones) { + assertNull(current.creationTimeMillis()); + assertNotNull(current.name()); + assertNull(current.dnsName()); + assertNotNull(current.description()); + assertNull(current.nameServerSet()); + assertTrue(zone.nameServers().isEmpty()); + assertNotNull(current.generatedId()); + } + } finally { + DNS.delete(ZONE1.name()); + DNS.delete(ZONE_EMPTY_DESCRIPTION.name()); + } + } + + @Test + public void testCreateValidZoneBatch() { + try { + DnsBatch batch = DNS.batch(); + DnsBatchResult completeZoneResult = batch.createZone(ZONE1); + DnsBatchResult partialZoneResult = batch.createZone(ZONE_EMPTY_DESCRIPTION); + batch.submit(); + Zone created = completeZoneResult.get(); + assertEquals(ZONE1.description(), created.description()); + assertEquals(ZONE1.dnsName(), created.dnsName()); + assertEquals(ZONE1.name(), created.name()); + assertNotNull(created.creationTimeMillis()); + assertNotNull(created.nameServers()); + assertNull(created.nameServerSet()); + assertNotNull(created.generatedId()); + Zone retrieved = DNS.getZone(ZONE1.name()); + assertEquals(created, retrieved); + created = partialZoneResult.get(); + assertEquals(ZONE_EMPTY_DESCRIPTION.description(), created.description()); + assertEquals(ZONE_EMPTY_DESCRIPTION.dnsName(), created.dnsName()); + assertEquals(ZONE_EMPTY_DESCRIPTION.name(), created.name()); + assertNotNull(created.creationTimeMillis()); + assertNotNull(created.nameServers()); + assertNull(created.nameServerSet()); + assertNotNull(created.generatedId()); + retrieved = DNS.getZone(ZONE_EMPTY_DESCRIPTION.name()); + assertEquals(created, retrieved); + } finally { + DNS.delete(ZONE1.name()); + DNS.delete(ZONE_EMPTY_DESCRIPTION.name()); + } + } + + @Test + public void testCreateZoneWithErrorsBatch() { + try { + DnsBatch batch = DNS.batch(); + DnsBatchResult nameErrorResult = batch.createZone(ZONE_NAME_ERROR); + DnsBatchResult noPeriodResult = batch.createZone(ZONE_DNS_NO_PERIOD); + batch.submit(); + try { + nameErrorResult.get(); + fail("Zone name is missing a period. The service returns an error."); + } catch (DnsException ex) { + // expected + assertFalse(ex.retryable()); + } + try { + noPeriodResult.get(); + fail("Zone name is missing a period. The service returns an error."); + } catch (DnsException ex) { + // expected + assertFalse(ex.retryable()); + } + } finally { + DNS.delete(ZONE_NAME_ERROR.name()); + DNS.delete(ZONE_DNS_NO_PERIOD.name()); + } + } + + @Test + public void testCreateZoneWithOptionsBatch() { + try { + DnsBatch batch = DNS.batch(); + DnsBatchResult batchResult = + batch.createZone(ZONE1, Dns.ZoneOption.fields(ZoneField.CREATION_TIME)); + batch.submit(); + Zone created = batchResult.get(); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNotNull(created.creationTimeMillis()); + assertNull(created.description()); + assertNull(created.dnsName()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.generatedId()); + created.delete(); + batch = DNS.batch(); + batchResult = batch.createZone(ZONE1, Dns.ZoneOption.fields(ZoneField.DESCRIPTION)); + batch.submit(); + created = batchResult.get(); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertEquals(ZONE1.description(), created.description()); + assertNull(created.dnsName()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.generatedId()); + created.delete(); + batch = DNS.batch(); + batchResult = batch.createZone(ZONE1, Dns.ZoneOption.fields(ZoneField.DNS_NAME)); + batch.submit(); + created = batchResult.get(); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertEquals(ZONE1.dnsName(), created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.generatedId()); + created.delete(); + batch = DNS.batch(); + batchResult = batch.createZone(ZONE1, Dns.ZoneOption.fields(ZoneField.NAME)); + batch.submit(); + created = batchResult.get(); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.generatedId()); + created.delete(); + batch = DNS.batch(); + batchResult = batch.createZone(ZONE1, Dns.ZoneOption.fields(ZoneField.NAME_SERVER_SET)); + batch.submit(); + created = batchResult.get(); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); // we did not set it + assertNull(created.generatedId()); + created.delete(); + batch = DNS.batch(); + batchResult = batch.createZone(ZONE1, Dns.ZoneOption.fields(ZoneField.NAME_SERVERS)); + batch.submit(); + created = batchResult.get(); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertFalse(created.nameServers().isEmpty()); + assertNull(created.nameServerSet()); + assertNull(created.generatedId()); + created.delete(); + batch = DNS.batch(); + batchResult = batch.createZone(ZONE1, Dns.ZoneOption.fields(ZoneField.ZONE_ID)); + batch.submit(); + created = batchResult.get(); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertNotNull(created.nameServers()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNotNull(created.generatedId()); + created.delete(); + batch = DNS.batch(); + batchResult = batch.createZone(ZONE1, Dns.ZoneOption.fields(ZoneField.ZONE_ID, + ZoneField.NAME_SERVERS, ZoneField.NAME_SERVER_SET, ZoneField.DESCRIPTION)); + batch.submit(); + // combination of multiple things + created = batchResult.get(); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertEquals(ZONE1.description(), created.description()); + assertFalse(created.nameServers().isEmpty()); + assertNull(created.nameServerSet()); // we did not set it + assertNotNull(created.generatedId()); + } finally { + DNS.delete(ZONE1.name()); + } + } + + @Test + public void testGetZoneBatch() { + try { + DNS.create(ZONE1, Dns.ZoneOption.fields(ZoneField.NAME)); + DnsBatch batch = DNS.batch(); + DnsBatchResult timeResult = + batch.getZone(ZONE1.name(), Dns.ZoneOption.fields(ZoneField.CREATION_TIME)); + DnsBatchResult descriptionResult = + batch.getZone(ZONE1.name(), Dns.ZoneOption.fields(ZoneField.DESCRIPTION)); + DnsBatchResult dnsNameResult = + batch.getZone(ZONE1.name(), Dns.ZoneOption.fields(ZoneField.DNS_NAME)); + DnsBatchResult nameResult = + batch.getZone(ZONE1.name(), Dns.ZoneOption.fields(ZoneField.NAME)); + DnsBatchResult nameServerSetResult = + batch.getZone(ZONE1.name(), Dns.ZoneOption.fields(ZoneField.NAME_SERVER_SET)); + DnsBatchResult nameServersResult = + batch.getZone(ZONE1.name(), Dns.ZoneOption.fields(ZoneField.NAME_SERVERS)); + DnsBatchResult idResult = + batch.getZone(ZONE1.name(), Dns.ZoneOption.fields(ZoneField.ZONE_ID)); + DnsBatchResult combinationResult = batch.getZone(ZONE1.name(), + Dns.ZoneOption.fields(ZoneField.ZONE_ID, ZoneField.NAME_SERVERS, + ZoneField.NAME_SERVER_SET, ZoneField.DESCRIPTION)); + batch.submit(); + Zone created = timeResult.get(); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNotNull(created.creationTimeMillis()); + assertNull(created.description()); + assertNull(created.dnsName()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.generatedId()); + created = descriptionResult.get(); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertEquals(ZONE1.description(), created.description()); + assertNull(created.dnsName()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.generatedId()); + created = dnsNameResult.get(); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertEquals(ZONE1.dnsName(), created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.generatedId()); + created = nameResult.get(); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.generatedId()); + created = nameServerSetResult.get(); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); // we did not set it + assertNull(created.generatedId()); + created = nameServersResult.get(); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertFalse(created.nameServers().isEmpty()); + assertNull(created.nameServerSet()); + assertNull(created.generatedId()); + created = idResult.get(); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertNotNull(created.nameServers()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNotNull(created.generatedId()); + // combination of multiple things + created = combinationResult.get(); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertEquals(ZONE1.description(), created.description()); + assertFalse(created.nameServers().isEmpty()); + assertNull(created.nameServerSet()); // we did not set it + assertNotNull(created.generatedId()); + } finally { + DNS.delete(ZONE1.name()); + } + } + + @Test + public void testDeleteZoneBatch() { + try { + Zone created = DNS.create(ZONE1); + assertEquals(created, DNS.getZone(ZONE1.name())); + DnsBatch batch = DNS.batch(); + DnsBatchResult result = batch.deleteZone(ZONE1.name()); + batch.submit(); + assertNull(DNS.getZone(ZONE1.name())); + assertTrue(result.get()); + } finally { + DNS.delete(ZONE1.name()); + } + } + + @Test + public void testGetProjectBatch() { + // fetches all fields + DnsBatch batch = DNS.batch(); + DnsBatchResult result = batch.getProject(); + DnsBatchResult resultQuota = + batch.getProject(Dns.ProjectOption.fields(ProjectField.QUOTA)); + DnsBatchResult resultId = + batch.getProject(Dns.ProjectOption.fields(ProjectField.PROJECT_ID)); + DnsBatchResult resultNumber = + batch.getProject(Dns.ProjectOption.fields(ProjectField.PROJECT_NUMBER)); + DnsBatchResult resultCombination = + batch.getProject(Dns.ProjectOption.fields(ProjectField.PROJECT_NUMBER, + ProjectField.QUOTA, ProjectField.PROJECT_ID)); + batch.submit(); + assertNotNull(result.get().quota()); + assertNotNull(resultQuota.get().quota()); + assertNull(resultId.get().quota()); + assertNull(resultNumber.get().quota()); + assertNotNull(resultCombination.get().quota()); + } + + @Test + public void testCreateChangeBatch() { + try { + DNS.create(ZONE1, Dns.ZoneOption.fields(ZoneField.NAME)); + DnsBatch batch = DNS.batch(); + DnsBatchResult result = + batch.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); + batch.submit(); + ChangeRequest created = result.get(); + assertEquals(CHANGE_ADD_ZONE1.additions(), created.additions()); + assertNotNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertNotNull(created.generatedId()); + assertTrue(ImmutableList.of(ChangeRequest.Status.PENDING, ChangeRequest.Status.DONE) + .contains(created.status())); + assertEqChangesIgnoreStatus(created, DNS.getChangeRequest(ZONE1.name(), "1")); + waitForChangeToComplete(created); + created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + waitForChangeToComplete(created); + // with options + batch = DNS.batch(); + result = batch.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(ChangeRequestField.ID)); + batch.submit(); + created = result.get(); + assertTrue(created.additions().isEmpty()); + assertNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertNotNull(created.generatedId()); + assertNull(created.status()); + waitForChangeToComplete(created); + created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + waitForChangeToComplete(created); + batch = DNS.batch(); + result = batch.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(ChangeRequestField.STATUS)); + batch.submit(); + created = result.get(); + assertTrue(created.additions().isEmpty()); + assertNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertNotNull(created.generatedId()); + assertNotNull(created.status()); + waitForChangeToComplete(created); + created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + waitForChangeToComplete(created); + batch = DNS.batch(); + result = batch.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(ChangeRequestField.START_TIME)); + batch.submit(); + created = result.get(); + assertTrue(created.additions().isEmpty()); + assertNotNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertNotNull(created.generatedId()); + assertNull(created.status()); + waitForChangeToComplete(created); + created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + waitForChangeToComplete(created); + batch = DNS.batch(); + result = batch.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(ChangeRequestField.ADDITIONS)); + batch.submit(); + created = result.get(); + assertEquals(CHANGE_ADD_ZONE1.additions(), created.additions()); + assertNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertNotNull(created.generatedId()); + assertNull(created.status()); + // finishes with delete otherwise we cannot delete the zone + waitForChangeToComplete(created); + batch = DNS.batch(); + result = batch.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1, + Dns.ChangeRequestOption.fields(ChangeRequestField.DELETIONS)); + batch.submit(); + created = result.get(); + waitForChangeToComplete(created); + assertEquals(CHANGE_DELETE_ZONE1.deletions(), created.deletions()); + assertNull(created.startTimeMillis()); + assertTrue(created.additions().isEmpty()); + assertNotNull(created.generatedId()); + assertNull(created.status()); + waitForChangeToComplete(created); + } finally { + clear(); + } + } + + @Test + public void testGetChangeBatch() { + try { + Zone zone = DNS.create(ZONE1, Dns.ZoneOption.fields(ZoneField.NAME)); + ChangeRequest created = zone.applyChangeRequest(CHANGE_ADD_ZONE1); + waitForChangeToComplete(zone.name(), created.generatedId()); + DnsBatch batch = DNS.batch(); + DnsBatchResult completeResult = + batch.getChangeRequest(zone.name(), created.generatedId()); + DnsBatchResult idResult = + batch.getChangeRequest(zone.name(), created.generatedId(), + Dns.ChangeRequestOption.fields(ChangeRequestField.ID)); + DnsBatchResult statusResult = + batch.getChangeRequest(zone.name(), created.generatedId(), + Dns.ChangeRequestOption.fields(ChangeRequestField.STATUS)); + DnsBatchResult timeResult = + batch.getChangeRequest(zone.name(), created.generatedId(), + Dns.ChangeRequestOption.fields(ChangeRequestField.START_TIME)); + DnsBatchResult additionsResult = + batch.getChangeRequest(zone.name(), created.generatedId(), + Dns.ChangeRequestOption.fields(ChangeRequestField.ADDITIONS)); + batch.submit(); + assertEqChangesIgnoreStatus(created, completeResult.get()); + // with options + ChangeRequest retrieved = idResult.get(); + assertEquals(created.generatedId(), retrieved.generatedId()); + assertEquals(0, retrieved.additions().size()); + assertEquals(0, retrieved.deletions().size()); + assertNull(retrieved.startTimeMillis()); + assertNull(retrieved.status()); + retrieved = statusResult.get(); + assertEquals(created.generatedId(), retrieved.generatedId()); + assertEquals(0, retrieved.additions().size()); + assertEquals(0, retrieved.deletions().size()); + assertNull(retrieved.startTimeMillis()); + assertEquals(ChangeRequestInfo.Status.DONE, retrieved.status()); + retrieved = timeResult.get(); + assertEquals(created.generatedId(), retrieved.generatedId()); + assertEquals(0, retrieved.additions().size()); + assertEquals(0, retrieved.deletions().size()); + assertEquals(created.startTimeMillis(), retrieved.startTimeMillis()); + assertNull(retrieved.status()); + retrieved = additionsResult.get(); + assertEquals(created.generatedId(), retrieved.generatedId()); + assertEquals(2, retrieved.additions().size()); + assertTrue(retrieved.additions().contains(A_RECORD_ZONE1)); + assertTrue(retrieved.additions().contains(AAAA_RECORD_ZONE1)); + assertEquals(0, retrieved.deletions().size()); + assertNull(retrieved.startTimeMillis()); + assertNull(retrieved.status()); + // finishes with delete otherwise we cannot delete the zone + created = zone.applyChangeRequest(CHANGE_DELETE_ZONE1, + Dns.ChangeRequestOption.fields(ChangeRequestField.DELETIONS)); + batch = DNS.batch(); + DnsBatchResult deletionsResult = + batch.getChangeRequest(zone.name(), created.generatedId(), + Dns.ChangeRequestOption.fields(ChangeRequestField.DELETIONS)); + batch.submit(); + retrieved = deletionsResult.get(); + assertEquals(created.generatedId(), retrieved.generatedId()); + assertEquals(0, retrieved.additions().size()); + assertEquals(2, retrieved.deletions().size()); + assertTrue(retrieved.deletions().contains(AAAA_RECORD_ZONE1)); + assertTrue(retrieved.deletions().contains(A_RECORD_ZONE1)); + assertNull(retrieved.startTimeMillis()); + assertNull(retrieved.status()); + waitForChangeToComplete(zone.name(), created.generatedId()); + } finally { + clear(); + } + } + + @Test + public void testListChangesBatch() { + try { + DnsBatch batch = DNS.batch(); + DnsBatchResult> result = batch.listChangeRequests(ZONE1.name()); + batch.submit(); + try { + result.get(); + fail("Zone does not exist yet"); + } catch (DnsException ex) { + // expected + assertEquals(404, ex.code()); + assertFalse(ex.retryable()); + } + // zone exists but has no changes + DNS.create(ZONE1); + batch = DNS.batch(); + result = batch.listChangeRequests(ZONE1.name()); + batch.submit(); + assertEquals(1, Iterables.size(result.get().values())); // default change creating SOA and NS + // zone has changes + ChangeRequest change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); + waitForChangeToComplete(ZONE1.name(), change.generatedId()); + change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + waitForChangeToComplete(ZONE1.name(), change.generatedId()); + batch = DNS.batch(); + result = batch.listChangeRequests(ZONE1.name()); + DnsBatchResult> errorPageSize = batch.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.pageSize(0)); + DnsBatchResult> errorPageNegative = batch.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.pageSize(-1)); + DnsBatchResult> resultAscending = batch.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING)); + DnsBatchResult> resultDescending = batch.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.DESCENDING)); + DnsBatchResult> resultAdditions = batch.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(ChangeRequestField.ADDITIONS)); + DnsBatchResult> resultDeletions = batch.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(ChangeRequestField.DELETIONS)); + DnsBatchResult> resultId = batch.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(ChangeRequestField.ID)); + DnsBatchResult> resultTime = batch.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(ChangeRequestField.START_TIME)); + DnsBatchResult> resultStatus = batch.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(ChangeRequestField.STATUS)); + batch.submit(); + assertEquals(3, Iterables.size(result.get().values())); + // error in options + try { + errorPageSize.get(); + fail(); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + assertFalse(ex.retryable()); + } + try { + errorPageNegative.get(); + fail(); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + assertFalse(ex.retryable()); + } + // sorting order + ImmutableList ascending = + ImmutableList.copyOf(resultAscending.get().iterateAll()); + ImmutableList descending = + ImmutableList.copyOf(resultDescending.get().iterateAll()); + int size = 3; + assertEquals(size, descending.size()); + assertEquals(size, ascending.size()); + for (int i = 0; i < size; i++) { + assertEquals(descending.get(i), ascending.get(size - i - 1)); + } + // field options + change = Iterables.get(resultAdditions.get().values(), 1); + assertEquals(CHANGE_ADD_ZONE1.additions(), change.additions()); + assertTrue(change.deletions().isEmpty()); + assertNotNull(change.generatedId()); + assertNull(change.startTimeMillis()); + assertNull(change.status()); + change = Iterables.get(resultDeletions.get().values(), 2); + assertTrue(change.additions().isEmpty()); + assertNotNull(change.deletions()); + assertNotNull(change.generatedId()); + assertNull(change.startTimeMillis()); + assertNull(change.status()); + change = Iterables.get(resultId.get().values(), 1); + assertTrue(change.additions().isEmpty()); + assertTrue(change.deletions().isEmpty()); + assertNotNull(change.generatedId()); + assertNull(change.startTimeMillis()); + assertNull(change.status()); + change = Iterables.get(resultTime.get().values(), 1); + assertTrue(change.additions().isEmpty()); + assertTrue(change.deletions().isEmpty()); + assertNotNull(change.generatedId()); + assertNotNull(change.startTimeMillis()); + assertNull(change.status()); + change = Iterables.get(resultStatus.get().values(), 1); + assertTrue(change.additions().isEmpty()); + assertTrue(change.deletions().isEmpty()); + assertNotNull(change.generatedId()); + assertNull(change.startTimeMillis()); + assertEquals(ChangeRequest.Status.DONE, change.status()); + } finally { + clear(); + } + } + + @Test + public void testListDnsRecordSetsBatch() { + try { + Zone zone = DNS.create(ZONE1); + DnsBatch batch = DNS.batch(); + DnsBatchResult> result = batch.listRecordSets(zone.name()); + batch.submit(); + ImmutableList recordSets = ImmutableList.copyOf(result.get().iterateAll()); + assertEquals(2, recordSets.size()); + ImmutableList defaultRecords = + ImmutableList.of(RecordSet.Type.NS, RecordSet.Type.SOA); + for (RecordSet recordSet : recordSets) { + assertTrue(defaultRecords.contains(recordSet.type())); + } + // field options + batch = DNS.batch(); + DnsBatchResult> ttlResult = batch.listRecordSets(zone.name(), + Dns.RecordSetListOption.fields(RecordSetField.TTL)); + DnsBatchResult> nameResult = batch.listRecordSets(zone.name(), + Dns.RecordSetListOption.fields(RecordSetField.NAME)); + DnsBatchResult> recordsResult = batch.listRecordSets(zone.name(), + Dns.RecordSetListOption.fields(RecordSetField.DNS_RECORDS)); + DnsBatchResult> pageSizeResult = batch.listRecordSets(zone.name(), + Dns.RecordSetListOption.fields(RecordSetField.TYPE), + Dns.RecordSetListOption.pageSize(1)); + batch.submit(); + Iterator recordSetIterator = ttlResult.get().iterateAll(); + int counter = 0; + while (recordSetIterator.hasNext()) { + RecordSet recordSet = recordSetIterator.next(); + assertEquals(recordSets.get(counter).ttl(), recordSet.ttl()); + assertEquals(recordSets.get(counter).name(), recordSet.name()); + assertEquals(recordSets.get(counter).type(), recordSet.type()); + assertTrue(recordSet.records().isEmpty()); + counter++; + } + assertEquals(2, counter); + recordSetIterator = nameResult.get().iterateAll(); + counter = 0; + while (recordSetIterator.hasNext()) { + RecordSet recordSet = recordSetIterator.next(); + assertEquals(recordSets.get(counter).name(), recordSet.name()); + assertEquals(recordSets.get(counter).type(), recordSet.type()); + assertTrue(recordSet.records().isEmpty()); + assertNull(recordSet.ttl()); + counter++; + } + assertEquals(2, counter); + recordSetIterator = recordsResult.get().iterateAll(); + counter = 0; + while (recordSetIterator.hasNext()) { + RecordSet recordSet = recordSetIterator.next(); + assertEquals(recordSets.get(counter).records(), recordSet.records()); + assertEquals(recordSets.get(counter).name(), recordSet.name()); + assertEquals(recordSets.get(counter).type(), recordSet.type()); + assertNull(recordSet.ttl()); + counter++; + } + assertEquals(2, counter); + recordSetIterator = pageSizeResult.get().iterateAll(); // also test paging + counter = 0; + while (recordSetIterator.hasNext()) { + RecordSet recordSet = recordSetIterator.next(); + assertEquals(recordSets.get(counter).type(), recordSet.type()); + assertEquals(recordSets.get(counter).name(), recordSet.name()); + assertTrue(recordSet.records().isEmpty()); + assertNull(recordSet.ttl()); + counter++; + } + assertEquals(2, counter); + // test page size + Page recordSetPage = pageSizeResult.get(); + assertEquals(1, ImmutableList.copyOf(recordSetPage.values().iterator()).size()); + // test name filter + ChangeRequest change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); + waitForChangeToComplete(ZONE1.name(), change.generatedId()); + batch = DNS.batch(); + result = batch.listRecordSets(ZONE1.name(), + Dns.RecordSetListOption.dnsName(A_RECORD_ZONE1.name())); + batch.submit(); + recordSetIterator = result.get().iterateAll(); + counter = 0; + while (recordSetIterator.hasNext()) { + RecordSet recordSet = recordSetIterator.next(); + assertTrue(ImmutableList.of(A_RECORD_ZONE1.type(), AAAA_RECORD_ZONE1.type()) + .contains(recordSet.type())); + counter++; + } + assertEquals(2, counter); + // test type filter + batch = DNS.batch(); + result = batch.listRecordSets(ZONE1.name(), + Dns.RecordSetListOption.dnsName(A_RECORD_ZONE1.name()), + Dns.RecordSetListOption.type(A_RECORD_ZONE1.type())); + batch.submit(); + recordSetIterator = result.get().iterateAll(); + counter = 0; + while (recordSetIterator.hasNext()) { + RecordSet recordSet = recordSetIterator.next(); + assertEquals(A_RECORD_ZONE1, recordSet); + counter++; + } + assertEquals(1, counter); + batch = DNS.batch(); + DnsBatchResult> noNameError = batch.listRecordSets(ZONE1.name(), + Dns.RecordSetListOption.type(A_RECORD_ZONE1.type())); + DnsBatchResult> zeroSizeError = + batch.listRecordSets(ZONE1.name(), Dns.RecordSetListOption.pageSize(0)); + DnsBatchResult> negativeSizeError = + batch.listRecordSets(ZONE1.name(), Dns.RecordSetListOption.pageSize(-1)); + batch.submit(); + // check wrong arguments + try { + // name is not set + noNameError.get(); + fail(); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + assertFalse(ex.retryable()); + } + try { + zeroSizeError.get(); + fail(); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + assertFalse(ex.retryable()); + } + try { + negativeSizeError.get(); + fail(); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + assertFalse(ex.retryable()); + } + waitForChangeToComplete(ZONE1.name(), change.generatedId()); + } finally { + clear(); + } + } + + @Test + public void testBatchCombined() { + // only testing that the combination is possible + // the results are validated in the other test methods + try { + DNS.create(ZONE1); + DnsBatch batch = DNS.batch(); + DnsBatchResult zoneResult = batch.getZone(ZONE_NAME1); + DnsBatchResult changeRequestResult = batch.getChangeRequest(ZONE_NAME1, "0"); + DnsBatchResult> pageResult = batch.listRecordSets(ZONE_NAME1); + DnsBatchResult projectResult = batch.getProject(); + assertFalse(zoneResult.completed()); + try { + zoneResult.get(); + fail("this should be submitted first"); + } catch (IllegalStateException ex) { + // expected + } + batch.submit(); + assertNotNull(zoneResult.get().creationTimeMillis()); + assertEquals(ZONE1.dnsName(), zoneResult.get().dnsName()); + assertEquals(ZONE1.description(), zoneResult.get().description()); + assertFalse(zoneResult.get().nameServers().isEmpty()); + assertNull(zoneResult.get().nameServerSet()); // we did not set it + assertNotNull(zoneResult.get().generatedId()); + assertNotNull(projectResult.get().quota()); + assertEquals(2, Iterables.size(pageResult.get().values())); + assertNotNull(changeRequestResult.get()); + } finally { + DNS.delete(ZONE1.name()); + } + } } diff --git a/gcloud-java-dns/src/test/java/com/google/cloud/dns/testing/LocalDnsHelperTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/testing/LocalDnsHelperTest.java index fce958d3a126..6831485f821e 100644 --- a/gcloud-java-dns/src/test/java/com/google/cloud/dns/testing/LocalDnsHelperTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/testing/LocalDnsHelperTest.java @@ -23,16 +23,22 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import com.google.api.client.googleapis.json.GoogleJsonError; import com.google.api.services.dns.model.Change; +import com.google.api.services.dns.model.ChangesListResponse; import com.google.api.services.dns.model.ManagedZone; +import com.google.api.services.dns.model.ManagedZonesListResponse; import com.google.api.services.dns.model.Project; import com.google.api.services.dns.model.ResourceRecordSet; +import com.google.api.services.dns.model.ResourceRecordSetsListResponse; import com.google.cloud.dns.DnsException; import com.google.cloud.dns.spi.DefaultDnsRpc; import com.google.cloud.dns.spi.DnsRpc; +import com.google.cloud.dns.spi.RpcBatch; import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import org.junit.AfterClass; @@ -72,6 +78,24 @@ public class LocalDnsHelperTest { private static final String REAL_PROJECT_ID = LOCAL_DNS_HELPER.options().projectId(); private Map optionsMap; + private static abstract class FailExpectedCallback implements RpcBatch.Callback { + @Override + public void onSuccess(T t) { + fail(); + } + + public abstract void onFailure(GoogleJsonError e); + } + + private static abstract class SuccessExpectedCallback implements RpcBatch.Callback { + public abstract void onSuccess(T t); + + @Override + public void onFailure(GoogleJsonError e) { + fail(); + } + } + @BeforeClass public static void before() { ZONE1.setName(ZONE_NAME1); @@ -682,7 +706,7 @@ public void testListZones() { } @Test - public void testListDnsRecords() { + public void testListRecordSets() { // no zone exists try { RPC.listRecordSets(ZONE_NAME1, EMPTY_RPC_OPTIONS); @@ -1445,4 +1469,1052 @@ private static ResourceRecordSet copyRrset(ResourceRecordSet set) { copy.setType(set.getType()); return copy; } + + @Test + public void testGetProjectBatch() { + // the projects are automatically created when getProject is called + assertNotNull(LOCAL_DNS_HELPER.getProject(PROJECT_ID1, null)); + assertNotNull(LOCAL_DNS_HELPER.getProject(PROJECT_ID2, null)); + RpcBatch batch = RPC.createBatch(); + batch.addGetProject(new SuccessExpectedCallback() { + @Override + public void onSuccess(Project project) { + assertNotNull(project.getQuota()); + assertEquals(REAL_PROJECT_ID, project.getId()); + } + }, EMPTY_RPC_OPTIONS); + batch.addGetProject(new SuccessExpectedCallback() { + @Override + public void onSuccess(Project project) { + assertNull(project.getId()); + assertNotNull(project.getNumber()); + assertNull(project.getQuota()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "number")); + batch.addGetProject(new SuccessExpectedCallback() { + @Override + public void onSuccess(Project project) { + assertNotNull(project.getId()); + assertNull(project.getNumber()); + assertNull(project.getQuota()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "id")); + batch.addGetProject(new SuccessExpectedCallback() { + @Override + public void onSuccess(Project project) { + assertNull(project.getId()); + assertNull(project.getNumber()); + assertNotNull(project.getQuota()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "quota")); + batch.submit(); + } + + @Test + public void testCreateZoneBatch() { + RpcBatch batch = RPC.createBatch(); + batch.addCreateZone(ZONE1, new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZone created) { + // check that default records were created + DnsRpc.ListResult listResult + = RPC.listRecordSets(ZONE1.getName(), EMPTY_RPC_OPTIONS); + ImmutableList defaultTypes = ImmutableList.of("SOA", "NS"); + Iterator iterator = listResult.results().iterator(); + assertTrue(defaultTypes.contains(iterator.next().getType())); + assertTrue(defaultTypes.contains(iterator.next().getType())); + assertFalse(iterator.hasNext()); + assertEquals(created, LOCAL_DNS_HELPER.findZone(REAL_PROJECT_ID, ZONE1.getName()).zone()); + ManagedZone zone = RPC.getZone(ZONE_NAME1, EMPTY_RPC_OPTIONS); + assertEquals(created, zone); + } + }, EMPTY_RPC_OPTIONS); + batch.submit(); + batch = RPC.createBatch(); + batch.addCreateZone(null, new FailExpectedCallback() { + @Override + public void onFailure(GoogleJsonError googleJsonError) { + assertEquals(400, googleJsonError.getCode()); + assertTrue(googleJsonError.getMessage().contains("entity.managedZone")); + } + }, EMPTY_RPC_OPTIONS); + batch.addCreateZone(ZONE1, new FailExpectedCallback() { + @Override + public void onFailure(GoogleJsonError ex) { + assertEquals(409, ex.getCode()); + assertTrue(ex.getMessage().contains("already exists")); + } + }, EMPTY_RPC_OPTIONS); + batch.submit(); + // field options + resetProjects(); + batch = RPC.createBatch(); + batch.addCreateZone(copyZoneNewName(ZONE1, "z1"), + new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZone zone) { + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNotNull(zone.getId()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "id")); + batch.addCreateZone(copyZoneNewName(ZONE1, "z2"), + new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZone zone) { + assertNotNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "creationTime")); + batch.addCreateZone(copyZoneNewName(ZONE1, "z3"), + new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZone zone) { + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNotNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "dnsName")); + batch.addCreateZone(copyZoneNewName(ZONE1, "z4"), + new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZone zone) { + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNotNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "description")); + batch.addCreateZone(copyZoneNewName(ZONE1, "z5"), + new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZone zone) { + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNotNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "nameServers")); + batch.addCreateZone(copyZoneNewName(ZONE1, "z6"), + new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZone zone) { + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNotNull(zone.getNameServerSet()); + assertNull(zone.getId()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "nameServerSet")); + batch.addCreateZone(copyZoneNewName(ZONE1, "z7"), + new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZone zone) { + assertNull(zone.getCreationTime()); + assertNotNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNotNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNotNull(zone.getNameServerSet()); + assertNotNull(zone.getId()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "nameServerSet,description,id,name")); + batch.submit(); + } + + @Test + public void testGetZoneBatch() { + // non-existent + assertNull(RPC.getZone(ZONE_NAME1, EMPTY_RPC_OPTIONS)); + // existent + final ManagedZone created = RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + ManagedZone zone = RPC.getZone(ZONE_NAME1, EMPTY_RPC_OPTIONS); + assertEquals(created, zone); + assertEquals(ZONE1.getName(), zone.getName()); + // field options + RpcBatch batch = RPC.createBatch(); + batch.addGetZone(ZONE1.getName(), + new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZone zone) { + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertEquals(created.getId(), zone.getId()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "id")); + batch.addGetZone(ZONE1.getName(), + new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZone zone) { + assertEquals(created.getCreationTime(), zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "creationTime")); + batch.addGetZone(ZONE1.getName(), + new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZone zone) { + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertEquals(created.getDnsName(), zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "dnsName")); + batch.addGetZone(ZONE1.getName(), + new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZone zone) { + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertEquals(created.getDescription(), zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "description")); + batch.addGetZone(ZONE1.getName(), + new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZone zone) { + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertEquals(created.getNameServers(), zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "nameServers")); + batch.addGetZone(ZONE1.getName(), + new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZone zone) { + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertEquals(created.getNameServerSet(), zone.getNameServerSet()); + assertNull(zone.getId()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "nameServerSet")); + batch.addGetZone(ZONE1.getName(), + new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZone zone) { + assertNull(zone.getCreationTime()); + assertEquals(created.getName(), zone.getName()); + assertNull(zone.getDnsName()); + assertEquals(created.getDescription(), zone.getDescription()); + assertNull(zone.getNameServers()); + assertEquals(created.getNameServerSet(), zone.getNameServerSet()); + assertEquals(created.getId(), zone.getId()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "nameServerSet,description,id,name")); + batch.submit(); + } + + @Test + public void testDeleteZoneBatch() { + RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + RpcBatch batch = RPC.createBatch(); + batch.addDeleteZone(ZONE1.getName(), new SuccessExpectedCallback() { + @Override + public void onSuccess(Void response) { + assertNull(RPC.getZone(ZONE1.getName(), EMPTY_RPC_OPTIONS)); + } + }); + batch.submit(); + batch = RPC.createBatch(); + assertNull(RPC.getZone(ZONE1.getName(), EMPTY_RPC_OPTIONS)); + // deleting non-existent zone + batch.addDeleteZone(ZONE1.getName(), new FailExpectedCallback() { + @Override + public void onFailure(GoogleJsonError ex) { + // expected + assertEquals(404, ex.getCode()); + } + }); + batch.submit(); + RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + RPC.create(ZONE2, EMPTY_RPC_OPTIONS); + assertNotNull(RPC.getZone(ZONE1.getName(), EMPTY_RPC_OPTIONS)); + assertNotNull(RPC.getZone(ZONE2.getName(), EMPTY_RPC_OPTIONS)); + // delete mutiple + batch = RPC.createBatch(); + batch.addDeleteZone(ZONE2.getName(), new SuccessExpectedCallback() { + @Override + public void onSuccess(Void response) { + assertNull(RPC.getZone(ZONE2.getName(), EMPTY_RPC_OPTIONS)); + } + }); + batch.addDeleteZone(ZONE1.getName(), new SuccessExpectedCallback() { + @Override + public void onSuccess(Void response) { + assertNull(RPC.getZone(ZONE1.getName(), EMPTY_RPC_OPTIONS)); + } + }); + batch.submit(); + RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + RPC.applyChangeRequest(ZONE1.getName(), CHANGE_KEEP, EMPTY_RPC_OPTIONS); + batch = RPC.createBatch(); + batch.addDeleteZone(ZONE1.getName(), new FailExpectedCallback() { + @Override + public void onFailure(GoogleJsonError ex) { + // expected + assertEquals(400, ex.getCode()); + assertTrue(ex.getMessage().contains("not empty")); + } + }); + batch.submit(); + } + + private static ManagedZone copyZoneNewName(ManagedZone zone, String name) { + ManagedZone copy = new ManagedZone(); + for (String key : zone.keySet()) { + copy.set(key, zone.get(key)); + } + copy.setName(name); + return copy; + } + + @Test + public void testListZonesBatch() { + RpcBatch batch = RPC.createBatch(); + batch.addListZones(new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZonesListResponse zones) { + assertEquals(0, zones.getManagedZones().size()); + } + }, EMPTY_RPC_OPTIONS); + batch.submit(); + // some zones exists + + final ManagedZone first = RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + final ManagedZone second = RPC.create(ZONE2, EMPTY_RPC_OPTIONS); + batch = RPC.createBatch(); + batch.addListZones(new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZonesListResponse zones) { + List results = zones.getManagedZones(); + assertEquals(2, results.size()); + assertTrue(results.contains(first)); + assertTrue(results.contains(second)); + } + }, EMPTY_RPC_OPTIONS); + // error in options + batch.addListZones(new FailExpectedCallback() { + @Override + public void onFailure(GoogleJsonError ex) { + // expected + assertEquals(400, ex.getCode()); + assertTrue(ex.getMessage().contains("parameters.maxResults")); + } + }, ImmutableMap.of(DnsRpc.Option.PAGE_SIZE, 0)); + batch.addListZones(new FailExpectedCallback() { + @Override + public void onFailure(GoogleJsonError ex) { + // expected + assertEquals(400, ex.getCode()); + assertTrue(ex.getMessage().contains("parameters.maxResults")); + } + }, ImmutableMap.of(DnsRpc.Option.PAGE_SIZE, -1)); + // ok size + batch.addListZones(new RpcBatch.Callback() { + @Override + public void onSuccess(ManagedZonesListResponse response) { + assertEquals(1, response.getManagedZones().size()); + } + + @Override + public void onFailure(GoogleJsonError ex) { + fail(); + } + }, ImmutableMap.of(DnsRpc.Option.PAGE_SIZE, 1)); + // dns name problems + batch.addListZones(new FailExpectedCallback() { + @Override + public void onFailure(GoogleJsonError ex) { + // expected + assertEquals(400, ex.getCode()); + assertTrue(ex.getMessage().contains("parameters.dnsName")); + } + }, ImmutableMap.of(DnsRpc.Option.DNS_NAME, "aaa")); + // ok name + batch.addListZones(new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZonesListResponse response) { + assertEquals(0, response.getManagedZones().size()); + } + }, ImmutableMap.of(DnsRpc.Option.DNS_NAME, "aaaa.")); + // field options + batch.addListZones(new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZonesListResponse response) { + ManagedZone zone = response.getManagedZones().get(0); + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNotNull(zone.getId()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "managedZones(id)")); + batch.addListZones(new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZonesListResponse response) { + ManagedZone zone = response.getManagedZones().get(0); + assertNotNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "managedZones(creationTime)")); + batch.addListZones(new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZonesListResponse response) { + ManagedZone zone = response.getManagedZones().get(0); + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNotNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "managedZones(dnsName)")); + batch.addListZones(new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZonesListResponse response) { + ManagedZone zone = response.getManagedZones().get(0); + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNotNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "managedZones(description)")); + batch.addListZones(new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZonesListResponse response) { + ManagedZone zone = response.getManagedZones().get(0); + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNotNull(zone.getNameServers()); + assertNull(zone.getNameServerSet()); + assertNull(zone.getId()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "managedZones(nameServers)")); + batch.addListZones(new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZonesListResponse response) { + ManagedZone zone = response.getManagedZones().get(0); + assertNull(response.getNextPageToken()); + assertNull(zone.getCreationTime()); + assertNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNotNull(zone.getNameServerSet()); + assertNull(zone.getId()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "managedZones(nameServerSet)")); + batch.addListZones(new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZonesListResponse response) { + ManagedZone zone = response.getManagedZones().get(0); + assertNull(zone.getCreationTime()); + assertNotNull(zone.getName()); + assertNull(zone.getDnsName()); + assertNotNull(zone.getDescription()); + assertNull(zone.getNameServers()); + assertNotNull(zone.getNameServerSet()); + assertNotNull(zone.getId()); + assertEquals(zone.getName(), response.getNextPageToken()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, + "managedZones(nameServerSet,description,id,name),nextPageToken", + DnsRpc.Option.PAGE_SIZE, 1)); + batch.submit(); + } + + @Test + public void testListRecordSetsBatch() { + // no zone exists + RpcBatch batch = RPC.createBatch(); + batch.addListRecordSets(ZONE_NAME1, new FailExpectedCallback() { + @Override + public void onFailure(GoogleJsonError ex) { + // expected + assertEquals(404, ex.getCode()); + assertTrue(ex.getMessage().contains("managedZone")); + } + }, EMPTY_RPC_OPTIONS); + batch.submit(); + // zone exists but has no records + batch = RPC.createBatch(); + RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + batch.addListRecordSets(ZONE_NAME1, + new SuccessExpectedCallback() { + @Override + public void onSuccess(ResourceRecordSetsListResponse response) { + assertEquals(2, response.getRrsets().size()); // contains default NS and SOA + } + }, EMPTY_RPC_OPTIONS); + batch.submit(); + // zone has records + RPC.applyChangeRequest(ZONE_NAME1, CHANGE_KEEP, EMPTY_RPC_OPTIONS); + batch = RPC.createBatch(); + batch.addListRecordSets(ZONE_NAME1, + new SuccessExpectedCallback() { + @Override + public void onSuccess(ResourceRecordSetsListResponse response) { + assertEquals(3, response.getRrsets().size()); + } + }, EMPTY_RPC_OPTIONS); + batch.addListRecordSets(ZONE_NAME1, new FailExpectedCallback() { + @Override + public void onFailure(GoogleJsonError ex) { + // expected + assertEquals(400, ex.getCode()); + assertTrue(ex.getMessage().contains("parameters.maxResults")); + } + }, ImmutableMap.of(DnsRpc.Option.PAGE_SIZE, 0)); + batch.addListRecordSets(ZONE_NAME1, new FailExpectedCallback() { + @Override + public void onFailure(GoogleJsonError ex) { + // expected + assertEquals(400, ex.getCode()); + assertTrue(ex.getMessage().contains("parameters.maxResults")); + } + }, ImmutableMap.of(DnsRpc.Option.PAGE_SIZE, -1)); + // ok size + batch.addListRecordSets(ZONE_NAME1, + new SuccessExpectedCallback() { + @Override + public void onSuccess(ResourceRecordSetsListResponse response) { + assertEquals(2, response.getRrsets().size()); + } + }, ImmutableMap.of(DnsRpc.Option.PAGE_SIZE, 2)); + // dns name filter + batch.addListRecordSets(ZONE_NAME1, new FailExpectedCallback() { + @Override + public void onFailure(GoogleJsonError ex) { + // expected + assertEquals(400, ex.getCode()); + assertTrue(ex.getMessage().contains("parameters.name")); + } + }, ImmutableMap.of(DnsRpc.Option.NAME, "aaa")); + // dns name filter + batch.addListRecordSets(ZONE_NAME1, + new SuccessExpectedCallback() { + @Override + public void onSuccess(ResourceRecordSetsListResponse response) { + assertEquals(0, response.getRrsets().size()); + } + }, ImmutableMap.of(DnsRpc.Option.NAME, "aaa.")); + // filter type but no name + batch.addListRecordSets(ZONE_NAME1, new FailExpectedCallback() { + @Override + public void onFailure(GoogleJsonError ex) { + // expected + assertEquals(400, ex.getCode()); + assertTrue(ex.getMessage().contains("parameters.name")); + } + }, ImmutableMap.of(DnsRpc.Option.DNS_TYPE, "A")); + batch.addListRecordSets(ZONE_NAME1, + new SuccessExpectedCallback() { + @Override + public void onSuccess(ResourceRecordSetsListResponse response) { + assertEquals(1, response.getRrsets().size()); + } + }, ImmutableMap.of(DnsRpc.Option.NAME, ZONE1.getDnsName(), DnsRpc.Option.DNS_TYPE, "SOA")); + // field options + batch.addListRecordSets(ZONE_NAME1, + new SuccessExpectedCallback() { + @Override + public void onSuccess(ResourceRecordSetsListResponse response) { + ResourceRecordSet record = response.getRrsets().get(0); + assertNotNull(record.getName()); + assertNull(record.getRrdatas()); + assertNull(record.getType()); + assertNull(record.getTtl()); + assertNull(response.getNextPageToken()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "rrsets(name)")); + batch.addListRecordSets(ZONE_NAME1, + new SuccessExpectedCallback() { + @Override + public void onSuccess(ResourceRecordSetsListResponse response) { + ResourceRecordSet record = response.getRrsets().get(0); + assertNull(record.getName()); + assertNotNull(record.getRrdatas()); + assertNull(record.getType()); + assertNull(record.getTtl()); + assertNull(response.getNextPageToken()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "rrsets(rrdatas)")); + batch.addListRecordSets(ZONE_NAME1, + new SuccessExpectedCallback() { + @Override + public void onSuccess(ResourceRecordSetsListResponse response) { + ResourceRecordSet record = response.getRrsets().get(0); + assertNull(record.getName()); + assertNull(record.getRrdatas()); + assertNull(record.getType()); + assertNotNull(record.getTtl()); + assertNull(response.getNextPageToken()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "rrsets(ttl)")); + batch.addListRecordSets(ZONE_NAME1, + new SuccessExpectedCallback() { + @Override + public void onSuccess(ResourceRecordSetsListResponse response) { + ResourceRecordSet record = response.getRrsets().get(0); + assertNull(record.getName()); + assertNull(record.getRrdatas()); + assertNotNull(record.getType()); + assertNull(record.getTtl()); + assertNull(response.getNextPageToken()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "rrsets(type)")); + batch.addListRecordSets(ZONE_NAME1, + new SuccessExpectedCallback() { + @Override + public void onSuccess(ResourceRecordSetsListResponse response) { + ResourceRecordSet record = response.getRrsets().get(0); + assertNull(record.getName()); + assertNull(record.getRrdatas()); + assertNull(record.getType()); + assertNull(record.getTtl()); + assertNull(response.getNextPageToken()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "nextPageToken")); + batch.addListRecordSets(ZONE_NAME1, + new SuccessExpectedCallback() { + @Override + public void onSuccess(ResourceRecordSetsListResponse response) { + assertEquals(1, response.getRrsets().size()); + ResourceRecordSet record = response.getRrsets().get(0); + assertNotNull(record.getName()); + assertNotNull(record.getRrdatas()); + assertNull(record.getType()); + assertNull(record.getTtl()); + assertNotNull(response.getNextPageToken()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "nextPageToken,rrsets(name,rrdatas)", + DnsRpc.Option.PAGE_SIZE, 1)); + batch.submit(); + } + + @Test + public void testCreateChangeBatch() { + // non-existent zone + RpcBatch batch = RPC.createBatch(); + batch.addApplyChangeRequest(ZONE_NAME1, CHANGE1, new FailExpectedCallback() { + @Override + public void onFailure(GoogleJsonError ex) { + // expected + assertEquals(404, ex.getCode()); + } + }, EMPTY_RPC_OPTIONS); + batch.submit(); + // existent zone + RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + assertNull(RPC.getChangeRequest(ZONE_NAME1, "1", EMPTY_RPC_OPTIONS)); + batch = RPC.createBatch(); + batch.addApplyChangeRequest(ZONE_NAME1, CHANGE1, new SuccessExpectedCallback() { + @Override + public void onSuccess(Change response) { + assertEquals(RPC.getChangeRequest(ZONE_NAME1, "1", EMPTY_RPC_OPTIONS), response); + } + }, EMPTY_RPC_OPTIONS); + batch.submit(); + // field options + RPC.applyChangeRequest(ZONE1.getName(), CHANGE_KEEP, EMPTY_RPC_OPTIONS); + batch = RPC.createBatch(); + batch.addApplyChangeRequest(ZONE1.getName(), CHANGE_COMPLEX, + new SuccessExpectedCallback() { + @Override + public void onSuccess(Change complex) { + assertNotNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNull(complex.getStatus()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "additions")); + batch.addApplyChangeRequest(ZONE1.getName(), CHANGE_COMPLEX, + new SuccessExpectedCallback() { + @Override + public void onSuccess(Change complex) { + assertNull(complex.getAdditions()); + assertNotNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNull(complex.getStatus()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "deletions")); + batch.addApplyChangeRequest(ZONE1.getName(), CHANGE_COMPLEX, + new SuccessExpectedCallback() { + @Override + public void onSuccess(Change complex) { + assertNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNotNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNull(complex.getStatus()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "id")); + batch.addApplyChangeRequest(ZONE1.getName(), CHANGE_COMPLEX, + new SuccessExpectedCallback() { + @Override + public void onSuccess(Change complex) { + assertNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNotNull(complex.getStartTime()); + assertNull(complex.getStatus()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "startTime")); + batch.addApplyChangeRequest(ZONE1.getName(), CHANGE_COMPLEX, + new SuccessExpectedCallback() { + @Override + public void onSuccess(Change complex) { + assertNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNotNull(complex.getStatus()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "status")); + batch.submit(); + } + + @Test + public void testGetChangeBatch() { + // existent + RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + final Change created = RPC.applyChangeRequest(ZONE1.getName(), CHANGE1, EMPTY_RPC_OPTIONS); + RpcBatch batch = RPC.createBatch(); + batch.addGetChangeRequest(ZONE1.getName(), "1", new SuccessExpectedCallback() { + @Override + public void onSuccess(Change retrieved) { + assertEquals(created, retrieved); + } + }, EMPTY_RPC_OPTIONS); + // non-existent + batch.addGetChangeRequest(ZONE1.getName(), "2", new FailExpectedCallback() { + @Override + public void onFailure(GoogleJsonError googleJsonError) { + // expected + assertEquals(404, googleJsonError.getCode()); + } + }, EMPTY_RPC_OPTIONS); + // non-existent zone + batch.addGetChangeRequest(ZONE_NAME2, "1", new FailExpectedCallback() { + @Override + public void onFailure(GoogleJsonError ex) { + // expected + assertEquals(404, ex.getCode()); + assertTrue(ex.getMessage().contains("managedZone")); + } + }, EMPTY_RPC_OPTIONS); + batch.submit(); + // field options + RPC.applyChangeRequest(ZONE1.getName(), CHANGE_KEEP, EMPTY_RPC_OPTIONS); + Change keep = RPC.applyChangeRequest(ZONE1.getName(), CHANGE_COMPLEX, EMPTY_RPC_OPTIONS); + batch = RPC.createBatch(); + batch.addGetChangeRequest(ZONE1.getName(), keep.getId(), new SuccessExpectedCallback() { + @Override + public void onSuccess(Change complex) { + assertNotNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNull(complex.getStatus()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "additions")); + batch.addGetChangeRequest(ZONE1.getName(), keep.getId(), new SuccessExpectedCallback() { + @Override + public void onSuccess(Change complex) { + assertNull(complex.getAdditions()); + assertNotNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNull(complex.getStatus()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "deletions")); + batch.addGetChangeRequest(ZONE1.getName(), keep.getId(), new SuccessExpectedCallback() { + @Override + public void onSuccess(Change complex) { + assertNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNotNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNull(complex.getStatus()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "id")); + batch.addGetChangeRequest(ZONE1.getName(), keep.getId(), new SuccessExpectedCallback() { + @Override + public void onSuccess(Change complex) { + assertNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNotNull(complex.getStartTime()); + assertNull(complex.getStatus()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "startTime")); + batch.addGetChangeRequest(ZONE1.getName(), keep.getId(), new SuccessExpectedCallback() { + @Override + public void onSuccess(Change complex) { + assertNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNotNull(complex.getStatus()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "status")); + batch.submit(); + } + + @Test + public void testListChangesBatch() { + RpcBatch batch = RPC.createBatch(); + batch.addListChangeRequests(ZONE_NAME1, new FailExpectedCallback() { + @Override + public void onFailure(GoogleJsonError ex) { + // expected + assertEquals(404, ex.getCode()); + assertTrue(ex.getMessage().contains("managedZone")); + } + }, EMPTY_RPC_OPTIONS); + batch.submit(); + + // zone exists but has no changes bu the default + batch = RPC.createBatch(); + RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + batch.addListChangeRequests(ZONE_NAME1, new SuccessExpectedCallback() { + @Override + public void onSuccess(ChangesListResponse response) { + assertEquals(1, response.getChanges().size()); + } + }, EMPTY_RPC_OPTIONS); + batch.submit(); + // zone has changes + RPC.applyChangeRequest(ZONE1.getName(), CHANGE1, EMPTY_RPC_OPTIONS); + RPC.applyChangeRequest(ZONE1.getName(), CHANGE2, EMPTY_RPC_OPTIONS); + RPC.applyChangeRequest(ZONE1.getName(), CHANGE_KEEP, EMPTY_RPC_OPTIONS); + batch = RPC.createBatch(); + batch.addListChangeRequests(ZONE_NAME1, new SuccessExpectedCallback() { + @Override + public void onSuccess(ChangesListResponse response) { + assertEquals(4, response.getChanges().size()); + } + }, EMPTY_RPC_OPTIONS); + // error in options + batch.addListChangeRequests(ZONE_NAME1, new FailExpectedCallback() { + @Override + public void onFailure(GoogleJsonError ex) { + assertEquals(400, ex.getCode()); + assertTrue(ex.getMessage().contains("parameters.maxResults")); + } + }, ImmutableMap.of(DnsRpc.Option.PAGE_SIZE, 0)); + batch.addListChangeRequests(ZONE_NAME1, new FailExpectedCallback() { + @Override + public void onFailure(GoogleJsonError ex) { + assertEquals(400, ex.getCode()); + assertTrue(ex.getMessage().contains("parameters.maxResults")); + } + }, ImmutableMap.of(DnsRpc.Option.PAGE_SIZE, -1)); + // ok size + batch.addListChangeRequests(ZONE_NAME1, new SuccessExpectedCallback() { + @Override + public void onSuccess(ChangesListResponse response) { + assertEquals(2, response.getChanges().size()); + } + }, ImmutableMap.of(DnsRpc.Option.PAGE_SIZE, 2)); + final Iterable descending = RPC.listChangeRequests(ZONE1.getName(), + ImmutableMap.of(DnsRpc.Option.SORTING_ORDER, "descending")).results(); + batch.addListChangeRequests(ZONE_NAME1, new SuccessExpectedCallback() { + @Override + public void onSuccess(ChangesListResponse response) { + List changes = response.getChanges(); + for (int i = 0; i < 4; i++) { + assertEquals(Iterables.get(descending, i), changes.get(i)); + } + } + }, ImmutableMap.of(DnsRpc.Option.SORTING_ORDER, "descending")); + batch.addListChangeRequests(ZONE_NAME1, new SuccessExpectedCallback() { + @Override + public void onSuccess(ChangesListResponse response) { + List changes = response.getChanges(); + for (int i = 0; i < 4; i++) { + assertEquals(Iterables.get(descending, i), changes.get(3 - i)); + } + } + }, ImmutableMap.of(DnsRpc.Option.SORTING_ORDER, "ascending")); + batch.addListChangeRequests(ZONE_NAME1, new FailExpectedCallback() { + @Override + public void onFailure(GoogleJsonError ex) { + // expected + assertEquals(400, ex.getCode()); + assertTrue(ex.getMessage().contains("parameters.sortOrder")); + } + }, ImmutableMap.of(DnsRpc.Option.SORTING_ORDER, "something else")); + batch.submit(); + // field options + batch = RPC.createBatch(); + RPC.applyChangeRequest(ZONE1.getName(), CHANGE_COMPLEX, EMPTY_RPC_OPTIONS); + batch.addListChangeRequests(ZONE1.getName(), + new SuccessExpectedCallback() { + @Override + public void onSuccess(ChangesListResponse response) { + Change complex = response.getChanges().get(0); + assertNotNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNull(complex.getStatus()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "additions", + DnsRpc.Option.SORTING_ORDER, "descending")); + batch.addListChangeRequests(ZONE1.getName(), + new SuccessExpectedCallback() { + @Override + public void onSuccess(ChangesListResponse response) { + Change complex = response.getChanges().get(0); + assertNull(complex.getAdditions()); + assertNotNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNull(complex.getStatus()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "deletions", + DnsRpc.Option.SORTING_ORDER, "descending")); + batch.addListChangeRequests(ZONE1.getName(), + new SuccessExpectedCallback() { + @Override + public void onSuccess(ChangesListResponse response) { + Change complex = response.getChanges().get(0); + assertNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNotNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNull(complex.getStatus()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "id", + DnsRpc.Option.SORTING_ORDER, "descending")); + batch.addListChangeRequests(ZONE1.getName(), + new SuccessExpectedCallback() { + @Override + public void onSuccess(ChangesListResponse response) { + Change complex = response.getChanges().get(0); + assertNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNotNull(complex.getStartTime()); + assertNull(complex.getStatus()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "startTime", + DnsRpc.Option.SORTING_ORDER, "descending")); + batch.addListChangeRequests(ZONE1.getName(), + new SuccessExpectedCallback() { + @Override + public void onSuccess(ChangesListResponse response) { + Change complex = response.getChanges().get(0); + assertNull(complex.getAdditions()); + assertNull(complex.getDeletions()); + assertNull(complex.getId()); + assertNull(complex.getStartTime()); + assertNotNull(complex.getStatus()); + } + }, ImmutableMap.of(DnsRpc.Option.FIELDS, "status", + DnsRpc.Option.SORTING_ORDER, "descending")); + batch.submit(); + } + + @Test + public void testCombined() { + final ManagedZone created = RPC.create(ZONE1, EMPTY_RPC_OPTIONS); + RpcBatch batch = RPC.createBatch(); + batch.addListZones(new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZonesListResponse response) { + assertEquals(1, response.getManagedZones().size()); + assertEquals(created, response.getManagedZones().get(0)); + } + }, EMPTY_RPC_OPTIONS); + batch.addGetZone(created.getName(), new SuccessExpectedCallback() { + @Override + public void onSuccess(ManagedZone response) { + assertEquals(created, response); + } + }, EMPTY_RPC_OPTIONS); + batch.addListChangeRequests(created.getName(), + new SuccessExpectedCallback() { + @Override + public void onSuccess(ChangesListResponse response) { + assertEquals(1, response.getChanges().size()); + assertEquals(RPC.getChangeRequest(created.getName(), "0", EMPTY_RPC_OPTIONS), + response.getChanges().get(0)); + } + }, EMPTY_RPC_OPTIONS); + batch.addListRecordSets(created.getName(), + new SuccessExpectedCallback() { + @Override + public void onSuccess(ResourceRecordSetsListResponse response) { + assertEquals(2, response.getRrsets().size()); + } + }, EMPTY_RPC_OPTIONS); + batch.addGetChangeRequest(created.getName(), "0", new SuccessExpectedCallback() { + @Override + public void onSuccess(Change response) { + assertEquals(RPC.getChangeRequest(created.getName(), "0", EMPTY_RPC_OPTIONS), response); + } + }, EMPTY_RPC_OPTIONS); + batch.submit(); + } } From 0a6c6f703802e0c336a4158f17f178b94e74acf0 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 21 Apr 2016 20:26:32 +0200 Subject: [PATCH 265/375] Chain cause exception to service exception in translateAndThrow (#946) * Chain cause exception to service exception in translateAndThrow * Make exception constructors package scoped, better test coverage * Make exception classes final with public constructors --- .../cloud/bigquery/BigQueryException.java | 11 +- .../cloud/bigquery/BigQueryExceptionTest.java | 36 ++++- .../cloud/datastore/DatastoreException.java | 12 +- .../datastore/DatastoreExceptionTest.java | 33 ++++- .../com/google/cloud/dns/DnsException.java | 8 +- .../google/cloud/dns/DnsExceptionTest.java | 138 ++++++++++++++++++ .../java/com/google/cloud/dns/ZoneTest.java | 2 +- .../ResourceManagerException.java | 10 +- .../ResourceManagerExceptionTest.java | 29 +++- .../cloud/storage/StorageException.java | 10 +- .../cloud/storage/StorageExceptionTest.java | 29 +++- 11 files changed, 287 insertions(+), 31 deletions(-) create mode 100644 gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsExceptionTest.java diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryException.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryException.java index 7f314a01b088..0b0c7d3152e3 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryException.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryException.java @@ -31,7 +31,7 @@ * @see Google Cloud * BigQuery error codes */ -public class BigQueryException extends BaseServiceException { +public final class BigQueryException extends BaseServiceException { // see: https://cloud.google.com/bigquery/troubleshooting-errors private static final Set RETRYABLE_ERRORS = ImmutableSet.of( @@ -44,7 +44,12 @@ public class BigQueryException extends BaseServiceException { private final BigQueryError error; public BigQueryException(int code, String message) { - this(code, message, null); + this(code, message, (Throwable) null); + } + + public BigQueryException(int code, String message, Throwable cause) { + super(code, message, null, true, cause); + this.error = null; } public BigQueryException(int code, String message, BigQueryError error) { @@ -100,6 +105,6 @@ public int hashCode() { */ static BaseServiceException translateAndThrow(RetryHelperException ex) { BaseServiceException.translateAndPropagateIfPossible(ex); - throw new BigQueryException(UNKNOWN_CODE, ex.getMessage()); + throw new BigQueryException(UNKNOWN_CODE, ex.getMessage(), ex.getCause()); } } diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/BigQueryExceptionTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/BigQueryExceptionTest.java index b0a32cd7f0c7..e97606bfc463 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/BigQueryExceptionTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/BigQueryExceptionTest.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import com.google.cloud.BaseServiceException; @@ -86,18 +87,29 @@ public void testBigqueryException() { assertTrue(exception.retryable()); assertTrue(exception.idempotent()); - IOException cause = new SocketTimeoutException(); + IOException cause = new SocketTimeoutException("socketTimeoutMessage"); exception = new BigQueryException(cause); + assertEquals(BigQueryException.UNKNOWN_CODE, exception.code()); assertNull(exception.reason()); - assertNull(exception.getMessage()); + assertEquals("socketTimeoutMessage", exception.getMessage()); + assertEquals(cause, exception.getCause()); assertTrue(exception.retryable()); assertTrue(exception.idempotent()); - assertEquals(cause, exception.getCause()); + assertSame(cause, exception.getCause()); + + exception = new BigQueryException(504, "message", cause); + assertEquals(504, exception.code()); + assertEquals("message", exception.getMessage()); + assertNull(exception.reason()); + assertNull(exception.error()); + assertTrue(exception.retryable()); + assertTrue(exception.idempotent()); + assertSame(cause, exception.getCause()); } @Test public void testTranslateAndThrow() throws Exception { - BigQueryException cause = new BigQueryException(503, "message"); + Exception cause = new BigQueryException(503, "message"); RetryHelperException exceptionMock = createMock(RetryHelperException.class); expect(exceptionMock.getCause()).andReturn(cause).times(2); replay(exceptionMock); @@ -111,5 +123,21 @@ public void testTranslateAndThrow() throws Exception { } finally { verify(exceptionMock); } + cause = new IllegalArgumentException("message"); + exceptionMock = createMock(RetryHelperException.class); + expect(exceptionMock.getMessage()).andReturn("message").times(1); + expect(exceptionMock.getCause()).andReturn(cause).times(2); + replay(exceptionMock); + try { + BigQueryException.translateAndThrow(exceptionMock); + } catch (BaseServiceException ex) { + assertEquals(BigQueryException.UNKNOWN_CODE, ex.code()); + assertEquals("message", ex.getMessage()); + assertFalse(ex.retryable()); + assertTrue(ex.idempotent()); + assertSame(cause, ex.getCause()); + } finally { + verify(exceptionMock); + } } } diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreException.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreException.java index 419cffc7bf3e..42c0079e0a77 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreException.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreException.java @@ -30,19 +30,19 @@ * @see Google Cloud * Datastore error codes */ -public class DatastoreException extends BaseServiceException { +public final class DatastoreException extends BaseServiceException { // see https://cloud.google.com/datastore/docs/concepts/errors#Error_Codes" private static final Set RETRYABLE_ERRORS = ImmutableSet.of( new Error(10, "ABORTED"), new Error(4, "DEADLINE_EXCEEDED"), new Error(14, "UNAVAILABLE")); private static final long serialVersionUID = 2663750991205874435L; - public DatastoreException(int code, String message, String reason, Throwable cause) { - super(code, message, reason, true, cause); + public DatastoreException(int code, String message, String reason) { + this(code, message, reason, null); } - public DatastoreException(int code, String message, String reason) { - super(code, message, reason, true); + public DatastoreException(int code, String message, String reason, Throwable cause) { + super(code, message, reason, true, cause); } public DatastoreException(IOException exception) { @@ -63,7 +63,7 @@ protected Set retryableErrors() { */ static DatastoreException translateAndThrow(RetryHelperException ex) { BaseServiceException.translateAndPropagateIfPossible(ex); - throw new DatastoreException(UNKNOWN_CODE, ex.getMessage(), null); + throw new DatastoreException(UNKNOWN_CODE, ex.getMessage(), null, ex.getCause()); } /** diff --git a/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreExceptionTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreExceptionTest.java index cf086ff25ba0..0da45f083210 100644 --- a/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreExceptionTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreExceptionTest.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -66,18 +67,28 @@ public void testDatastoreException() throws Exception { assertFalse(exception.retryable()); assertTrue(exception.idempotent()); - IOException cause = new SocketTimeoutException(); + IOException cause = new SocketTimeoutException("socketTimeoutMessage"); exception = new DatastoreException(cause); + assertEquals(DatastoreException.UNKNOWN_CODE, exception.code()); assertNull(exception.reason()); - assertNull(exception.getMessage()); + assertEquals("socketTimeoutMessage", exception.getMessage()); + assertEquals(cause, exception.getCause()); assertTrue(exception.retryable()); assertTrue(exception.idempotent()); + assertSame(cause, exception.getCause()); + exception = new DatastoreException(2, "message", "INTERNAL", cause); + assertEquals(2, exception.code()); + assertEquals("INTERNAL", exception.reason()); + assertEquals("message", exception.getMessage()); + assertFalse(exception.retryable()); + assertTrue(exception.idempotent()); + assertSame(cause, exception.getCause()); } @Test public void testTranslateAndThrow() throws Exception { - DatastoreException cause = new DatastoreException(14, "message", "UNAVAILABLE"); + Exception cause = new DatastoreException(14, "message", "UNAVAILABLE"); RetryHelper.RetryHelperException exceptionMock = createMock(RetryHelper.RetryHelperException.class); expect(exceptionMock.getCause()).andReturn(cause).times(2); @@ -92,6 +103,22 @@ public void testTranslateAndThrow() throws Exception { } finally { verify(exceptionMock); } + cause = new IllegalArgumentException("message"); + exceptionMock = createMock(RetryHelper.RetryHelperException.class); + expect(exceptionMock.getMessage()).andReturn("message").times(1); + expect(exceptionMock.getCause()).andReturn(cause).times(2); + replay(exceptionMock); + try { + DatastoreException.translateAndThrow(exceptionMock); + } catch (BaseServiceException ex) { + assertEquals(DatastoreException.UNKNOWN_CODE, ex.code()); + assertEquals("message", ex.getMessage()); + assertFalse(ex.retryable()); + assertTrue(ex.idempotent()); + assertSame(cause, ex.getCause()); + } finally { + verify(exceptionMock); + } } @Test diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsException.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsException.java index 274ff91b3bd0..90c32aee1681 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsException.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsException.java @@ -28,7 +28,7 @@ /** * DNS service exception. */ -public class DnsException extends BaseServiceException { +public final class DnsException extends BaseServiceException { // see: https://cloud.google.com/dns/troubleshooting private static final Set RETRYABLE_ERRORS = ImmutableSet.of( @@ -48,8 +48,8 @@ public DnsException(GoogleJsonError error, boolean idempotent) { super(error, idempotent); } - private DnsException(int code, String message) { - super(code, message, null, true); + public DnsException(int code, String message, Throwable cause) { + super(code, message, null, true, cause); } @Override @@ -66,6 +66,6 @@ protected Set retryableErrors() { */ static DnsException translateAndThrow(RetryHelperException ex) { BaseServiceException.translateAndPropagateIfPossible(ex); - throw new DnsException(UNKNOWN_CODE, ex.getMessage()); + throw new DnsException(UNKNOWN_CODE, ex.getMessage(), ex.getCause()); } } diff --git a/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsExceptionTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsExceptionTest.java new file mode 100644 index 000000000000..f97d9f697baa --- /dev/null +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsExceptionTest.java @@ -0,0 +1,138 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.dns; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import com.google.api.client.googleapis.json.GoogleJsonError; +import com.google.cloud.BaseServiceException; +import com.google.cloud.RetryHelper.RetryHelperException; + +import org.junit.Test; + +import java.io.IOException; +import java.net.SocketTimeoutException; + +public class DnsExceptionTest { + + @Test + public void testDnsException() throws Exception { + IOException cause = new SocketTimeoutException("socketTimeoutMessage"); + DnsException exception = new DnsException(500, "message", cause); + assertEquals(500, exception.code()); + assertEquals("message", exception.getMessage()); + assertNull(exception.reason()); + assertTrue(exception.retryable()); + assertTrue(exception.idempotent()); + assertSame(cause, exception.getCause()); + + exception = new DnsException(502, "message", cause); + assertEquals(502, exception.code()); + assertEquals("message", exception.getMessage()); + assertNull(exception.reason()); + assertTrue(exception.retryable()); + assertTrue(exception.idempotent()); + assertSame(cause, exception.getCause()); + + exception = new DnsException(503, "message", cause); + assertEquals(503, exception.code()); + assertEquals("message", exception.getMessage()); + assertNull(exception.reason()); + assertTrue(exception.retryable()); + assertTrue(exception.idempotent()); + assertSame(cause, exception.getCause()); + + exception = new DnsException(429, "message", cause); + assertEquals(429, exception.code()); + assertEquals("message", exception.getMessage()); + assertNull(exception.reason()); + assertTrue(exception.retryable()); + assertTrue(exception.idempotent()); + assertSame(cause, exception.getCause()); + + exception = new DnsException(404, "message", cause); + assertEquals(404, exception.code()); + assertEquals("message", exception.getMessage()); + assertNull(exception.reason()); + assertFalse(exception.retryable()); + assertTrue(exception.idempotent()); + assertSame(cause, exception.getCause()); + + exception = new DnsException(cause, true); + assertEquals(DnsException.UNKNOWN_CODE, exception.code()); + assertNull(exception.reason()); + assertEquals("socketTimeoutMessage", exception.getMessage()); + assertEquals(cause, exception.getCause()); + assertTrue(exception.retryable()); + assertTrue(exception.idempotent()); + assertSame(cause, exception.getCause()); + + GoogleJsonError error = new GoogleJsonError(); + error.setCode(503); + error.setMessage("message"); + exception = new DnsException(error, true); + assertEquals(503, exception.code()); + assertEquals("message", exception.getMessage()); + assertTrue(exception.retryable()); + assertTrue(exception.idempotent()); + } + + @Test + public void testTranslateAndThrow() throws Exception { + IOException timeoutException = new SocketTimeoutException("message"); + Exception cause = new DnsException(timeoutException, true); + RetryHelperException exceptionMock = createMock(RetryHelperException.class); + expect(exceptionMock.getCause()).andReturn(cause).times(2); + replay(exceptionMock); + try { + DnsException.translateAndThrow(exceptionMock); + } catch (BaseServiceException ex) { + assertEquals(DnsException.UNKNOWN_CODE, ex.code()); + assertNull(ex.reason()); + assertEquals("message", ex.getMessage()); + assertEquals(timeoutException, ex.getCause()); + assertTrue(ex.retryable()); + assertTrue(ex.idempotent()); + } finally { + verify(exceptionMock); + } + cause = new IllegalArgumentException("message"); + exceptionMock = createMock(RetryHelperException.class); + expect(exceptionMock.getMessage()).andReturn("message").times(1); + expect(exceptionMock.getCause()).andReturn(cause).times(2); + replay(exceptionMock); + try { + DnsException.translateAndThrow(exceptionMock); + } catch (BaseServiceException ex) { + assertEquals(DnsException.UNKNOWN_CODE, ex.code()); + assertEquals("message", ex.getMessage()); + assertFalse(ex.retryable()); + assertTrue(ex.idempotent()); + assertSame(cause, ex.getCause()); + } finally { + verify(exceptionMock); + } + } +} diff --git a/gcloud-java-dns/src/test/java/com/google/cloud/dns/ZoneTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/ZoneTest.java index e1f6c8917647..aefc716bf46a 100644 --- a/gcloud-java-dns/src/test/java/com/google/cloud/dns/ZoneTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/ZoneTest.java @@ -64,7 +64,7 @@ public class ZoneTest { ChangeRequestInfo.builder().generatedId("someid").build(); private static final ChangeRequestInfo CHANGE_REQUEST_NO_ID = ChangeRequestInfo.builder().build(); - private static final DnsException EXCEPTION = createStrictMock(DnsException.class); + private static final DnsException EXCEPTION = new DnsException(-1, "message", null); private static final DnsOptions OPTIONS = createStrictMock(DnsOptions.class); private Dns dns; diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerException.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerException.java index 1df014e450ee..2a6906fc0090 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerException.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerException.java @@ -30,7 +30,7 @@ * @see Google Cloud * Resource Manager error codes */ -public class ResourceManagerException extends BaseServiceException { +public final class ResourceManagerException extends BaseServiceException { // see https://cloud.google.com/resource-manager/v1/errors/core_errors private static final Set RETRYABLE_ERRORS = ImmutableSet.of( @@ -48,7 +48,11 @@ public class ResourceManagerException extends BaseServiceException { private static final long serialVersionUID = -9207194488966554136L; public ResourceManagerException(int code, String message) { - super(code, message, null, true); + this(code, message, null); + } + + public ResourceManagerException(int code, String message, Throwable cause) { + super(code, message, null, true, cause); } public ResourceManagerException(IOException exception) { @@ -70,6 +74,6 @@ protected Set retryableErrors() { */ static ResourceManagerException translateAndThrow(RetryHelperException ex) { BaseServiceException.translateAndPropagateIfPossible(ex); - throw new ResourceManagerException(UNKNOWN_CODE, ex.getMessage()); + throw new ResourceManagerException(UNKNOWN_CODE, ex.getMessage(), ex.getCause()); } } diff --git a/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ResourceManagerExceptionTest.java b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ResourceManagerExceptionTest.java index 2ac8d1acba7f..8e725b366a6b 100644 --- a/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ResourceManagerExceptionTest.java +++ b/gcloud-java-resourcemanager/src/test/java/com/google/cloud/resourcemanager/ResourceManagerExceptionTest.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import com.google.cloud.BaseServiceException; @@ -71,12 +72,20 @@ public void testResourceManagerException() { assertNull(exception.getMessage()); assertTrue(exception.retryable()); assertTrue(exception.idempotent()); - assertEquals(cause, exception.getCause()); + assertSame(cause, exception.getCause()); + + exception = new ResourceManagerException(404, "message", cause); + assertEquals(404, exception.code()); + assertEquals("message", exception.getMessage()); + assertNull(exception.reason()); + assertFalse(exception.retryable()); + assertTrue(exception.idempotent()); + assertSame(cause, exception.getCause()); } @Test public void testTranslateAndThrow() throws Exception { - ResourceManagerException cause = new ResourceManagerException(503, "message"); + Exception cause = new ResourceManagerException(503, "message"); RetryHelperException exceptionMock = createMock(RetryHelperException.class); expect(exceptionMock.getCause()).andReturn(cause).times(2); replay(exceptionMock); @@ -90,5 +99,21 @@ public void testTranslateAndThrow() throws Exception { } finally { verify(exceptionMock); } + cause = new IllegalArgumentException("message"); + exceptionMock = createMock(RetryHelperException.class); + expect(exceptionMock.getMessage()).andReturn("message").times(1); + expect(exceptionMock.getCause()).andReturn(cause).times(2); + replay(exceptionMock); + try { + ResourceManagerException.translateAndThrow(exceptionMock); + } catch (BaseServiceException ex) { + assertEquals(ResourceManagerException.UNKNOWN_CODE, ex.code()); + assertEquals("message", ex.getMessage()); + assertFalse(ex.retryable()); + assertTrue(ex.idempotent()); + assertSame(cause, ex.getCause()); + } finally { + verify(exceptionMock); + } } } diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageException.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageException.java index d6333c5c24e3..e0dcd8df0946 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageException.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageException.java @@ -31,7 +31,7 @@ * @see Google Cloud * Storage error codes */ -public class StorageException extends BaseServiceException { +public final class StorageException extends BaseServiceException { // see: https://cloud.google.com/storage/docs/resumable-uploads-xml#practices private static final Set RETRYABLE_ERRORS = ImmutableSet.of( @@ -46,7 +46,11 @@ public class StorageException extends BaseServiceException { private static final long serialVersionUID = -4168430271327813063L; public StorageException(int code, String message) { - super(code, message, null, true); + this(code, message, null); + } + + public StorageException(int code, String message, Throwable cause) { + super(code, message, null, true, cause); } public StorageException(IOException exception) { @@ -71,6 +75,6 @@ protected Set retryableErrors() { */ static StorageException translateAndThrow(RetryHelperException ex) { BaseServiceException.translateAndPropagateIfPossible(ex); - throw new StorageException(UNKNOWN_CODE, ex.getMessage()); + throw new StorageException(UNKNOWN_CODE, ex.getMessage(), ex.getCause()); } } diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageExceptionTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageExceptionTest.java index a562ec1194c9..1f16ff04cee3 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageExceptionTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageExceptionTest.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import com.google.api.client.googleapis.json.GoogleJsonError; @@ -93,7 +94,7 @@ public void testStorageException() { assertNull(exception.getMessage()); assertTrue(exception.retryable()); assertTrue(exception.idempotent()); - assertEquals(cause, exception.getCause()); + assertSame(cause, exception.getCause()); GoogleJsonError error = new GoogleJsonError(); error.setCode(503); @@ -103,11 +104,19 @@ public void testStorageException() { assertEquals("message", exception.getMessage()); assertTrue(exception.retryable()); assertTrue(exception.idempotent()); + + exception = new StorageException(400, "message", cause); + assertEquals(400, exception.code()); + assertEquals("message", exception.getMessage()); + assertNull(exception.reason()); + assertFalse(exception.retryable()); + assertTrue(exception.idempotent()); + assertSame(cause, exception.getCause()); } @Test public void testTranslateAndThrow() throws Exception { - StorageException cause = new StorageException(503, "message"); + Exception cause = new StorageException(503, "message"); RetryHelperException exceptionMock = createMock(RetryHelperException.class); expect(exceptionMock.getCause()).andReturn(cause).times(2); replay(exceptionMock); @@ -121,5 +130,21 @@ public void testTranslateAndThrow() throws Exception { } finally { verify(exceptionMock); } + cause = new IllegalArgumentException("message"); + exceptionMock = createMock(RetryHelperException.class); + expect(exceptionMock.getMessage()).andReturn("message").times(1); + expect(exceptionMock.getCause()).andReturn(cause).times(2); + replay(exceptionMock); + try { + StorageException.translateAndThrow(exceptionMock); + } catch (BaseServiceException ex) { + assertEquals(StorageException.UNKNOWN_CODE, ex.code()); + assertEquals("message", ex.getMessage()); + assertFalse(ex.retryable()); + assertTrue(ex.idempotent()); + assertSame(cause, ex.getCause()); + } finally { + verify(exceptionMock); + } } } From d829e97d5ade0e9a6e697dac39294cdc34267a03 Mon Sep 17 00:00:00 2001 From: Shin Fan Date: Thu, 21 Apr 2016 22:52:14 -0700 Subject: [PATCH 266/375] Update gcloud pubsub. (#951) - compatible with GAX 0.0.11 - better documentation --- .../cloud/pubsub/spi/v1/PublisherApi.java | 131 +++++++++++++----- .../pubsub/spi/v1/PublisherSettings.java | 81 ++++++++++- .../cloud/pubsub/spi/v1/SubscriberApi.java | 128 ++++++++++++----- .../pubsub/spi/v1/SubscriberSettings.java | 93 ++++++++++++- gcloud-java-pubsub/pom.xml | 2 +- .../cloud/pubsub/spi/v1/PublisherApi.java | 131 +++++++++++++----- .../pubsub/spi/v1/PublisherSettings.java | 81 ++++++++++- .../cloud/pubsub/spi/v1/SubscriberApi.java | 128 ++++++++++++----- .../pubsub/spi/v1/SubscriberSettings.java | 93 ++++++++++++- 9 files changed, 717 insertions(+), 151 deletions(-) diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java index 886945e0504e..6f7139bf4270 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java @@ -33,6 +33,7 @@ package com.google.cloud.pubsub.spi.v1; +import com.google.api.gax.core.PageAccessor; import com.google.api.gax.grpc.ApiCallable; import com.google.api.gax.protobuf.PathTemplate; import com.google.protobuf.Empty; @@ -59,6 +60,60 @@ * Service Description: The service that an application uses to manipulate topics, and to send * messages to a topic. * + *

    This class provides the ability to make remote calls to the backing service through method + * calls that map to API methods. Sample code to get started: + * + *

    + * 
    + * try (PublisherApi publisherApi = PublisherApi.defaultInstance()) {
    + *   // make calls here
    + * String name = "";
    + * Topic callResult = createTopic(name);
    + * }
    + * 
    + * 
    + * + *

    Note: close() needs to be called on the publisherApi object to clean up resources such + * as threads. In the example above, try-with-resources is used, which automatically calls + * close(). + * + *

    The surface of this class includes several types of Java methods for each of the API's methods: + * + *

      + *
    1. A "flattened" method. With this type of method, the fields of the request type have been + * converted into function parameters. It may be the case that not all fields are available + * as parameters, and not every API method will have a flattened method entry point. + *
    2. A "request object" method. This type of method only takes one parameter, a request + * object, which must be constructed before the call. Not every API method will have a request + * object method. + *
    3. A "callable" method. This type of method takes no parameters and returns an immutable + * ApiCallable object, which can be used to initiate calls to the service. + *
    + * + *

    See the individual methods for example code. + * + *

    Many parameters require resource names to be formatted in a particular way. To assist + * with these names, this class includes a format method for each type of name, and additionally + * a parse method to extract the individual identifiers contained within names that are + * returned. + * + *

    This class can be customized by passing in a custom instance of PublisherSettings to + * create(). For example: + * + * + *

    + * 
    + * ConnectionSettings defaultConnectionSettings =
    + *     PublisherSettings.defaultInstance().toBuilder().getConnectionSettings();
    + * ConnectionSettings updatedConnectionSettings =
    + *     defaultConnectionSettings.toBuilder().provideCredentialsWith(myCredentials).build();
    + * PublisherSettings publisherSettings = PublisherSettings.defaultInstance().toBuilder().
    + *     provideChannelWith(updatedConnectionSettings)
    + *     .build();
    + * PublisherApi publisherApi = PublisherApi.create(publisherSettings);
    + * 
    + * 
    + * * * */ @@ -71,11 +126,11 @@ public class PublisherApi implements AutoCloseable { private final ApiCallable publishCallable; private final ApiCallable getTopicCallable; private final ApiCallable listTopicsCallable; - private final ApiCallable> listTopicsIterableCallable; + private final ApiCallable> listTopicsPagedCallable; private final ApiCallable listTopicSubscriptionsCallable; - private final ApiCallable> - listTopicSubscriptionsIterableCallable; + private final ApiCallable> + listTopicSubscriptionsPagedCallable; private final ApiCallable deleteTopicCallable; private static final PathTemplate PROJECT_PATH_TEMPLATE = @@ -179,12 +234,12 @@ protected PublisherApi(PublisherSettings settings) throws IOException { } this.getTopicCallable = ApiCallable.create(settings.getTopicSettings(), settings); this.listTopicsCallable = ApiCallable.create(settings.listTopicsSettings(), settings); - this.listTopicsIterableCallable = - ApiCallable.createIterable(settings.listTopicsSettings(), settings); + this.listTopicsPagedCallable = + ApiCallable.createPagedVariant(settings.listTopicsSettings(), settings); this.listTopicSubscriptionsCallable = ApiCallable.create(settings.listTopicSubscriptionsSettings(), settings); - this.listTopicSubscriptionsIterableCallable = - ApiCallable.createIterable(settings.listTopicSubscriptionsSettings(), settings); + this.listTopicSubscriptionsPagedCallable = + ApiCallable.createPagedVariant(settings.listTopicSubscriptionsSettings(), settings); this.deleteTopicCallable = ApiCallable.create(settings.deleteTopicSettings(), settings); if (settings.shouldAutoCloseChannel()) { @@ -213,7 +268,7 @@ public void close() throws IOException { * underscores (`_`), periods (`.`), tildes (`~`), plus (`+`) or percent * signs (`%`). It must be between 3 and 255 characters in length, and it * must not start with `"goog"`. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final Topic createTopic(String name) { Topic request = Topic.newBuilder().setName(name).build(); @@ -229,7 +284,7 @@ public final Topic createTopic(String name) { * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ private Topic createTopic(Topic request) { return createTopicCallable().call(request); @@ -241,7 +296,7 @@ private Topic createTopic(Topic request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable createTopicCallable() { return createTopicCallable; @@ -260,7 +315,7 @@ public final ApiCallable createTopicCallable() { * * @param topic The messages in the request will be published on this topic. * @param messages The messages to publish. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final PublishResponse publish(String topic, List messages) { PublishRequest request = @@ -279,7 +334,7 @@ public final PublishResponse publish(String topic, List messages) * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public PublishResponse publish(PublishRequest request) { return publishCallable().call(request); @@ -293,7 +348,7 @@ public PublishResponse publish(PublishRequest request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable publishCallable() { return publishCallable; @@ -309,7 +364,7 @@ public final ApiCallable publishCallable() { * * * @param topic The name of the topic to get. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final Topic getTopic(String topic) { GetTopicRequest request = GetTopicRequest.newBuilder().setTopic(topic).build(); @@ -325,7 +380,7 @@ public final Topic getTopic(String topic) { * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ private Topic getTopic(GetTopicRequest request) { return getTopicCallable().call(request); @@ -337,7 +392,7 @@ private Topic getTopic(GetTopicRequest request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable getTopicCallable() { return getTopicCallable; @@ -353,9 +408,9 @@ public final ApiCallable getTopicCallable() { * * * @param project The name of the cloud project that topics belong to. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ - public final Iterable listTopics(String project) { + public final PageAccessor listTopics(String project) { ListTopicsRequest request = ListTopicsRequest.newBuilder().setProject(project).build(); return listTopics(request); } @@ -368,10 +423,10 @@ public final Iterable listTopics(String project) { * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ - public final Iterable listTopics(ListTopicsRequest request) { - return listTopicsIterableCallable().call(request); + public final PageAccessor listTopics(ListTopicsRequest request) { + return listTopicsPagedCallable().call(request); } // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. @@ -380,10 +435,10 @@ public final Iterable listTopics(ListTopicsRequest request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ - public final ApiCallable> listTopicsIterableCallable() { - return listTopicsIterableCallable; + public final ApiCallable> listTopicsPagedCallable() { + return listTopicsPagedCallable; } // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. @@ -392,7 +447,7 @@ public final ApiCallable> listTopicsIterableC * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable listTopicsCallable() { return listTopicsCallable; @@ -408,9 +463,9 @@ public final ApiCallable listTopicsCallab * * * @param topic The name of the topic that subscriptions are attached to. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ - public final Iterable listTopicSubscriptions(String topic) { + public final PageAccessor listTopicSubscriptions(String topic) { ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder().setTopic(topic).build(); return listTopicSubscriptions(request); @@ -424,10 +479,10 @@ public final Iterable listTopicSubscriptions(String topic) { * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ - public final Iterable listTopicSubscriptions(ListTopicSubscriptionsRequest request) { - return listTopicSubscriptionsIterableCallable().call(request); + public final PageAccessor listTopicSubscriptions(ListTopicSubscriptionsRequest request) { + return listTopicSubscriptionsPagedCallable().call(request); } // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. @@ -436,11 +491,11 @@ public final Iterable listTopicSubscriptions(ListTopicSubscriptionsReque * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ - public final ApiCallable> - listTopicSubscriptionsIterableCallable() { - return listTopicSubscriptionsIterableCallable; + public final ApiCallable> + listTopicSubscriptionsPagedCallable() { + return listTopicSubscriptionsPagedCallable; } // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. @@ -449,7 +504,7 @@ public final Iterable listTopicSubscriptions(ListTopicSubscriptionsReque * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable listTopicSubscriptionsCallable() { @@ -470,7 +525,7 @@ public final Iterable listTopicSubscriptions(ListTopicSubscriptionsReque * * * @param topic Name of the topic to delete. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final void deleteTopic(String topic) { DeleteTopicRequest request = DeleteTopicRequest.newBuilder().setTopic(topic).build(); @@ -490,7 +545,7 @@ public final void deleteTopic(String topic) { * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ private void deleteTopic(DeleteTopicRequest request) { deleteTopicCallable().call(request); @@ -506,7 +561,7 @@ private void deleteTopic(DeleteTopicRequest request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable deleteTopicCallable() { return deleteTopicCallable; diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherSettings.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherSettings.java index 72d24404d87a..230adc5ec35c 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherSettings.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherSettings.java @@ -73,6 +73,32 @@ // Manually-added imports: add custom (non-generated) imports after this point. // AUTO-GENERATED DOCUMENTATION AND CLASS - see instructions at the top of the file for editing. +/** + * Settings class to configure an instance of {@link PublisherApi}. + * + *

    The default instance has everything set to sensible defaults: + * + *

      + *
    • The default service address (pubsub-experimental.googleapis.com) and default port (443) + * are used. + *
    • Credentials are acquired automatically through Application Default Credentials. + *
    • Retries are configured for idempotent methods but not for non-idempotent methods. + *
    + * + *

    The builder of this class is recursive, so contained classes are themselves builders. + * When build() is called, the tree of builders is called to create the complete settings + * object. For example, to set the total timeout of CreateTopic to 30 seconds: + * + *

    + * 
    + * PublisherSettings.Builder publisherSettingsBuilder =
    + *     PublisherSettings.defaultInstance().toBuilder();
    + * publisherSettingsBuilder.CreateTopicSettings().getRetrySettingsBuilder()
    + *     .setTotalTimeout(Duration.standardSeconds(30));
    + * PublisherSettings publisherSettings = publisherSettingsBuilder.build();
    + * 
    + * 
    + */ @javax.annotation.Generated("by GAPIC") public class PublisherSettings extends ServiceApiSettings { @@ -113,41 +139,68 @@ public class PublisherSettings extends ServiceApiSettings { private final SimpleCallSettings deleteTopicSettings; + /** + * Returns the object with the settings used for calls to createTopic. + */ public SimpleCallSettings createTopicSettings() { return createTopicSettings; } + /** + * Returns the object with the settings used for calls to publish. + */ public BundlingCallSettings publishSettings() { return publishSettings; } + /** + * Returns the object with the settings used for calls to getTopic. + */ public SimpleCallSettings getTopicSettings() { return getTopicSettings; } + /** + * Returns the object with the settings used for calls to listTopics. + */ public PageStreamingCallSettings listTopicsSettings() { return listTopicsSettings; } + /** + * Returns the object with the settings used for calls to listTopicSubscriptions. + */ public PageStreamingCallSettings< ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> listTopicSubscriptionsSettings() { return listTopicSubscriptionsSettings; } + /** + * Returns the object with the settings used for calls to deleteTopic. + */ public SimpleCallSettings deleteTopicSettings() { return deleteTopicSettings; } + /** + * Returns an instance of this class with recommended defaults. + */ public static PublisherSettings defaultInstance() throws IOException { return newBuilder().build(); } + /** + * Returns a new builder for this class. + */ public static Builder newBuilder() { return new Builder(); } + /** + * Returns a builder containing all the values of this settings class. + */ public Builder toBuilder() { return new Builder(this); } @@ -286,6 +339,9 @@ public long countBytes(PublishRequest request) { } }; + /** + * Builder for PublisherSettings. + */ public static class Builder extends ServiceApiSettings.Builder { private final ImmutableList methodSettingsBuilders; @@ -332,7 +388,7 @@ public static class Builder extends ServiceApiSettings.Builder { private Builder() { super( - ConnectionSettings.builder() + ConnectionSettings.newBuilder() .setServiceAddress(DEFAULT_SERVICE_ADDRESS) .setPort(DEFAULT_SERVICE_PORT) .provideCredentialsWith(DEFAULT_SERVICE_SCOPES) @@ -440,34 +496,57 @@ public Builder setClientLibHeader(String name, String version) { return this; } + /** + * Applies the given settings to all of the API methods in this service. Only + * values that are non-null will be applied, so this method is not capable + * of un-setting any values. + */ public Builder applyToAllApiMethods(ApiCallSettings.Builder apiCallSettings) throws Exception { super.applyToAllApiMethods(methodSettingsBuilders, apiCallSettings); return this; } + /** + * Returns the builder for the settings used for calls to createTopic. + */ public SimpleCallSettings.Builder createTopicSettings() { return createTopicSettings; } + /** + * Returns the builder for the settings used for calls to publish. + */ public BundlingCallSettings.Builder publishSettings() { return publishSettings; } + /** + * Returns the builder for the settings used for calls to getTopic. + */ public SimpleCallSettings.Builder getTopicSettings() { return getTopicSettings; } + /** + * Returns the builder for the settings used for calls to listTopics. + */ public PageStreamingCallSettings.Builder listTopicsSettings() { return listTopicsSettings; } + /** + * Returns the builder for the settings used for calls to listTopicSubscriptions. + */ public PageStreamingCallSettings.Builder< ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> listTopicSubscriptionsSettings() { return listTopicSubscriptionsSettings; } + /** + * Returns the builder for the settings used for calls to deleteTopic. + */ public SimpleCallSettings.Builder deleteTopicSettings() { return deleteTopicSettings; } diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java index 2bfafd62ef0e..322154991e5b 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java @@ -33,6 +33,7 @@ package com.google.cloud.pubsub.spi.v1; +import com.google.api.gax.core.PageAccessor; import com.google.api.gax.grpc.ApiCallable; import com.google.api.gax.protobuf.PathTemplate; import com.google.protobuf.Empty; @@ -60,6 +61,63 @@ * Service Description: The service that an application uses to manipulate subscriptions and to * consume messages from a subscription via the `Pull` method. * + *

    This class provides the ability to make remote calls to the backing service through method + * calls that map to API methods. Sample code to get started: + * + *

    + * 
    + * try (SubscriberApi subscriberApi = SubscriberApi.defaultInstance()) {
    + *   // make calls here
    + * String name = "";
    + * String topic = "";
    + * PushConfig pushConfig = PushConfig.newBuilder().build();
    + * int ackDeadlineSeconds = 0;
    + * Subscription callResult = createSubscription(name, topic, pushConfig, ackDeadlineSeconds);
    + * }
    + * 
    + * 
    + * + *

    Note: close() needs to be called on the subscriberApi object to clean up resources such + * as threads. In the example above, try-with-resources is used, which automatically calls + * close(). + * + *

    The surface of this class includes several types of Java methods for each of the API's methods: + * + *

      + *
    1. A "flattened" method. With this type of method, the fields of the request type have been + * converted into function parameters. It may be the case that not all fields are available + * as parameters, and not every API method will have a flattened method entry point. + *
    2. A "request object" method. This type of method only takes one parameter, a request + * object, which must be constructed before the call. Not every API method will have a request + * object method. + *
    3. A "callable" method. This type of method takes no parameters and returns an immutable + * ApiCallable object, which can be used to initiate calls to the service. + *
    + * + *

    See the individual methods for example code. + * + *

    Many parameters require resource names to be formatted in a particular way. To assist + * with these names, this class includes a format method for each type of name, and additionally + * a parse method to extract the individual identifiers contained within names that are + * returned. + * + *

    This class can be customized by passing in a custom instance of SubscriberSettings to + * create(). For example: + * + * + *

    + * 
    + * ConnectionSettings defaultConnectionSettings =
    + *     SubscriberSettings.defaultInstance().toBuilder().getConnectionSettings();
    + * ConnectionSettings updatedConnectionSettings =
    + *     defaultConnectionSettings.toBuilder().provideCredentialsWith(myCredentials).build();
    + * SubscriberSettings subscriberSettings = SubscriberSettings.defaultInstance().toBuilder().
    + *     provideChannelWith(updatedConnectionSettings)
    + *     .build();
    + * SubscriberApi subscriberApi = SubscriberApi.create(subscriberSettings);
    + * 
    + * 
    + * * * */ @@ -72,8 +130,8 @@ public class SubscriberApi implements AutoCloseable { private final ApiCallable getSubscriptionCallable; private final ApiCallable listSubscriptionsCallable; - private final ApiCallable> - listSubscriptionsIterableCallable; + private final ApiCallable> + listSubscriptionsPagedCallable; private final ApiCallable deleteSubscriptionCallable; private final ApiCallable modifyAckDeadlineCallable; private final ApiCallable acknowledgeCallable; @@ -179,8 +237,8 @@ protected SubscriberApi(SubscriberSettings settings) throws IOException { this.getSubscriptionCallable = ApiCallable.create(settings.getSubscriptionSettings(), settings); this.listSubscriptionsCallable = ApiCallable.create(settings.listSubscriptionsSettings(), settings); - this.listSubscriptionsIterableCallable = - ApiCallable.createIterable(settings.listSubscriptionsSettings(), settings); + this.listSubscriptionsPagedCallable = + ApiCallable.createPagedVariant(settings.listSubscriptionsSettings(), settings); this.deleteSubscriptionCallable = ApiCallable.create(settings.deleteSubscriptionSettings(), settings); this.modifyAckDeadlineCallable = @@ -243,7 +301,7 @@ public void close() throws IOException { * system will eventually redeliver the message. * * If this parameter is not set, the default value of 10 seconds is used. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final Subscription createSubscription( String name, String topic, PushConfig pushConfig, int ackDeadlineSeconds) { @@ -271,7 +329,7 @@ public final Subscription createSubscription( * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public Subscription createSubscription(Subscription request) { return createSubscriptionCallable().call(request); @@ -288,7 +346,7 @@ public Subscription createSubscription(Subscription request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable createSubscriptionCallable() { return createSubscriptionCallable; @@ -307,7 +365,7 @@ public final ApiCallable createSubscriptionCallable( * * * @param subscription The name of the subscription to get. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final Subscription getSubscription(String subscription) { GetSubscriptionRequest request = @@ -327,7 +385,7 @@ public final Subscription getSubscription(String subscription) { * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ private Subscription getSubscription(GetSubscriptionRequest request) { return getSubscriptionCallable().call(request); @@ -342,7 +400,7 @@ private Subscription getSubscription(GetSubscriptionRequest request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable getSubscriptionCallable() { return getSubscriptionCallable; @@ -361,9 +419,9 @@ public final ApiCallable getSubscriptionCa * * * @param project The name of the cloud project that subscriptions belong to. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ - public final Iterable listSubscriptions(String project) { + public final PageAccessor listSubscriptions(String project) { ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder().setProject(project).build(); return listSubscriptions(request); @@ -380,10 +438,10 @@ public final Iterable listSubscriptions(String project) { * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ - public final Iterable listSubscriptions(ListSubscriptionsRequest request) { - return listSubscriptionsIterableCallable().call(request); + public final PageAccessor listSubscriptions(ListSubscriptionsRequest request) { + return listSubscriptionsPagedCallable().call(request); } // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. @@ -395,11 +453,11 @@ public final Iterable listSubscriptions(ListSubscriptionsRequest r * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ - public final ApiCallable> - listSubscriptionsIterableCallable() { - return listSubscriptionsIterableCallable; + public final ApiCallable> + listSubscriptionsPagedCallable() { + return listSubscriptionsPagedCallable; } // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. @@ -411,7 +469,7 @@ public final Iterable listSubscriptions(ListSubscriptionsRequest r * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable listSubscriptionsCallable() { @@ -432,7 +490,7 @@ public final Iterable listSubscriptions(ListSubscriptionsRequest r * * * @param subscription The subscription to delete. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final void deleteSubscription(String subscription) { DeleteSubscriptionRequest request = @@ -453,7 +511,7 @@ public final void deleteSubscription(String subscription) { * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ private void deleteSubscription(DeleteSubscriptionRequest request) { deleteSubscriptionCallable().call(request); @@ -469,7 +527,7 @@ private void deleteSubscription(DeleteSubscriptionRequest request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable deleteSubscriptionCallable() { return deleteSubscriptionCallable; @@ -494,7 +552,7 @@ public final ApiCallable deleteSubscriptionCal * ack deadline will expire 10 seconds after the `ModifyAckDeadline` call * was made. Specifying zero may immediately make the message available for * another pull request. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final void modifyAckDeadline( String subscription, List ackIds, int ackDeadlineSeconds) { @@ -519,7 +577,7 @@ public final void modifyAckDeadline( * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public void modifyAckDeadline(ModifyAckDeadlineRequest request) { modifyAckDeadlineCallable().call(request); @@ -534,7 +592,7 @@ public void modifyAckDeadline(ModifyAckDeadlineRequest request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable modifyAckDeadlineCallable() { return modifyAckDeadlineCallable; @@ -558,7 +616,7 @@ public final ApiCallable modifyAckDeadlineCalla * @param subscription The subscription whose message is being acknowledged. * @param ackIds The acknowledgment ID for the messages being acknowledged that was returned * by the Pub/Sub system in the `Pull` response. Must not be empty. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final void acknowledge(String subscription, List ackIds) { AcknowledgeRequest request = @@ -581,7 +639,7 @@ public final void acknowledge(String subscription, List ackIds) { * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public void acknowledge(AcknowledgeRequest request) { acknowledgeCallable().call(request); @@ -599,7 +657,7 @@ public void acknowledge(AcknowledgeRequest request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable acknowledgeCallable() { return acknowledgeCallable; @@ -624,7 +682,7 @@ public final ApiCallable acknowledgeCallable() { * than returning no messages. * @param maxMessages The maximum number of messages returned for this request. The Pub/Sub * system may return fewer than the number specified. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final PullResponse pull(String subscription, boolean returnImmediately, int maxMessages) { PullRequest request = @@ -648,7 +706,7 @@ public final PullResponse pull(String subscription, boolean returnImmediately, i * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public PullResponse pull(PullRequest request) { return pullCallable().call(request); @@ -663,7 +721,7 @@ public PullResponse pull(PullRequest request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable pullCallable() { return pullCallable; @@ -690,7 +748,7 @@ public final ApiCallable pullCallable() { * stop pushing messages from the given subscription and allow * messages to be pulled and acknowledged - effectively pausing * the subscription if `Pull` is not called. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final void modifyPushConfig(String subscription, PushConfig pushConfig) { ModifyPushConfigRequest request = @@ -715,7 +773,7 @@ public final void modifyPushConfig(String subscription, PushConfig pushConfig) { * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public void modifyPushConfig(ModifyPushConfigRequest request) { modifyPushConfigCallable().call(request); @@ -732,7 +790,7 @@ public void modifyPushConfig(ModifyPushConfigRequest request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable modifyPushConfigCallable() { return modifyPushConfigCallable; diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberSettings.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberSettings.java index a46c956ae29d..39fdadccea2a 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberSettings.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberSettings.java @@ -66,6 +66,32 @@ // Manually-added imports: add custom (non-generated) imports after this point. // AUTO-GENERATED DOCUMENTATION AND CLASS - see instructions at the top of the file for editing. +/** + * Settings class to configure an instance of {@link SubscriberApi}. + * + *

    The default instance has everything set to sensible defaults: + * + *

      + *
    • The default service address (pubsub-experimental.googleapis.com) and default port (443) + * are used. + *
    • Credentials are acquired automatically through Application Default Credentials. + *
    • Retries are configured for idempotent methods but not for non-idempotent methods. + *
    + * + *

    The builder of this class is recursive, so contained classes are themselves builders. + * When build() is called, the tree of builders is called to create the complete settings + * object. For example, to set the total timeout of CreateSubscription to 30 seconds: + * + *

    + * 
    + * SubscriberSettings.Builder subscriberSettingsBuilder =
    + *     SubscriberSettings.defaultInstance().toBuilder();
    + * subscriberSettingsBuilder.CreateSubscriptionSettings().getRetrySettingsBuilder()
    + *     .setTotalTimeout(Duration.standardSeconds(30));
    + * SubscriberSettings subscriberSettings = subscriberSettingsBuilder.build();
    + * 
    + * 
    + */ @javax.annotation.Generated("by GAPIC") public class SubscriberSettings extends ServiceApiSettings { @@ -106,48 +132,81 @@ public class SubscriberSettings extends ServiceApiSettings { private final SimpleCallSettings pullSettings; private final SimpleCallSettings modifyPushConfigSettings; + /** + * Returns the object with the settings used for calls to createSubscription. + */ public SimpleCallSettings createSubscriptionSettings() { return createSubscriptionSettings; } + /** + * Returns the object with the settings used for calls to getSubscription. + */ public SimpleCallSettings getSubscriptionSettings() { return getSubscriptionSettings; } + /** + * Returns the object with the settings used for calls to listSubscriptions. + */ public PageStreamingCallSettings< ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> listSubscriptionsSettings() { return listSubscriptionsSettings; } + /** + * Returns the object with the settings used for calls to deleteSubscription. + */ public SimpleCallSettings deleteSubscriptionSettings() { return deleteSubscriptionSettings; } + /** + * Returns the object with the settings used for calls to modifyAckDeadline. + */ public SimpleCallSettings modifyAckDeadlineSettings() { return modifyAckDeadlineSettings; } + /** + * Returns the object with the settings used for calls to acknowledge. + */ public SimpleCallSettings acknowledgeSettings() { return acknowledgeSettings; } + /** + * Returns the object with the settings used for calls to pull. + */ public SimpleCallSettings pullSettings() { return pullSettings; } + /** + * Returns the object with the settings used for calls to modifyPushConfig. + */ public SimpleCallSettings modifyPushConfigSettings() { return modifyPushConfigSettings; } + /** + * Returns an instance of this class with recommended defaults. + */ public static SubscriberSettings defaultInstance() throws IOException { return newBuilder().build(); } + /** + * Returns a new builder for this class. + */ public static Builder newBuilder() { return new Builder(); } + /** + * Returns a builder containing all the values of this settings class. + */ public Builder toBuilder() { return new Builder(this); } @@ -202,6 +261,9 @@ public Iterable extractResources(ListSubscriptionsResponse payload } }; + /** + * Builder for SubscriberSettings. + */ public static class Builder extends ServiceApiSettings.Builder { private final ImmutableList methodSettingsBuilders; @@ -250,7 +312,7 @@ public static class Builder extends ServiceApiSettings.Builder { private Builder() { super( - ConnectionSettings.builder() + ConnectionSettings.newBuilder() .setServiceAddress(DEFAULT_SERVICE_ADDRESS) .setPort(DEFAULT_SERVICE_PORT) .provideCredentialsWith(DEFAULT_SERVICE_SCOPES) @@ -363,43 +425,72 @@ public Builder setClientLibHeader(String name, String version) { return this; } + /** + * Applies the given settings to all of the API methods in this service. Only + * values that are non-null will be applied, so this method is not capable + * of un-setting any values. + */ public Builder applyToAllApiMethods(ApiCallSettings.Builder apiCallSettings) throws Exception { super.applyToAllApiMethods(methodSettingsBuilders, apiCallSettings); return this; } + /** + * Returns the builder for the settings used for calls to createSubscription. + */ public SimpleCallSettings.Builder createSubscriptionSettings() { return createSubscriptionSettings; } + /** + * Returns the builder for the settings used for calls to getSubscription. + */ public SimpleCallSettings.Builder getSubscriptionSettings() { return getSubscriptionSettings; } + /** + * Returns the builder for the settings used for calls to listSubscriptions. + */ public PageStreamingCallSettings.Builder< ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> listSubscriptionsSettings() { return listSubscriptionsSettings; } + /** + * Returns the builder for the settings used for calls to deleteSubscription. + */ public SimpleCallSettings.Builder deleteSubscriptionSettings() { return deleteSubscriptionSettings; } + /** + * Returns the builder for the settings used for calls to modifyAckDeadline. + */ public SimpleCallSettings.Builder modifyAckDeadlineSettings() { return modifyAckDeadlineSettings; } + /** + * Returns the builder for the settings used for calls to acknowledge. + */ public SimpleCallSettings.Builder acknowledgeSettings() { return acknowledgeSettings; } + /** + * Returns the builder for the settings used for calls to pull. + */ public SimpleCallSettings.Builder pullSettings() { return pullSettings; } + /** + * Returns the builder for the settings used for calls to modifyPushConfig. + */ public SimpleCallSettings.Builder modifyPushConfigSettings() { return modifyPushConfigSettings; } diff --git a/gcloud-java-pubsub/pom.xml b/gcloud-java-pubsub/pom.xml index cae94315abf9..4a7485450433 100644 --- a/gcloud-java-pubsub/pom.xml +++ b/gcloud-java-pubsub/pom.xml @@ -19,7 +19,7 @@ com.google.api gax - 0.0.9 + 0.0.11 com.google.api.grpc diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java index 886945e0504e..6f7139bf4270 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java @@ -33,6 +33,7 @@ package com.google.cloud.pubsub.spi.v1; +import com.google.api.gax.core.PageAccessor; import com.google.api.gax.grpc.ApiCallable; import com.google.api.gax.protobuf.PathTemplate; import com.google.protobuf.Empty; @@ -59,6 +60,60 @@ * Service Description: The service that an application uses to manipulate topics, and to send * messages to a topic. * + *

    This class provides the ability to make remote calls to the backing service through method + * calls that map to API methods. Sample code to get started: + * + *

    + * 
    + * try (PublisherApi publisherApi = PublisherApi.defaultInstance()) {
    + *   // make calls here
    + * String name = "";
    + * Topic callResult = createTopic(name);
    + * }
    + * 
    + * 
    + * + *

    Note: close() needs to be called on the publisherApi object to clean up resources such + * as threads. In the example above, try-with-resources is used, which automatically calls + * close(). + * + *

    The surface of this class includes several types of Java methods for each of the API's methods: + * + *

      + *
    1. A "flattened" method. With this type of method, the fields of the request type have been + * converted into function parameters. It may be the case that not all fields are available + * as parameters, and not every API method will have a flattened method entry point. + *
    2. A "request object" method. This type of method only takes one parameter, a request + * object, which must be constructed before the call. Not every API method will have a request + * object method. + *
    3. A "callable" method. This type of method takes no parameters and returns an immutable + * ApiCallable object, which can be used to initiate calls to the service. + *
    + * + *

    See the individual methods for example code. + * + *

    Many parameters require resource names to be formatted in a particular way. To assist + * with these names, this class includes a format method for each type of name, and additionally + * a parse method to extract the individual identifiers contained within names that are + * returned. + * + *

    This class can be customized by passing in a custom instance of PublisherSettings to + * create(). For example: + * + * + *

    + * 
    + * ConnectionSettings defaultConnectionSettings =
    + *     PublisherSettings.defaultInstance().toBuilder().getConnectionSettings();
    + * ConnectionSettings updatedConnectionSettings =
    + *     defaultConnectionSettings.toBuilder().provideCredentialsWith(myCredentials).build();
    + * PublisherSettings publisherSettings = PublisherSettings.defaultInstance().toBuilder().
    + *     provideChannelWith(updatedConnectionSettings)
    + *     .build();
    + * PublisherApi publisherApi = PublisherApi.create(publisherSettings);
    + * 
    + * 
    + * * * */ @@ -71,11 +126,11 @@ public class PublisherApi implements AutoCloseable { private final ApiCallable publishCallable; private final ApiCallable getTopicCallable; private final ApiCallable listTopicsCallable; - private final ApiCallable> listTopicsIterableCallable; + private final ApiCallable> listTopicsPagedCallable; private final ApiCallable listTopicSubscriptionsCallable; - private final ApiCallable> - listTopicSubscriptionsIterableCallable; + private final ApiCallable> + listTopicSubscriptionsPagedCallable; private final ApiCallable deleteTopicCallable; private static final PathTemplate PROJECT_PATH_TEMPLATE = @@ -179,12 +234,12 @@ protected PublisherApi(PublisherSettings settings) throws IOException { } this.getTopicCallable = ApiCallable.create(settings.getTopicSettings(), settings); this.listTopicsCallable = ApiCallable.create(settings.listTopicsSettings(), settings); - this.listTopicsIterableCallable = - ApiCallable.createIterable(settings.listTopicsSettings(), settings); + this.listTopicsPagedCallable = + ApiCallable.createPagedVariant(settings.listTopicsSettings(), settings); this.listTopicSubscriptionsCallable = ApiCallable.create(settings.listTopicSubscriptionsSettings(), settings); - this.listTopicSubscriptionsIterableCallable = - ApiCallable.createIterable(settings.listTopicSubscriptionsSettings(), settings); + this.listTopicSubscriptionsPagedCallable = + ApiCallable.createPagedVariant(settings.listTopicSubscriptionsSettings(), settings); this.deleteTopicCallable = ApiCallable.create(settings.deleteTopicSettings(), settings); if (settings.shouldAutoCloseChannel()) { @@ -213,7 +268,7 @@ public void close() throws IOException { * underscores (`_`), periods (`.`), tildes (`~`), plus (`+`) or percent * signs (`%`). It must be between 3 and 255 characters in length, and it * must not start with `"goog"`. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final Topic createTopic(String name) { Topic request = Topic.newBuilder().setName(name).build(); @@ -229,7 +284,7 @@ public final Topic createTopic(String name) { * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ private Topic createTopic(Topic request) { return createTopicCallable().call(request); @@ -241,7 +296,7 @@ private Topic createTopic(Topic request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable createTopicCallable() { return createTopicCallable; @@ -260,7 +315,7 @@ public final ApiCallable createTopicCallable() { * * @param topic The messages in the request will be published on this topic. * @param messages The messages to publish. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final PublishResponse publish(String topic, List messages) { PublishRequest request = @@ -279,7 +334,7 @@ public final PublishResponse publish(String topic, List messages) * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public PublishResponse publish(PublishRequest request) { return publishCallable().call(request); @@ -293,7 +348,7 @@ public PublishResponse publish(PublishRequest request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable publishCallable() { return publishCallable; @@ -309,7 +364,7 @@ public final ApiCallable publishCallable() { * * * @param topic The name of the topic to get. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final Topic getTopic(String topic) { GetTopicRequest request = GetTopicRequest.newBuilder().setTopic(topic).build(); @@ -325,7 +380,7 @@ public final Topic getTopic(String topic) { * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ private Topic getTopic(GetTopicRequest request) { return getTopicCallable().call(request); @@ -337,7 +392,7 @@ private Topic getTopic(GetTopicRequest request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable getTopicCallable() { return getTopicCallable; @@ -353,9 +408,9 @@ public final ApiCallable getTopicCallable() { * * * @param project The name of the cloud project that topics belong to. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ - public final Iterable listTopics(String project) { + public final PageAccessor listTopics(String project) { ListTopicsRequest request = ListTopicsRequest.newBuilder().setProject(project).build(); return listTopics(request); } @@ -368,10 +423,10 @@ public final Iterable listTopics(String project) { * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ - public final Iterable listTopics(ListTopicsRequest request) { - return listTopicsIterableCallable().call(request); + public final PageAccessor listTopics(ListTopicsRequest request) { + return listTopicsPagedCallable().call(request); } // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. @@ -380,10 +435,10 @@ public final Iterable listTopics(ListTopicsRequest request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ - public final ApiCallable> listTopicsIterableCallable() { - return listTopicsIterableCallable; + public final ApiCallable> listTopicsPagedCallable() { + return listTopicsPagedCallable; } // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. @@ -392,7 +447,7 @@ public final ApiCallable> listTopicsIterableC * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable listTopicsCallable() { return listTopicsCallable; @@ -408,9 +463,9 @@ public final ApiCallable listTopicsCallab * * * @param topic The name of the topic that subscriptions are attached to. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ - public final Iterable listTopicSubscriptions(String topic) { + public final PageAccessor listTopicSubscriptions(String topic) { ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder().setTopic(topic).build(); return listTopicSubscriptions(request); @@ -424,10 +479,10 @@ public final Iterable listTopicSubscriptions(String topic) { * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ - public final Iterable listTopicSubscriptions(ListTopicSubscriptionsRequest request) { - return listTopicSubscriptionsIterableCallable().call(request); + public final PageAccessor listTopicSubscriptions(ListTopicSubscriptionsRequest request) { + return listTopicSubscriptionsPagedCallable().call(request); } // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. @@ -436,11 +491,11 @@ public final Iterable listTopicSubscriptions(ListTopicSubscriptionsReque * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ - public final ApiCallable> - listTopicSubscriptionsIterableCallable() { - return listTopicSubscriptionsIterableCallable; + public final ApiCallable> + listTopicSubscriptionsPagedCallable() { + return listTopicSubscriptionsPagedCallable; } // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. @@ -449,7 +504,7 @@ public final Iterable listTopicSubscriptions(ListTopicSubscriptionsReque * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable listTopicSubscriptionsCallable() { @@ -470,7 +525,7 @@ public final Iterable listTopicSubscriptions(ListTopicSubscriptionsReque * * * @param topic Name of the topic to delete. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final void deleteTopic(String topic) { DeleteTopicRequest request = DeleteTopicRequest.newBuilder().setTopic(topic).build(); @@ -490,7 +545,7 @@ public final void deleteTopic(String topic) { * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ private void deleteTopic(DeleteTopicRequest request) { deleteTopicCallable().call(request); @@ -506,7 +561,7 @@ private void deleteTopic(DeleteTopicRequest request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable deleteTopicCallable() { return deleteTopicCallable; diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherSettings.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherSettings.java index 72d24404d87a..230adc5ec35c 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherSettings.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherSettings.java @@ -73,6 +73,32 @@ // Manually-added imports: add custom (non-generated) imports after this point. // AUTO-GENERATED DOCUMENTATION AND CLASS - see instructions at the top of the file for editing. +/** + * Settings class to configure an instance of {@link PublisherApi}. + * + *

    The default instance has everything set to sensible defaults: + * + *

      + *
    • The default service address (pubsub-experimental.googleapis.com) and default port (443) + * are used. + *
    • Credentials are acquired automatically through Application Default Credentials. + *
    • Retries are configured for idempotent methods but not for non-idempotent methods. + *
    + * + *

    The builder of this class is recursive, so contained classes are themselves builders. + * When build() is called, the tree of builders is called to create the complete settings + * object. For example, to set the total timeout of CreateTopic to 30 seconds: + * + *

    + * 
    + * PublisherSettings.Builder publisherSettingsBuilder =
    + *     PublisherSettings.defaultInstance().toBuilder();
    + * publisherSettingsBuilder.CreateTopicSettings().getRetrySettingsBuilder()
    + *     .setTotalTimeout(Duration.standardSeconds(30));
    + * PublisherSettings publisherSettings = publisherSettingsBuilder.build();
    + * 
    + * 
    + */ @javax.annotation.Generated("by GAPIC") public class PublisherSettings extends ServiceApiSettings { @@ -113,41 +139,68 @@ public class PublisherSettings extends ServiceApiSettings { private final SimpleCallSettings deleteTopicSettings; + /** + * Returns the object with the settings used for calls to createTopic. + */ public SimpleCallSettings createTopicSettings() { return createTopicSettings; } + /** + * Returns the object with the settings used for calls to publish. + */ public BundlingCallSettings publishSettings() { return publishSettings; } + /** + * Returns the object with the settings used for calls to getTopic. + */ public SimpleCallSettings getTopicSettings() { return getTopicSettings; } + /** + * Returns the object with the settings used for calls to listTopics. + */ public PageStreamingCallSettings listTopicsSettings() { return listTopicsSettings; } + /** + * Returns the object with the settings used for calls to listTopicSubscriptions. + */ public PageStreamingCallSettings< ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> listTopicSubscriptionsSettings() { return listTopicSubscriptionsSettings; } + /** + * Returns the object with the settings used for calls to deleteTopic. + */ public SimpleCallSettings deleteTopicSettings() { return deleteTopicSettings; } + /** + * Returns an instance of this class with recommended defaults. + */ public static PublisherSettings defaultInstance() throws IOException { return newBuilder().build(); } + /** + * Returns a new builder for this class. + */ public static Builder newBuilder() { return new Builder(); } + /** + * Returns a builder containing all the values of this settings class. + */ public Builder toBuilder() { return new Builder(this); } @@ -286,6 +339,9 @@ public long countBytes(PublishRequest request) { } }; + /** + * Builder for PublisherSettings. + */ public static class Builder extends ServiceApiSettings.Builder { private final ImmutableList methodSettingsBuilders; @@ -332,7 +388,7 @@ public static class Builder extends ServiceApiSettings.Builder { private Builder() { super( - ConnectionSettings.builder() + ConnectionSettings.newBuilder() .setServiceAddress(DEFAULT_SERVICE_ADDRESS) .setPort(DEFAULT_SERVICE_PORT) .provideCredentialsWith(DEFAULT_SERVICE_SCOPES) @@ -440,34 +496,57 @@ public Builder setClientLibHeader(String name, String version) { return this; } + /** + * Applies the given settings to all of the API methods in this service. Only + * values that are non-null will be applied, so this method is not capable + * of un-setting any values. + */ public Builder applyToAllApiMethods(ApiCallSettings.Builder apiCallSettings) throws Exception { super.applyToAllApiMethods(methodSettingsBuilders, apiCallSettings); return this; } + /** + * Returns the builder for the settings used for calls to createTopic. + */ public SimpleCallSettings.Builder createTopicSettings() { return createTopicSettings; } + /** + * Returns the builder for the settings used for calls to publish. + */ public BundlingCallSettings.Builder publishSettings() { return publishSettings; } + /** + * Returns the builder for the settings used for calls to getTopic. + */ public SimpleCallSettings.Builder getTopicSettings() { return getTopicSettings; } + /** + * Returns the builder for the settings used for calls to listTopics. + */ public PageStreamingCallSettings.Builder listTopicsSettings() { return listTopicsSettings; } + /** + * Returns the builder for the settings used for calls to listTopicSubscriptions. + */ public PageStreamingCallSettings.Builder< ListTopicSubscriptionsRequest, ListTopicSubscriptionsResponse, String> listTopicSubscriptionsSettings() { return listTopicSubscriptionsSettings; } + /** + * Returns the builder for the settings used for calls to deleteTopic. + */ public SimpleCallSettings.Builder deleteTopicSettings() { return deleteTopicSettings; } diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java index 2bfafd62ef0e..322154991e5b 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java @@ -33,6 +33,7 @@ package com.google.cloud.pubsub.spi.v1; +import com.google.api.gax.core.PageAccessor; import com.google.api.gax.grpc.ApiCallable; import com.google.api.gax.protobuf.PathTemplate; import com.google.protobuf.Empty; @@ -60,6 +61,63 @@ * Service Description: The service that an application uses to manipulate subscriptions and to * consume messages from a subscription via the `Pull` method. * + *

    This class provides the ability to make remote calls to the backing service through method + * calls that map to API methods. Sample code to get started: + * + *

    + * 
    + * try (SubscriberApi subscriberApi = SubscriberApi.defaultInstance()) {
    + *   // make calls here
    + * String name = "";
    + * String topic = "";
    + * PushConfig pushConfig = PushConfig.newBuilder().build();
    + * int ackDeadlineSeconds = 0;
    + * Subscription callResult = createSubscription(name, topic, pushConfig, ackDeadlineSeconds);
    + * }
    + * 
    + * 
    + * + *

    Note: close() needs to be called on the subscriberApi object to clean up resources such + * as threads. In the example above, try-with-resources is used, which automatically calls + * close(). + * + *

    The surface of this class includes several types of Java methods for each of the API's methods: + * + *

      + *
    1. A "flattened" method. With this type of method, the fields of the request type have been + * converted into function parameters. It may be the case that not all fields are available + * as parameters, and not every API method will have a flattened method entry point. + *
    2. A "request object" method. This type of method only takes one parameter, a request + * object, which must be constructed before the call. Not every API method will have a request + * object method. + *
    3. A "callable" method. This type of method takes no parameters and returns an immutable + * ApiCallable object, which can be used to initiate calls to the service. + *
    + * + *

    See the individual methods for example code. + * + *

    Many parameters require resource names to be formatted in a particular way. To assist + * with these names, this class includes a format method for each type of name, and additionally + * a parse method to extract the individual identifiers contained within names that are + * returned. + * + *

    This class can be customized by passing in a custom instance of SubscriberSettings to + * create(). For example: + * + * + *

    + * 
    + * ConnectionSettings defaultConnectionSettings =
    + *     SubscriberSettings.defaultInstance().toBuilder().getConnectionSettings();
    + * ConnectionSettings updatedConnectionSettings =
    + *     defaultConnectionSettings.toBuilder().provideCredentialsWith(myCredentials).build();
    + * SubscriberSettings subscriberSettings = SubscriberSettings.defaultInstance().toBuilder().
    + *     provideChannelWith(updatedConnectionSettings)
    + *     .build();
    + * SubscriberApi subscriberApi = SubscriberApi.create(subscriberSettings);
    + * 
    + * 
    + * * * */ @@ -72,8 +130,8 @@ public class SubscriberApi implements AutoCloseable { private final ApiCallable getSubscriptionCallable; private final ApiCallable listSubscriptionsCallable; - private final ApiCallable> - listSubscriptionsIterableCallable; + private final ApiCallable> + listSubscriptionsPagedCallable; private final ApiCallable deleteSubscriptionCallable; private final ApiCallable modifyAckDeadlineCallable; private final ApiCallable acknowledgeCallable; @@ -179,8 +237,8 @@ protected SubscriberApi(SubscriberSettings settings) throws IOException { this.getSubscriptionCallable = ApiCallable.create(settings.getSubscriptionSettings(), settings); this.listSubscriptionsCallable = ApiCallable.create(settings.listSubscriptionsSettings(), settings); - this.listSubscriptionsIterableCallable = - ApiCallable.createIterable(settings.listSubscriptionsSettings(), settings); + this.listSubscriptionsPagedCallable = + ApiCallable.createPagedVariant(settings.listSubscriptionsSettings(), settings); this.deleteSubscriptionCallable = ApiCallable.create(settings.deleteSubscriptionSettings(), settings); this.modifyAckDeadlineCallable = @@ -243,7 +301,7 @@ public void close() throws IOException { * system will eventually redeliver the message. * * If this parameter is not set, the default value of 10 seconds is used. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final Subscription createSubscription( String name, String topic, PushConfig pushConfig, int ackDeadlineSeconds) { @@ -271,7 +329,7 @@ public final Subscription createSubscription( * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public Subscription createSubscription(Subscription request) { return createSubscriptionCallable().call(request); @@ -288,7 +346,7 @@ public Subscription createSubscription(Subscription request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable createSubscriptionCallable() { return createSubscriptionCallable; @@ -307,7 +365,7 @@ public final ApiCallable createSubscriptionCallable( * * * @param subscription The name of the subscription to get. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final Subscription getSubscription(String subscription) { GetSubscriptionRequest request = @@ -327,7 +385,7 @@ public final Subscription getSubscription(String subscription) { * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ private Subscription getSubscription(GetSubscriptionRequest request) { return getSubscriptionCallable().call(request); @@ -342,7 +400,7 @@ private Subscription getSubscription(GetSubscriptionRequest request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable getSubscriptionCallable() { return getSubscriptionCallable; @@ -361,9 +419,9 @@ public final ApiCallable getSubscriptionCa * * * @param project The name of the cloud project that subscriptions belong to. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ - public final Iterable listSubscriptions(String project) { + public final PageAccessor listSubscriptions(String project) { ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder().setProject(project).build(); return listSubscriptions(request); @@ -380,10 +438,10 @@ public final Iterable listSubscriptions(String project) { * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ - public final Iterable listSubscriptions(ListSubscriptionsRequest request) { - return listSubscriptionsIterableCallable().call(request); + public final PageAccessor listSubscriptions(ListSubscriptionsRequest request) { + return listSubscriptionsPagedCallable().call(request); } // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. @@ -395,11 +453,11 @@ public final Iterable listSubscriptions(ListSubscriptionsRequest r * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ - public final ApiCallable> - listSubscriptionsIterableCallable() { - return listSubscriptionsIterableCallable; + public final ApiCallable> + listSubscriptionsPagedCallable() { + return listSubscriptionsPagedCallable; } // AUTO-GENERATED DOCUMENTATION AND METHOD - see instructions at the top of the file for editing. @@ -411,7 +469,7 @@ public final Iterable listSubscriptions(ListSubscriptionsRequest r * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable listSubscriptionsCallable() { @@ -432,7 +490,7 @@ public final Iterable listSubscriptions(ListSubscriptionsRequest r * * * @param subscription The subscription to delete. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final void deleteSubscription(String subscription) { DeleteSubscriptionRequest request = @@ -453,7 +511,7 @@ public final void deleteSubscription(String subscription) { * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ private void deleteSubscription(DeleteSubscriptionRequest request) { deleteSubscriptionCallable().call(request); @@ -469,7 +527,7 @@ private void deleteSubscription(DeleteSubscriptionRequest request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable deleteSubscriptionCallable() { return deleteSubscriptionCallable; @@ -494,7 +552,7 @@ public final ApiCallable deleteSubscriptionCal * ack deadline will expire 10 seconds after the `ModifyAckDeadline` call * was made. Specifying zero may immediately make the message available for * another pull request. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final void modifyAckDeadline( String subscription, List ackIds, int ackDeadlineSeconds) { @@ -519,7 +577,7 @@ public final void modifyAckDeadline( * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public void modifyAckDeadline(ModifyAckDeadlineRequest request) { modifyAckDeadlineCallable().call(request); @@ -534,7 +592,7 @@ public void modifyAckDeadline(ModifyAckDeadlineRequest request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable modifyAckDeadlineCallable() { return modifyAckDeadlineCallable; @@ -558,7 +616,7 @@ public final ApiCallable modifyAckDeadlineCalla * @param subscription The subscription whose message is being acknowledged. * @param ackIds The acknowledgment ID for the messages being acknowledged that was returned * by the Pub/Sub system in the `Pull` response. Must not be empty. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final void acknowledge(String subscription, List ackIds) { AcknowledgeRequest request = @@ -581,7 +639,7 @@ public final void acknowledge(String subscription, List ackIds) { * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public void acknowledge(AcknowledgeRequest request) { acknowledgeCallable().call(request); @@ -599,7 +657,7 @@ public void acknowledge(AcknowledgeRequest request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable acknowledgeCallable() { return acknowledgeCallable; @@ -624,7 +682,7 @@ public final ApiCallable acknowledgeCallable() { * than returning no messages. * @param maxMessages The maximum number of messages returned for this request. The Pub/Sub * system may return fewer than the number specified. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final PullResponse pull(String subscription, boolean returnImmediately, int maxMessages) { PullRequest request = @@ -648,7 +706,7 @@ public final PullResponse pull(String subscription, boolean returnImmediately, i * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public PullResponse pull(PullRequest request) { return pullCallable().call(request); @@ -663,7 +721,7 @@ public PullResponse pull(PullRequest request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable pullCallable() { return pullCallable; @@ -690,7 +748,7 @@ public final ApiCallable pullCallable() { * stop pushing messages from the given subscription and allow * messages to be pulled and acknowledged - effectively pausing * the subscription if `Pull` is not called. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final void modifyPushConfig(String subscription, PushConfig pushConfig) { ModifyPushConfigRequest request = @@ -715,7 +773,7 @@ public final void modifyPushConfig(String subscription, PushConfig pushConfig) { * * * @param request The request object containing all of the parameters for the API call. - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public void modifyPushConfig(ModifyPushConfigRequest request) { modifyPushConfigCallable().call(request); @@ -732,7 +790,7 @@ public void modifyPushConfig(ModifyPushConfigRequest request) { * * * - * @throws ApiException if the remote call fails + * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final ApiCallable modifyPushConfigCallable() { return modifyPushConfigCallable; diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberSettings.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberSettings.java index a46c956ae29d..39fdadccea2a 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberSettings.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberSettings.java @@ -66,6 +66,32 @@ // Manually-added imports: add custom (non-generated) imports after this point. // AUTO-GENERATED DOCUMENTATION AND CLASS - see instructions at the top of the file for editing. +/** + * Settings class to configure an instance of {@link SubscriberApi}. + * + *

    The default instance has everything set to sensible defaults: + * + *

      + *
    • The default service address (pubsub-experimental.googleapis.com) and default port (443) + * are used. + *
    • Credentials are acquired automatically through Application Default Credentials. + *
    • Retries are configured for idempotent methods but not for non-idempotent methods. + *
    + * + *

    The builder of this class is recursive, so contained classes are themselves builders. + * When build() is called, the tree of builders is called to create the complete settings + * object. For example, to set the total timeout of CreateSubscription to 30 seconds: + * + *

    + * 
    + * SubscriberSettings.Builder subscriberSettingsBuilder =
    + *     SubscriberSettings.defaultInstance().toBuilder();
    + * subscriberSettingsBuilder.CreateSubscriptionSettings().getRetrySettingsBuilder()
    + *     .setTotalTimeout(Duration.standardSeconds(30));
    + * SubscriberSettings subscriberSettings = subscriberSettingsBuilder.build();
    + * 
    + * 
    + */ @javax.annotation.Generated("by GAPIC") public class SubscriberSettings extends ServiceApiSettings { @@ -106,48 +132,81 @@ public class SubscriberSettings extends ServiceApiSettings { private final SimpleCallSettings pullSettings; private final SimpleCallSettings modifyPushConfigSettings; + /** + * Returns the object with the settings used for calls to createSubscription. + */ public SimpleCallSettings createSubscriptionSettings() { return createSubscriptionSettings; } + /** + * Returns the object with the settings used for calls to getSubscription. + */ public SimpleCallSettings getSubscriptionSettings() { return getSubscriptionSettings; } + /** + * Returns the object with the settings used for calls to listSubscriptions. + */ public PageStreamingCallSettings< ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> listSubscriptionsSettings() { return listSubscriptionsSettings; } + /** + * Returns the object with the settings used for calls to deleteSubscription. + */ public SimpleCallSettings deleteSubscriptionSettings() { return deleteSubscriptionSettings; } + /** + * Returns the object with the settings used for calls to modifyAckDeadline. + */ public SimpleCallSettings modifyAckDeadlineSettings() { return modifyAckDeadlineSettings; } + /** + * Returns the object with the settings used for calls to acknowledge. + */ public SimpleCallSettings acknowledgeSettings() { return acknowledgeSettings; } + /** + * Returns the object with the settings used for calls to pull. + */ public SimpleCallSettings pullSettings() { return pullSettings; } + /** + * Returns the object with the settings used for calls to modifyPushConfig. + */ public SimpleCallSettings modifyPushConfigSettings() { return modifyPushConfigSettings; } + /** + * Returns an instance of this class with recommended defaults. + */ public static SubscriberSettings defaultInstance() throws IOException { return newBuilder().build(); } + /** + * Returns a new builder for this class. + */ public static Builder newBuilder() { return new Builder(); } + /** + * Returns a builder containing all the values of this settings class. + */ public Builder toBuilder() { return new Builder(this); } @@ -202,6 +261,9 @@ public Iterable extractResources(ListSubscriptionsResponse payload } }; + /** + * Builder for SubscriberSettings. + */ public static class Builder extends ServiceApiSettings.Builder { private final ImmutableList methodSettingsBuilders; @@ -250,7 +312,7 @@ public static class Builder extends ServiceApiSettings.Builder { private Builder() { super( - ConnectionSettings.builder() + ConnectionSettings.newBuilder() .setServiceAddress(DEFAULT_SERVICE_ADDRESS) .setPort(DEFAULT_SERVICE_PORT) .provideCredentialsWith(DEFAULT_SERVICE_SCOPES) @@ -363,43 +425,72 @@ public Builder setClientLibHeader(String name, String version) { return this; } + /** + * Applies the given settings to all of the API methods in this service. Only + * values that are non-null will be applied, so this method is not capable + * of un-setting any values. + */ public Builder applyToAllApiMethods(ApiCallSettings.Builder apiCallSettings) throws Exception { super.applyToAllApiMethods(methodSettingsBuilders, apiCallSettings); return this; } + /** + * Returns the builder for the settings used for calls to createSubscription. + */ public SimpleCallSettings.Builder createSubscriptionSettings() { return createSubscriptionSettings; } + /** + * Returns the builder for the settings used for calls to getSubscription. + */ public SimpleCallSettings.Builder getSubscriptionSettings() { return getSubscriptionSettings; } + /** + * Returns the builder for the settings used for calls to listSubscriptions. + */ public PageStreamingCallSettings.Builder< ListSubscriptionsRequest, ListSubscriptionsResponse, Subscription> listSubscriptionsSettings() { return listSubscriptionsSettings; } + /** + * Returns the builder for the settings used for calls to deleteSubscription. + */ public SimpleCallSettings.Builder deleteSubscriptionSettings() { return deleteSubscriptionSettings; } + /** + * Returns the builder for the settings used for calls to modifyAckDeadline. + */ public SimpleCallSettings.Builder modifyAckDeadlineSettings() { return modifyAckDeadlineSettings; } + /** + * Returns the builder for the settings used for calls to acknowledge. + */ public SimpleCallSettings.Builder acknowledgeSettings() { return acknowledgeSettings; } + /** + * Returns the builder for the settings used for calls to pull. + */ public SimpleCallSettings.Builder pullSettings() { return pullSettings; } + /** + * Returns the builder for the settings used for calls to modifyPushConfig. + */ public SimpleCallSettings.Builder modifyPushConfigSettings() { return modifyPushConfigSettings; } From 121783ac3b346abafb5d568be794cde1c941a47c Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 22 Apr 2016 21:29:07 +0200 Subject: [PATCH 267/375] Make DNS batch get zone/changerequest return null for NOT_FOUND (#953) --- .../google/cloud/BaseServiceException.java | 17 ++++++- .../java/com/google/cloud/dns/DnsBatch.java | 44 ++++++++++++----- .../com/google/cloud/dns/spi/RpcBatch.java | 2 +- .../com/google/cloud/dns/DnsBatchTest.java | 49 ++++++++++++++++++- 4 files changed, 94 insertions(+), 18 deletions(-) diff --git a/gcloud-java-core/src/main/java/com/google/cloud/BaseServiceException.java b/gcloud-java-core/src/main/java/com/google/cloud/BaseServiceException.java index ad2d6bf07144..7cc55fd7a19b 100644 --- a/gcloud-java-core/src/main/java/com/google/cloud/BaseServiceException.java +++ b/gcloud-java-core/src/main/java/com/google/cloud/BaseServiceException.java @@ -135,8 +135,21 @@ public BaseServiceException(IOException exception, boolean idempotent) { this.debugInfo = debugInfo; } - public BaseServiceException(GoogleJsonError error, boolean idempotent) { - this(error.getCode(), error.getMessage(), reason(error), idempotent); + public BaseServiceException(GoogleJsonError googleJsonError, boolean idempotent) { + super(googleJsonError.getMessage()); + Error error = new Error(googleJsonError.getCode(), reason(googleJsonError)); + this.code = error.code; + this.reason = error.reason; + this.retryable = isRetryable(idempotent, error); + if (this.reason != null) { + GoogleJsonError.ErrorInfo errorInfo = googleJsonError.getErrors().get(0); + this.location = errorInfo.getLocation(); + this.debugInfo = (String) errorInfo.get("debugInfo"); + } else { + this.location = null; + this.debugInfo = null; + } + this.idempotent = idempotent; } public BaseServiceException(int code, String message, String reason, boolean idempotent) { diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsBatch.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsBatch.java index d81fc27f3a1a..8037b6b28ce2 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsBatch.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsBatch.java @@ -91,7 +91,7 @@ public DnsBatchResult> listZones(Dns.ZoneListOption... options) { public DnsBatchResult createZone(ZoneInfo zone, Dns.ZoneOption... options) { DnsBatchResult result = new DnsBatchResult<>(); // todo this can cause misleading report of a failure, intended to be fixed within #924 - RpcBatch.Callback callback = createZoneCallback(this.options, result, true); + RpcBatch.Callback callback = createZoneCallback(this.options, result, false, true); Map optionMap = DnsImpl.optionMap(options); batch.addCreateZone(zone.toPb(), callback, optionMap); return result; @@ -118,7 +118,7 @@ public DnsBatchResult deleteZone(String zoneName) { */ public DnsBatchResult getZone(String zoneName, Dns.ZoneOption... options) { DnsBatchResult result = new DnsBatchResult<>(); - RpcBatch.Callback callback = createZoneCallback(this.options, result, true); + RpcBatch.Callback callback = createZoneCallback(this.options, result, true, true); Map optionMap = DnsImpl.optionMap(options); batch.addGetZone(zoneName, callback, optionMap); return result; @@ -186,7 +186,7 @@ public DnsBatchResult> listChangeRequests(String zoneName, public DnsBatchResult getChangeRequest(String zoneName, String changeRequestId, Dns.ChangeRequestOption... options) { DnsBatchResult result = new DnsBatchResult<>(); - RpcBatch.Callback callback = createChangeRequestCallback(zoneName, result, true); + RpcBatch.Callback callback = createChangeRequestCallback(zoneName, result, true, true); Map optionMap = DnsImpl.optionMap(options); batch.addGetChangeRequest(zoneName, changeRequestId, callback, optionMap); return result; @@ -197,20 +197,21 @@ public DnsBatchResult getChangeRequest(String zoneName, String ch * {@code zoneName} to this batch. The {@code options} can be used to restrict the fields returned * in the same way as for {@link Dns#applyChangeRequest(String, ChangeRequestInfo, * Dns.ChangeRequestOption...)}. Calling {@link DnsBatchResult#get()} on the return value yields - * the created {@link ChangeRequest} if successful, {@code null} if the change request does not - * exist, or throws a {@link DnsException} if the operation failed or the zone does not exist. + * the created {@link ChangeRequest} if successful or throws a {@link DnsException} if the + * operation failed or the zone does not exist. */ public DnsBatchResult applyChangeRequest(String zoneName, ChangeRequestInfo changeRequest, Dns.ChangeRequestOption... options) { DnsBatchResult result = new DnsBatchResult<>(); - RpcBatch.Callback callback = createChangeRequestCallback(zoneName, result, false); + RpcBatch.Callback callback = + createChangeRequestCallback(zoneName, result, false, false); Map optionMap = DnsImpl.optionMap(options); batch.addApplyChangeRequest(zoneName, changeRequest.toPb(), callback, optionMap); return result; } /** - * Submits this batch for processing using a single HTTP request. + * Submits this batch for processing using a single RPC request. */ public void submit() { batch.submit(); @@ -259,7 +260,7 @@ public void onFailure(GoogleJsonError googleJsonError) { * A joint callback for both "get zone" and "create zone" operations. */ private RpcBatch.Callback createZoneCallback(final DnsOptions serviceOptions, - final DnsBatchResult result, final boolean idempotent) { + final DnsBatchResult result, final boolean nullForNotFound, final boolean idempotent) { return new RpcBatch.Callback() { @Override public void onSuccess(ManagedZone response) { @@ -268,7 +269,12 @@ public void onSuccess(ManagedZone response) { @Override public void onFailure(GoogleJsonError googleJsonError) { - result.error(new DnsException(googleJsonError, idempotent)); + DnsException serviceException = new DnsException(googleJsonError, idempotent); + if (nullForNotFound && serviceException.code() == HTTP_NOT_FOUND) { + result.success(null); + } else { + result.error(serviceException); + } } }; } @@ -337,17 +343,29 @@ public void onFailure(GoogleJsonError googleJsonError) { * A joint callback for both "get change request" and "create change request" operations. */ private RpcBatch.Callback createChangeRequestCallback(final String zoneName, - final DnsBatchResult result, final boolean idempotent) { + final DnsBatchResult result, final boolean nullForNotFound, + final boolean idempotent) { return new RpcBatch.Callback() { @Override public void onSuccess(Change response) { - result.success(response == null ? null : ChangeRequest.fromPb(options.service(), - zoneName, response)); + result.success(response == null ? null : ChangeRequest.fromPb(options.service(), zoneName, + response)); } @Override public void onFailure(GoogleJsonError googleJsonError) { - result.error(new DnsException(googleJsonError, idempotent)); + DnsException serviceException = new DnsException(googleJsonError, idempotent); + if (serviceException.code() == HTTP_NOT_FOUND) { + if ("entity.parameters.changeId".equals(serviceException.location()) + || (serviceException.getMessage() != null + && serviceException.getMessage().contains("parameters.changeId"))) { + // the change id was not found, but the zone exists + result.success(null); + return; + } + // the zone does not exist, so throw an exception + } + result.error(serviceException); } }; } diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/RpcBatch.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/RpcBatch.java index 154ffa4a3c99..6fa3cfb70718 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/RpcBatch.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/spi/RpcBatch.java @@ -110,7 +110,7 @@ void addApplyChangeRequest(String zoneName, Change change, Callback call Map options); /** - * Submits a batch of requests for processing using a single HTTP request to Cloud DNS. + * Submits a batch of requests for processing using a single RPC request to Cloud DNS. */ void submit(); } diff --git a/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsBatchTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsBatchTest.java index bd743a3babb6..746a65ab7155 100644 --- a/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsBatchTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsBatchTest.java @@ -19,6 +19,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -218,7 +219,9 @@ public void testCreateZone() { } // testing error here, success is tested with options RpcBatch.Callback capturedCallback = callback.getValue(); - capturedCallback.onFailure(GOOGLE_JSON_ERROR); + GoogleJsonError error = new GoogleJsonError(); + error.setCode(404); + capturedCallback.onFailure(error); try { batchResult.get(); fail("Should throw a DnsException on error."); @@ -279,6 +282,23 @@ public void testGetZone() { } } + @Test + public void testGetZoneNotFound() { + EasyMock.reset(batchMock); + Capture> callback = Capture.newInstance(); + Capture> capturedOptions = Capture.newInstance(); + batchMock.addGetZone(EasyMock.eq(ZONE_NAME), EasyMock.capture(callback), + EasyMock.capture(capturedOptions)); + EasyMock.replay(batchMock); + DnsBatchResult batchResult = dnsBatch.getZone(ZONE_NAME); + assertEquals(0, capturedOptions.getValue().size()); + GoogleJsonError error = new GoogleJsonError(); + error.setCode(404); + RpcBatch.Callback capturedCallback = callback.getValue(); + capturedCallback.onFailure(error); + assertNull(batchResult.get()); + } + @Test public void testGetZoneWithOptions() { EasyMock.reset(dns, batchMock, optionsMock); @@ -556,6 +576,29 @@ public void testGetChangeRequest() { } } + @Test + public void testGetChangeRequestNotFound() { + EasyMock.reset(batchMock); + Capture> callback = Capture.newInstance(); + Capture> capturedOptions = Capture.newInstance(); + batchMock.addGetChangeRequest(EasyMock.eq(ZONE_NAME), + EasyMock.eq(CHANGE_REQUEST_COMPLETE.generatedId()), EasyMock.capture(callback), + EasyMock.capture(capturedOptions)); + EasyMock.replay(batchMock); + DnsBatchResult batchResult = dnsBatch.getChangeRequest(ZONE_NAME, + CHANGE_REQUEST_COMPLETE.generatedId()); + assertEquals(0, capturedOptions.getValue().size()); + RpcBatch.Callback capturedCallback = callback.getValue(); + GoogleJsonError error = new GoogleJsonError(); + GoogleJsonError.ErrorInfo errorInfo = new GoogleJsonError.ErrorInfo(); + errorInfo.setReason("reason"); + errorInfo.setLocation("entity.parameters.changeId"); + error.setCode(404); + error.setErrors(ImmutableList.of(errorInfo)); + capturedCallback.onFailure(error); + assertNull(batchResult.get()); + } + @Test public void testGetChangeRequestWithOptions() { EasyMock.reset(dns, batchMock, optionsMock); @@ -599,7 +642,9 @@ public void testApplyChangeRequest() { } // testing error here, success is tested with options RpcBatch.Callback capturedCallback = callback.getValue(); - capturedCallback.onFailure(GOOGLE_JSON_ERROR); + GoogleJsonError error = new GoogleJsonError(); + error.setCode(404); + capturedCallback.onFailure(error); try { batchResult.get(); fail("Should throw a DnsException on error."); From 8e914de344aa61a6ff9def81534024f7bbe59c43 Mon Sep 17 00:00:00 2001 From: Shin Fan Date: Mon, 25 Apr 2016 14:15:29 -0700 Subject: [PATCH 268/375] Add custom port support to LocalPubsubHelper (#956) --- .../pubsub/testing/LocalPubsubHelper.java | 41 ++++++++++++------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/testing/LocalPubsubHelper.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/testing/LocalPubsubHelper.java index 9b1be716094b..88acb46101b1 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/testing/LocalPubsubHelper.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/testing/LocalPubsubHelper.java @@ -35,63 +35,76 @@ * A class that runs a Pubsub emulator instance for use in tests. */ public class LocalPubsubHelper { + + private final int port; private final LocalServiceHelper serviceHelper; - private final List gcloudCommand; - private final URL emulatorUrl; // Local server settings private static final int DEFAULT_PORT = 8080; private static final String DEFAULT_HOST = "localhost"; + private static final URL EMULATOR_URL; // GCloud emulator settings - private static final String GCLOUD_CMD_TEXT = "gcloud beta emulators pubsub start --host-port"; + private static final String GCLOUD_CMD_TEXT = "gcloud beta emulators pubsub start"; + private static final String GCLOUD_CMD_PORT_FLAG = "--host-port="; private static final String VERSION_PREFIX = "pubsub-emulator"; private static final String MIN_VERSION = "2016.01.13"; + private static final String BIN_CMD_PORT_FLAG = "--port="; // Downloadable emulator settings private static final String FILENAME = "pubsub-emulator-20160113-2.zip"; private static final String BIN_NAME = "pubsub-emulator/bin/cloud-pubsub-fake"; private static final String MD5_CHECKSUM = "20943e9defa300f2de101568459c133d"; + static { + try { + EMULATOR_URL = new URL("http://storage.googleapis.com/pubsub/tools/" + FILENAME); + } catch (MalformedURLException ex) { + throw new IllegalStateException(ex); + } + } + /** * Constructs a new LocalPubsubHelper. The method start() must * be called before it is used. - * @throws MalformedURLException */ - public LocalPubsubHelper() throws MalformedURLException { - gcloudCommand = new ArrayList<>(Arrays.asList(GCLOUD_CMD_TEXT.split(" "))); - gcloudCommand.add(DEFAULT_HOST); - emulatorUrl = new URL("http://storage.googleapis.com/pubsub/tools/" + FILENAME); + public LocalPubsubHelper() { + port = LocalServiceHelper.findAvailablePort(DEFAULT_PORT); + List gcloudCommand = new ArrayList<>(Arrays.asList(GCLOUD_CMD_TEXT.split(" "))); + gcloudCommand.add(GCLOUD_CMD_PORT_FLAG + port); GCloudEmulatorRunner gcloudRunner = new GCloudEmulatorRunner(gcloudCommand, VERSION_PREFIX, MIN_VERSION); DownloadableEmulatorRunner downloadRunner = - new DownloadableEmulatorRunner(Arrays.asList(BIN_NAME), emulatorUrl, MD5_CHECKSUM); + new DownloadableEmulatorRunner(Arrays.asList(BIN_NAME, BIN_CMD_PORT_FLAG + port), + EMULATOR_URL, MD5_CHECKSUM); serviceHelper = - new LocalServiceHelper(Arrays.asList(gcloudRunner, downloadRunner), DEFAULT_PORT); + new LocalServiceHelper(Arrays.asList(gcloudRunner, downloadRunner), port); } /** * Start the local pubsub emulator through gcloud, download the zip file if user does not have * gcloud installed. + * * @throws InterruptedException * @throws IOException */ public void start() throws IOException, InterruptedException { - String blockUntilOutput = Integer.toString(DEFAULT_PORT); + String blockUntilOutput = Integer.toString(port); serviceHelper.start(blockUntilOutput); } /** * Reset the internal state of the emulator. - * @throws InterruptedException + * * @throws IOException */ - public void reset() throws IOException, InterruptedException { + public void reset() throws IOException { this.serviceHelper.sendPostRequest("/reset"); } /** * Quit the local emulator and related local service. + * * @throws InterruptedException * @throws IOException */ @@ -104,7 +117,7 @@ public void stop() throws IOException, InterruptedException { * Creates a channel for making requests to the in-memory service. */ public ManagedChannel createChannel() { - return NettyChannelBuilder.forAddress(DEFAULT_HOST, DEFAULT_PORT) + return NettyChannelBuilder.forAddress(DEFAULT_HOST, port) .negotiationType(NegotiationType.PLAINTEXT) .build(); } From 766a76df8cd2e90890b4bc34b2fde39d7e79dc19 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 28 Apr 2016 12:02:39 +0200 Subject: [PATCH 269/375] Revert maven-source-plugin to version 2.4 to speed up builds (#961) * Speed up builds by using an older version of maven-source-plugin (2.4) that doesn't have speed issues on ubuntu (as does 3.0.0) * Add comment to clarify maven-source-plugin downgrade --- pom.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 421ee0a49540..752f7613f207 100644 --- a/pom.xml +++ b/pom.xml @@ -426,7 +426,12 @@ org.apache.maven.plugins maven-source-plugin - 3.0.0 + + 2.4 attach-sources From 0cb8e3e41f03e6c61a65911e5116f51a80e3a66e Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 28 Apr 2016 16:04:50 +0200 Subject: [PATCH 270/375] Add PubSub API prototype and related classes (#962) * adding PubSubOptions, PubSub and its factories * Adding data types and define API * Add ReceivedMessage and fix review comments * Fix code review comments and add DefaultPubSubRpc * - Fix some codacy issues - Make messages consistent with proto defaults - Rename acknowledge to ack - Add nack - Add PullCallback * applying code review comments * add ByteArray * translate exceptions and add more info regarding pull * consider returnNullOn before throwing * Fix pubsub-related codacy issues --- gcloud-java-core/pom.xml | 10 + .../main/java/com/google/cloud/AsyncPage.java | 23 ++ .../google/cloud/BaseServiceException.java | 11 + .../main/java/com/google/cloud/ByteArray.java | 165 +++++++++++ gcloud-java-pubsub/pom.xml | 6 + .../java/com/google/cloud/pubsub/Message.java | 252 ++++++++++++++++ .../java/com/google/cloud/pubsub/PubSub.java | 237 +++++++++++++++ .../google/cloud/pubsub/PubSubException.java | 46 +++ .../google/cloud/pubsub/PubSubFactory.java | 25 ++ .../com/google/cloud/pubsub/PubSubImpl.java | 275 ++++++++++++++++++ .../google/cloud/pubsub/PubSubOptions.java | 121 ++++++++ .../com/google/cloud/pubsub/PushConfig.java | 142 +++++++++ .../google/cloud/pubsub/ReceivedMessage.java | 184 ++++++++++++ .../com/google/cloud/pubsub/Subscription.java | 158 ++++++++++ .../google/cloud/pubsub/SubscriptionInfo.java | 189 ++++++++++++ .../java/com/google/cloud/pubsub/Topic.java | 162 +++++++++++ .../com/google/cloud/pubsub/TopicInfo.java | 119 ++++++++ .../com/google/cloud/pubsub/package-info.java | 29 ++ .../cloud/pubsub/spi/DefaultPubSubRpc.java | 199 +++++++++++++ .../google/cloud/pubsub/spi/PubSubRpc.java | 72 +++++ .../cloud/pubsub/spi/PubSubRpcFactory.java | 27 ++ 21 files changed, 2452 insertions(+) create mode 100644 gcloud-java-core/src/main/java/com/google/cloud/AsyncPage.java create mode 100644 gcloud-java-core/src/main/java/com/google/cloud/ByteArray.java create mode 100644 gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Message.java create mode 100644 gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java create mode 100644 gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubException.java create mode 100644 gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubFactory.java create mode 100644 gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java create mode 100644 gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubOptions.java create mode 100644 gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PushConfig.java create mode 100644 gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/ReceivedMessage.java create mode 100644 gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java create mode 100644 gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionInfo.java create mode 100644 gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Topic.java create mode 100644 gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicInfo.java create mode 100644 gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/package-info.java create mode 100644 gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java create mode 100644 gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/PubSubRpc.java create mode 100644 gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/PubSubRpcFactory.java diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml index 22648d2e6ffa..a2f9b40ad71e 100644 --- a/gcloud-java-core/pom.xml +++ b/gcloud-java-core/pom.xml @@ -98,5 +98,15 @@ 3.4 test
    + + com.google.protobuf + protobuf-java + 3.0.0-beta-1 + + + com.google.api + gax + 0.0.11 +
    diff --git a/gcloud-java-core/src/main/java/com/google/cloud/AsyncPage.java b/gcloud-java-core/src/main/java/com/google/cloud/AsyncPage.java new file mode 100644 index 000000000000..ea2905795e62 --- /dev/null +++ b/gcloud-java-core/src/main/java/com/google/cloud/AsyncPage.java @@ -0,0 +1,23 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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; + +import java.util.concurrent.Future; + +public interface AsyncPage extends Page { + Future> nextPageAsync(); +} diff --git a/gcloud-java-core/src/main/java/com/google/cloud/BaseServiceException.java b/gcloud-java-core/src/main/java/com/google/cloud/BaseServiceException.java index 6dc87f4abb3e..a2a1486f8dce 100644 --- a/gcloud-java-core/src/main/java/com/google/cloud/BaseServiceException.java +++ b/gcloud-java-core/src/main/java/com/google/cloud/BaseServiceException.java @@ -18,6 +18,7 @@ import com.google.api.client.googleapis.json.GoogleJsonError; import com.google.api.client.googleapis.json.GoogleJsonResponseException; +import com.google.api.gax.grpc.ApiException; import com.google.common.base.MoreObjects; import java.io.IOException; @@ -143,6 +144,16 @@ public BaseServiceException(int code, String message, String reason, boolean ide this.debugInfo = null; } + public BaseServiceException(ApiException apiException, boolean idempotent) { + super(apiException.getMessage(), apiException); + this.code = apiException.getStatusCode().value(); + this.reason = apiException.getStatusCode().name(); + this.idempotent = idempotent; + this.retryable = apiException.isRetryable(); + this.location = null; + this.debugInfo = null; + } + protected Set retryableErrors() { return Collections.emptySet(); } diff --git a/gcloud-java-core/src/main/java/com/google/cloud/ByteArray.java b/gcloud-java-core/src/main/java/com/google/cloud/ByteArray.java new file mode 100644 index 000000000000..f23fb0876b41 --- /dev/null +++ b/gcloud-java-core/src/main/java/com/google/cloud/ByteArray.java @@ -0,0 +1,165 @@ +/* + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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; + +import com.google.common.base.MoreObjects; +import com.google.common.base.MoreObjects.ToStringHelper; +import com.google.protobuf.ByteString; + +import java.io.BufferedInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.Iterator; + +/** + * An immutable byte array holder. + */ +public class ByteArray implements Iterable, Serializable { + + private static final long serialVersionUID = -1908809133893782840L; + private final ByteString byteString; + + protected ByteArray(ByteString byteString) { + this.byteString = byteString; + } + + protected ByteArray(ByteArray byteArray) { + this.byteString = byteArray.byteString(); + } + + @Override + public final Iterator iterator() { + return byteString.iterator(); + } + + @Override + public String toString() { + ToStringHelper toStringHelper = MoreObjects.toStringHelper(this); + StringBuilder stBuilder = new StringBuilder(); + for (int i = 0; i < Math.min(256, byteString.size()); i++) { + stBuilder.append(String.format("%02x", byteString.byteAt(i))); + } + if (byteString.size() > 256) { + stBuilder.append("..."); + } + return toStringHelper.add("bytes", stBuilder.toString()).toString(); + } + + @Override + public final int hashCode() { + return byteString.hashCode(); + } + + @Override + public final boolean equals(Object obj) { + return obj == this + || obj instanceof ByteArray && byteString.equals(((ByteArray) obj).byteString); + } + + /** + * Returns the size of this blob. + */ + public final int length() { + return byteString.size(); + } + + /** + * Returns a copy as byte array. + */ + public final byte[] toByteArray() { + return byteString.toByteArray(); + } + + /** + * Returns the content as {@code UTF-8} string. + */ + public final String toStringUtf8() { + return byteString.toStringUtf8(); + } + + /** + * Returns a read-only {@link ByteBuffer} for this blob content. + */ + public final ByteBuffer asReadOnlyByteBuffer() { + return byteString.asReadOnlyByteBuffer(); + } + + /** + * Returns an {@link InputStream} for this blob content. + */ + public final InputStream asInputStream() { + final ByteBuffer byteBuffer = asReadOnlyByteBuffer(); + return new InputStream() { + @Override public int read() { + return !byteBuffer.hasRemaining() ? -1 : byteBuffer.get() & 0xFF; + } + }; + } + + protected ByteString byteString() { + return byteString; + } + + /** + * Copies bytes into a ByteBuffer. + * + * @throws java.nio.ReadOnlyBufferException if the target is read-only + * @throws java.nio.BufferOverflowException if the target's remaining() space is not large + * enough to hold the data + */ + public final void copyTo(ByteBuffer target) { + byteString.copyTo(target); + } + + /** + * Copies bytes into a buffer. + * + * @throws IndexOutOfBoundsException if an offset or size is negative or too large + */ + public final void copyTo(byte[] target) { + byteString.copyTo(target, 0, 0, length()); + } + + public static final ByteArray copyFrom(byte[] bytes) { + return new ByteArray(ByteString.copyFrom(bytes)); + } + + /** + * Copy the bytes using {@code UTF-8} decoding. + */ + public static final ByteArray copyFrom(String string) { + return new ByteArray(ByteString.copyFrom(string, StandardCharsets.UTF_8)); + } + + public static final ByteArray copyFrom(ByteBuffer bytes) { + return new ByteArray(ByteString.copyFrom(bytes)); + } + + public static final ByteArray copyFrom(InputStream input) throws IOException { + BufferedInputStream bufferedInput = new BufferedInputStream(input); + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + int value; + while ((value = bufferedInput.read()) != -1) { + bytes.write(value); + } + return copyFrom(bytes.toByteArray()); + } +} diff --git a/gcloud-java-pubsub/pom.xml b/gcloud-java-pubsub/pom.xml index 4a7485450433..8724ed627e1c 100644 --- a/gcloud-java-pubsub/pom.xml +++ b/gcloud-java-pubsub/pom.xml @@ -4,6 +4,7 @@ gcloud-java-pubsub jar GCloud Java Pub/Sub + https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-pubsub Java idiomatic client for Google Cloud Pub/Sub. @@ -16,6 +17,11 @@ gcloud-java-pubsub + + ${project.groupId} + gcloud-java-core + ${project.version} + com.google.api gax diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Message.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Message.java new file mode 100644 index 000000000000..830f9115a41d --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Message.java @@ -0,0 +1,252 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.cloud.ByteArray; +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableMap; +import com.google.protobuf.ByteString; +import com.google.protobuf.Timestamp; +import com.google.pubsub.v1.PubsubMessage; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * Pub/Sub message. + */ +public class Message implements Serializable { + + private static final long serialVersionUID = -1436515787233340634L; + private static final long NANOS_PER_MILLISECOND = 1000000; + private static final long MILLIS_PER_SECOND = 1000; + + private final String id; + private final InternalByteArray payload; + private final ImmutableMap attributes; + private final Long publishTime; + + private static final class InternalByteArray extends ByteArray { + + private static final long serialVersionUID = -3330181485911805428L; + + protected InternalByteArray(ByteString byteString) { + super(byteString); + } + + protected InternalByteArray(ByteArray byteArray) { + super(byteArray); + } + + @Override + protected ByteString byteString() { + return super.byteString(); + } + } + + /** + * Builder for Message. + */ + public abstract static class Builder { + + abstract Builder id(String id); + + public abstract Builder payload(String payload); + + public abstract Builder payload(ByteArray payload); + + public abstract Builder attributes(Map attributes); + + public abstract Builder addAttribute(String name, String value); + + public abstract Builder removeAttribute(String name); + + public abstract Builder clearAttributes(); + + abstract Builder publishTime(long publishTime); + + public abstract Message build(); + } + + static final class BuilderImpl extends Builder { + + private String id = ""; + private ByteArray payload; + private Map attributes = new HashMap<>(); + private Long publishTime; + + private BuilderImpl() {} + + BuilderImpl(Message message) { + id = message.id; + payload = message.payload; + attributes = new HashMap<>(message.attributes); + publishTime = message.publishTime; + } + + @Override + BuilderImpl id(String id) { + this.id = checkNotNull(id); + return this; + } + + @Override + public Builder payload(String payload) { + return payload(ByteArray.copyFrom(payload)); + } + + @Override + public Builder payload(ByteArray payload) { + this.payload = payload; + return this; + } + + @Override + public Builder addAttribute(String name, String value) { + attributes.put(name, value); + return this; + } + + @Override + public Builder attributes(Map attributes) { + this.attributes = new HashMap<>(attributes); + return this; + } + + @Override + public Builder removeAttribute(String name) { + attributes.remove(name); + return this; + } + + @Override + public Builder clearAttributes() { + attributes.clear(); + return this; + } + + @Override + Builder publishTime(long publishTime) { + this.publishTime = publishTime; + return this; + } + + @Override + public Message build() { + return new Message(this); + } + } + + Message(BuilderImpl builder) { + id = builder.id; + payload = new InternalByteArray(checkNotNull(builder.payload)); + attributes = ImmutableMap.copyOf(builder.attributes); + publishTime = builder.publishTime; + } + + public Long publishTime() { + return publishTime; + } + + public Map attributes() { + return attributes; + } + + public String id() { + return id; + } + + public String payloadAsString() { + return payload.toStringUtf8(); + } + + public ByteArray payload() { + return payload; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + return Objects.equals(toPb(), ((Message) o).toPb()); + } + + @Override + public int hashCode() { + return Objects.hash(serialVersionUID, id, payload, attributes, publishTime); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id) + .add("payload", payload) + .add("attributes", attributes) + .add("publishTime", publishTime) + .toString(); + } + + PubsubMessage toPb() { + PubsubMessage.Builder builder = PubsubMessage.newBuilder(); + if (id != null) { + builder.setMessageId(id); + } + builder.setData(payload.byteString()); + builder.getAttributes().putAll(attributes); + Timestamp.Builder tsBuilder = Timestamp.newBuilder(); + tsBuilder.setSeconds(publishTime / MILLIS_PER_SECOND); + tsBuilder.setNanos((int) (publishTime % MILLIS_PER_SECOND * NANOS_PER_MILLISECOND)); + builder.setPublishTime(tsBuilder); + return builder.build(); + } + + static Message fromPb(PubsubMessage messagePb) { + Builder builder = builder(new InternalByteArray(messagePb.getData())); + if (messagePb.hasPublishTime()) { + Timestamp ts = messagePb.getPublishTime(); + builder.publishTime( + ts.getSeconds() * MILLIS_PER_SECOND + ts.getNanos() / NANOS_PER_MILLISECOND); + } + builder.id(messagePb.getMessageId()); + for (Map.Entry entry : messagePb.getAttributes().entrySet()) { + builder.addAttribute(entry.getKey(), entry.getValue()); + } + return builder.build(); + } + + public Builder toBuilder() { + return new BuilderImpl(this); + } + + public static Message of(String payload) { + return builder(payload).build(); + } + + public static Builder builder(String payload) { + return new BuilderImpl().payload(payload); + } + + public static Builder builder(ByteArray payload) { + return new BuilderImpl().payload(payload); + } +} diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java new file mode 100644 index 000000000000..2695cd0064e8 --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java @@ -0,0 +1,237 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import com.google.cloud.AsyncPage; +import com.google.cloud.Page; +import com.google.cloud.Service; + +import java.io.Serializable; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +/** + * An interface for Google Cloud Pub/Sub. + * + * @see Google Cloud Pub/Sub + */ +public interface PubSub extends Service { + + final class ListOption implements Serializable { + + private static final long serialVersionUID = 6517442127283383124L; + + private final Option option; + private final Object value; + + enum Option { + PAGE_SIZE, PAGE_TOKEN + } + + private ListOption(Option option, Object value) { + this.option = option; + this.value = value; + } + + Option option() { + return option; + } + + Object value() { + return value; + } + + public static ListOption pageSize(int pageSize) { + return new ListOption(Option.PAGE_SIZE, pageSize); + } + + public static ListOption pageToken(String pageToken) { + return new ListOption(Option.PAGE_TOKEN, pageToken); + } + } + + final class PullOption implements Serializable { + + private static final long serialVersionUID = -5220474819637439937L; + + private final Option option; + private final Object value; + + enum Option { + MAX_MESSAGES + } + + private PullOption(Option option, Object value) { + this.option = option; + this.value = value; + } + + Option option() { + return option; + } + + Object value() { + return value; + } + + public static PullOption maxMessages(int maxMessages) { + return new PullOption(Option.MAX_MESSAGES, maxMessages); + } + } + + /** + * A callback to process pulled messages. + * The message will be ack'ed upon successful return or nack'ed if exception is thrown. + */ + interface MessageProcessor { + void process(Message message) throws Exception; + } + + /** + * An interface to control message consumer settings. + */ + interface MessageConsumer extends AutoCloseable { + + final class PullOption implements Serializable { + + private static final long serialVersionUID = 4792164134340316582L; + + private final Option option; + private final Object value; + + enum Option { + MAX_CONCURRENT_CALLBACKS + } + + private PullOption(Option option, Object value) { + this.option = option; + this.value = value; + } + + Option option() { + return option; + } + + Object value() { + return value; + } + + public static PullOption maxConcurrentCallbacks(int maxConcurrency) { + return new PullOption(Option.MAX_CONCURRENT_CALLBACKS, maxConcurrency); + } + } + + void start(MessageConsumer.PullOption... options); + + void stop(); + } + + Topic create(TopicInfo topic); + + Future createAsync(TopicInfo topic); + + // null if not found + Topic getTopic(String topic); + + Future getTopicAsync(String topic); + + // false if not found + boolean deleteTopic(String topic); + + Future deleteTopicAsync(String topic); + + Page listTopics(ListOption... options); + + Future> listTopicsAsync(ListOption... options); + + String publish(String topic, Message message); + + Future publishAsync(String topic, Message message); + + List publish(String topic, Message message, Message... messages); + + Future> publishAsync(String topic, Message message, Message... messages); + + List publish(String topic, Iterable messages); + + Future> publishAsync(String topic, Iterable messages); + + Subscription create(SubscriptionInfo subscription); + + Future createAsync(SubscriptionInfo subscription); + + // null if not found + Subscription getSubscription(String subscription); + + Future getSubscriptionAsync(String subscription); + + void replacePushConfig(String subscription, PushConfig pushConfig); + + Future replacePushConfigAsync(String subscription, PushConfig pushConfig); + + // false if not found + boolean deleteSubscription(String subscription); + + Future deleteSubscriptionAsync(String subscription); + + Page listSubscriptions(ListOption... options); + + Future> listSubscriptionsAsync(ListOption... options); + + Page listSubscriptions(String topic, ListOption... options); + + Future> listSubscriptionsAsync(String topic, ListOption... options); + + Iterator pull(String subscription, PullOption... options); + + Future> pullAsync(String subscription, PullOption... options); + + MessageConsumer pullAsync(String subscription, MessageProcessor callback); + + void ack(String subscription, String ackId, String... ackIds); + + Future ackAsync(String subscription, String ackId, String... ackIds); + + void ack(String subscription, Iterable ackIds); + + Future ackAsync(String subscription, Iterable ackIds); + + void nack(String subscription, String ackId, String... ackIds); + + Future nackAsync(String subscription, String ackId, String... ackIds); + + void nack(String subscription, Iterable ackIds); + + Future nackAsync(String subscription, Iterable ackIds); + + void modifyAckDeadline(String subscription, int deadline, TimeUnit unit, String ackId, + String... ackIds); + + Future modifyAckDeadlineAsync(String subscription, int deadline, TimeUnit unit, + String ackId, String... ackIds); + + void modifyAckDeadline(String subscription, int deadline, TimeUnit unit, Iterable ackIds); + + Future modifyAckDeadlineAsync(String subscription, int deadline, TimeUnit unit, + Iterable ackIds); + + // IAM Policy operations: getPolicy, replacePolicy, testPermissions + // Not sure if ready (docs is not up-to-date) + // Looks like policy is per resource (topic or subscription) but not per service? +} diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubException.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubException.java new file mode 100644 index 000000000000..0ff6fa7e56c3 --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubException.java @@ -0,0 +1,46 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import com.google.api.gax.grpc.ApiException; +import com.google.cloud.BaseServiceException; + +import java.io.IOException; +import java.util.Set; + +/** + * Pub/Sub service exception. + * + * @see Google Cloud Pub/Sub error codes + */ +public final class PubSubException extends BaseServiceException { + + private static final long serialVersionUID = 6434989638600001226L; + + public PubSubException(IOException ex, boolean idempotent) { + super(ex, idempotent); + } + + public PubSubException(ApiException apiException, boolean idempotent) { + super(apiException, idempotent); + } + + @Override + protected Set retryableErrors() { + return null; + } +} diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubFactory.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubFactory.java new file mode 100644 index 000000000000..8aa073f3a10a --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubFactory.java @@ -0,0 +1,25 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import com.google.cloud.ServiceFactory; + +/** + * An interface for Pub/Sub factories. + */ +public interface PubSubFactory + extends ServiceFactory {} diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java new file mode 100644 index 000000000000..bc9e428b6ab1 --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java @@ -0,0 +1,275 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static com.google.common.util.concurrent.Futures.lazyTransform; + +import com.google.cloud.AsyncPage; +import com.google.cloud.BaseService; +import com.google.cloud.Page; +import com.google.cloud.pubsub.spi.PubSubRpc; +import com.google.common.base.Function; +import com.google.common.base.Throwables; +import com.google.common.util.concurrent.Uninterruptibles; +import com.google.protobuf.Empty; +import com.google.pubsub.v1.DeleteTopicRequest; +import com.google.pubsub.v1.GetTopicRequest; + +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +class PubSubImpl extends BaseService implements PubSub { + + private final PubSubRpc rpc; + + PubSubImpl(PubSubOptions options) { + super(options); + rpc = options.rpc(); + } + + private static V get(Future future) { + try { + return Uninterruptibles.getUninterruptibly(future); + } catch (ExecutionException ex) { + throw Throwables.propagate(ex.getCause()); + } + } + + @Override + public Topic create(TopicInfo topic) { + return get(createAsync(topic)); + } + + @Override + public Future createAsync(TopicInfo topic) { + return lazyTransform(rpc.create(topic.toPb()), Topic.fromPbFunction(this)); + } + + @Override + public Topic getTopic(String topic) { + return get(getTopicAsync(topic)); + } + + @Override + public Future getTopicAsync(String topic) { + GetTopicRequest request = GetTopicRequest.newBuilder().setTopic(topic).build(); + return lazyTransform(rpc.get(request), Topic.fromPbFunction(this)); + } + + @Override + public boolean deleteTopic(String topic) { + return get(deleteTopicAsync(topic)); + } + + @Override + public Future deleteTopicAsync(String topic) { + DeleteTopicRequest request = DeleteTopicRequest.newBuilder().setTopic(topic).build(); + return lazyTransform(rpc.delete(request), new Function() { + @Override + public Boolean apply(Empty input) { + return true; + } + }); + } + + @Override + public Page listTopics(ListOption... options) { + return null; + } + + @Override + public Future> listTopicsAsync(ListOption... options) { + return null; + } + + @Override + public String publish(String topic, Message message) { + return null; + } + + @Override + public Future publishAsync(String topic, Message message) { + return null; + } + + @Override + public List publish(String topic, Message message, Message... messages) { + return null; + } + + @Override + public Future> publishAsync(String topic, Message message, Message... messages) { + return null; + } + + @Override + public List publish(String topic, Iterable messages) { + return null; + } + + @Override + public Future> publishAsync(String topic, Iterable messages) { + return null; + } + + @Override + public Subscription create(SubscriptionInfo subscription) { + return null; + } + + @Override + public Future createAsync(SubscriptionInfo subscription) { + return null; + } + + @Override + public Subscription getSubscription(String subscription) { + return null; + } + + @Override + public Future getSubscriptionAsync(String subscription) { + return null; + } + + @Override + public void replacePushConfig(String subscription, PushConfig pushConfig) { + + } + + @Override + public Future replacePushConfigAsync(String subscription, PushConfig pushConfig) { + return null; + } + + @Override + public boolean deleteSubscription(String subscription) { + return false; + } + + @Override + public Future deleteSubscriptionAsync(String subscription) { + return null; + } + + @Override + public Page listSubscriptions(ListOption... options) { + return null; + } + + @Override + public Future> listSubscriptionsAsync(ListOption... options) { + return null; + } + + @Override + public Page listSubscriptions(String topic, ListOption... options) { + return null; + } + + @Override + public Future> listSubscriptionsAsync(String topic, + ListOption... options) { + return null; + } + + @Override + public Iterator pull(String subscription, PullOption... options) { + // this should set return_immediately to true + return null; + } + + @Override + public Future> pullAsync(String subscription, PullOption... options) { + // though this method can set return_immediately to false (as future can be canceled) I + // suggest to keep it false so sync could delegate to asyc and use the same options + // this method also should use the VTKIT thread-pool to renew ack deadline for non consumed + // messages + return null; + } + + @Override + public MessageConsumer pullAsync(String subscription, MessageProcessor callback) { + // this method should use the VTKIT thread-pool (maybe getting it should be part of the spi) + return null; + } + + @Override + public void ack(String subscription, String ackId, String... ackIds) { + } + + @Override + public Future ackAsync(String subscription, String ackId, String... ackIds) { + return null; + } + + @Override + public void ack(String subscription, Iterable ackIds) { + + } + + @Override + public Future ackAsync(String subscription, Iterable ackIds) { + return null; + } + + @Override + public void nack(String subscription, String ackId, String... ackIds) { + } + + @Override + public Future nackAsync(String subscription, String ackId, String... ackIds) { + return null; + } + + @Override + public void nack(String subscription, Iterable ackIds) { + + } + + @Override + public Future nackAsync(String subscription, Iterable ackIds) { + return null; + } + + @Override + public void modifyAckDeadline(String subscription, int deadline, TimeUnit unit, String ackId, + String... ackIds) { + + } + + @Override + public Future modifyAckDeadlineAsync(String subscription, int deadline, TimeUnit unit, + String ackId, String... ackIds) { + return null; + } + + @Override + public void modifyAckDeadline(String subscription, int deadline, TimeUnit unit, + Iterable ackIds) { + + } + + @Override + public Future modifyAckDeadlineAsync(String subscription, int deadline, TimeUnit unit, + Iterable ackIds) { + return null; + } +} diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubOptions.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubOptions.java new file mode 100644 index 000000000000..73482ccef25f --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubOptions.java @@ -0,0 +1,121 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import com.google.cloud.ServiceOptions; +import com.google.cloud.pubsub.spi.DefaultPubSubRpc; +import com.google.cloud.pubsub.spi.PubSubRpc; +import com.google.cloud.pubsub.spi.PubSubRpcFactory; +import com.google.common.collect.ImmutableSet; + +import java.io.IOException; +import java.util.Set; + +public class PubSubOptions extends ServiceOptions { + + private static final long serialVersionUID = 6740347843343421456L; + private static final String PUBSUB_SCOPE = "https://www.googleapis.com/auth/pubsub"; + private static final Set SCOPES = ImmutableSet.of(PUBSUB_SCOPE); + private static final String DEFAULT_HOST = "https://pubsub.googleapis.com"; + + public static class DefaultPubSubFactory implements PubSubFactory { + private static final PubSubFactory INSTANCE = new DefaultPubSubFactory(); + + @Override + public PubSub create(PubSubOptions options) { + return new PubSubImpl(options); + } + } + + /** + * Returns a default {@code PubSubOptions} instance. + */ + public static PubSubOptions defaultInstance() { + return builder().build(); + } + + public static class DefaultPubSubRpcFactory implements PubSubRpcFactory { + private static final PubSubRpcFactory INSTANCE = new DefaultPubSubRpcFactory(); + + @Override + public PubSubRpc create(PubSubOptions options) { + try { + return new DefaultPubSubRpc(options); + } catch (IOException e) { + throw new PubSubException(e, true); + } + } + } + + @Override + protected String defaultHost() { + return DEFAULT_HOST; + } + + public static class Builder extends + ServiceOptions.Builder { + + private Builder() {} + + private Builder(PubSubOptions options) { + super(options); + } + + @Override + public PubSubOptions build() { + return new PubSubOptions(this); + } + } + + private PubSubOptions(Builder builder) { + super(PubSubFactory.class, PubSubRpcFactory.class, builder); + } + + @Override + protected PubSubFactory defaultServiceFactory() { + return DefaultPubSubFactory.INSTANCE; + } + + @Override + protected PubSubRpcFactory defaultRpcFactory() { + return DefaultPubSubRpcFactory.INSTANCE; + } + + @Override + protected Set scopes() { + return SCOPES; + } + + @Override + public boolean equals(Object obj) { + return obj instanceof PubSubOptions && baseEquals((PubSubOptions) obj); + } + + @Override + public int hashCode() { + return baseHashCode(); + } + + @Override + public Builder toBuilder() { + return new Builder(this); + } + + public static Builder builder() { + return new Builder(); + } +} diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PushConfig.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PushConfig.java new file mode 100644 index 000000000000..61b64a07b36b --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PushConfig.java @@ -0,0 +1,142 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableMap; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +/** + * PubSub subscription push configuration. + */ +public final class PushConfig implements Serializable { + + private static final long serialVersionUID = 4408885787064092231L; + + private final String endpoint; + private final ImmutableMap attributes; + + public static final class Builder { + + private String endpoint; + private final Map attributes = new HashMap<>(); + + private Builder() { + } + + public Builder endPoint(String endpoint) { + this.endpoint = checkNotNull(endpoint); + return this; + } + + public Builder addAttribute(String name, String value) { + attributes.put(name, value); + return this; + } + + public Builder removeAttribute(String name) { + attributes.remove(name); + return this; + } + + public Builder clearAttributes() { + attributes.clear(); + return this; + } + + public PushConfig build() { + return new PushConfig(this); + } + } + + private PushConfig(Builder builder) { + endpoint = builder.endpoint; + attributes = ImmutableMap.copyOf(builder.attributes); + } + + public String endpoint() { + return endpoint; + } + + public Map attributes() { + return attributes; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + PushConfig that = (PushConfig) o; + return Objects.equals(endpoint, that.endpoint) && Objects.equals(attributes, that.attributes); + } + + @Override + public int hashCode() { + return Objects.hash(endpoint, attributes); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("attributes", attributes) + .add("endpoint", endpoint) + .toString(); + } + + public Builder toBuilder() { + return builder(endpoint, attributes); + } + + public static PushConfig of(String endpoint) { + return builder(endpoint).build(); + } + + public static PushConfig of(String endpoint, Map attributes) { + return builder(endpoint, attributes).build(); + } + + public static Builder builder(String endPoint) { + return new Builder().endPoint(endPoint); + } + + public static Builder builder(String endpoint, Map attributes) { + Builder builder = builder(endpoint); + for (Map.Entry entry : attributes.entrySet()) { + builder.addAttribute(entry.getKey(), entry.getValue()); + } + return builder; + } + + com.google.pubsub.v1.PushConfig toPb() { + return com.google.pubsub.v1.PushConfig.newBuilder().setPushEndpoint(endpoint) + .putAllAttributes(attributes).build(); + } + + static PushConfig fromPb(com.google.pubsub.v1.PushConfig pushConfigPb) { + return builder(pushConfigPb.getPushEndpoint(), pushConfigPb.getAttributes()).build(); + } +} diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/ReceivedMessage.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/ReceivedMessage.java new file mode 100644 index 000000000000..c3cb705cb6d7 --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/ReceivedMessage.java @@ -0,0 +1,184 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.cloud.ByteArray; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +public class ReceivedMessage extends Message { + + private static final long serialVersionUID = -4178477763916251733L; + + private final String subscription; + private final String ackId; + private transient PubSub pubsub; + private final PubSubOptions options; + + public static final class Builder extends Message.Builder { + + private final String subscription; + private final String ackId; + private final PubSub pubsub; + private final BuilderImpl delegate; + + private Builder(String subscription, String ackId, PubSub pubsub, BuilderImpl delegate) { + this.subscription = subscription; + this.ackId = ackId; + this.pubsub = pubsub; + this.delegate = delegate; + } + + @Override + Builder id(String id) { + delegate.id(id); + return this; + } + + @Override + public Builder payload(String payload) { + delegate.payload(payload); + return this; + } + + @Override + public Builder payload(ByteArray payload) { + delegate.payload(payload); + return this; + } + + @Override + public Builder attributes(Map attributes) { + delegate.attributes(attributes); + return this; + } + + @Override + public Builder addAttribute(String name, String value) { + delegate.addAttribute(name, value); + return this; + } + + @Override + public Builder removeAttribute(String name) { + delegate.removeAttribute(name); + return this; + } + + @Override + public Builder clearAttributes() { + delegate.clearAttributes(); + return this; + } + + @Override + Builder publishTime(long publishTime) { + delegate.publishTime(publishTime); + return this; + } + + @Override + public ReceivedMessage build() { + return new ReceivedMessage(this); + } + } + + ReceivedMessage(Builder builder) { + super(builder.delegate); + subscription = checkNotNull(builder.subscription); + ackId = checkNotNull(builder.ackId); + pubsub = checkNotNull(builder.pubsub); + options = pubsub.options(); + } + + @Override + public Builder toBuilder() { + return new Builder(subscription, ackId, pubsub, new BuilderImpl(this)); + } + + @Override + public int hashCode() { + return Objects.hash(options, super.hashCode()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + ReceivedMessage other = (ReceivedMessage) obj; + return Objects.equals(toPb(), other.toPb()) && Objects.equals(options, other.options); + } + + public PubSub pubSub() { + return pubsub; + } + + public String subscription() { + return subscription; + } + + public String ackId() { + return ackId; + } + + public void ack() { + pubsub.ack(subscription, ackId); + } + + public Future ackAsync() { + return pubsub.ackAsync(subscription, ackId); + } + + public void nack() { + pubsub.nack(subscription, ackId); + } + + public Future nackAsync() { + return pubsub.nackAsync(subscription, ackId); + } + + public void modifyAckDeadline(int deadline, TimeUnit unit) { + pubsub.modifyAckDeadline(subscription, deadline, unit, ackId); + } + + public Future modifyAckDeadlineAsync(int deadline, TimeUnit unit) { + return pubsub.modifyAckDeadlineAsync(subscription, deadline, unit, ackId); + } + + private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { + input.defaultReadObject(); + this.pubsub = options.service(); + } + + static ReceivedMessage fromPb(PubSub storage, String subscription, + com.google.pubsub.v1.ReceivedMessage msgPb) { + Message message = fromPb(msgPb.getMessage()); + String ackId = msgPb.getAckId(); + return new Builder(subscription, ackId, storage, new BuilderImpl(message)).build(); + } +} diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java new file mode 100644 index 000000000000..d49328ad7486 --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java @@ -0,0 +1,158 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.cloud.pubsub.PubSub.MessageConsumer; +import com.google.cloud.pubsub.PubSub.MessageProcessor; +import com.google.cloud.pubsub.PubSub.PullOption; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.util.Iterator; +import java.util.Objects; +import java.util.concurrent.Future; + +/** + * PubSub subscription. + */ +public class Subscription extends SubscriptionInfo { + + private static final long serialVersionUID = -4153366055659552230L; + + private final PubSubOptions options; + private transient PubSub pubsub; + + public static final class Builder extends SubscriptionInfo.Builder { + + private final PubSub pubsub; + private final BuilderImpl delegate; + + private Builder(Subscription subscription) { + pubsub = subscription.pubsub; + delegate = new BuilderImpl(subscription); + } + + @Override + public Builder topic(String name) { + delegate.topic(name); + return this; + } + + @Override + public Builder name(String name) { + delegate.name(name); + return this; + } + + @Override + public Builder pushConfig(PushConfig pushConfig) { + delegate.pushConfig(pushConfig); + return this; + } + + @Override + public Builder ackDeadLineSeconds(int ackDeadLineSeconds) { + delegate.ackDeadLineSeconds(ackDeadLineSeconds); + return this; + } + + @Override + public Subscription build() { + return new Subscription(this.pubsub, this.delegate); + } + } + + Subscription(PubSub pubsub, BuilderImpl builder) { + super(builder); + this.pubsub = checkNotNull(pubsub); + options = pubsub.options(); + } + + @Override + public Builder toBuilder() { + return new Builder(this); + } + + @Override + public int hashCode() { + return Objects.hash(options, super.hashCode()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + Subscription other = (Subscription) obj; + return Objects.equals(toPb(), other.toPb()) && Objects.equals(options, other.options); + } + + public PubSub pubSub() { + return pubsub; + } + + public boolean delete() { + return pubsub.deleteSubscription(name()); + } + + public Future deleteAsync() { + return pubsub.deleteSubscriptionAsync(name()); + } + + public Subscription reload() { + return pubsub.getSubscription(name()); + } + + public Future reloadAsync() { + return pubsub.getSubscriptionAsync(name()); + } + + public void replacePushConfig(PushConfig pushConfig) { + pubsub.replacePushConfig(name(), pushConfig); + } + + public Future replacePushConfigAsync(PushConfig pushConfig) { + return pubsub.replacePushConfigAsync(name(), pushConfig); + } + + public Iterator pull(PullOption... options) { + return pubsub.pull(name(), options); + } + + public Future> pullAsync(PullOption... options) { + return pubsub.pullAsync(name(), options); + } + + public MessageConsumer pullAsync(MessageProcessor callback) { + return pubsub.pullAsync(name(), callback); + } + + private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { + input.defaultReadObject(); + this.pubsub = options.service(); + } + + static Subscription fromPb(PubSub storage, com.google.pubsub.v1.Subscription subscriptionPb) { + SubscriptionInfo subscriptionInfo = SubscriptionInfo.fromPb(subscriptionPb); + return new Subscription(storage, new BuilderImpl(subscriptionInfo)); + } +} diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionInfo.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionInfo.java new file mode 100644 index 000000000000..97e7b35becd9 --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionInfo.java @@ -0,0 +1,189 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; + +import java.io.Serializable; +import java.util.Objects; + +/** + * Pub/Sub subscription information. + */ +public class SubscriptionInfo implements Serializable { + + private static final long serialVersionUID = 1860057426574127128L; + + private final String name; + private final String topic; + private final PushConfig pushConfig; + private final int ackDeadlineSeconds; + + + /** + * Builder for Subscription. + */ + public abstract static class Builder { + + public abstract Builder name(String name); + + public abstract Builder topic(String name); + + public abstract Builder pushConfig(PushConfig pushConfig); + + public abstract Builder ackDeadLineSeconds(int ackDeadLineSeconds); + + public abstract SubscriptionInfo build(); + } + + static final class BuilderImpl extends Builder { + + private String name; + private String topic; + private PushConfig pushConfig; + private int ackDeadlineSeconds; + + private BuilderImpl(String topic, String name) { + this.topic = checkNotNull(topic); + this.name = checkNotNull(name); + } + + BuilderImpl(SubscriptionInfo subscription) { + name = subscription.name; + topic = subscription.topic; + pushConfig = subscription.pushConfig; + ackDeadlineSeconds = subscription.ackDeadlineSeconds; + } + + @Override + public Builder name(String name) { + this.name = checkNotNull(name); + return this; + } + + @Override + public Builder topic(String topic) { + this.topic = checkNotNull(topic); + return this; + } + + @Override + public Builder pushConfig(PushConfig pushConfig) { + this.pushConfig = pushConfig; + return this; + } + + @Override + public Builder ackDeadLineSeconds(int ackDeadlineSeconds) { + this.ackDeadlineSeconds = ackDeadlineSeconds; + return this; + } + + @Override + public SubscriptionInfo build() { + return new SubscriptionInfo(this); + } + } + + SubscriptionInfo(BuilderImpl builder) { + topic = builder.topic; + name = builder.name; + pushConfig = builder.pushConfig; + ackDeadlineSeconds = builder.ackDeadlineSeconds; + } + + public String topic() { + return topic; + } + + public String name() { + return name; + } + + public PushConfig pushConfig() { + return pushConfig; + } + + public long ackDeadlineSeconds() { + return ackDeadlineSeconds; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + return Objects.equals(toPb(), ((SubscriptionInfo) o).toPb()); + } + + @Override + public int hashCode() { + return Objects.hash(topic, name, pushConfig, ackDeadlineSeconds); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("topic", topic) + .add("name", name) + .add("pushConfig", pushConfig) + .add("ackDeadlineSeconds", ackDeadlineSeconds) + .toString(); + } + + com.google.pubsub.v1.Subscription toPb() { + com.google.pubsub.v1.Subscription.Builder builder = + com.google.pubsub.v1.Subscription.newBuilder(); + builder.setTopic(topic); + builder.setName(name); + builder.setAckDeadlineSeconds(ackDeadlineSeconds); + if (pushConfig != null) { + builder.setPushConfig(pushConfig.toPb()); + } + return builder.build(); + } + + static SubscriptionInfo fromPb(com.google.pubsub.v1.Subscription subscription) { + Builder builder = builder(subscription.getTopic(), subscription.getName()); + builder.ackDeadLineSeconds(subscription.getAckDeadlineSeconds()); + if (subscription.hasPushConfig()) { + builder.pushConfig(PushConfig.fromPb(subscription.getPushConfig())); + } + return builder.build(); + } + + public Builder toBuilder() { + return new BuilderImpl(this); + } + + public static SubscriptionInfo of(String topic, String name) { + return builder(topic, name).build(); + } + + public static SubscriptionInfo of(String topic, String name, String endpoint) { + return builder(topic, name).pushConfig(PushConfig.of(endpoint)).build(); + } + + public static Builder builder(String topic, String name) { + return new BuilderImpl(topic, name); + } +} diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Topic.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Topic.java new file mode 100644 index 000000000000..77dd31fcd876 --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Topic.java @@ -0,0 +1,162 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.cloud.AsyncPage; +import com.google.cloud.Page; +import com.google.cloud.pubsub.PubSub.ListOption; +import com.google.common.base.Function; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.Future; + +/** + * PubSub Topic. + */ +public class Topic extends TopicInfo { + + private static final long serialVersionUID = -2686692223763315944L; + + private final PubSubOptions options; + private transient PubSub pubsub; + + public static final class Builder extends TopicInfo.Builder { + + private final PubSub pubsub; + private final BuilderImpl delegate; + + private Builder(Topic topic) { + pubsub = topic.pubsub; + delegate = new BuilderImpl(topic); + } + + @Override + public Builder name(String name) { + delegate.name(name); + return this; + } + + @Override + public Topic build() { + return new Topic(this.pubsub, this.delegate); + } + } + + Topic(PubSub pubsub, BuilderImpl builder) { + super(builder); + this.pubsub = checkNotNull(pubsub); + options = pubsub.options(); + } + + @Override + public Builder toBuilder() { + return new Builder(this); + } + + @Override + public int hashCode() { + return Objects.hash(options, super.hashCode()); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + Topic other = (Topic) obj; + return Objects.equals(toPb(), other.toPb()) && Objects.equals(options, other.options); + } + + public PubSub pubSub() { + return pubsub; + } + + public boolean delete() { + return pubsub.deleteTopic(name()); + } + + public Future deleteAsync() { + return pubsub.deleteTopicAsync(name()); + } + + public Topic reload() { + return pubsub.getTopic(name()); + } + + public Future reloadAsync() { + return pubsub.getTopicAsync(name()); + } + + public String publish(Message message) { + return pubsub.publish(name(), message); + } + + public Future publishAsync(Message message) { + return pubsub.publishAsync(name(), message); + } + + public List publish(Message message, Message... messages) { + return pubsub.publish(name(), message, messages); + } + + public Future> publishAsync(Message message, Message... messages) { + return pubsub.publishAsync(name(), message, messages); + } + + public List publish(Iterable messages) { + return pubsub.publish(name(), messages); + } + + public Future> publishAsync(Iterable messages) { + return pubsub.publishAsync(name(), messages); + } + + public Page listSubscriptions(ListOption... options) { + return pubsub.listSubscriptions(name(), options); + } + + public Future> listSubscriptionsAsync(ListOption... options) { + return pubsub.listSubscriptionsAsync(name(), options); + } + + private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { + input.defaultReadObject(); + this.pubsub = options.service(); + } + + static Topic fromPb(PubSub storage, com.google.pubsub.v1.Topic topicPb) { + TopicInfo topicInfo = TopicInfo.fromPb(topicPb); + return new Topic(storage, new BuilderImpl(topicInfo)); + } + + static Function fromPbFunction(final PubSub pubsub) { + return new Function() { + @Override + public Topic apply(com.google.pubsub.v1.Topic topicPb) { + return fromPb(pubsub, topicPb); + } + }; + } +} diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicInfo.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicInfo.java new file mode 100644 index 000000000000..37f4ae289b6f --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicInfo.java @@ -0,0 +1,119 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; + +import java.io.Serializable; +import java.util.Objects; + +/** + * Pub/Sub Topic information. + */ +public class TopicInfo implements Serializable { + + private static final long serialVersionUID = -5907624842808725353L; + + private final String name; + + /** + * Builder for TopicInfo. + */ + public abstract static class Builder { + + public abstract Builder name(String name); + + public abstract TopicInfo build(); + } + + static final class BuilderImpl extends Builder { + + private String name; + + BuilderImpl(String name) { + this.name = checkNotNull(name); + } + + BuilderImpl(TopicInfo topicInfo) { + this.name = topicInfo.name; + } + + @Override + public Builder name(String name) { + this.name = checkNotNull(name); + return this; + } + + @Override + public TopicInfo build() { + return new TopicInfo(this); + } + } + + TopicInfo(BuilderImpl builder) { + name = builder.name; + } + + public String name() { + return name; + } + + @Override + public int hashCode() { + return Objects.hash(name); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null || getClass() != obj.getClass()) { + return false; + } + return Objects.equals(toPb(), ((TopicInfo) obj).toPb()); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("name", name) + .toString(); + } + + com.google.pubsub.v1.Topic toPb() { + return com.google.pubsub.v1.Topic.newBuilder().setName(name).build(); + } + + static TopicInfo fromPb(com.google.pubsub.v1.Topic topicPb) { + return builder(topicPb.getName()).build(); + } + + public Builder toBuilder() { + return new BuilderImpl(this); + } + + public static TopicInfo of(String name) { + return builder(name).build(); + } + + public static Builder builder(String name) { + return new BuilderImpl(name); + } +} diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/package-info.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/package-info.java new file mode 100644 index 000000000000..05dc8dcbf036 --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/package-info.java @@ -0,0 +1,29 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +/** + * A client to Google Cloud Pub/Sub. + * + *

    Here's a simple usage example for using gcloud-pubsub: + * todo: add example + *

     {@code
    + * PubSub pubsub = PubSubOptions.defaultInstance().service();
    + * }
    + * + * @see Google Cloud Pub/Sub + */ + +package com.google.cloud.pubsub; diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java new file mode 100644 index 000000000000..ebe83841a4ac --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java @@ -0,0 +1,199 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub.spi; + +import com.google.api.gax.core.ConnectionSettings; +import com.google.api.gax.core.RetrySettings; +import com.google.api.gax.grpc.ApiCallSettings; +import com.google.api.gax.grpc.ApiException; +import com.google.cloud.RetryParams; +import com.google.cloud.pubsub.PubSubException; +import com.google.cloud.pubsub.PubSubOptions; +import com.google.cloud.pubsub.spi.v1.PublisherApi; +import com.google.cloud.pubsub.spi.v1.PublisherSettings; +import com.google.cloud.pubsub.spi.v1.SubscriberApi; +import com.google.cloud.pubsub.spi.v1.SubscriberSettings; +import com.google.common.base.Function; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.protobuf.Empty; +import com.google.pubsub.v1.AcknowledgeRequest; +import com.google.pubsub.v1.DeleteSubscriptionRequest; +import com.google.pubsub.v1.DeleteTopicRequest; +import com.google.pubsub.v1.GetSubscriptionRequest; +import com.google.pubsub.v1.GetTopicRequest; +import com.google.pubsub.v1.ListSubscriptionsRequest; +import com.google.pubsub.v1.ListSubscriptionsResponse; +import com.google.pubsub.v1.ListTopicSubscriptionsRequest; +import com.google.pubsub.v1.ListTopicSubscriptionsResponse; +import com.google.pubsub.v1.ListTopicsRequest; +import com.google.pubsub.v1.ListTopicsResponse; +import com.google.pubsub.v1.ModifyAckDeadlineRequest; +import com.google.pubsub.v1.ModifyPushConfigRequest; +import com.google.pubsub.v1.PublishRequest; +import com.google.pubsub.v1.PublishResponse; +import com.google.pubsub.v1.PullRequest; +import com.google.pubsub.v1.PullResponse; +import com.google.pubsub.v1.Subscription; +import com.google.pubsub.v1.Topic; + +import org.joda.time.Duration; + +import java.io.IOException; +import java.util.Set; +import java.util.concurrent.Future; + +import autovalue.shaded.com.google.common.common.collect.Sets; +import io.grpc.Status.Code; + +public class DefaultPubSubRpc implements PubSubRpc { + + private final PublisherApi publisherApi; + private final SubscriberApi subscriberApi; + + public DefaultPubSubRpc(PubSubOptions options) throws IOException { + try { + // Provide (and use a common thread-pool). + // This depends on https://github.com/googleapis/gax-java/issues/73 + PublisherSettings.Builder pbuilder = PublisherSettings.defaultInstance().toBuilder(); + pbuilder.provideChannelWith(ConnectionSettings.newBuilder() + .provideCredentialsWith(options.authCredentials().credentials()).build()); + pbuilder.applyToAllApiMethods(apiCallSettings(options)); + publisherApi = PublisherApi.create(pbuilder.build()); + SubscriberSettings.Builder sBuilder = SubscriberSettings.defaultInstance().toBuilder(); + sBuilder.provideChannelWith(ConnectionSettings.newBuilder() + .provideCredentialsWith(options.authCredentials().credentials()).build()); + sBuilder.applyToAllApiMethods(apiCallSettings(options)); + subscriberApi = SubscriberApi.create(sBuilder.build()); + } catch (Exception ex) { + throw new IOException(ex); + } + } + + private static ApiCallSettings.Builder apiCallSettings(PubSubOptions options) { + // TODO: specify timeout these settings: + // retryParams.retryMaxAttempts(), retryParams.retryMinAttempts() + RetryParams retryParams = options.retryParams(); + final RetrySettings.Builder builder = RetrySettings.newBuilder() + .setTotalTimeout(Duration.millis(retryParams.totalRetryPeriodMillis())) + .setInitialRpcTimeout(Duration.millis(options.connectTimeout())) + .setRpcTimeoutMultiplier(1.5) + .setMaxRpcTimeout(Duration.millis(options.connectTimeout() + options.readTimeout())) + .setInitialRetryDelay(Duration.millis(retryParams.initialRetryDelayMillis())) + .setRetryDelayMultiplier(retryParams.retryDelayBackoffFactor()) + .setMaxRetryDelay(Duration.millis(retryParams.maxRetryDelayMillis())); + return ApiCallSettings.newBuilder().setRetrySettingsBuilder(builder); + } + + private static Future translate(ListenableFuture from, final boolean idempotent, + int... returnNullOn) { + final Set returnNullOnSet = Sets.newHashSetWithExpectedSize(returnNullOn.length); + for (int value : returnNullOn) { + returnNullOnSet.add(value); + } + return Futures.catching(from, ApiException.class, new Function() { + @Override + public V apply(ApiException exception) { + if (returnNullOnSet.contains(exception.getStatusCode().value())) { + return null; + } + throw new PubSubException(exception, idempotent); + } + }); + } + + @Override + public Future create(Topic topic) { + // TODO: it would be nice if we can get the idempotent inforamtion from the ApiCallSettings + // or from the exception + return translate(publisherApi.createTopicCallable().futureCall(topic), true); + } + + @Override + public Future publish(PublishRequest request) { + return translate(publisherApi.publishCallable().futureCall(request), false); + } + + @Override + public Future get(GetTopicRequest request) { + return translate(publisherApi.getTopicCallable().futureCall(request), true, + Code.NOT_FOUND.value()); + } + + @Override + public Future list(ListTopicsRequest request) { + // we should consider using gax PageAccessor once + // https://github.com/googleapis/gax-java/issues/74 is fixed + // Though it is a cleaner SPI without it, but PageAccessor is an interface + // and if it saves code we should not easily dismiss it. + return translate(publisherApi.listTopicsCallable().futureCall(request), true); + } + + @Override + public Future list(ListTopicSubscriptionsRequest request) { + return translate(publisherApi.listTopicSubscriptionsCallable().futureCall(request), true); + } + + @Override + public Future delete(DeleteTopicRequest request) { + // TODO: check if null is not going to work for Empty + return translate(publisherApi.deleteTopicCallable().futureCall(request), true, + Code.NOT_FOUND.value()); + } + + @Override + public Future create(Subscription subscription) { + return translate(subscriberApi.createSubscriptionCallable().futureCall(subscription), false); + } + + @Override + public Future get(GetSubscriptionRequest request) { + return translate(subscriberApi.getSubscriptionCallable().futureCall(request), true, + Code.NOT_FOUND.value()); + } + + @Override + public Future list(ListSubscriptionsRequest request) { + return translate(subscriberApi.listSubscriptionsCallable().futureCall(request), true); + } + + @Override + public Future delete(DeleteSubscriptionRequest request) { + return translate(subscriberApi.deleteSubscriptionCallable().futureCall(request), true, + Code.NOT_FOUND.value()); + } + + @Override + public Future modify(ModifyAckDeadlineRequest request) { + return translate(subscriberApi.modifyAckDeadlineCallable().futureCall(request), false); + } + + @Override + public Future acknowledge(AcknowledgeRequest request) { + return translate(subscriberApi.acknowledgeCallable().futureCall(request), false); + } + + @Override + public Future pull(PullRequest request) { + return translate(subscriberApi.pullCallable().futureCall(request), false); + } + + @Override + public Future modify(ModifyPushConfigRequest request) { + return translate(subscriberApi.modifyPushConfigCallable().futureCall(request), false); + } +} diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/PubSubRpc.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/PubSubRpc.java new file mode 100644 index 000000000000..8474ba042234 --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/PubSubRpc.java @@ -0,0 +1,72 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub.spi; + +import com.google.protobuf.Empty; +import com.google.pubsub.v1.AcknowledgeRequest; +import com.google.pubsub.v1.DeleteSubscriptionRequest; +import com.google.pubsub.v1.DeleteTopicRequest; +import com.google.pubsub.v1.GetSubscriptionRequest; +import com.google.pubsub.v1.GetTopicRequest; +import com.google.pubsub.v1.ListSubscriptionsRequest; +import com.google.pubsub.v1.ListSubscriptionsResponse; +import com.google.pubsub.v1.ListTopicSubscriptionsRequest; +import com.google.pubsub.v1.ListTopicSubscriptionsResponse; +import com.google.pubsub.v1.ListTopicsRequest; +import com.google.pubsub.v1.ListTopicsResponse; +import com.google.pubsub.v1.ModifyAckDeadlineRequest; +import com.google.pubsub.v1.ModifyPushConfigRequest; +import com.google.pubsub.v1.PublishRequest; +import com.google.pubsub.v1.PublishResponse; +import com.google.pubsub.v1.PullRequest; +import com.google.pubsub.v1.PullResponse; +import com.google.pubsub.v1.Subscription; +import com.google.pubsub.v1.Topic; + +import java.util.concurrent.Future; + +public interface PubSubRpc { + + // in all cases root cause of ExecutionException is PubSubException + Future create(Topic topic); + + Future publish(PublishRequest request); + + Future get(GetTopicRequest request); + + Future list(ListTopicsRequest request); + + Future list(ListTopicSubscriptionsRequest request); + + Future delete(DeleteTopicRequest request); + + Future create(Subscription subscription); + + Future get(GetSubscriptionRequest request); + + Future list(ListSubscriptionsRequest request); + + Future delete(DeleteSubscriptionRequest request); + + Future modify(ModifyAckDeadlineRequest request); + + Future acknowledge(AcknowledgeRequest request); + + Future pull(PullRequest request); + + Future modify(ModifyPushConfigRequest request); +} diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/PubSubRpcFactory.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/PubSubRpcFactory.java new file mode 100644 index 000000000000..d3648a68399f --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/PubSubRpcFactory.java @@ -0,0 +1,27 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub.spi; + +import com.google.cloud.pubsub.PubSubOptions; +import com.google.cloud.spi.ServiceRpcFactory; + +/** + * An interface for Pub/Sub RPC factory. + * Implementation will be loaded via {@link java.util.ServiceLoader}. + */ +public interface PubSubRpcFactory extends ServiceRpcFactory { +} From 90894b3fba4a7df743322d024dfb3b0d01d9deec Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 22 Feb 2016 15:42:45 +0100 Subject: [PATCH 271/375] Add gcloud-java-compute module --- gcloud-java-compute/README.md | 100 +++++++++++++++ gcloud-java-compute/pom.xml | 49 ++++++++ .../com/google/gcloud/compute/Compute.java | 27 +++++ .../gcloud/compute/ComputeException.java | 59 +++++++++ .../google/gcloud/compute/ComputeFactory.java | 25 ++++ .../google/gcloud/compute/ComputeImpl.java | 30 +++++ .../google/gcloud/compute/ComputeOptions.java | 114 ++++++++++++++++++ .../com/google/gcloud/spi/ComputeRpc.java | 20 +++ .../google/gcloud/spi/ComputeRpcFactory.java | 26 ++++ .../google/gcloud/spi/DefaultComputeRpc.java | 46 +++++++ gcloud-java/pom.xml | 5 + pom.xml | 1 + 12 files changed, 502 insertions(+) create mode 100644 gcloud-java-compute/README.md create mode 100644 gcloud-java-compute/pom.xml create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeException.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeFactory.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeOptions.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpcFactory.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java diff --git a/gcloud-java-compute/README.md b/gcloud-java-compute/README.md new file mode 100644 index 000000000000..aef53c781c20 --- /dev/null +++ b/gcloud-java-compute/README.md @@ -0,0 +1,100 @@ +Google Cloud Java Client for Compute (Alpha) +==================================== + +Java idiomatic client for [Google Cloud Compute] (https://cloud.google.com/compute). + +[![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java) +[![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) + +[![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) +[![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969) + +- [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) + + +> Note: This client is a work-in-progress, and may occasionally +> make backwards-incompatible changes. + +Quickstart +---------- +If you are using Maven, add this to your pom.xml file + +If you are using Gradle, add this to your dependencies + +If you are using SBT, add this to your dependencies + + +Example Application +------------------- + + +Authentication +-------------- + +See the [Authentication](https://github.com/GoogleCloudPlatform/gcloud-java#authentication) section in the base directory's README. + +About Google Cloud BigQuery +-------------------------- + +[Google Cloud Compute][cloud-compute] delivers virtual machines running in Google's innovative data +centers and worldwide fiber network. Compute Engine's tooling and workflow support enable scaling +from single instances to global, load-balanced cloud computing. Compute Engine's VMs boot quickly, +come with persistent disk storage, deliver consistent performance and are available in many +configurations. + +Be sure to activate the Google Cloud Compute API on the Developer's Console to use Compute from +your project. + +See the ``gcloud-java`` API [compute documentation][compute-api] to learn how to interact +with Google Cloud Compute using this Client Library. + +Getting Started +--------------- + + +Troubleshooting +--------------- + +To get help, follow the `gcloud-java` links in the `gcloud-*`[shared Troubleshooting document](https://github.com/GoogleCloudPlatform/gcloud-common/blob/master/troubleshooting/readme.md#troubleshooting). + +Java Versions +------------- + +Java 7 or above is required for using this client. + +Testing +------- + +This library has tools to help make tests for code using Cloud BigQuery. + +See [TESTING] to read more about testing. + +Versioning +---------- + +This library follows [Semantic Versioning] (http://semver.org/). + +It is currently in major version zero (``0.y.z``), which means that anything +may change at any time and the public API should not be considered +stable. + +Contributing +------------ + +Contributions to this library are always welcome and highly encouraged. + +See [CONTRIBUTING] for more information on how to get started. + +License +------- + +Apache 2.0 - See [LICENSE] for more information. + + +[CONTRIBUTING]:https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/CONTRIBUTING.md +[LICENSE]: https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/LICENSE +[TESTING]: https://github.com/GoogleCloudPlatform/gcloud-java/blob/master/TESTING.md#testing-code-that-uses-compute +[cloud-platform]: https://cloud.google.com/ + +[cloud-compute]: https://cloud.google.com/compute/ +[compute-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/compute/package-summary.html diff --git a/gcloud-java-compute/pom.xml b/gcloud-java-compute/pom.xml new file mode 100644 index 000000000000..70e4f127c119 --- /dev/null +++ b/gcloud-java-compute/pom.xml @@ -0,0 +1,49 @@ + + + 4.0.0 + gcloud-java-compute + jar + GCloud Java compute + + Java idiomatic client for Google Cloud Compute Engine. + + + com.google.gcloud + gcloud-java-pom + 0.1.5-SNAPSHOT + + + gcloud-java-compute + + + + ${project.groupId} + gcloud-java-core + ${project.version} + + + com.google.apis + google-api-services-compute + v1-rev93-1.21.0 + compile + + + com.google.guava + guava-jdk5 + + + + + junit + junit + 4.12 + test + + + org.easymock + easymock + 3.4 + test + + + diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java new file mode 100644 index 000000000000..4576f62f84b9 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java @@ -0,0 +1,27 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import com.google.gcloud.Service; + +/** + * An interface for Google Cloud Compute Engine. + * + * @see Google Cloud Compute Engine + */ +public interface Compute extends Service { +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeException.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeException.java new file mode 100644 index 000000000000..94a409305338 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeException.java @@ -0,0 +1,59 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import com.google.common.collect.ImmutableSet; +import com.google.gcloud.BaseServiceException; +import com.google.gcloud.RetryHelper.RetryHelperException; +import com.google.gcloud.RetryHelper.RetryInterruptedException; + +import java.io.IOException; +import java.util.Set; + +/** + * Compute Engine service exception. + */ +public class ComputeException extends BaseServiceException { + + private static final Set RETRYABLE_ERRORS = ImmutableSet.of(new Error(500, null)); + private static final long serialVersionUID = -8039359778707845810L; + + public ComputeException(int code, String message) { + super(code, message, null, true); + } + + public ComputeException(IOException exception) { + super(exception, true); + } + + @Override + protected Set retryableErrors() { + return RETRYABLE_ERRORS; + } + + /** + * Translate RetryHelperException to the ComputeException that caused the error. This method will + * always throw an exception. + * + * @throws ComputeException when {@code ex} was caused by a {@code ComputeException} + * @throws RetryInterruptedException when {@code ex} is a {@code RetryInterruptedException} + */ + static BaseServiceException translateAndThrow(RetryHelperException ex) { + BaseServiceException.translateAndPropagateIfPossible(ex); + throw new ComputeException(UNKNOWN_CODE, ex.getMessage()); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeFactory.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeFactory.java new file mode 100644 index 000000000000..100631eef91d --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeFactory.java @@ -0,0 +1,25 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import com.google.gcloud.ServiceFactory; + +/** + * An interface for Compute factories. + */ +public interface ComputeFactory extends ServiceFactory { +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java new file mode 100644 index 000000000000..8a3a82af8827 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java @@ -0,0 +1,30 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import com.google.gcloud.BaseService; +import com.google.gcloud.spi.ComputeRpc; + +final class ComputeImpl extends BaseService implements Compute { + + private final ComputeRpc computeRpc; + + ComputeImpl(ComputeOptions options) { + super(options); + computeRpc = options.rpc(); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeOptions.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeOptions.java new file mode 100644 index 000000000000..9fab138b26b4 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeOptions.java @@ -0,0 +1,114 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import com.google.common.collect.ImmutableSet; +import com.google.gcloud.ServiceOptions; +import com.google.gcloud.spi.ComputeRpc; +import com.google.gcloud.spi.ComputeRpcFactory; +import com.google.gcloud.spi.DefaultComputeRpc; + +import java.util.Set; + +public class ComputeOptions extends ServiceOptions { + + private static final String COMPUTE_SCOPE = "https://www.googleapis.com/auth/compute"; + private static final Set SCOPES = ImmutableSet.of(COMPUTE_SCOPE); + private static final long serialVersionUID = 6509557711917342058L; + + public static class DefaultComputeFactory implements ComputeFactory { + + private static final ComputeFactory INSTANCE = new DefaultComputeFactory(); + + @Override + public Compute create(ComputeOptions options) { + return new ComputeImpl(options); + } + } + + public static class DefaultComputeRpcFactory implements ComputeRpcFactory { + + private static final ComputeRpcFactory INSTANCE = new DefaultComputeRpcFactory(); + + @Override + public ComputeRpc create(ComputeOptions options) { + return new DefaultComputeRpc(options); + } + } + + public static class Builder extends + ServiceOptions.Builder { + + private Builder() { + } + + private Builder(ComputeOptions options) { + super(options); + } + + @Override + public ComputeOptions build() { + return new ComputeOptions(this); + } + } + + private ComputeOptions(Builder builder) { + super(ComputeFactory.class, ComputeRpcFactory.class, builder); + } + + @Override + protected ComputeFactory defaultServiceFactory() { + return DefaultComputeFactory.INSTANCE; + } + + @Override + protected ComputeRpcFactory defaultRpcFactory() { + return DefaultComputeRpcFactory.INSTANCE; + } + + @Override + protected Set scopes() { + return SCOPES; + } + + @Override + public Builder toBuilder() { + return new Builder(this); + } + + @Override + public int hashCode() { + return baseHashCode(); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof ComputeOptions)) { + return false; + } + ComputeOptions other = (ComputeOptions) obj; + return baseEquals(other); + } + + public static ComputeOptions defaultInstance() { + return builder().build(); + } + + public static Builder builder() { + return new Builder(); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java new file mode 100644 index 000000000000..b7a59a9413c4 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java @@ -0,0 +1,20 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.spi; + +public interface ComputeRpc { +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpcFactory.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpcFactory.java new file mode 100644 index 000000000000..5defc86199ef --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpcFactory.java @@ -0,0 +1,26 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.spi; + +import com.google.gcloud.compute.ComputeOptions; + +/** + * An interface for Compute RPC factory. + * Implementation will be loaded via {@link java.util.ServiceLoader}. + */ +public interface ComputeRpcFactory extends ServiceRpcFactory { +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java new file mode 100644 index 000000000000..6667588dd0ef --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java @@ -0,0 +1,46 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.spi; + +import com.google.api.client.http.HttpRequestInitializer; +import com.google.api.client.http.HttpTransport; +import com.google.api.client.json.jackson.JacksonFactory; +import com.google.api.services.compute.Compute; +import com.google.gcloud.compute.ComputeException; +import com.google.gcloud.compute.ComputeOptions; + +import java.io.IOException; + +public class DefaultComputeRpc implements ComputeRpc { + + private final ComputeOptions options; + private final Compute compute; + + public DefaultComputeRpc(ComputeOptions options) { + HttpTransport transport = options.httpTransportFactory().create(); + HttpRequestInitializer initializer = options.httpRequestInitializer(); + this.options = options; + compute = new Compute.Builder(transport, new JacksonFactory(), initializer) + .setRootUrl(options.host()) + .setApplicationName(options.applicationName()) + .build(); + } + + private static ComputeException translate(IOException exception) { + return new ComputeException(exception); + } +} diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml index 7dbd14e591cc..e26dfa63ab01 100644 --- a/gcloud-java/pom.xml +++ b/gcloud-java/pom.xml @@ -19,6 +19,11 @@ gcloud-java-bigquery ${project.version}
    + + ${project.groupId} + gcloud-java-compute + ${project.version} + ${project.groupId} gcloud-java-core diff --git a/pom.xml b/pom.xml index 752f7613f207..87de4a252021 100644 --- a/pom.xml +++ b/pom.xml @@ -95,6 +95,7 @@ gcloud-java gcloud-java-bigquery + gcloud-java-compute gcloud-java-contrib gcloud-java-core gcloud-java-datastore From a566ef45e67da44a9d7c13c69ee3f5b3602f353a Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 22 Feb 2016 16:04:51 +0100 Subject: [PATCH 272/375] Add Compute Engine immutable resources --- .../com/google/gcloud/compute/DiskType.java | 227 +++++++++++ .../com/google/gcloud/compute/DiskTypeId.java | 110 +++++ .../com/google/gcloud/compute/License.java | 98 +++++ .../com/google/gcloud/compute/LicenseId.java | 115 ++++++ .../google/gcloud/compute/MachineType.java | 298 ++++++++++++++ .../google/gcloud/compute/MachineTypeId.java | 97 +++++ .../com/google/gcloud/compute/Region.java | 319 +++++++++++++++ .../com/google/gcloud/compute/RegionId.java | 103 +++++ .../gcloud/compute/RegionResourceId.java | 79 ++++ .../com/google/gcloud/compute/ResourceId.java | 74 ++++ .../java/com/google/gcloud/compute/Zone.java | 380 ++++++++++++++++++ .../com/google/gcloud/compute/ZoneId.java | 112 ++++++ .../google/gcloud/compute/ZoneResourceId.java | 79 ++++ .../google/gcloud/compute/DiskTypeIdTest.java | 65 +++ .../google/gcloud/compute/DiskTypeTest.java | 73 ++++ .../google/gcloud/compute/LicenseIdTest.java | 61 +++ .../google/gcloud/compute/LicenseTest.java | 52 +++ .../gcloud/compute/MachineTypeIdTest.java | 65 +++ .../gcloud/compute/MachineTypeTest.java | 90 +++++ .../google/gcloud/compute/RegionIdTest.java | 61 +++ .../com/google/gcloud/compute/RegionTest.java | 85 ++++ .../gcloud/compute/SerializationTest.java | 157 ++++++++ .../com/google/gcloud/compute/ZoneIdTest.java | 61 +++ .../com/google/gcloud/compute/ZoneTest.java | 86 ++++ 24 files changed, 2947 insertions(+) create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionResourceId.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/ResourceId.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneResourceId.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java new file mode 100644 index 000000000000..2cc6cb9bb865 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java @@ -0,0 +1,227 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; + +import java.io.Serializable; +import java.math.BigInteger; +import java.util.Objects; + +/** + * Google Compute Engine Disk type. A disk type represents the type of disk to use, such as a + * {@code pd-ssd} or {@code pd-standard}. + */ +public final class DiskType implements Serializable { + + static final Function FROM_PB_FUNCTION = + new Function() { + @Override + public DiskType apply(com.google.api.services.compute.model.DiskType pb) { + return DiskType.fromPb(pb); + } + }; + static final Function TO_PB_FUNCTION = + new Function() { + @Override + public com.google.api.services.compute.model.DiskType apply(DiskType diskType) { + return diskType.toPb(); + } + }; + + private static final long serialVersionUID = -944042261695072026L; + + private final Long id; + private final DiskTypeId diskTypeId; + private final String creationTimestamp; + private final String description; + private final String validDiskSize; + private final String selfLink; + private final Long defaultDiskSizeGb; + + static final class Builder { + + private Long id; + private DiskTypeId diskTypeId; + private String creationTimestamp; + private String description; + private String validDiskSize; + private String selfLink; + private Long defaultDiskSizeGb; + + private Builder() {} + + Builder id(Long id) { + this.id = id; + return this; + } + + Builder creationTimestamp(String creationTimestamp) { + this.creationTimestamp = creationTimestamp; + return this; + } + + Builder diskTypeId(DiskTypeId diskTypeId) { + this.diskTypeId = diskTypeId; + return this; + } + + Builder description(String description) { + this.description = description; + return this; + } + + Builder validDiskSize(String validDiskSize) { + this.validDiskSize = validDiskSize; + return this; + } + + Builder selfLink(String selfLink) { + this.selfLink = selfLink; + return this; + } + + Builder defaultDiskSizeGb(Long defaultDiskSizeGb) { + this.defaultDiskSizeGb = defaultDiskSizeGb; + return this; + } + + /** + * Creates a {@code DiskType} object. + */ + DiskType build() { + return new DiskType(this); + } + } + + private DiskType(Builder builder) { + this.id = builder.id; + this.creationTimestamp = builder.creationTimestamp; + this.diskTypeId = builder.diskTypeId; + this.description = builder.description; + this.validDiskSize = builder.validDiskSize; + this.selfLink = builder.selfLink; + this.defaultDiskSizeGb = builder.defaultDiskSizeGb; + } + + /** + * Returns the creation timestamp in RFC3339 text format. + * + * @see RFC3339 + */ + public String creationTimestamp() { + return creationTimestamp; + } + + /** + * Returns the disk type's identity. + */ + public DiskTypeId diskTypeId() { + return diskTypeId; + } + + /** + * Returns an unique identifier for the disk type; defined by the service. + */ + public Long id() { + return id; + } + + /** + * Returns a textual description of the disk type. + */ + public String description() { + return description; + } + + /** + * Returns an optional textual description of the valid disk size, such as "10GB-10TB". + */ + public String validDiskSize() { + return validDiskSize; + } + + /** + * Returns a service-defined URL for the disk type. + */ + public String selfLink() { + return selfLink; + } + + /** + * Returns the service-defined default disk size in GB. + */ + public Long defaultDiskSizeGb() { + return defaultDiskSizeGb; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id) + .add("creationTimestamp", creationTimestamp) + .add("description", description) + .add("validDiskSize", validDiskSize) + .add("selfLink", selfLink) + .add("defaultDiskSizeGb", defaultDiskSizeGb) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof DiskType && Objects.equals(toPb(), ((DiskType) obj).toPb()); + } + + com.google.api.services.compute.model.DiskType toPb() { + com.google.api.services.compute.model.DiskType diskTypePb = + new com.google.api.services.compute.model.DiskType(); + if (id != null) { + diskTypePb.setId(BigInteger.valueOf(id)); + } + diskTypePb.setCreationTimestamp(creationTimestamp); + diskTypePb.setDescription(description); + diskTypePb.setValidDiskSize(validDiskSize); + diskTypePb.setSelfLink(selfLink); + diskTypePb.setDefaultDiskSizeGb(defaultDiskSizeGb); + diskTypePb.setZone(diskTypeId.zoneId().toUrl()); + return diskTypePb; + } + + static Builder builder() { + return new Builder(); + } + + static DiskType fromPb(com.google.api.services.compute.model.DiskType diskTypePb) { + Builder builder = builder(); + if (diskTypePb.getId() != null ) { + builder.id(diskTypePb.getId().longValue()); + } + builder.creationTimestamp(diskTypePb.getCreationTimestamp()); + builder.diskTypeId(DiskTypeId.fromUrl(diskTypePb.getSelfLink())); + builder.description(diskTypePb.getDescription()); + builder.validDiskSize(diskTypePb.getValidDiskSize()); + builder.selfLink(diskTypePb.getSelfLink()); + builder.defaultDiskSizeGb(diskTypePb.getDefaultDiskSizeGb()); + return builder.build(); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java new file mode 100644 index 000000000000..527f7da124b4 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java @@ -0,0 +1,110 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; + +import java.util.Objects; + +/** + * Identity for a Google Compute Engine disk type. + */ +public final class DiskTypeId extends ZoneResourceId { + + private static final long serialVersionUID = 7337881474103686219L; + + private final String diskType; + + DiskTypeId(String project, String zone, String diskType) { + super(project, zone); + this.diskType = checkNotNull(diskType); + } + + /** + * Returns the name of the disk type resource. The name must be 1-63 characters long, and comply + * with RFC1035. Specifically, the name must be 1-63 characters long and match the regular + * expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a + * lowercase letter, and all following characters must be a dash, lowercase letter, or digit, + * except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public String diskType() { + return diskType; + } + + @Override + public String toUrl() { + return super.toUrl() + "/diskTypes/" + diskType; + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper().add("diskType", diskType); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), diskType); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof DiskTypeId && baseEquals((DiskTypeId) obj); + } + + @Override + DiskTypeId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return DiskTypeId.of(projectId, zone(), diskType); + } + + /** + * Returns a disk type identity given the zone identity and the disk type name. + */ + public static DiskTypeId of(ZoneId zoneId, String diskType) { + return new DiskTypeId(zoneId.project(), zoneId.zone(), diskType); + } + + /** + * Returns a disk type identity given the zone disk and disk type. + */ + public static DiskTypeId of(String zone, String diskType) { + return of(ZoneId.of(null, zone), diskType); + } + + /** + * Returns a disk type identity given project disk, zone disk and disk type. + */ + public static DiskTypeId of(String project, String zone, String diskType) { + return of(ZoneId.of(project, zone), diskType); + } + + static DiskTypeId fromUrl(String url) { + int projectsIndex = url.indexOf("/projects/"); + int zonesIndex = url.indexOf("/zones/"); + int diskTypesIndex = url.indexOf("/diskTypes/"); + String project = url.substring(projectsIndex + 10, zonesIndex); + String zone = url.substring(zonesIndex + 7, diskTypesIndex); + String diskType = url.substring(diskTypesIndex + 11, url.length()); + return DiskTypeId.of(project, zone, diskType); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java new file mode 100644 index 000000000000..17e4f0d22be0 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java @@ -0,0 +1,98 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; + +import java.io.Serializable; +import java.util.Objects; + +/** + * A Google Compute Engine License. A License represents a software license. Licenses are used to + * track software usage in images, persistent disks, snapshots, and virtual machine instances. + */ +public final class License implements Serializable { + + private static final long serialVersionUID = 6907923910319640363L; + + private final LicenseId licenseId; + private final Boolean chargesUseFee; + private final String selfLink; + + License(LicenseId licenseId, Boolean chargesUseFee, String selfLink) { + this.licenseId = checkNotNull(licenseId); + this.chargesUseFee = chargesUseFee; + this.selfLink = selfLink; + } + + /** + * Returns the identity of the license. + */ + public LicenseId licenseId() { + return licenseId; + } + + /** + * Returns {@code true} if the customer will be charged a license fee for running software that + * contains this license on an instance. + */ + public Boolean chargesUseFee() { + return chargesUseFee; + } + + /** + * Returns a service-defined URL for the license. + */ + public String selfLink() { + return selfLink; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("licenseId", licenseId) + .add("chargesUseFee", chargesUseFee) + .add("selfLink", selfLink) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(licenseId, chargesUseFee, selfLink); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof License && Objects.equals(toPb(), ((License) obj).toPb()); + } + + com.google.api.services.compute.model.License toPb() { + com.google.api.services.compute.model.License licensePb = + new com.google.api.services.compute.model.License(); + licensePb.setName(licenseId.license()); + licensePb.setChargesUseFee(chargesUseFee); + licensePb.setSelfLink(selfLink); + return licensePb; + } + + static License fromPb(com.google.api.services.compute.model.License licensePb) { + return new License(LicenseId.fromUrl(licensePb.getSelfLink()), licensePb.getChargesUseFee(), + licensePb.getSelfLink()); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java new file mode 100644 index 000000000000..f32695e03c03 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java @@ -0,0 +1,115 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; + +import java.util.Objects; + +/** + * Identity for a Google Compute Engine license. + */ +public final class LicenseId extends ResourceId { + + static final Function FROM_URL_FUNCTION = new Function() { + @Override + public LicenseId apply(String pb) { + return LicenseId.fromUrl(pb); + } + }; + static final Function TO_URL_FUNCTION = new Function() { + @Override + public String apply(LicenseId licenseId) { + return licenseId.toUrl(); + } + }; + + private static final long serialVersionUID = -2239484554024469651L; + + private final String license; + + LicenseId(String project, String license) { + super(project); + this.license = checkNotNull(license); + } + + /** + * Returns the name of the license. The name must be 1-63 characters long, and comply with + * RFC1035. Specifically, the name must be 1-63 characters long and match the regular expression + * {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a lowercase letter, + * and all following characters must be a dash, lowercase letter, or digit, except the last + * character, which cannot be a dash. + * + * @see RFC1035 + */ + public String license() { + return license; + } + + @Override + public String toUrl() { + return super.toUrl() + "/global/licenses/" + license; + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper().add("license", license); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), license); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof LicenseId && baseEquals((LicenseId) obj); + } + + @Override + LicenseId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return LicenseId.of(projectId, license); + } + + /** + * Returns a license identity given the license name. + */ + public static LicenseId of(String license) { + return new LicenseId(null, license); + } + + /** + * Returns a license identity given project and license names. + */ + public static LicenseId of(String project, String license) { + return new LicenseId(project, license); + } + + static LicenseId fromUrl(String url) { + int projectsIndex = url.indexOf("/projects/"); + int licensesIndex = url.indexOf("/global/licenses/"); + String project = url.substring(projectsIndex + 10, licensesIndex); + String license = url.substring(licensesIndex + 17, url.length()); + return LicenseId.of(project, license); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java new file mode 100644 index 000000000000..bf1d6ce49f52 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java @@ -0,0 +1,298 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import com.google.api.services.compute.model.MachineType.ScratchDisks; +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; +import com.google.common.collect.Lists; + +import java.io.Serializable; +import java.math.BigInteger; +import java.util.List; +import java.util.Objects; + +public class MachineType implements Serializable { + + static final Function + FROM_PB_FUNCTION = + new Function() { + @Override + public MachineType apply(com.google.api.services.compute.model.MachineType pb) { + return MachineType.fromPb(pb); + } + }; + static final Function + TO_PB_FUNCTION = + new Function() { + @Override + public com.google.api.services.compute.model.MachineType apply(MachineType type) { + return type.toPb(); + } + }; + + private static final long serialVersionUID = -4210962597502860450L; + + private final MachineTypeId machineTypeId; + private final Long id; + private final String creationTimestamp; + private final String description; + private final String selfLink; + private final Integer guestCpus; + private final Integer memoryMb; + private final List scratchDisks; + private final Integer maximumPersistentDisks; + private final Long maximumPersistentDisksSizeGb; + + public static final class Builder { + + private MachineTypeId machineTypeId; + private Long id; + private String creationTimestamp; + private String description; + private String selfLink; + private Integer guestCpus; + private Integer memoryMb; + private List scratchDisks; + private Integer maximumPersistentDisks; + private Long maximumPersistentDisksSizeGb; + + Builder() {} + + + Builder machineTypeId(MachineTypeId machineTypeId) { + this.machineTypeId = machineTypeId; + return this; + } + + Builder id(Long id) { + this.id = id; + return this; + } + + Builder creationTimestamp(String creationTimestamp) { + this.creationTimestamp = creationTimestamp; + return this; + } + + Builder description(String description) { + this.description = description; + return this; + } + + Builder selfLink(String selfLink) { + this.selfLink = selfLink; + return this; + } + + Builder guestCpus(Integer guestCpus) { + this.guestCpus = guestCpus; + return this; + } + + Builder memoryMb(Integer memoryMb) { + this.memoryMb = memoryMb; + return this; + } + + Builder scratchDisks(List scratchDisks) { + this.scratchDisks = scratchDisks; + return this; + } + + Builder maximumPersistentDisks(Integer maximumPersistentDisks) { + this.maximumPersistentDisks = maximumPersistentDisks; + return this; + } + + Builder maximumPersistentDisksSizeGb(Long maximumPersistentDisksSizeGb) { + this.maximumPersistentDisksSizeGb = maximumPersistentDisksSizeGb; + return this; + } + + MachineType build() { + return new MachineType(this); + } + } + + MachineType(Builder builder) { + this.machineTypeId = builder.machineTypeId; + this.id = builder.id; + this.creationTimestamp = builder.creationTimestamp; + this.description = builder.description; + this.selfLink = builder.selfLink; + this.guestCpus = builder.guestCpus; + this.memoryMb = builder.memoryMb; + this.scratchDisks = builder.scratchDisks; + this.maximumPersistentDisks = builder.maximumPersistentDisks; + this.maximumPersistentDisksSizeGb = builder.maximumPersistentDisksSizeGb; + } + + /** + * Returns the machine type's identity. + */ + public MachineTypeId machineTypeId() { + return machineTypeId; + } + + /** + * Returns an unique identifier for the machin type; defined by the service. + */ + public Long id() { + return id; + } + + /** + * Returns the creation timestamp in RFC3339 text format. + * + * @see RFC3339 + */ + public String creationTimestamp() { + return creationTimestamp; + } + + /** + * Returns an optional textual description of the machine type. + */ + public String description() { + return description; + } + + /** + * Returns a service-defined URL for the machine type. + */ + public String selfLink() { + return selfLink; + } + + /** + * Returns the number of virtual CPUs that are available to the instance. + */ + public Integer guestCpus() { + return guestCpus; + } + + /** + * Returns the amount of physical memory available to the instance, defined in MB. + */ + public Integer memoryMb() { + return memoryMb; + } + + /** + * Returns the size of all extended scratch disks assigned to the instance, defined in GB. + */ + public List scratchDisks() { + return scratchDisks; + } + + /** + * Returns the maximum number of persistent disks allowed by this instance type. + */ + public Integer maximumPersistentDisks() { + return maximumPersistentDisks; + } + + /** + * Returns the maximum total persistent disks size allowed, defined in GB. + */ + public Long maximumPersistentDisksSizeGb() { + return maximumPersistentDisksSizeGb; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("machineTypeId", machineTypeId) + .add("id", id) + .add("creationTimestamp", creationTimestamp) + .add("description", description) + .add("selfLink", selfLink) + .add("guestCpus", guestCpus) + .add("memoryMb", memoryMb) + .add("scratchDisks", scratchDisks) + .add("maximumPersistentDisks", maximumPersistentDisks) + .add("maximumPersistentDisksSizeGb", maximumPersistentDisksSizeGb) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(machineTypeId); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof MachineType && Objects.equals(toPb(), ((MachineType) obj).toPb()); + } + + com.google.api.services.compute.model.MachineType toPb() { + com.google.api.services.compute.model.MachineType machineTypePb = + new com.google.api.services.compute.model.MachineType(); + if (id != null) { + machineTypePb.setId(BigInteger.valueOf(id)); + } + machineTypePb.setCreationTimestamp(creationTimestamp); + machineTypePb.setName(machineTypeId.machineType()); + machineTypePb.setDescription(description); + machineTypePb.setSelfLink(selfLink); + machineTypePb.setGuestCpus(guestCpus); + machineTypePb.setMemoryMb(memoryMb); + if (scratchDisks != null) { + machineTypePb.setScratchDisks(Lists.transform(scratchDisks, + new Function() { + @Override + public ScratchDisks apply(Integer diskSize) { + return new ScratchDisks().setDiskGb(diskSize); + } + })); + } + machineTypePb.setMaximumPersistentDisks(maximumPersistentDisks); + machineTypePb.setMaximumPersistentDisksSizeGb(maximumPersistentDisksSizeGb); + machineTypePb.setZone(machineTypeId.zoneId().zone()); + return machineTypePb; + } + + static Builder builder() { + return new Builder(); + } + + static MachineType fromPb(com.google.api.services.compute.model.MachineType machineTypePb) { + Builder builder = builder(); + builder.machineTypeId(MachineTypeId.fromUrl(machineTypePb.getSelfLink())); + if (machineTypePb.getId() != null) { + builder.id(machineTypePb.getId().longValue()); + } + builder.creationTimestamp(machineTypePb.getCreationTimestamp()); + builder.description(machineTypePb.getDescription()); + builder.selfLink(machineTypePb.getSelfLink()); + builder.guestCpus(machineTypePb.getGuestCpus()); + builder.memoryMb(machineTypePb.getMemoryMb()); + if (machineTypePb.getScratchDisks() != null) { + builder.scratchDisks( + Lists.transform(machineTypePb.getScratchDisks(), new Function() { + @Override + public Integer apply(ScratchDisks scratchDiskPb) { + return scratchDiskPb.getDiskGb(); + } + })); + } + builder.maximumPersistentDisks(machineTypePb.getMaximumPersistentDisks()); + builder.maximumPersistentDisksSizeGb(machineTypePb.getMaximumPersistentDisksSizeGb()); + return builder.build(); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java new file mode 100644 index 000000000000..4a215dd207d3 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java @@ -0,0 +1,97 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; + +import java.util.Objects; + +/** + * Identity for a Google Compute Engine machine type. + */ +public final class MachineTypeId extends ZoneResourceId { + + private static final long serialVersionUID = -5819598544478859608L; + + private final String machineType; + + MachineTypeId(String project, String zone, String machineType) { + super(project, zone); + this.machineType = checkNotNull(machineType); + } + + /** + * Returns the name of the machine type. + */ + public String machineType() { + return machineType; + } + + @Override + public String toUrl() { + return super.toUrl() + "/machineTypes/" + machineType; + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper().add("machineType", machineType); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), machineType); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof MachineTypeId && baseEquals((MachineTypeId) obj); + } + + @Override + MachineTypeId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return MachineTypeId.of(projectId, zone(), machineType); + } + + /** + * Returns a machine type identity given the zone and type names. + */ + public static MachineTypeId of(String zone, String machineType) { + return new MachineTypeId(null, zone, machineType); + } + + /** + * Returns a machine type identity given project, zone and type names. + */ + public static MachineTypeId of(String project, String zone, String machineType) { + return new MachineTypeId(project, zone, machineType); + } + + static MachineTypeId fromUrl(String url) { + int projectsIndex = url.indexOf("/projects/"); + int zonesIndex = url.indexOf("/zones/"); + int machineTypesIndex = url.indexOf("/machineTypes/"); + String project = url.substring(projectsIndex + 10, zonesIndex); + String zone = url.substring(zonesIndex + 7, machineTypesIndex); + String machineType = url.substring(machineTypesIndex + 14, url.length()); + return MachineTypeId.of(project, zone, machineType); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java new file mode 100644 index 000000000000..ded705bc2a8d --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java @@ -0,0 +1,319 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; +import com.google.common.collect.Lists; + +import java.io.Serializable; +import java.math.BigInteger; +import java.util.List; +import java.util.Objects; + +/** + * A Google Compute Engine region. + */ +public final class Region implements Serializable { + + static final Function FROM_PB_FUNCTION = + new Function() { + @Override + public Region apply(com.google.api.services.compute.model.Region pb) { + return Region.fromPb(pb); + } + }; + static final Function TO_PB_FUNCTION = + new Function() { + @Override + public com.google.api.services.compute.model.Region apply(Region region) { + return region.toPb(); + } + }; + + private static final long serialVersionUID = -3578710133393645135L; + + /** + * Status of the region. + */ + public enum Status { + UP, + DOWN + } + + /** + * A quota assigned to this region. + */ + public static class Quota implements Serializable { + + static final Function FROM_PB_FUNCTION = + new Function() { + @Override + public Quota apply(com.google.api.services.compute.model.Quota pb) { + return Quota.fromPb(pb); + } + }; + static final Function TO_PB_FUNCTION = + new Function() { + @Override + public com.google.api.services.compute.model.Quota apply(Quota quota) { + return quota.toPb(); + } + }; + private static final long serialVersionUID = -4357118665133226338L; + + private final String metric; + private final double limit; + private final double usage; + + /** + * Returns a region quota object. + */ + Quota(String metric, double limit, double usage) { + this.metric = metric; + this.limit = limit; + this.usage = usage; + } + + public String metric() { + return metric; + } + + public double limit() { + return limit; + } + + public double usage() { + return usage; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("metric", metric) + .add("limit", limit) + .add("usage", usage) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(metric, limit, usage); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Quota)) { + return false; + } + Quota other = (Quota) obj; + return Objects.equals(metric, other.metric) + && Objects.equals(limit, other.limit) + && Objects.equals(usage, other.usage); + } + + com.google.api.services.compute.model.Quota toPb() { + return new com.google.api.services.compute.model.Quota() + .setMetric(metric) + .setLimit(limit) + .setUsage(usage); + } + + static Quota fromPb(com.google.api.services.compute.model.Quota quotaPb) { + return new Quota(quotaPb.getMetric(), quotaPb.getLimit(), quotaPb.getUsage()); + } + } + + private final RegionId regionId; + private final Long id; + private final String creationTimestamp; + private final String description; + private final String selfLink; + private final Status status; + private final List zones; + private final List quotas; + + public static final class Builder { + + private RegionId regionId; + private Long id; + private String creationTimestamp; + private String description; + private String selfLink; + private Status status; + private List zones; + private List quotas; + + Builder() {} + + Builder regionId(RegionId regionId) { + this.regionId = regionId; + return this; + } + + Builder id(Long id) { + this.id = id; + return this; + } + + Builder creationTimestamp(String creationTimestamp) { + this.creationTimestamp = creationTimestamp; + return this; + } + + Builder description(String description) { + this.description = description; + return this; + } + + Builder selfLink(String selfLink) { + this.selfLink = selfLink; + return this; + } + + Builder status(Status status) { + this.status = status; + return this; + } + + Builder zones(List zones) { + this.zones = zones; + return this; + } + + Builder quotas(List quotas) { + this.quotas = quotas; + return this; + } + + Region build() { + return new Region(this); + } + } + + Region(Builder builder) { + this.regionId = builder.regionId; + this.id = builder.id; + this.creationTimestamp = builder.creationTimestamp; + this.description = builder.description; + this.selfLink = builder.selfLink; + this.status = builder.status; + this.zones = builder.zones; + this.quotas = builder.quotas; + } + + public RegionId regionId() { + return regionId; + } + + public Long id() { + return id; + } + + public String creationTimestamp() { + return creationTimestamp; + } + + public String description() { + return description; + } + + public String selfLink() { + return selfLink; + } + + public Status status() { + return status; + } + + public List zones() { + return zones; + } + + public List quotas() { + return quotas; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("regionId", regionId) + .add("id", id) + .add("creationTimestamp", creationTimestamp) + .add("description", description) + .add("selfLink", selfLink) + .add("status", status) + .add("zones", zones) + .add("quotas", quotas) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(regionId); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof Region && Objects.equals(toPb(), ((Region) obj).toPb()); + } + + com.google.api.services.compute.model.Region toPb() { + com.google.api.services.compute.model.Region regionPb = + new com.google.api.services.compute.model.Region(); + if (id != null) { + regionPb.setId(BigInteger.valueOf(id)); + } + regionPb.setCreationTimestamp(creationTimestamp); + regionPb.setName(regionId.region()); + regionPb.setDescription(description); + regionPb.setSelfLink(selfLink); + regionPb.setStatus(status.name()); + if (zones != null) { + regionPb.setZones(Lists.transform(zones, ZoneId.TO_URL_FUNCTION)); + } + if (quotas != null) { + regionPb.setQuotas(Lists.transform(quotas, Quota.TO_PB_FUNCTION)); + } + return regionPb; + } + + static Builder builder() { + return new Builder(); + } + + static Region fromPb(com.google.api.services.compute.model.Region regionPb) { + Builder builder = builder(); + builder.regionId(RegionId.fromUrl(regionPb.getSelfLink())); + if (regionPb.getId() != null) { + builder.id(regionPb.getId().longValue()); + } + builder.creationTimestamp(regionPb.getCreationTimestamp()); + builder.description(regionPb.getDescription()); + builder.selfLink(regionPb.getSelfLink()); + if (regionPb.getStatus() != null) { + builder.status(Status.valueOf(regionPb.getStatus())); + } + if (regionPb.getZones() != null) { + builder.zones(Lists.transform(regionPb.getZones(), ZoneId.FROM_URL_FUNCTION)); + } + if (regionPb.getQuotas() != null) { + builder.quotas(Lists.transform(regionPb.getQuotas(), Quota.FROM_PB_FUNCTION)); + } + return builder.build(); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java new file mode 100644 index 000000000000..60b603778863 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java @@ -0,0 +1,103 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects.ToStringHelper; + +import java.util.Objects; + +/** + * A Google Compute Engine region identity. + */ +public final class RegionId extends ResourceId { + + private static final long serialVersionUID = 5569092266957249294L; + + private final String region; + + RegionId(String project, String region) { + super(project); + this.region = checkNotNull(region); + } + + RegionId(RegionId regionId) { + super(regionId.project()); + this.region = checkNotNull(regionId.region()); + } + + /** + * Returns the name of the region. + */ + public final String region() { + return region; + } + + @Override + public String toUrl() { + return super.toUrl() + "/regions/" + region; + } + + @Override + ToStringHelper toStringHelper() { + return super.toStringHelper().add("region", region); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), region); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof RegionId && baseEquals((RegionId) obj); + } + + @Override + RegionId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return RegionId.of(projectId, region); + } + + /** + * Returns a new region identity given project and region names. + */ + public static RegionId of(String project, String region) { + return new RegionId(project, region); + } + + /** + * Returns a new region identity given region name. + */ + public static RegionId of(String region) { + return RegionId.of(null, region); + } + + /** + * Returns a new region identity given a region URL. + */ + static RegionId fromUrl(String url) { + int projectsIndex = url.indexOf("/projects/"); + int regionsIndex = url.indexOf("/regions/"); + String project = url.substring(projectsIndex + 10, regionsIndex); + String region = url.substring(regionsIndex + 9, url.length()); + return RegionId.of(project, region); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionResourceId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionResourceId.java new file mode 100644 index 000000000000..618ae0a9a4e1 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionResourceId.java @@ -0,0 +1,79 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects.ToStringHelper; + +import java.util.Objects; + +/** + * A base class for the identity of Google Compute Engine resources that live in a region. + */ +public abstract class RegionResourceId extends ResourceId { + + private static final long serialVersionUID = 5569092266957249294L; + + private final String region; + + RegionResourceId(String project, String region) { + super(project); + this.region = checkNotNull(region); + } + + RegionResourceId(RegionId regionId) { + super(regionId.project()); + this.region = checkNotNull(regionId.region()); + } + + /** + * Returns the name of the region this resource belongs to. + */ + public final String region() { + return region; + } + + /** + * Returns the identity of the region this resource belongs to. + */ + public final RegionId regionId() { + return RegionId.of(project(), region); + } + + @Override + public String toUrl() { + return super.toUrl() + "/regions/" + region; + } + + @Override + ToStringHelper toStringHelper() { + return super.toStringHelper().add("region", region); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), region); + } + + @Override + public boolean equals(Object obj) { + return obj != null + && obj.getClass().equals(RegionResourceId.class) + && baseEquals((RegionResourceId) obj); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ResourceId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ResourceId.java new file mode 100644 index 000000000000..dc69d6ae53b4 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ResourceId.java @@ -0,0 +1,74 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import com.google.common.base.MoreObjects; + +import java.io.Serializable; +import java.util.Objects; + +/** + * Base class for Google Compute Engine resource identities. + */ +public abstract class ResourceId implements Serializable { + + private static final long serialVersionUID = -8028734746870421573L; + + private String project; + + ResourceId(String project) { + this.project = project; + } + + /** + * Base URL for a resource URL. + */ + private static final String BASE_URL = "https://www.googleapis.com/compute/v1/projects/"; + + /** + * Returns a fully qualified URL to the entity. + */ + public String toUrl() { + return BASE_URL + project; + } + + /** + * Returns the name of the project. + */ + public final String project() { + return project; + } + + MoreObjects.ToStringHelper toStringHelper() { + return MoreObjects.toStringHelper(this).add("project", project); + } + + @Override + public String toString() { + return toStringHelper().toString(); + } + + final int baseHashCode() { + return Objects.hash(project); + } + + final boolean baseEquals(ResourceId resourceId) { + return Objects.equals(toUrl(), resourceId.toUrl()); + } + + abstract ResourceId setProjectId(String projectId); +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java new file mode 100644 index 000000000000..b98e863011bb --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java @@ -0,0 +1,380 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import com.google.api.services.compute.model.Zone.MaintenanceWindows; +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; +import com.google.common.collect.Lists; + +import java.io.Serializable; +import java.math.BigInteger; +import java.util.List; +import java.util.Objects; + +/** + * A Google Compute Engine zone. + */ +public final class Zone implements Serializable { + + static final Function FROM_PB_FUNCTION = + new Function() { + @Override + public Zone apply(com.google.api.services.compute.model.Zone pb) { + return Zone.fromPb(pb); + } + }; + static final Function TO_PB_FUNCTION = + new Function() { + @Override + public com.google.api.services.compute.model.Zone apply(Zone region) { + return region.toPb(); + } + }; + private static final long serialVersionUID = 6113636504417213010L; + + /** + * Status of the region. + */ + public enum Status { + UP, + DOWN + } + + /** + * A scheduled maintenance windows for this zone. When a zone is in a maintenance window, all + * resources which reside in the zone will be unavailable. + * + * @see Maintenance + * Windows + */ + public static class MaintenanceWindow implements Serializable { + + static final Function FROM_PB_FUNCTION = + new Function() { + @Override + public MaintenanceWindow apply(MaintenanceWindows pb) { + return MaintenanceWindow.fromPb(pb); + } + }; + static final Function TO_PB_FUNCTION = + new Function() { + @Override + public MaintenanceWindows apply(MaintenanceWindow maintenanceWindow) { + return maintenanceWindow.toPb(); + } + }; + + private static final long serialVersionUID = 2270641266683329963L; + + private final String name; + private final String description; + private final String beginTime; + private final String endTime; + + /** + * Returns a zone maintenance window object. + */ + MaintenanceWindow(String name, String description, String beginTime, String endTime) { + this.name = name; + this.description = description; + this.beginTime = beginTime; + this.endTime = endTime; + } + + /** + * Returns the disk of the maintanance window. + */ + public String name() { + return name; + } + + /** + * Returns a textual description of the maintenance window. + */ + public String description() { + return description; + } + + /** + * Returns the starting time of the maintenance window in RFC3339 text format. + * + * @see RFC3339 + */ + public String beginTime() { + return beginTime; + } + + /** + * Returns the ending time of the maintenance window in RFC3339 text format. + * + * @see RFC3339 + */ + public String endTime() { + return endTime; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("disk", name) + .add("description", description) + .add("beginTime", beginTime) + .add("endTime", endTime) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(name, description, beginTime, endTime); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof MaintenanceWindow)) { + return false; + } + MaintenanceWindow other = (MaintenanceWindow) obj; + return Objects.equals(name, other.name) + && Objects.equals(description, other.description) + && Objects.equals(beginTime, other.beginTime) + && Objects.equals(endTime, other.endTime); + } + + MaintenanceWindows toPb() { + return new MaintenanceWindows() + .setName(name) + .setDescription(description) + .setBeginTime(beginTime) + .setEndTime(endTime); + } + + static MaintenanceWindow fromPb(MaintenanceWindows windowPb) { + return new MaintenanceWindow(windowPb.getName(), windowPb.getDescription(), + windowPb.getBeginTime(), windowPb.getEndTime()); + } + } + + private final ZoneId zoneId; + private final Long id; + private final String creationTimestamp; + private final String description; + private final String selfLink; + private final Status status; + private final List maintenanceWindows; + private final RegionId region; + + public static final class Builder { + + private ZoneId zoneId; + private Long id; + private String creationTimestamp; + private String description; + private String selfLink; + private Status status; + private List maintenanceWindows; + private RegionId region; + + Builder() {} + + Builder zoneId(ZoneId zoneId) { + this.zoneId = zoneId; + return this; + } + + Builder id(Long id) { + this.id = id; + return this; + } + + Builder creationTimestamp(String creationTimestamp) { + this.creationTimestamp = creationTimestamp; + return this; + } + + Builder description(String description) { + this.description = description; + return this; + } + + Builder selfLink(String selfLink) { + this.selfLink = selfLink; + return this; + } + + Builder status(Status status) { + this.status = status; + return this; + } + + Builder maintenanceWindows(List maintenanceWindows) { + this.maintenanceWindows = maintenanceWindows; + return this; + } + + Builder region(RegionId region) { + this.region = region; + return this; + } + + Zone build() { + return new Zone(this); + } + } + + Zone(Builder builder) { + this.zoneId = builder.zoneId; + this.id = builder.id; + this.creationTimestamp = builder.creationTimestamp; + this.description = builder.description; + this.selfLink = builder.selfLink; + this.status = builder.status; + this.maintenanceWindows = builder.maintenanceWindows; + this.region = builder.region; + } + + /** + * Returns the zone's identity. + */ + public ZoneId zoneId() { + return zoneId; + } + + /** + * Returns the creation timestamp in RFC3339 text format. + * + * @see RFC3339 + */ + public String creationTimestamp() { + return creationTimestamp; + } + + /** + * Returns an optional textual description of the zone. + */ + public String description() { + return description; + } + + /** + * Returns an unique identifier for the zone; defined by the service. + */ + public Long id() { + return id; + } + + /** + * Returns a service-defined URL for the zone. + */ + public String selfLink() { + return selfLink; + } + + /** + * Returns the status of the zone. + */ + public Status status() { + return status; + } + + /** + * Returns the scheduled maintenance windows for this zone, if any. When the zone is in a + * maintenance window, all resources which reside in the zone will be unavailable. + * + * @see Maintenance + * Windows + */ + public List maintenanceWindows() { + return maintenanceWindows; + } + + /** + * Returns the identity of the region that hosts the zone. + */ + public RegionId region() { + return region; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("zoneId", zoneId) + .add("id", id) + .add("creationTimestamp", creationTimestamp) + .add("description", description) + .add("selfLink", selfLink) + .add("status", status) + .add("maintenanceWindows", maintenanceWindows) + .add("region", region) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(zoneId); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof Zone && Objects.equals(toPb(), ((Zone) obj).toPb()); + } + + com.google.api.services.compute.model.Zone toPb() { + com.google.api.services.compute.model.Zone zonePb = + new com.google.api.services.compute.model.Zone(); + zonePb.setId(BigInteger.valueOf(id)); + zonePb.setCreationTimestamp(creationTimestamp); + zonePb.setName(zoneId.zone()); + zonePb.setDescription(description); + zonePb.setSelfLink(selfLink); + zonePb.setStatus(status.name()); + if (maintenanceWindows != null) { + zonePb.setMaintenanceWindows( + Lists.transform(maintenanceWindows, MaintenanceWindow.TO_PB_FUNCTION)); + } + if (region != null) { + zonePb.setRegion(region.toUrl()); + } + return zonePb; + } + + static Builder builder() { + return new Builder(); + } + + static Zone fromPb(com.google.api.services.compute.model.Zone zonePb) { + Builder builder = builder(); + builder.zoneId(ZoneId.fromUrl(zonePb.getSelfLink())); + if (zonePb.getId() != null) { + builder.id(zonePb.getId().longValue()); + } + builder.creationTimestamp(zonePb.getCreationTimestamp()); + builder.description(zonePb.getDescription()); + builder.selfLink(zonePb.getSelfLink()); + if (zonePb.getStatus() != null) { + builder.status(Status.valueOf(zonePb.getStatus())); + } + if (zonePb.getMaintenanceWindows() != null) { + builder.maintenanceWindows( + Lists.transform(zonePb.getMaintenanceWindows(), MaintenanceWindow.FROM_PB_FUNCTION)); + } + if (zonePb.getRegion() != null) { + builder.region(RegionId.fromUrl(zonePb.getRegion())); + } + return builder.build(); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java new file mode 100644 index 000000000000..3637ae302483 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java @@ -0,0 +1,112 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Function; +import com.google.common.base.MoreObjects.ToStringHelper; + +import java.util.Objects; + +/** + * A Google Compute Engine zone identity. + */ +public final class ZoneId extends ResourceId { + + static final Function FROM_URL_FUNCTION = new Function() { + @Override + public ZoneId apply(String pb) { + return ZoneId.fromUrl(pb); + } + }; + static final Function TO_URL_FUNCTION = new Function() { + @Override + public String apply(ZoneId zoneId) { + return zoneId.toUrl(); + } + }; + + private static final long serialVersionUID = -7635391994812946733L; + + private final String zone; + + ZoneId(String project, String zone) { + super(project); + this.zone = checkNotNull(zone); + } + + /** + * Returns the name of the zone. + */ + public final String zone() { + return zone; + } + + @Override + public String toUrl() { + return super.toUrl() + "/zones/" + zone; + } + + @Override + ToStringHelper toStringHelper() { + return super.toStringHelper().add("zone", zone); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), zone); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof ZoneId && baseEquals((ZoneId) obj); + } + + @Override + ZoneId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return ZoneId.of(projectId, zone); + } + + /** + * Returns a new zone identity given project and zone names. + */ + public static ZoneId of(String project, String zone) { + return new ZoneId(project, zone); + } + + /** + * Returns a new zone identity given zone name. + */ + public static ZoneId of(String zone) { + return ZoneId.of(null, zone); + } + + /** + * Returns a new zone identity given a zone URL. + */ + static ZoneId fromUrl(String url) { + int projectsIndex = url.indexOf("/projects/"); + int zonesIndex = url.indexOf("/zones/"); + String project = url.substring(projectsIndex + 10, zonesIndex); + String zone = url.substring(zonesIndex + 7, url.length()); + return ZoneId.of(project, zone); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneResourceId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneResourceId.java new file mode 100644 index 000000000000..961ca7cd499b --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneResourceId.java @@ -0,0 +1,79 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects.ToStringHelper; + +import java.util.Objects; + +/** + * A base class for the identity of Google Compute Engine resources that live in a zone. + */ +public abstract class ZoneResourceId extends ResourceId { + + private static final long serialVersionUID = -6249546895344926888L; + + private final String zone; + + ZoneResourceId(String project, String zone) { + super(project); + this.zone = checkNotNull(zone); + } + + ZoneResourceId(ZoneId zoneId) { + super(zoneId.project()); + this.zone = checkNotNull(zoneId.zone()); + } + + /** + * Returns the name of the zone this resource belongs to. + */ + public final String zone() { + return zone; + } + + /** + * Returns the identity of the zone this resource belongs to. + */ + public final ZoneId zoneId() { + return ZoneId.of(project(), zone); + } + + @Override + public String toUrl() { + return super.toUrl() + "/zones/" + zone; + } + + @Override + ToStringHelper toStringHelper() { + return super.toStringHelper().add("zone", zone); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), zone); + } + + @Override + public boolean equals(Object obj) { + return obj != null + && obj.getClass().equals(ZoneResourceId.class) + && baseEquals((RegionResourceId) obj); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java new file mode 100644 index 000000000000..7bfb28362119 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Test; + +public class DiskTypeIdTest { + + private static final String PROJECT = "project"; + private static final String ZONE = "zone"; + private static final String DISK_TYPE = "diskType"; + private static final String URL = + "https://www.googleapis.com/compute/v1/projects/project/zones/zone/diskTypes/diskType"; + + @Test + public void testOf() { + DiskTypeId diskTypeId = DiskTypeId.of(PROJECT, ZONE, DISK_TYPE); + assertEquals(PROJECT, diskTypeId.project()); + assertEquals(ZONE, diskTypeId.zone()); + assertEquals(DISK_TYPE, diskTypeId.diskType()); + assertEquals(URL, diskTypeId.toUrl()); + diskTypeId = DiskTypeId.of(ZONE, DISK_TYPE); + assertNull(diskTypeId.project()); + assertEquals(ZONE, diskTypeId.zone()); + assertEquals(DISK_TYPE, diskTypeId.diskType()); + } + + @Test + public void testToAndFromUrl() { + DiskTypeId diskTypeId = DiskTypeId.of(PROJECT, ZONE, DISK_TYPE); + compareDiskTypeId(diskTypeId, DiskTypeId.fromUrl(diskTypeId.toUrl())); + } + + @Test + public void testSetProjectId() { + DiskTypeId diskTypeId = DiskTypeId.of(PROJECT, ZONE, DISK_TYPE); + compareDiskTypeId(diskTypeId, DiskTypeId.of(ZONE, DISK_TYPE).setProjectId(PROJECT)); + } + + private void compareDiskTypeId(DiskTypeId expected, DiskTypeId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.zone(), expected.zone()); + assertEquals(expected.diskType(), expected.diskType()); + assertEquals(expected.toUrl(), expected.toUrl()); + assertEquals(expected.hashCode(), expected.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java new file mode 100644 index 000000000000..239c37c49f67 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java @@ -0,0 +1,73 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class DiskTypeTest { + + private static final Long ID = 42L; + private static final String CREATION_TIMESTAMP = "2016-01-20T04:39:00.210-08:00"; + private static final String DESCRIPTION = "description"; + private static final String VALID_DISK_SIZE = "10GB-10TB"; + private static final Long DEFAULT_DISK_SIZE_GB = 10L; + private static final DiskTypeId DISK_TYPE_ID = DiskTypeId.of("project", "zone", "diskType"); + private static final DiskType DISK_TYPE = DiskType.builder() + .id(ID) + .diskTypeId(DISK_TYPE_ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .validDiskSize(VALID_DISK_SIZE) + .selfLink(DISK_TYPE_ID.toUrl()) + .defaultDiskSizeGb(DEFAULT_DISK_SIZE_GB) + .build(); + + @Test + public void testBuilder() { + assertEquals(ID, DISK_TYPE.id()); + assertEquals(DISK_TYPE_ID, DISK_TYPE.diskTypeId()); + assertEquals(CREATION_TIMESTAMP, DISK_TYPE.creationTimestamp()); + assertEquals(DESCRIPTION, DISK_TYPE.description()); + assertEquals(VALID_DISK_SIZE, DISK_TYPE.validDiskSize()); + assertEquals(DISK_TYPE_ID.toUrl(), DISK_TYPE.selfLink()); + assertEquals(DEFAULT_DISK_SIZE_GB, DISK_TYPE.defaultDiskSizeGb()); + } + + @Test + public void testToPbAndFromPb() { + compareDiskTypes(DISK_TYPE, DiskType.fromPb(DISK_TYPE.toPb())); + DiskType diskType = DiskType.builder() + .id(ID) + .diskTypeId(DISK_TYPE_ID) + .selfLink(DISK_TYPE_ID.toUrl()) + .build(); + compareDiskTypes(diskType, DiskType.fromPb(diskType.toPb())); + } + + private void compareDiskTypes(DiskType expected, DiskType value) { + assertEquals(expected.id(), value.id()); + assertEquals(expected.diskTypeId(), value.diskTypeId()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.validDiskSize(), value.validDiskSize()); + assertEquals(expected.selfLink(), value.selfLink()); + assertEquals(expected.defaultDiskSizeGb(), value.defaultDiskSizeGb()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java new file mode 100644 index 000000000000..bf473b8218b6 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Test; + +public class LicenseIdTest { + + private static final String PROJECT = "project"; + private static final String LICENSE = "license"; + private static final String URL = + "https://www.googleapis.com/compute/v1/projects/project/global/licenses/license"; + + @Test + public void testOf() { + LicenseId licenseId = LicenseId.of(PROJECT, LICENSE); + assertEquals(PROJECT, licenseId.project()); + assertEquals(LICENSE, licenseId.license()); + assertEquals(URL, licenseId.toUrl()); + licenseId = LicenseId.of(LICENSE); + assertNull(licenseId.project()); + assertEquals(LICENSE, licenseId.license()); + } + + @Test + public void testToAndFromUrl() { + LicenseId licenseId = LicenseId.of(PROJECT, LICENSE); + compareLicenseId(licenseId, LicenseId.fromUrl(licenseId.toUrl())); + } + + @Test + public void testSetProjectId() { + LicenseId licenseId = LicenseId.of(PROJECT, LICENSE); + compareLicenseId(licenseId, LicenseId.of(LICENSE).setProjectId(PROJECT)); + } + + private void compareLicenseId(LicenseId expected, LicenseId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.license(), expected.license()); + assertEquals(expected.toUrl(), expected.toUrl()); + assertEquals(expected.hashCode(), expected.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseTest.java new file mode 100644 index 000000000000..450979d8ecc8 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseTest.java @@ -0,0 +1,52 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class LicenseTest { + + private static final LicenseId LICENSE_ID = LicenseId.of("project", "license"); + private static final Boolean CHARGES_USE_FEE = true; + private static final String SELF_LINK = LICENSE_ID.toUrl(); + private static final License LICENSE = new License(LICENSE_ID, CHARGES_USE_FEE, SELF_LINK); + + @Test + public void testBuilder() { + assertEquals(LICENSE_ID, LICENSE.licenseId()); + assertEquals(CHARGES_USE_FEE, LICENSE.chargesUseFee()); + assertEquals(LICENSE_ID.toUrl(), LICENSE.selfLink()); + } + + @Test + public void testToAndFromPb() { + License license = License.fromPb(LICENSE.toPb()); + compareLicenses(LICENSE, license); + assertEquals(LICENSE_ID.project(), license.licenseId().project()); + assertEquals(LICENSE_ID.license(), license.licenseId().license()); + } + + private void compareLicenses(License expected, License value) { + assertEquals(expected, value); + assertEquals(expected.licenseId(), value.licenseId()); + assertEquals(expected.chargesUseFee(), value.chargesUseFee()); + assertEquals(expected.selfLink(), value.selfLink()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java new file mode 100644 index 000000000000..cb1353487947 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java @@ -0,0 +1,65 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Test; + +public class MachineTypeIdTest { + + private static final String PROJECT = "project"; + private static final String ZONE = "zone"; + private static final String TYPE = "type"; + private static final String URL = + "https://www.googleapis.com/compute/v1/projects/project/zones/zone/machineTypes/type"; + + @Test + public void testOf() { + MachineTypeId machineTypeId = MachineTypeId.of(PROJECT, ZONE, TYPE); + assertEquals(PROJECT, machineTypeId.project()); + assertEquals(ZONE, machineTypeId.zone()); + assertEquals(TYPE, machineTypeId.machineType()); + assertEquals(URL, machineTypeId.toUrl()); + machineTypeId = MachineTypeId.of(ZONE, TYPE); + assertNull(machineTypeId.project()); + assertEquals(ZONE, machineTypeId.zone()); + assertEquals(TYPE, machineTypeId.machineType()); + } + + @Test + public void testToAndFromUrl() { + MachineTypeId machineTypeId = MachineTypeId.of(PROJECT, ZONE, TYPE); + compareMachineTypeId(machineTypeId, MachineTypeId.fromUrl(machineTypeId.toUrl())); + } + + @Test + public void testSetProjectId() { + MachineTypeId machineTypeId = MachineTypeId.of(PROJECT, ZONE, TYPE); + compareMachineTypeId(machineTypeId, MachineTypeId.of(ZONE, TYPE).setProjectId(PROJECT)); + } + + private void compareMachineTypeId(MachineTypeId expected, MachineTypeId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.zone(), expected.zone()); + assertEquals(expected.machineType(), expected.machineType()); + assertEquals(expected.toUrl(), expected.toUrl()); + assertEquals(expected.hashCode(), expected.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java new file mode 100644 index 000000000000..ff89f2e1a77b --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java @@ -0,0 +1,90 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; + +import com.google.common.collect.ImmutableList; + +import org.junit.Test; + +import java.util.List; + +public class MachineTypeTest { + + private static final Long ID = 42L; + private static final String CREATION_TIMESTAMP = "2016-01-20T04:39:00.210-08:00"; + private static final String DESCRIPTION = "description"; + private static final MachineTypeId MACHINE_TYPE_ID = MachineTypeId.of("project", "zone", "type"); + private static final Integer GUEST_CPUS = 1; + private static final Integer MEMORY_MB = 2; + private static final List SCRATCH_DISKS = ImmutableList.of(3); + private static final Integer MAXIMUM_PERSISTENT_DISKS = 4; + private static final Long MAXIMUM_PERSISTENT_DISKS_SIZE_GB = 5L; + private static final MachineType MACHINE_TYPE = MachineType.builder() + .id(ID) + .machineTypeId(MACHINE_TYPE_ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .selfLink(MACHINE_TYPE_ID.toUrl()) + .guestCpus(GUEST_CPUS) + .memoryMb(MEMORY_MB) + .scratchDisks(SCRATCH_DISKS) + .maximumPersistentDisks(MAXIMUM_PERSISTENT_DISKS) + .maximumPersistentDisksSizeGb(MAXIMUM_PERSISTENT_DISKS_SIZE_GB) + .build(); + + @Test + public void testBuilder() { + assertEquals(ID, MACHINE_TYPE.id()); + assertEquals(MACHINE_TYPE_ID, MACHINE_TYPE.machineTypeId()); + assertEquals(CREATION_TIMESTAMP, MACHINE_TYPE.creationTimestamp()); + assertEquals(DESCRIPTION, MACHINE_TYPE.description()); + assertEquals(MACHINE_TYPE_ID.toUrl(), MACHINE_TYPE.selfLink()); + assertEquals(GUEST_CPUS, MACHINE_TYPE.guestCpus()); + assertEquals(MEMORY_MB, MACHINE_TYPE.memoryMb()); + assertEquals(SCRATCH_DISKS, MACHINE_TYPE.scratchDisks()); + assertEquals(MAXIMUM_PERSISTENT_DISKS, MACHINE_TYPE.maximumPersistentDisks()); + assertEquals(MAXIMUM_PERSISTENT_DISKS_SIZE_GB, MACHINE_TYPE.maximumPersistentDisksSizeGb()); + } + + @Test + public void testToPbAndFromPb() { + compareMachineTypes(MACHINE_TYPE, MachineType.fromPb(MACHINE_TYPE.toPb())); + MachineType machineType = MachineType.builder() + .id(ID) + .machineTypeId(MACHINE_TYPE_ID) + .selfLink(MACHINE_TYPE_ID.toUrl()) + .build(); + compareMachineTypes(machineType, MachineType.fromPb(machineType.toPb())); + } + + private void compareMachineTypes(MachineType expected, MachineType value) { + assertEquals(expected.id(), value.id()); + assertEquals(expected.machineTypeId(), value.machineTypeId()); + assertEquals(expected.id(), value.id()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.selfLink(), value.selfLink()); + assertEquals(expected.guestCpus(), value.guestCpus()); + assertEquals(expected.memoryMb(), value.memoryMb()); + assertEquals(expected.scratchDisks(), value.scratchDisks()); + assertEquals(expected.maximumPersistentDisks(), value.maximumPersistentDisks()); + assertEquals(expected.maximumPersistentDisksSizeGb(), value.maximumPersistentDisksSizeGb()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java new file mode 100644 index 000000000000..7796c9dde66a --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Test; + +public class RegionIdTest { + + private static final String PROJECT = "project"; + private static final String REGION = "region"; + private static final String URL = + "https://www.googleapis.com/compute/v1/projects/project/regions/region"; + + @Test + public void testOf() { + RegionId regionId = RegionId.of(PROJECT, REGION); + assertEquals(PROJECT, regionId.project()); + assertEquals(REGION, regionId.region()); + assertEquals(URL, regionId.toUrl()); + regionId = RegionId.of(REGION); + assertNull(regionId.project()); + assertEquals(REGION, regionId.region()); + } + + @Test + public void testToAndFromUrl() { + RegionId regionId = RegionId.of(PROJECT, REGION); + compareRegionId(regionId, RegionId.fromUrl(regionId.toUrl())); + } + + @Test + public void testSetProjectId() { + RegionId regionId = RegionId.of(PROJECT, REGION); + compareRegionId(regionId, RegionId.of(REGION).setProjectId(PROJECT)); + } + + private void compareRegionId(RegionId expected, RegionId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.region(), expected.region()); + assertEquals(expected.toUrl(), expected.toUrl()); + assertEquals(expected.hashCode(), expected.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java new file mode 100644 index 000000000000..45b93730d84f --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java @@ -0,0 +1,85 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; + +import com.google.common.collect.ImmutableList; + +import org.junit.Test; + +import java.util.List; + +public class RegionTest { + + private static final RegionId REGION_ID = RegionId.of("project", "region"); + private static final Long ID = 42L; + private static final String CREATION_TIMESTAMP = "2016-01-20T04:39:00.210-08:00"; + private static final String DESCRIPTION = "description"; + private static final Region.Status STATUS = Region.Status.DOWN; + private static final ZoneId ZONE_ID1 = ZoneId.of("project", "zone1"); + private static final ZoneId ZONE_ID2 = ZoneId.of("project", "zone2"); + private static final List ZONES = ImmutableList.of(ZONE_ID1, ZONE_ID2); + private static final Region.Quota QUOTA1 = + new Region.Quota("METRIC1", 2, 1); + private static final Region.Quota QUOTA2 = + new Region.Quota("METRIC2", 4, 3); + private static final List QUOTAS = ImmutableList.of(QUOTA1, QUOTA2); + private static final Region REGION = Region.builder() + .regionId(REGION_ID) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .selfLink(REGION_ID.toUrl()) + .status(STATUS) + .zones(ZONES) + .quotas(QUOTAS) + .build(); + + @Test + public void testBuilder() { + assertEquals(REGION_ID, REGION.regionId()); + assertEquals(ID, REGION.id()); + assertEquals(CREATION_TIMESTAMP, REGION.creationTimestamp()); + assertEquals(DESCRIPTION, REGION.description()); + assertEquals(REGION_ID.toUrl(), REGION.selfLink()); + assertEquals(STATUS, REGION.status()); + assertEquals(ZONES, REGION.zones()); + assertEquals(QUOTAS, REGION.quotas()); + } + + @Test + public void testToAndFromPb() { + Region region = Region.fromPb(REGION.toPb()); + compareRegions(REGION, region); + assertEquals(REGION_ID.project(), region.regionId().project()); + assertEquals(REGION_ID.region(), region.regionId().region()); + } + + private void compareRegions(Region expected, Region value) { + assertEquals(expected, value); + assertEquals(expected.regionId(), value.regionId()); + assertEquals(expected.id(), value.id()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.selfLink(), value.selfLink()); + assertEquals(expected.status(), value.status()); + assertEquals(expected.zones(), value.zones()); + assertEquals(expected.quotas(), value.quotas()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java new file mode 100644 index 000000000000..2b35be0f8bbb --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java @@ -0,0 +1,157 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotSame; + +import com.google.common.collect.ImmutableList; +import com.google.gcloud.AuthCredentials; +import com.google.gcloud.RetryParams; +import com.google.gcloud.compute.Zone.MaintenanceWindow; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.util.List; + +import org.junit.Test; + +public class SerializationTest { + + private static final Long ID = 42L; + private static final String CREATION_TIMESTAMP = "2016-01-20T04:39:00.210-08:00"; + private static final String DESCRIPTION = "description"; + private static final String VALID_DISK_SIZE = "10GB-10TB"; + private static final Long DEFAULT_DISK_SIZE_GB = 10L; + private static final DiskTypeId DISK_TYPE_ID = DiskTypeId.of("project", "zone", "diskType"); + private static final DiskType DISK_TYPE = DiskType.builder() + .id(ID) + .diskTypeId(DISK_TYPE_ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .validDiskSize(VALID_DISK_SIZE) + .selfLink(DISK_TYPE_ID.toUrl()) + .defaultDiskSizeGb(DEFAULT_DISK_SIZE_GB) + .build(); + private static final MachineTypeId MACHINE_TYPE_ID = MachineTypeId.of("project", "zone", "type"); + private static final Integer GUEST_CPUS = 1; + private static final Integer MEMORY_MB = 2; + private static final List SCRATCH_DISKS = ImmutableList.of(3); + private static final Integer MAXIMUM_PERSISTENT_DISKS = 4; + private static final Long MAXIMUM_PERSISTENT_DISKS_SIZE_GB = 5L; + private static final MachineType MACHINE_TYPE = MachineType.builder() + .id(ID) + .machineTypeId(MACHINE_TYPE_ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .selfLink(MACHINE_TYPE_ID.toUrl()) + .guestCpus(GUEST_CPUS) + .memoryMb(MEMORY_MB) + .scratchDisks(SCRATCH_DISKS) + .maximumPersistentDisks(MAXIMUM_PERSISTENT_DISKS) + .maximumPersistentDisksSizeGb(MAXIMUM_PERSISTENT_DISKS_SIZE_GB) + .build(); + private static final RegionId REGION_ID = RegionId.of("project", "region"); + private static final Region.Status REGION_STATUS = Region.Status.DOWN; + private static final ZoneId ZONE_ID1 = ZoneId.of("project", "zone1"); + private static final ZoneId ZONE_ID2 = ZoneId.of("project", "zone2"); + private static final List ZONES = ImmutableList.of(ZONE_ID1, ZONE_ID2); + private static final Region.Quota QUOTA1 = + new Region.Quota("METRIC1", 2, 1); + private static final Region.Quota QUOTA2 = + new Region.Quota("METRIC2", 4, 3); + private static final List QUOTAS = ImmutableList.of(QUOTA1, QUOTA2); + private static final Region REGION = Region.builder() + .regionId(REGION_ID) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .selfLink(REGION_ID.toUrl()) + .status(REGION_STATUS) + .zones(ZONES) + .quotas(QUOTAS) + .build(); + private static final ZoneId ZONE_ID = ZoneId.of("project", "zone"); + private static final Zone.Status ZONE_STATUS = Zone.Status.DOWN; + private static final MaintenanceWindow WINDOW1 = new MaintenanceWindow("NAME1", "DESCRIPTION1", + "2016-01-20T04:39:00.210-08:00", "2016-01-21T04:39:00.210-08:00"); + private static final MaintenanceWindow WINDOW2 = new MaintenanceWindow("NAME2", "DESCRIPTION2", + "2016-01-21T04:39:00.210-08:00", "2016-01-22T04:39:00.210-08:00"); + private static final List WINDOWS = ImmutableList.of(WINDOW1, WINDOW2); + private static final Zone ZONE = Zone.builder() + .zoneId(ZONE_ID) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .selfLink(ZONE_ID.toUrl()) + .status(ZONE_STATUS) + .maintenanceWindows(WINDOWS) + .region(REGION_ID) + .build(); + private static final LicenseId LICENSE_ID = LicenseId.of("project", "license"); + private static final Boolean CHARGES_USE_FEE = true; + private static final String SELF_LINK = LICENSE_ID.toUrl(); + private static final License LICENSE = new License(LICENSE_ID, CHARGES_USE_FEE, SELF_LINK); + + @Test + public void testServiceOptions() throws Exception { + ComputeOptions options = ComputeOptions.builder() + .projectId("p1") + .authCredentials(AuthCredentials.createForAppEngine()) + .build(); + ComputeOptions serializedCopy = serializeAndDeserialize(options); + assertEquals(options, serializedCopy); + + options = options.toBuilder() + .projectId("p2") + .retryParams(RetryParams.defaultInstance()) + .authCredentials(null) + .build(); + serializedCopy = serializeAndDeserialize(options); + assertEquals(options, serializedCopy); + } + + @Test + public void testModelAndRequests() throws Exception { + Serializable[] objects = {DISK_TYPE_ID, DISK_TYPE, MACHINE_TYPE_ID, MACHINE_TYPE, REGION_ID, + REGION, ZONE_ID, ZONE, LICENSE_ID, LICENSE}; + for (Serializable obj : objects) { + Object copy = serializeAndDeserialize(obj); + assertEquals(obj, obj); + assertEquals(obj, copy); + assertNotSame(obj, copy); + assertEquals(copy, copy); + } + } + + @SuppressWarnings("unchecked") + private T serializeAndDeserialize(T obj) + throws IOException, ClassNotFoundException { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + try (ObjectOutputStream output = new ObjectOutputStream(bytes)) { + output.writeObject(obj); + } + try (ObjectInputStream input = + new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray()))) { + return (T) input.readObject(); + } + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java new file mode 100644 index 000000000000..5722036db1b4 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Test; + +public class ZoneIdTest { + + private static final String PROJECT = "project"; + private static final String ZONE = "zone"; + private static final String URL = + "https://www.googleapis.com/compute/v1/projects/project/zones/zone"; + + @Test + public void testOf() { + ZoneId zoneId = ZoneId.of(PROJECT, ZONE); + assertEquals(PROJECT, zoneId.project()); + assertEquals(ZONE, zoneId.zone()); + assertEquals(URL, zoneId.toUrl()); + zoneId = ZoneId.of(ZONE); + assertNull(zoneId.project()); + assertEquals(ZONE, zoneId.zone()); + } + + @Test + public void testToAndFromUrl() { + ZoneId zoneId = ZoneId.of(PROJECT, ZONE); + compareZoneId(zoneId, ZoneId.fromUrl(zoneId.toUrl())); + } + + @Test + public void testSetProjectId() { + ZoneId zoneId = ZoneId.of(PROJECT, ZONE); + compareZoneId(zoneId, ZoneId.of(ZONE).setProjectId(PROJECT)); + } + + private void compareZoneId(ZoneId expected, ZoneId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.zone(), expected.zone()); + assertEquals(expected.toUrl(), expected.toUrl()); + assertEquals(expected.hashCode(), expected.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java new file mode 100644 index 000000000000..02ab2574cd70 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java @@ -0,0 +1,86 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; + +import com.google.common.collect.ImmutableList; +import com.google.gcloud.compute.Zone.MaintenanceWindow; + +import org.junit.Test; + +import java.util.List; + +public class ZoneTest { + + private static final ZoneId ZONE_ID = ZoneId.of("project", "zone"); + private static final RegionId REGION_ID = RegionId.of("project", "region"); + private static final Long ID = 42L; + private static final String CREATION_TIMESTAMP = "2016-01-20T04:39:00.210-08:00"; + private static final String DESCRIPTION = "description"; + private static final Zone.Status STATUS = Zone.Status.DOWN; + private static final MaintenanceWindow WINDOW1 = new MaintenanceWindow("NAME1", "DESCRIPTION1", + "2016-01-20T04:39:00.210-08:00", "2016-01-21T04:39:00.210-08:00"); + private static final MaintenanceWindow WINDOW2 = new MaintenanceWindow("NAME2", "DESCRIPTION2", + "2016-01-21T04:39:00.210-08:00", "2016-01-22T04:39:00.210-08:00"); + private static final List WINDOWS = ImmutableList.of(WINDOW1, WINDOW2); + private static final Zone ZONE = Zone.builder() + .zoneId(ZONE_ID) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .selfLink(ZONE_ID.toUrl()) + .status(STATUS) + .maintenanceWindows(WINDOWS) + .region(REGION_ID) + .build(); + + @Test + public void testBuilder() { + assertEquals(REGION_ID, ZONE.region()); + assertEquals(ID, ZONE.id()); + assertEquals(CREATION_TIMESTAMP, ZONE.creationTimestamp()); + assertEquals(DESCRIPTION, ZONE.description()); + assertEquals(ZONE_ID.toUrl(), ZONE.selfLink()); + assertEquals(STATUS, ZONE.status()); + assertEquals(WINDOWS, ZONE.maintenanceWindows()); + assertEquals(REGION_ID, ZONE.region()); + } + + @Test + public void testToAndFromPb() { + com.google.api.services.compute.model.Zone zonePb = ZONE.toPb(); + assertEquals(REGION_ID.toUrl(), zonePb.getRegion()); + Zone zone = Zone.fromPb(zonePb); + compareZones(ZONE, zone); + assertEquals(ZONE_ID.project(), zone.zoneId().project()); + assertEquals(ZONE_ID.zone(), zone.zoneId().zone()); + } + + private void compareZones(Zone expected, Zone value) { + assertEquals(expected, value); + assertEquals(expected.zoneId(), value.zoneId()); + assertEquals(expected.id(), value.id()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.selfLink(), value.selfLink()); + assertEquals(expected.status(), value.status()); + assertEquals(expected.maintenanceWindows(), value.maintenanceWindows()); + assertEquals(expected.region(), value.region()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} From c9f028e46c53e99dc7bace55874967a81284bca5 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 22 Feb 2016 23:01:35 +0100 Subject: [PATCH 273/375] Add DeprecationStatus to disk and machine type, other fixes --- gcloud-java-compute/README.md | 4 +- gcloud-java-compute/pom.xml | 2 +- .../gcloud/compute/DeprecationStatus.java | 162 ++++++++++++++++++ .../com/google/gcloud/compute/DiskType.java | 36 +++- .../com/google/gcloud/compute/DiskTypeId.java | 16 +- .../com/google/gcloud/compute/License.java | 4 +- .../com/google/gcloud/compute/LicenseId.java | 2 +- .../google/gcloud/compute/MachineType.java | 42 ++++- .../google/gcloud/compute/MachineTypeId.java | 18 +- .../com/google/gcloud/compute/Region.java | 15 +- .../com/google/gcloud/compute/RegionId.java | 4 +- .../java/com/google/gcloud/compute/Zone.java | 21 +-- .../com/google/gcloud/compute/ZoneId.java | 2 +- .../gcloud/compute/DeprecationStatusTest.java | 78 +++++++++ .../google/gcloud/compute/DiskTypeIdTest.java | 3 + .../google/gcloud/compute/DiskTypeTest.java | 26 ++- .../google/gcloud/compute/LicenseIdTest.java | 2 + .../gcloud/compute/MachineTypeIdTest.java | 2 + .../gcloud/compute/MachineTypeTest.java | 11 +- .../google/gcloud/compute/RegionIdTest.java | 2 + .../gcloud/compute/SerializationTest.java | 12 +- .../com/google/gcloud/compute/ZoneIdTest.java | 2 + 22 files changed, 415 insertions(+), 51 deletions(-) create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java diff --git a/gcloud-java-compute/README.md b/gcloud-java-compute/README.md index aef53c781c20..653a586d76e6 100644 --- a/gcloud-java-compute/README.md +++ b/gcloud-java-compute/README.md @@ -33,7 +33,7 @@ Authentication See the [Authentication](https://github.com/GoogleCloudPlatform/gcloud-java#authentication) section in the base directory's README. -About Google Cloud BigQuery +About Google Cloud Compute -------------------------- [Google Cloud Compute][cloud-compute] delivers virtual machines running in Google's innovative data @@ -65,7 +65,7 @@ Java 7 or above is required for using this client. Testing ------- -This library has tools to help make tests for code using Cloud BigQuery. +This library has tools to help make tests for code using Cloud Compute. See [TESTING] to read more about testing. diff --git a/gcloud-java-compute/pom.xml b/gcloud-java-compute/pom.xml index 70e4f127c119..419c7c4780a2 100644 --- a/gcloud-java-compute/pom.xml +++ b/gcloud-java-compute/pom.xml @@ -24,7 +24,7 @@ com.google.apis google-api-services-compute - v1-rev93-1.21.0 + v1-rev97-1.21.0 compile diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java new file mode 100644 index 000000000000..7b16107c9210 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java @@ -0,0 +1,162 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; + +import java.io.Serializable; +import java.util.Objects; + +/** + * The deprecation status associated to a Google Compute Engine resource. + */ +public final class DeprecationStatus implements Serializable { + + private static final long serialVersionUID = -2695077634793679794L; + + private final String deleted; + private final String deprecated; + private final String obsolete; + private final T replacement; + private final Status status; + + /** + * The deprecation status of a Google Compute Engine resource. + */ + public enum Status { + /** + * Operations that create Google Compute Engine entity using a deprecated resource will return + * successfully but with a warning indicating the deprecation and suggesting a replacement. + */ + DEPRECATED, + /** + * Operations that create Google Compute Engine entity using an obsolete resource will be + * rejected and result in an error. + */ + OBSOLETE, + /** + * Operations that create Google Compute Engine entity using a deleted resource will be + * rejected and result in an error. + */ + DELETED + } + + DeprecationStatus(String deleted, String deprecated, String obsolete, T replacement, + Status status) { + this.deleted = deleted; + this.deprecated = deprecated; + this.obsolete = obsolete; + this.replacement = replacement; + this.status = status; + } + + /** + * Returns an optional RFC3339 timestamp on or after which the deprecation state of this resource + * will be changed to {@link Status#DELETED}. + * + * @see RFC3339 + */ + public String deleted() { + return deleted; + } + + /** + * Returns an optional RFC3339 timestamp on or after which the deprecation state of this resource + * will be changed to {@link Status#DEPRECATED}. + * + * @see RFC3339 + */ + public String deprecated() { + return deprecated; + } + + /** + * Returns an optional RFC3339 timestamp on or after which the deprecation state of this resource + * will be changed to {@link Status#OBSOLETE}. + * + * @see RFC3339 + */ + public String obsolete() { + return obsolete; + } + + /** + * Returns the identity of the suggested replacement for a deprecated resource. The suggested + * replacement resource must be the same kind of resource as the deprecated resource. + */ + public T replacement() { + return replacement; + } + + /** + * Returns the deprecation state of this resource. + */ + public Status status() { + return status; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("deleted", deleted) + .add("deprecated", deprecated) + .add("obsolete", obsolete) + .add("replacement", replacement) + .add("status", status) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(deleted, deprecated, obsolete, replacement, status); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof DeprecationStatus + && Objects.equals(toPb(), ((DeprecationStatus) obj).toPb()); + } + + com.google.api.services.compute.model.DeprecationStatus toPb() { + com.google.api.services.compute.model.DeprecationStatus deprecationStatusPb = + new com.google.api.services.compute.model.DeprecationStatus(); + deprecationStatusPb.setDeleted(deleted); + deprecationStatusPb.setDeprecated(deprecated); + deprecationStatusPb.setObsolete(obsolete); + if (replacement != null) { + deprecationStatusPb.setReplacement(replacement.toUrl()); + } + if (status() != null) { + deprecationStatusPb.setState(status.name()); + } + return deprecationStatusPb; + } + + static DeprecationStatus fromPb( + com.google.api.services.compute.model.DeprecationStatus deprecationStatusPb, + Function fromUrl) { + return new DeprecationStatus( + deprecationStatusPb.getDeleted(), + deprecationStatusPb.getDeprecated(), + deprecationStatusPb.getObsolete(), + deprecationStatusPb.getReplacement() != null + ? fromUrl.apply(deprecationStatusPb.getReplacement()) : null, + deprecationStatusPb.getState() != null + ? Status.valueOf(deprecationStatusPb.getState()) : null); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java index 2cc6cb9bb865..48701cc2a3be 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java @@ -24,8 +24,10 @@ import java.util.Objects; /** - * Google Compute Engine Disk type. A disk type represents the type of disk to use, such as a + * A Google Compute Engine disk type. A disk type represents the type of disk to use, such as * {@code pd-ssd} or {@code pd-standard}. + * + * @see Disk Types */ public final class DiskType implements Serializable { @@ -53,6 +55,7 @@ public com.google.api.services.compute.model.DiskType apply(DiskType diskType) { private final String validDiskSize; private final String selfLink; private final Long defaultDiskSizeGb; + private final DeprecationStatus deprecationStatus; static final class Builder { @@ -63,6 +66,7 @@ static final class Builder { private String validDiskSize; private String selfLink; private Long defaultDiskSizeGb; + private DeprecationStatus deprecationStatus; private Builder() {} @@ -101,9 +105,11 @@ Builder defaultDiskSizeGb(Long defaultDiskSizeGb) { return this; } - /** - * Creates a {@code DiskType} object. - */ + Builder deprecationStatus(DeprecationStatus deprecationStatus) { + this.deprecationStatus = deprecationStatus; + return this; + } + DiskType build() { return new DiskType(this); } @@ -117,6 +123,7 @@ private DiskType(Builder builder) { this.validDiskSize = builder.validDiskSize; this.selfLink = builder.selfLink; this.defaultDiskSizeGb = builder.defaultDiskSizeGb; + this.deprecationStatus = builder.deprecationStatus; } /** @@ -170,6 +177,15 @@ public Long defaultDiskSizeGb() { return defaultDiskSizeGb; } + /** + * Returns the deprecation status of the disk type. If {@link DeprecationStatus#status()} is + * either {@link DeprecationStatus.Status#DELETED} or {@link DeprecationStatus.Status#OBSOLETE} + * the disk type should not be used. Returns {@code null} if the disk type is not deprecated. + */ + public DeprecationStatus deprecationStatus() { + return deprecationStatus; + } + @Override public String toString() { return MoreObjects.toStringHelper(this) @@ -179,12 +195,13 @@ public String toString() { .add("validDiskSize", validDiskSize) .add("selfLink", selfLink) .add("defaultDiskSizeGb", defaultDiskSizeGb) + .add("deprecationStatus", deprecationStatus) .toString(); } @Override public int hashCode() { - return Objects.hash(id); + return Objects.hash(diskTypeId); } @Override @@ -204,6 +221,9 @@ com.google.api.services.compute.model.DiskType toPb() { diskTypePb.setSelfLink(selfLink); diskTypePb.setDefaultDiskSizeGb(defaultDiskSizeGb); diskTypePb.setZone(diskTypeId.zoneId().toUrl()); + if (deprecationStatus != null) { + diskTypePb.setDeprecated(deprecationStatus.toPb()); + } return diskTypePb; } @@ -213,7 +233,7 @@ static Builder builder() { static DiskType fromPb(com.google.api.services.compute.model.DiskType diskTypePb) { Builder builder = builder(); - if (diskTypePb.getId() != null ) { + if (diskTypePb.getId() != null) { builder.id(diskTypePb.getId().longValue()); } builder.creationTimestamp(diskTypePb.getCreationTimestamp()); @@ -222,6 +242,10 @@ static DiskType fromPb(com.google.api.services.compute.model.DiskType diskTypePb builder.validDiskSize(diskTypePb.getValidDiskSize()); builder.selfLink(diskTypePb.getSelfLink()); builder.defaultDiskSizeGb(diskTypePb.getDefaultDiskSizeGb()); + if (diskTypePb.getDeprecated() != null) { + builder.deprecationStatus( + DeprecationStatus.fromPb(diskTypePb.getDeprecated(), DiskTypeId.FROM_URL_FUNCTION)); + } return builder.build(); } } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java index 527f7da124b4..dfaa58b6f481 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java @@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.base.Function; import com.google.common.base.MoreObjects; import java.util.Objects; @@ -27,11 +28,24 @@ */ public final class DiskTypeId extends ZoneResourceId { + static final Function FROM_URL_FUNCTION = new Function() { + @Override + public DiskTypeId apply(String pb) { + return DiskTypeId.fromUrl(pb); + } + }; + static final Function TO_URL_FUNCTION = new Function() { + @Override + public String apply(DiskTypeId diskTypeId) { + return diskTypeId.toUrl(); + } + }; + private static final long serialVersionUID = 7337881474103686219L; private final String diskType; - DiskTypeId(String project, String zone, String diskType) { + private DiskTypeId(String project, String zone, String diskType) { super(project, zone); this.diskType = checkNotNull(diskType); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java index 17e4f0d22be0..5116761a0b2f 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java @@ -26,6 +26,8 @@ /** * A Google Compute Engine License. A License represents a software license. Licenses are used to * track software usage in images, persistent disks, snapshots, and virtual machine instances. + * + * @see Licenses */ public final class License implements Serializable { @@ -74,7 +76,7 @@ public String toString() { @Override public int hashCode() { - return Objects.hash(licenseId, chargesUseFee, selfLink); + return Objects.hash(licenseId); } @Override diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java index f32695e03c03..2fd2b5eb3058 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java @@ -45,7 +45,7 @@ public String apply(LicenseId licenseId) { private final String license; - LicenseId(String project, String license) { + private LicenseId(String project, String license) { super(project); this.license = checkNotNull(license); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java index bf1d6ce49f52..29581852f346 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java @@ -26,7 +26,14 @@ import java.util.List; import java.util.Objects; -public class MachineType implements Serializable { +/** + * A Google Compute Engine machine type. A machine type determine the virtualized hardware + * specifications of your virtual machine instances, such as the amount of memory or number of + * virtual CPUs. + * + * @see Machine Types + */ +public final class MachineType implements Serializable { static final Function FROM_PB_FUNCTION = @@ -57,8 +64,9 @@ public com.google.api.services.compute.model.MachineType apply(MachineType type) private final List scratchDisks; private final Integer maximumPersistentDisks; private final Long maximumPersistentDisksSizeGb; + private final DeprecationStatus deprecationStatus; - public static final class Builder { + static final class Builder { private MachineTypeId machineTypeId; private Long id; @@ -70,9 +78,9 @@ public static final class Builder { private List scratchDisks; private Integer maximumPersistentDisks; private Long maximumPersistentDisksSizeGb; + private DeprecationStatus deprecationStatus; - Builder() {} - + private Builder() {} Builder machineTypeId(MachineTypeId machineTypeId) { this.machineTypeId = machineTypeId; @@ -124,12 +132,17 @@ Builder maximumPersistentDisksSizeGb(Long maximumPersistentDisksSizeGb) { return this; } + Builder deprecationStatus(DeprecationStatus deprecationStatus) { + this.deprecationStatus = deprecationStatus; + return this; + } + MachineType build() { return new MachineType(this); } } - MachineType(Builder builder) { + private MachineType(Builder builder) { this.machineTypeId = builder.machineTypeId; this.id = builder.id; this.creationTimestamp = builder.creationTimestamp; @@ -140,6 +153,7 @@ MachineType build() { this.scratchDisks = builder.scratchDisks; this.maximumPersistentDisks = builder.maximumPersistentDisks; this.maximumPersistentDisksSizeGb = builder.maximumPersistentDisksSizeGb; + this.deprecationStatus = builder.deprecationStatus; } /** @@ -214,6 +228,16 @@ public Long maximumPersistentDisksSizeGb() { return maximumPersistentDisksSizeGb; } + /** + * Returns the deprecation status of the machine type. If {@link DeprecationStatus#status()} is + * either {@link DeprecationStatus.Status#DELETED} or {@link DeprecationStatus.Status#OBSOLETE} + * the machine type should not be used. Returns {@code null} if the machine type is not + * deprecated. + */ + public DeprecationStatus deprecationStatus() { + return deprecationStatus; + } + @Override public String toString() { return MoreObjects.toStringHelper(this) @@ -227,6 +251,7 @@ public String toString() { .add("scratchDisks", scratchDisks) .add("maximumPersistentDisks", maximumPersistentDisks) .add("maximumPersistentDisksSizeGb", maximumPersistentDisksSizeGb) + .add("deprecationStatus", deprecationStatus) .toString(); } @@ -264,6 +289,9 @@ public ScratchDisks apply(Integer diskSize) { machineTypePb.setMaximumPersistentDisks(maximumPersistentDisks); machineTypePb.setMaximumPersistentDisksSizeGb(maximumPersistentDisksSizeGb); machineTypePb.setZone(machineTypeId.zoneId().zone()); + if (deprecationStatus != null) { + machineTypePb.setDeprecated(deprecationStatus.toPb()); + } return machineTypePb; } @@ -293,6 +321,10 @@ public Integer apply(ScratchDisks scratchDiskPb) { } builder.maximumPersistentDisks(machineTypePb.getMaximumPersistentDisks()); builder.maximumPersistentDisksSizeGb(machineTypePb.getMaximumPersistentDisksSizeGb()); + if (machineTypePb.getDeprecated() != null) { + builder.deprecationStatus( + DeprecationStatus.fromPb(machineTypePb.getDeprecated(), MachineTypeId.FROM_URL_FUNCTION)); + } return builder.build(); } } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java index 4a215dd207d3..04073863b814 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java @@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.base.Function; import com.google.common.base.MoreObjects; import java.util.Objects; @@ -27,11 +28,26 @@ */ public final class MachineTypeId extends ZoneResourceId { + static final Function FROM_URL_FUNCTION = + new Function() { + @Override + public MachineTypeId apply(String pb) { + return MachineTypeId.fromUrl(pb); + } + }; + static final Function TO_URL_FUNCTION = + new Function() { + @Override + public String apply(MachineTypeId machineTypeId) { + return machineTypeId.toUrl(); + } + }; + private static final long serialVersionUID = -5819598544478859608L; private final String machineType; - MachineTypeId(String project, String zone, String machineType) { + private MachineTypeId(String project, String zone, String machineType) { super(project, zone); this.machineType = checkNotNull(machineType); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java index ded705bc2a8d..2195d79244ef 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java @@ -18,6 +18,7 @@ import com.google.common.base.Function; import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import java.io.Serializable; @@ -27,6 +28,8 @@ /** * A Google Compute Engine region. + * + * @see Region and Zones */ public final class Region implements Serializable { @@ -58,7 +61,7 @@ public enum Status { /** * A quota assigned to this region. */ - public static class Quota implements Serializable { + public static final class Quota implements Serializable { static final Function FROM_PB_FUNCTION = new Function() { @@ -147,7 +150,7 @@ static Quota fromPb(com.google.api.services.compute.model.Quota quotaPb) { private final List zones; private final List quotas; - public static final class Builder { + static final class Builder { private RegionId regionId; private Long id; @@ -158,7 +161,7 @@ public static final class Builder { private List zones; private List quotas; - Builder() {} + private Builder() {} Builder regionId(RegionId regionId) { this.regionId = regionId; @@ -191,12 +194,12 @@ Builder status(Status status) { } Builder zones(List zones) { - this.zones = zones; + this.zones = ImmutableList.copyOf(zones); return this; } Builder quotas(List quotas) { - this.quotas = quotas; + this.quotas = ImmutableList.copyOf(quotas); return this; } @@ -205,7 +208,7 @@ Region build() { } } - Region(Builder builder) { + private Region(Builder builder) { this.regionId = builder.regionId; this.id = builder.id; this.creationTimestamp = builder.creationTimestamp; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java index 60b603778863..09c81941ee43 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java @@ -31,12 +31,12 @@ public final class RegionId extends ResourceId { private final String region; - RegionId(String project, String region) { + private RegionId(String project, String region) { super(project); this.region = checkNotNull(region); } - RegionId(RegionId regionId) { + private RegionId(RegionId regionId) { super(regionId.project()); this.region = checkNotNull(regionId.region()); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java index b98e863011bb..87bf085cf047 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java @@ -28,6 +28,8 @@ /** * A Google Compute Engine zone. + * + * @see Region and Zones */ public final class Zone implements Serializable { @@ -45,6 +47,7 @@ public com.google.api.services.compute.model.Zone apply(Zone region) { return region.toPb(); } }; + private static final long serialVersionUID = 6113636504417213010L; /** @@ -62,7 +65,7 @@ public enum Status { * @see Maintenance * Windows */ - public static class MaintenanceWindow implements Serializable { + public static final class MaintenanceWindow implements Serializable { static final Function FROM_PB_FUNCTION = new Function() { @@ -145,14 +148,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { - if (!(obj instanceof MaintenanceWindow)) { - return false; - } - MaintenanceWindow other = (MaintenanceWindow) obj; - return Objects.equals(name, other.name) - && Objects.equals(description, other.description) - && Objects.equals(beginTime, other.beginTime) - && Objects.equals(endTime, other.endTime); + return obj instanceof MaintenanceWindow + && Objects.equals(toPb(), ((MaintenanceWindow) obj).toPb()); } MaintenanceWindows toPb() { @@ -178,7 +175,7 @@ static MaintenanceWindow fromPb(MaintenanceWindows windowPb) { private final List maintenanceWindows; private final RegionId region; - public static final class Builder { + static final class Builder { private ZoneId zoneId; private Long id; @@ -189,7 +186,7 @@ public static final class Builder { private List maintenanceWindows; private RegionId region; - Builder() {} + private Builder() {} Builder zoneId(ZoneId zoneId) { this.zoneId = zoneId; @@ -236,7 +233,7 @@ Zone build() { } } - Zone(Builder builder) { + private Zone(Builder builder) { this.zoneId = builder.zoneId; this.id = builder.id; this.creationTimestamp = builder.creationTimestamp; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java index 3637ae302483..14e38c22cad7 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java @@ -45,7 +45,7 @@ public String apply(ZoneId zoneId) { private final String zone; - ZoneId(String project, String zone) { + private ZoneId(String project, String zone) { super(project); this.zone = checkNotNull(zone); } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java new file mode 100644 index 000000000000..32bda09a5bdd --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java @@ -0,0 +1,78 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; + +import com.google.gcloud.compute.DeprecationStatus.Status; + +import org.junit.Test; + +public class DeprecationStatusTest { + + private static final String DELETED = "2016-01-20T04:39:00.210-08:00"; + private static final String DEPRECATED = "2016-01-20T04:37:00.210-08:00"; + private static final String OBSOLETE = "2016-01-20T04:38:00.210-08:00"; + private static final DiskTypeId DISK_TYPE_ID = DiskTypeId.of("project", "zone","diskType"); + private static final MachineTypeId MACHINE_TYPE_ID = + MachineTypeId.of("project", "zone","machineType"); + private static final Status STATUS = Status.DELETED; + private static final DeprecationStatus DISK_TYPE_STATUS = + new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, DISK_TYPE_ID, STATUS); + private static final DeprecationStatus MACHINE_TYPE_STATUS = + new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, MACHINE_TYPE_ID, STATUS); + + @Test + public void testConstructor() { + assertEquals(DELETED, DISK_TYPE_STATUS.deleted()); + assertEquals(DEPRECATED, DISK_TYPE_STATUS.deprecated()); + assertEquals(OBSOLETE, DISK_TYPE_STATUS.obsolete()); + assertEquals(DISK_TYPE_ID, DISK_TYPE_STATUS.replacement()); + assertEquals(STATUS, DISK_TYPE_STATUS.status()); + assertEquals(DELETED, MACHINE_TYPE_STATUS.deleted()); + assertEquals(DEPRECATED, MACHINE_TYPE_STATUS.deprecated()); + assertEquals(OBSOLETE, MACHINE_TYPE_STATUS.obsolete()); + assertEquals(MACHINE_TYPE_ID, MACHINE_TYPE_STATUS.replacement()); + assertEquals(STATUS, MACHINE_TYPE_STATUS.status()); + } + + @Test + public void testToAndFromPb() { + DeprecationStatus diskStatus = + DeprecationStatus.fromPb(DISK_TYPE_STATUS.toPb(), DiskTypeId.FROM_URL_FUNCTION); + compareDeprecationStatus(DISK_TYPE_STATUS, diskStatus); + DeprecationStatus machineStatus = + DeprecationStatus.fromPb(MACHINE_TYPE_STATUS.toPb(), MachineTypeId.FROM_URL_FUNCTION); + compareDeprecationStatus(MACHINE_TYPE_STATUS, machineStatus); + diskStatus = new DeprecationStatus<>(null, DEPRECATED, null, DISK_TYPE_ID, STATUS); + assertEquals(diskStatus, + DeprecationStatus.fromPb(diskStatus.toPb(), DiskTypeId.FROM_URL_FUNCTION)); + machineStatus = new DeprecationStatus<>(null, DEPRECATED, null, MACHINE_TYPE_ID, STATUS); + assertEquals(machineStatus, + DeprecationStatus.fromPb(machineStatus.toPb(), MachineTypeId.FROM_URL_FUNCTION)); + } + + private void compareDeprecationStatus(DeprecationStatus expected, DeprecationStatus value) { + assertEquals(expected, value); + assertEquals(expected.deleted(), value.deleted()); + assertEquals(expected.deprecated(), value.deprecated()); + assertEquals(expected.obsolete(), value.obsolete()); + assertEquals(expected.replacement(), value.replacement()); + assertEquals(expected.status(), value.status()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java index 7bfb28362119..0555f7c1d570 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java @@ -18,6 +18,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import org.junit.Test; @@ -45,12 +46,14 @@ public void testOf() { @Test public void testToAndFromUrl() { DiskTypeId diskTypeId = DiskTypeId.of(PROJECT, ZONE, DISK_TYPE); + assertSame(diskTypeId, diskTypeId.setProjectId(PROJECT)); compareDiskTypeId(diskTypeId, DiskTypeId.fromUrl(diskTypeId.toUrl())); } @Test public void testSetProjectId() { DiskTypeId diskTypeId = DiskTypeId.of(PROJECT, ZONE, DISK_TYPE); + assertSame(diskTypeId, diskTypeId.setProjectId(PROJECT)); compareDiskTypeId(diskTypeId, DiskTypeId.of(ZONE, DISK_TYPE).setProjectId(PROJECT)); } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java index 239c37c49f67..5d486c78cd5c 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java @@ -28,15 +28,22 @@ public class DiskTypeTest { private static final String VALID_DISK_SIZE = "10GB-10TB"; private static final Long DEFAULT_DISK_SIZE_GB = 10L; private static final DiskTypeId DISK_TYPE_ID = DiskTypeId.of("project", "zone", "diskType"); + private static final String DELETED = "2016-01-20T04:39:00.210-08:00"; + private static final String DEPRECATED = "2016-01-20T04:37:00.210-08:00"; + private static final String OBSOLETE = "2016-01-20T04:38:00.210-08:00"; + private static final DeprecationStatus.Status STATUS = DeprecationStatus.Status.DELETED; + private static final DeprecationStatus DEPRECATION_STATUS = + new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, DISK_TYPE_ID, STATUS); private static final DiskType DISK_TYPE = DiskType.builder() - .id(ID) - .diskTypeId(DISK_TYPE_ID) - .creationTimestamp(CREATION_TIMESTAMP) - .description(DESCRIPTION) - .validDiskSize(VALID_DISK_SIZE) - .selfLink(DISK_TYPE_ID.toUrl()) - .defaultDiskSizeGb(DEFAULT_DISK_SIZE_GB) - .build(); + .id(ID) + .diskTypeId(DISK_TYPE_ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .validDiskSize(VALID_DISK_SIZE) + .selfLink(DISK_TYPE_ID.toUrl()) + .defaultDiskSizeGb(DEFAULT_DISK_SIZE_GB) + .deprecationStatus(DEPRECATION_STATUS) + .build(); @Test public void testBuilder() { @@ -47,6 +54,7 @@ public void testBuilder() { assertEquals(VALID_DISK_SIZE, DISK_TYPE.validDiskSize()); assertEquals(DISK_TYPE_ID.toUrl(), DISK_TYPE.selfLink()); assertEquals(DEFAULT_DISK_SIZE_GB, DISK_TYPE.defaultDiskSizeGb()); + assertEquals(DEPRECATION_STATUS, DISK_TYPE.deprecationStatus()); } @Test @@ -61,6 +69,7 @@ public void testToPbAndFromPb() { } private void compareDiskTypes(DiskType expected, DiskType value) { + assertEquals(expected, value); assertEquals(expected.id(), value.id()); assertEquals(expected.diskTypeId(), value.diskTypeId()); assertEquals(expected.creationTimestamp(), value.creationTimestamp()); @@ -68,6 +77,7 @@ private void compareDiskTypes(DiskType expected, DiskType value) { assertEquals(expected.validDiskSize(), value.validDiskSize()); assertEquals(expected.selfLink(), value.selfLink()); assertEquals(expected.defaultDiskSizeGb(), value.defaultDiskSizeGb()); + assertEquals(expected.deprecationStatus(), value.deprecationStatus()); assertEquals(expected.hashCode(), value.hashCode()); } } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java index bf473b8218b6..eb5c40849956 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java @@ -18,6 +18,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import org.junit.Test; @@ -48,6 +49,7 @@ public void testToAndFromUrl() { @Test public void testSetProjectId() { LicenseId licenseId = LicenseId.of(PROJECT, LICENSE); + assertSame(licenseId, licenseId.setProjectId(PROJECT)); compareLicenseId(licenseId, LicenseId.of(LICENSE).setProjectId(PROJECT)); } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java index cb1353487947..34241fb9e3d1 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java @@ -18,6 +18,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import org.junit.Test; @@ -51,6 +52,7 @@ public void testToAndFromUrl() { @Test public void testSetProjectId() { MachineTypeId machineTypeId = MachineTypeId.of(PROJECT, ZONE, TYPE); + assertSame(machineTypeId, machineTypeId.setProjectId(PROJECT)); compareMachineTypeId(machineTypeId, MachineTypeId.of(ZONE, TYPE).setProjectId(PROJECT)); } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java index ff89f2e1a77b..285f4939c5fd 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java @@ -35,6 +35,12 @@ public class MachineTypeTest { private static final List SCRATCH_DISKS = ImmutableList.of(3); private static final Integer MAXIMUM_PERSISTENT_DISKS = 4; private static final Long MAXIMUM_PERSISTENT_DISKS_SIZE_GB = 5L; + private static final String DELETED = "2016-01-20T04:39:00.210-08:00"; + private static final String DEPRECATED = "2016-01-20T04:37:00.210-08:00"; + private static final String OBSOLETE = "2016-01-20T04:38:00.210-08:00"; + private static final DeprecationStatus.Status STATUS = DeprecationStatus.Status.DELETED; + private static final DeprecationStatus DEPRECATION_STATUS = + new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, MACHINE_TYPE_ID, STATUS); private static final MachineType MACHINE_TYPE = MachineType.builder() .id(ID) .machineTypeId(MACHINE_TYPE_ID) @@ -46,6 +52,7 @@ public class MachineTypeTest { .scratchDisks(SCRATCH_DISKS) .maximumPersistentDisks(MAXIMUM_PERSISTENT_DISKS) .maximumPersistentDisksSizeGb(MAXIMUM_PERSISTENT_DISKS_SIZE_GB) + .deprecationStatus(DEPRECATION_STATUS) .build(); @Test @@ -60,6 +67,7 @@ public void testBuilder() { assertEquals(SCRATCH_DISKS, MACHINE_TYPE.scratchDisks()); assertEquals(MAXIMUM_PERSISTENT_DISKS, MACHINE_TYPE.maximumPersistentDisks()); assertEquals(MAXIMUM_PERSISTENT_DISKS_SIZE_GB, MACHINE_TYPE.maximumPersistentDisksSizeGb()); + assertEquals(DEPRECATION_STATUS, MACHINE_TYPE.deprecationStatus()); } @Test @@ -74,7 +82,7 @@ public void testToPbAndFromPb() { } private void compareMachineTypes(MachineType expected, MachineType value) { - assertEquals(expected.id(), value.id()); + assertEquals(expected, value); assertEquals(expected.machineTypeId(), value.machineTypeId()); assertEquals(expected.id(), value.id()); assertEquals(expected.creationTimestamp(), value.creationTimestamp()); @@ -85,6 +93,7 @@ private void compareMachineTypes(MachineType expected, MachineType value) { assertEquals(expected.scratchDisks(), value.scratchDisks()); assertEquals(expected.maximumPersistentDisks(), value.maximumPersistentDisks()); assertEquals(expected.maximumPersistentDisksSizeGb(), value.maximumPersistentDisksSizeGb()); + assertEquals(expected.deprecationStatus(), value.deprecationStatus()); assertEquals(expected.hashCode(), value.hashCode()); } } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java index 7796c9dde66a..74d08aa27ab6 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java @@ -18,6 +18,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import org.junit.Test; @@ -48,6 +49,7 @@ public void testToAndFromUrl() { @Test public void testSetProjectId() { RegionId regionId = RegionId.of(PROJECT, REGION); + assertSame(regionId, regionId.setProjectId(PROJECT)); compareRegionId(regionId, RegionId.of(REGION).setProjectId(PROJECT)); } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java index 2b35be0f8bbb..4ef16bbc0181 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java @@ -24,6 +24,8 @@ import com.google.gcloud.RetryParams; import com.google.gcloud.compute.Zone.MaintenanceWindow; +import org.junit.Test; + import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -32,8 +34,6 @@ import java.io.Serializable; import java.util.List; -import org.junit.Test; - public class SerializationTest { private static final Long ID = 42L; @@ -106,6 +106,12 @@ public class SerializationTest { .maintenanceWindows(WINDOWS) .region(REGION_ID) .build(); + private static final String DELETED = "2016-01-20T04:39:00.210-08:00"; + private static final String DEPRECATED = "2016-01-20T04:37:00.210-08:00"; + private static final String OBSOLETE = "2016-01-20T04:38:00.210-08:00"; + private static final DeprecationStatus DEPRECATION_STATUS = + new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, MACHINE_TYPE_ID, + DeprecationStatus.Status.DELETED); private static final LicenseId LICENSE_ID = LicenseId.of("project", "license"); private static final Boolean CHARGES_USE_FEE = true; private static final String SELF_LINK = LICENSE_ID.toUrl(); @@ -132,7 +138,7 @@ public void testServiceOptions() throws Exception { @Test public void testModelAndRequests() throws Exception { Serializable[] objects = {DISK_TYPE_ID, DISK_TYPE, MACHINE_TYPE_ID, MACHINE_TYPE, REGION_ID, - REGION, ZONE_ID, ZONE, LICENSE_ID, LICENSE}; + REGION, ZONE_ID, ZONE, LICENSE_ID, LICENSE, DEPRECATION_STATUS}; for (Serializable obj : objects) { Object copy = serializeAndDeserialize(obj); assertEquals(obj, obj); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java index 5722036db1b4..5c3ccdac86d0 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java @@ -18,6 +18,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import org.junit.Test; @@ -48,6 +49,7 @@ public void testToAndFromUrl() { @Test public void testSetProjectId() { ZoneId zoneId = ZoneId.of(PROJECT, ZONE); + assertSame(zoneId, zoneId.setProjectId(PROJECT)); compareZoneId(zoneId, ZoneId.of(ZONE).setProjectId(PROJECT)); } From 35fc77d4127abfdd6fe2d7c8121ae7df14449024 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 23 Feb 2016 11:19:43 +0100 Subject: [PATCH 274/375] Migrate IDs from Long to BigInteger --- .../com/google/gcloud/compute/DiskType.java | 16 ++++------ .../google/gcloud/compute/MachineType.java | 16 ++++------ .../com/google/gcloud/compute/Region.java | 32 ++++++++----------- .../java/com/google/gcloud/compute/Zone.java | 30 ++++++++--------- .../google/gcloud/compute/DiskTypeTest.java | 4 ++- .../gcloud/compute/MachineTypeTest.java | 3 +- .../com/google/gcloud/compute/RegionTest.java | 3 +- .../gcloud/compute/SerializationTest.java | 3 +- .../com/google/gcloud/compute/ZoneTest.java | 3 +- 9 files changed, 51 insertions(+), 59 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java index 48701cc2a3be..a9d12fc20813 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java @@ -48,7 +48,7 @@ public com.google.api.services.compute.model.DiskType apply(DiskType diskType) { private static final long serialVersionUID = -944042261695072026L; - private final Long id; + private final BigInteger id; private final DiskTypeId diskTypeId; private final String creationTimestamp; private final String description; @@ -59,7 +59,7 @@ public com.google.api.services.compute.model.DiskType apply(DiskType diskType) { static final class Builder { - private Long id; + private BigInteger id; private DiskTypeId diskTypeId; private String creationTimestamp; private String description; @@ -70,7 +70,7 @@ static final class Builder { private Builder() {} - Builder id(Long id) { + Builder id(BigInteger id) { this.id = id; return this; } @@ -145,7 +145,7 @@ public DiskTypeId diskTypeId() { /** * Returns an unique identifier for the disk type; defined by the service. */ - public Long id() { + public BigInteger id() { return id; } @@ -212,9 +212,7 @@ public boolean equals(Object obj) { com.google.api.services.compute.model.DiskType toPb() { com.google.api.services.compute.model.DiskType diskTypePb = new com.google.api.services.compute.model.DiskType(); - if (id != null) { - diskTypePb.setId(BigInteger.valueOf(id)); - } + diskTypePb.setId(id); diskTypePb.setCreationTimestamp(creationTimestamp); diskTypePb.setDescription(description); diskTypePb.setValidDiskSize(validDiskSize); @@ -233,9 +231,7 @@ static Builder builder() { static DiskType fromPb(com.google.api.services.compute.model.DiskType diskTypePb) { Builder builder = builder(); - if (diskTypePb.getId() != null) { - builder.id(diskTypePb.getId().longValue()); - } + builder.id(diskTypePb.getId()); builder.creationTimestamp(diskTypePb.getCreationTimestamp()); builder.diskTypeId(DiskTypeId.fromUrl(diskTypePb.getSelfLink())); builder.description(diskTypePb.getDescription()); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java index 29581852f346..c6bb7780aba9 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java @@ -55,7 +55,7 @@ public com.google.api.services.compute.model.MachineType apply(MachineType type) private static final long serialVersionUID = -4210962597502860450L; private final MachineTypeId machineTypeId; - private final Long id; + private final BigInteger id; private final String creationTimestamp; private final String description; private final String selfLink; @@ -69,7 +69,7 @@ public com.google.api.services.compute.model.MachineType apply(MachineType type) static final class Builder { private MachineTypeId machineTypeId; - private Long id; + private BigInteger id; private String creationTimestamp; private String description; private String selfLink; @@ -87,7 +87,7 @@ Builder machineTypeId(MachineTypeId machineTypeId) { return this; } - Builder id(Long id) { + Builder id(BigInteger id) { this.id = id; return this; } @@ -166,7 +166,7 @@ public MachineTypeId machineTypeId() { /** * Returns an unique identifier for the machin type; defined by the service. */ - public Long id() { + public BigInteger id() { return id; } @@ -268,9 +268,7 @@ public boolean equals(Object obj) { com.google.api.services.compute.model.MachineType toPb() { com.google.api.services.compute.model.MachineType machineTypePb = new com.google.api.services.compute.model.MachineType(); - if (id != null) { - machineTypePb.setId(BigInteger.valueOf(id)); - } + machineTypePb.setId(id); machineTypePb.setCreationTimestamp(creationTimestamp); machineTypePb.setName(machineTypeId.machineType()); machineTypePb.setDescription(description); @@ -302,9 +300,7 @@ static Builder builder() { static MachineType fromPb(com.google.api.services.compute.model.MachineType machineTypePb) { Builder builder = builder(); builder.machineTypeId(MachineTypeId.fromUrl(machineTypePb.getSelfLink())); - if (machineTypePb.getId() != null) { - builder.id(machineTypePb.getId().longValue()); - } + builder.id(machineTypePb.getId()); builder.creationTimestamp(machineTypePb.getCreationTimestamp()); builder.description(machineTypePb.getDescription()); builder.selfLink(machineTypePb.getSelfLink()); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java index 2195d79244ef..b6e490482396 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java @@ -50,6 +50,15 @@ public com.google.api.services.compute.model.Region apply(Region region) { private static final long serialVersionUID = -3578710133393645135L; + private final RegionId regionId; + private final BigInteger id; + private final String creationTimestamp; + private final String description; + private final String selfLink; + private final Status status; + private final List zones; + private final List quotas; + /** * Status of the region. */ @@ -141,19 +150,10 @@ static Quota fromPb(com.google.api.services.compute.model.Quota quotaPb) { } } - private final RegionId regionId; - private final Long id; - private final String creationTimestamp; - private final String description; - private final String selfLink; - private final Status status; - private final List zones; - private final List quotas; - static final class Builder { private RegionId regionId; - private Long id; + private BigInteger id; private String creationTimestamp; private String description; private String selfLink; @@ -168,7 +168,7 @@ Builder regionId(RegionId regionId) { return this; } - Builder id(Long id) { + Builder id(BigInteger id) { this.id = id; return this; } @@ -223,7 +223,7 @@ public RegionId regionId() { return regionId; } - public Long id() { + public BigInteger id() { return id; } @@ -278,9 +278,7 @@ public boolean equals(Object obj) { com.google.api.services.compute.model.Region toPb() { com.google.api.services.compute.model.Region regionPb = new com.google.api.services.compute.model.Region(); - if (id != null) { - regionPb.setId(BigInteger.valueOf(id)); - } + regionPb.setId(id); regionPb.setCreationTimestamp(creationTimestamp); regionPb.setName(regionId.region()); regionPb.setDescription(description); @@ -302,9 +300,7 @@ static Builder builder() { static Region fromPb(com.google.api.services.compute.model.Region regionPb) { Builder builder = builder(); builder.regionId(RegionId.fromUrl(regionPb.getSelfLink())); - if (regionPb.getId() != null) { - builder.id(regionPb.getId().longValue()); - } + builder.id(regionPb.getId()); builder.creationTimestamp(regionPb.getCreationTimestamp()); builder.description(regionPb.getDescription()); builder.selfLink(regionPb.getSelfLink()); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java index 87bf085cf047..bb494477bf53 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java @@ -50,6 +50,15 @@ public com.google.api.services.compute.model.Zone apply(Zone region) { private static final long serialVersionUID = 6113636504417213010L; + private final ZoneId zoneId; + private final BigInteger id; + private final String creationTimestamp; + private final String description; + private final String selfLink; + private final Status status; + private final List maintenanceWindows; + private final RegionId region; + /** * Status of the region. */ @@ -166,19 +175,10 @@ static MaintenanceWindow fromPb(MaintenanceWindows windowPb) { } } - private final ZoneId zoneId; - private final Long id; - private final String creationTimestamp; - private final String description; - private final String selfLink; - private final Status status; - private final List maintenanceWindows; - private final RegionId region; - static final class Builder { private ZoneId zoneId; - private Long id; + private BigInteger id; private String creationTimestamp; private String description; private String selfLink; @@ -193,7 +193,7 @@ Builder zoneId(ZoneId zoneId) { return this; } - Builder id(Long id) { + Builder id(BigInteger id) { this.id = id; return this; } @@ -270,7 +270,7 @@ public String description() { /** * Returns an unique identifier for the zone; defined by the service. */ - public Long id() { + public BigInteger id() { return id; } @@ -333,7 +333,7 @@ public boolean equals(Object obj) { com.google.api.services.compute.model.Zone toPb() { com.google.api.services.compute.model.Zone zonePb = new com.google.api.services.compute.model.Zone(); - zonePb.setId(BigInteger.valueOf(id)); + zonePb.setId(id); zonePb.setCreationTimestamp(creationTimestamp); zonePb.setName(zoneId.zone()); zonePb.setDescription(description); @@ -356,9 +356,7 @@ static Builder builder() { static Zone fromPb(com.google.api.services.compute.model.Zone zonePb) { Builder builder = builder(); builder.zoneId(ZoneId.fromUrl(zonePb.getSelfLink())); - if (zonePb.getId() != null) { - builder.id(zonePb.getId().longValue()); - } + builder.id(zonePb.getId()); builder.creationTimestamp(zonePb.getCreationTimestamp()); builder.description(zonePb.getDescription()); builder.selfLink(zonePb.getSelfLink()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java index 5d486c78cd5c..02dc92d85e93 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java @@ -20,9 +20,11 @@ import org.junit.Test; +import java.math.BigInteger; + public class DiskTypeTest { - private static final Long ID = 42L; + private static final BigInteger ID = BigInteger.valueOf(42L); private static final String CREATION_TIMESTAMP = "2016-01-20T04:39:00.210-08:00"; private static final String DESCRIPTION = "description"; private static final String VALID_DISK_SIZE = "10GB-10TB"; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java index 285f4939c5fd..8c035a15a3c6 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java @@ -22,11 +22,12 @@ import org.junit.Test; +import java.math.BigInteger; import java.util.List; public class MachineTypeTest { - private static final Long ID = 42L; + private static final BigInteger ID = BigInteger.valueOf(42L); private static final String CREATION_TIMESTAMP = "2016-01-20T04:39:00.210-08:00"; private static final String DESCRIPTION = "description"; private static final MachineTypeId MACHINE_TYPE_ID = MachineTypeId.of("project", "zone", "type"); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java index 45b93730d84f..fafd80884c7d 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java @@ -22,12 +22,13 @@ import org.junit.Test; +import java.math.BigInteger; import java.util.List; public class RegionTest { private static final RegionId REGION_ID = RegionId.of("project", "region"); - private static final Long ID = 42L; + private static final BigInteger ID = BigInteger.valueOf(42L); private static final String CREATION_TIMESTAMP = "2016-01-20T04:39:00.210-08:00"; private static final String DESCRIPTION = "description"; private static final Region.Status STATUS = Region.Status.DOWN; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java index 4ef16bbc0181..04f52d9aea17 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java @@ -32,11 +32,12 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; +import java.math.BigInteger; import java.util.List; public class SerializationTest { - private static final Long ID = 42L; + private static final BigInteger ID = BigInteger.valueOf(42L); private static final String CREATION_TIMESTAMP = "2016-01-20T04:39:00.210-08:00"; private static final String DESCRIPTION = "description"; private static final String VALID_DISK_SIZE = "10GB-10TB"; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java index 02ab2574cd70..f0020197d699 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java @@ -23,13 +23,14 @@ import org.junit.Test; +import java.math.BigInteger; import java.util.List; public class ZoneTest { private static final ZoneId ZONE_ID = ZoneId.of("project", "zone"); private static final RegionId REGION_ID = RegionId.of("project", "region"); - private static final Long ID = 42L; + private static final BigInteger ID = BigInteger.valueOf(42L); private static final String CREATION_TIMESTAMP = "2016-01-20T04:39:00.210-08:00"; private static final String DESCRIPTION = "description"; private static final Zone.Status STATUS = Zone.Status.DOWN; From d34490f196965a6b71e7f84b3a43c17de98d30fd Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 24 Feb 2016 11:43:14 +0100 Subject: [PATCH 275/375] Add deprecation status to zone and region --- .../gcloud/compute/DeprecationStatus.java | 8 +-- .../com/google/gcloud/compute/Region.java | 51 +++++++++++++++++++ .../com/google/gcloud/compute/RegionId.java | 14 +++++ .../java/com/google/gcloud/compute/Zone.java | 25 +++++++++ .../gcloud/compute/DeprecationStatusTest.java | 4 +- .../com/google/gcloud/compute/RegionTest.java | 8 +++ .../com/google/gcloud/compute/ZoneTest.java | 8 +++ 7 files changed, 113 insertions(+), 5 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java index 7b16107c9210..1e8c5f98c7e6 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java @@ -40,17 +40,19 @@ public final class DeprecationStatus implements Serializab */ public enum Status { /** - * Operations that create Google Compute Engine entity using a deprecated resource will return + * Operations that create a Google Compute Engine entity using a deprecated resource will return * successfully but with a warning indicating the deprecation and suggesting a replacement. */ DEPRECATED, + /** - * Operations that create Google Compute Engine entity using an obsolete resource will be + * Operations that create a Google Compute Engine entity using an obsolete resource will be * rejected and result in an error. */ OBSOLETE, + /** - * Operations that create Google Compute Engine entity using a deleted resource will be + * Operations that create a Google Compute Engine entity using a deleted resource will be * rejected and result in an error. */ DELETED diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java index b6e490482396..abc8233ac04e 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java @@ -58,6 +58,7 @@ public com.google.api.services.compute.model.Region apply(Region region) { private final Status status; private final List zones; private final List quotas; + private final DeprecationStatus deprecationStatus; /** * Status of the region. @@ -160,6 +161,7 @@ static final class Builder { private Status status; private List zones; private List quotas; + private DeprecationStatus deprecationStatus; private Builder() {} @@ -203,6 +205,11 @@ Builder quotas(List quotas) { return this; } + Builder deprecationStatus(DeprecationStatus deprecationStatus) { + this.deprecationStatus = deprecationStatus; + return this; + } + Region build() { return new Region(this); } @@ -217,40 +224,76 @@ private Region(Builder builder) { this.status = builder.status; this.zones = builder.zones; this.quotas = builder.quotas; + this.deprecationStatus = builder.deprecationStatus; } + /** + * Returns the region's identity. + */ public RegionId regionId() { return regionId; } + /** + * Returns an unique identifier for the region; defined by the service. + */ public BigInteger id() { return id; } + /** + * Returns the creation timestamp in RFC3339 text format. + * + * @see RFC3339 + */ public String creationTimestamp() { return creationTimestamp; } + /** + * Returns an optional textual description of the region. + */ public String description() { return description; } + /** + * Returns a service-defined URL for the region. + */ public String selfLink() { return selfLink; } + /** + * Returns the status of the status. + */ public Status status() { return status; } + /** + * Returns a list of identities of zones available in this region. + */ public List zones() { return zones; } + /** + * Returns quotas assigned to this region. + */ public List quotas() { return quotas; } + /** + * Returns the deprecation status of the region. If {@link DeprecationStatus#status()} is either + * {@link DeprecationStatus.Status#DELETED} or {@link DeprecationStatus.Status#OBSOLETE} the + * region should not be used. Returns {@code null} if the region is not deprecated. + */ + public DeprecationStatus deprecationStatus() { + return deprecationStatus; + } + @Override public String toString() { return MoreObjects.toStringHelper(this) @@ -262,6 +305,7 @@ public String toString() { .add("status", status) .add("zones", zones) .add("quotas", quotas) + .add("deprecationStatus", deprecationStatus) .toString(); } @@ -290,6 +334,9 @@ com.google.api.services.compute.model.Region toPb() { if (quotas != null) { regionPb.setQuotas(Lists.transform(quotas, Quota.TO_PB_FUNCTION)); } + if (deprecationStatus != null) { + regionPb.setDeprecated(deprecationStatus.toPb()); + } return regionPb; } @@ -313,6 +360,10 @@ static Region fromPb(com.google.api.services.compute.model.Region regionPb) { if (regionPb.getQuotas() != null) { builder.quotas(Lists.transform(regionPb.getQuotas(), Quota.FROM_PB_FUNCTION)); } + if (regionPb.getDeprecated() != null) { + builder.deprecationStatus( + DeprecationStatus.fromPb(regionPb.getDeprecated(), RegionId.FROM_URL_FUNCTION)); + } return builder.build(); } } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java index 09c81941ee43..b172b0d46794 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java @@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkNotNull; +import com.google.common.base.Function; import com.google.common.base.MoreObjects.ToStringHelper; import java.util.Objects; @@ -27,6 +28,19 @@ */ public final class RegionId extends ResourceId { + static final Function FROM_URL_FUNCTION = new Function() { + @Override + public RegionId apply(String pb) { + return RegionId.fromUrl(pb); + } + }; + static final Function TO_URL_FUNCTION = new Function() { + @Override + public String apply(RegionId regionId) { + return regionId.toUrl(); + } + }; + private static final long serialVersionUID = 5569092266957249294L; private final String region; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java index bb494477bf53..fb8d974dc618 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java @@ -58,6 +58,7 @@ public com.google.api.services.compute.model.Zone apply(Zone region) { private final Status status; private final List maintenanceWindows; private final RegionId region; + private final DeprecationStatus deprecationStatus; /** * Status of the region. @@ -185,6 +186,7 @@ static final class Builder { private Status status; private List maintenanceWindows; private RegionId region; + private DeprecationStatus deprecationStatus; private Builder() {} @@ -228,6 +230,11 @@ Builder region(RegionId region) { return this; } + Builder deprecationStatus(DeprecationStatus deprecationStatus) { + this.deprecationStatus = deprecationStatus; + return this; + } + Zone build() { return new Zone(this); } @@ -242,6 +249,7 @@ private Zone(Builder builder) { this.status = builder.status; this.maintenanceWindows = builder.maintenanceWindows; this.region = builder.region; + this.deprecationStatus = builder.deprecationStatus; } /** @@ -306,6 +314,15 @@ public RegionId region() { return region; } + /** + * Returns the deprecation status of the zone. If {@link DeprecationStatus#status()} is either + * {@link DeprecationStatus.Status#DELETED} or {@link DeprecationStatus.Status#OBSOLETE} the zone + * should not be used. Returns {@code null} if the zone is not deprecated. + */ + public DeprecationStatus deprecationStatus() { + return deprecationStatus; + } + @Override public String toString() { return MoreObjects.toStringHelper(this) @@ -317,6 +334,7 @@ public String toString() { .add("status", status) .add("maintenanceWindows", maintenanceWindows) .add("region", region) + .add("deprecationStatus", deprecationStatus) .toString(); } @@ -346,6 +364,9 @@ com.google.api.services.compute.model.Zone toPb() { if (region != null) { zonePb.setRegion(region.toUrl()); } + if (deprecationStatus != null) { + zonePb.setDeprecated(deprecationStatus.toPb()); + } return zonePb; } @@ -370,6 +391,10 @@ static Zone fromPb(com.google.api.services.compute.model.Zone zonePb) { if (zonePb.getRegion() != null) { builder.region(RegionId.fromUrl(zonePb.getRegion())); } + if (zonePb.getDeprecated() != null) { + builder.deprecationStatus( + DeprecationStatus.fromPb(zonePb.getDeprecated(), ZoneId.FROM_URL_FUNCTION)); + } return builder.build(); } } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java index 32bda09a5bdd..2b7ec22e36bf 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java @@ -27,9 +27,9 @@ public class DeprecationStatusTest { private static final String DELETED = "2016-01-20T04:39:00.210-08:00"; private static final String DEPRECATED = "2016-01-20T04:37:00.210-08:00"; private static final String OBSOLETE = "2016-01-20T04:38:00.210-08:00"; - private static final DiskTypeId DISK_TYPE_ID = DiskTypeId.of("project", "zone","diskType"); + private static final DiskTypeId DISK_TYPE_ID = DiskTypeId.of("project", "zone", "diskType"); private static final MachineTypeId MACHINE_TYPE_ID = - MachineTypeId.of("project", "zone","machineType"); + MachineTypeId.of("project", "zone", "machineType"); private static final Status STATUS = Status.DELETED; private static final DeprecationStatus DISK_TYPE_STATUS = new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, DISK_TYPE_ID, STATUS); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java index fafd80884c7d..89deed2f1444 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java @@ -40,6 +40,11 @@ public class RegionTest { private static final Region.Quota QUOTA2 = new Region.Quota("METRIC2", 4, 3); private static final List QUOTAS = ImmutableList.of(QUOTA1, QUOTA2); + private static final String DELETED = "2016-01-20T04:39:00.210-08:00"; + private static final String DEPRECATED = "2016-01-20T04:37:00.210-08:00"; + private static final String OBSOLETE = "2016-01-20T04:38:00.210-08:00"; + private static final DeprecationStatus DEPRECATION_STATUS = new DeprecationStatus<>( + DELETED, DEPRECATED, OBSOLETE, REGION_ID, DeprecationStatus.Status.DELETED); private static final Region REGION = Region.builder() .regionId(REGION_ID) .id(ID) @@ -49,6 +54,7 @@ public class RegionTest { .status(STATUS) .zones(ZONES) .quotas(QUOTAS) + .deprecationStatus(DEPRECATION_STATUS) .build(); @Test @@ -61,6 +67,7 @@ public void testBuilder() { assertEquals(STATUS, REGION.status()); assertEquals(ZONES, REGION.zones()); assertEquals(QUOTAS, REGION.quotas()); + assertEquals(DEPRECATION_STATUS, REGION.deprecationStatus()); } @Test @@ -81,6 +88,7 @@ private void compareRegions(Region expected, Region value) { assertEquals(expected.status(), value.status()); assertEquals(expected.zones(), value.zones()); assertEquals(expected.quotas(), value.quotas()); + assertEquals(expected.deprecationStatus(), value.deprecationStatus()); assertEquals(expected.hashCode(), value.hashCode()); } } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java index f0020197d699..3fa2b228382a 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java @@ -39,6 +39,11 @@ public class ZoneTest { private static final MaintenanceWindow WINDOW2 = new MaintenanceWindow("NAME2", "DESCRIPTION2", "2016-01-21T04:39:00.210-08:00", "2016-01-22T04:39:00.210-08:00"); private static final List WINDOWS = ImmutableList.of(WINDOW1, WINDOW2); + private static final String DELETED = "2016-01-20T04:39:00.210-08:00"; + private static final String DEPRECATED = "2016-01-20T04:37:00.210-08:00"; + private static final String OBSOLETE = "2016-01-20T04:38:00.210-08:00"; + private static final DeprecationStatus DEPRECATION_STATUS = new DeprecationStatus<>( + DELETED, DEPRECATED, OBSOLETE, ZONE_ID, DeprecationStatus.Status.DELETED); private static final Zone ZONE = Zone.builder() .zoneId(ZONE_ID) .id(ID) @@ -47,6 +52,7 @@ public class ZoneTest { .selfLink(ZONE_ID.toUrl()) .status(STATUS) .maintenanceWindows(WINDOWS) + .deprecationStatus(DEPRECATION_STATUS) .region(REGION_ID) .build(); @@ -60,6 +66,7 @@ public void testBuilder() { assertEquals(STATUS, ZONE.status()); assertEquals(WINDOWS, ZONE.maintenanceWindows()); assertEquals(REGION_ID, ZONE.region()); + assertEquals(DEPRECATION_STATUS, ZONE.deprecationStatus()); } @Test @@ -82,6 +89,7 @@ private void compareZones(Zone expected, Zone value) { assertEquals(expected.status(), value.status()); assertEquals(expected.maintenanceWindows(), value.maintenanceWindows()); assertEquals(expected.region(), value.region()); + assertEquals(expected.deprecationStatus(), value.deprecationStatus()); assertEquals(expected.hashCode(), value.hashCode()); } } From 785c3fe3a43c2cb4af9a08279b7cf047fa9a71ba Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 24 Feb 2016 12:03:19 +0100 Subject: [PATCH 276/375] Add test for missing fields, fix NPE, minor docs and lint fixes --- gcloud-java-compute/README.md | 3 ++- .../src/main/java/com/google/gcloud/compute/DiskTypeId.java | 4 ++-- .../src/main/java/com/google/gcloud/compute/MachineType.java | 2 +- .../src/main/java/com/google/gcloud/compute/Region.java | 4 +++- .../src/main/java/com/google/gcloud/compute/Zone.java | 4 +++- .../src/test/java/com/google/gcloud/compute/DiskTypeTest.java | 1 - .../test/java/com/google/gcloud/compute/MachineTypeTest.java | 1 - .../src/test/java/com/google/gcloud/compute/RegionTest.java | 2 ++ .../src/test/java/com/google/gcloud/compute/ZoneTest.java | 2 ++ 9 files changed, 15 insertions(+), 8 deletions(-) diff --git a/gcloud-java-compute/README.md b/gcloud-java-compute/README.md index 653a586d76e6..d1909f904095 100644 --- a/gcloud-java-compute/README.md +++ b/gcloud-java-compute/README.md @@ -10,7 +10,8 @@ Java idiomatic client for [Google Cloud Compute] (https://cloud.google.com/compu [![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969) - [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) - + + > Note: This client is a work-in-progress, and may occasionally > make backwards-incompatible changes. diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java index dfaa58b6f481..93ec44b51acf 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java @@ -99,14 +99,14 @@ public static DiskTypeId of(ZoneId zoneId, String diskType) { } /** - * Returns a disk type identity given the zone disk and disk type. + * Returns a disk type identity given the zone and disk type names. */ public static DiskTypeId of(String zone, String diskType) { return of(ZoneId.of(null, zone), diskType); } /** - * Returns a disk type identity given project disk, zone disk and disk type. + * Returns a disk type identity given project disk, zone and disk type names. */ public static DiskTypeId of(String project, String zone, String diskType) { return of(ZoneId.of(project, zone), diskType); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java index c6bb7780aba9..e8ac54094bf8 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java @@ -164,7 +164,7 @@ public MachineTypeId machineTypeId() { } /** - * Returns an unique identifier for the machin type; defined by the service. + * Returns an unique identifier for the machine type; defined by the service. */ public BigInteger id() { return id; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java index abc8233ac04e..8edfd869a2b1 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java @@ -327,7 +327,9 @@ com.google.api.services.compute.model.Region toPb() { regionPb.setName(regionId.region()); regionPb.setDescription(description); regionPb.setSelfLink(selfLink); - regionPb.setStatus(status.name()); + if (status != null) { + regionPb.setStatus(status.name()); + } if (zones != null) { regionPb.setZones(Lists.transform(zones, ZoneId.TO_URL_FUNCTION)); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java index fb8d974dc618..073f7f624dae 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java @@ -356,7 +356,9 @@ com.google.api.services.compute.model.Zone toPb() { zonePb.setName(zoneId.zone()); zonePb.setDescription(description); zonePb.setSelfLink(selfLink); - zonePb.setStatus(status.name()); + if (status != null) { + zonePb.setStatus(status.name()); + } if (maintenanceWindows != null) { zonePb.setMaintenanceWindows( Lists.transform(maintenanceWindows, MaintenanceWindow.TO_PB_FUNCTION)); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java index 02dc92d85e93..bbd3ad5207d3 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java @@ -63,7 +63,6 @@ public void testBuilder() { public void testToPbAndFromPb() { compareDiskTypes(DISK_TYPE, DiskType.fromPb(DISK_TYPE.toPb())); DiskType diskType = DiskType.builder() - .id(ID) .diskTypeId(DISK_TYPE_ID) .selfLink(DISK_TYPE_ID.toUrl()) .build(); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java index 8c035a15a3c6..fffacf28f6e9 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java @@ -75,7 +75,6 @@ public void testBuilder() { public void testToPbAndFromPb() { compareMachineTypes(MACHINE_TYPE, MachineType.fromPb(MACHINE_TYPE.toPb())); MachineType machineType = MachineType.builder() - .id(ID) .machineTypeId(MACHINE_TYPE_ID) .selfLink(MACHINE_TYPE_ID.toUrl()) .build(); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java index 89deed2f1444..94ca163f5b30 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java @@ -76,6 +76,8 @@ public void testToAndFromPb() { compareRegions(REGION, region); assertEquals(REGION_ID.project(), region.regionId().project()); assertEquals(REGION_ID.region(), region.regionId().region()); + region = Region.builder().regionId(REGION_ID).selfLink(REGION_ID.toUrl()).build(); + compareRegions(region, Region.fromPb(region.toPb())); } private void compareRegions(Region expected, Region value) { diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java index 3fa2b228382a..30cefd6b380a 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java @@ -77,6 +77,8 @@ public void testToAndFromPb() { compareZones(ZONE, zone); assertEquals(ZONE_ID.project(), zone.zoneId().project()); assertEquals(ZONE_ID.zone(), zone.zoneId().zone()); + zone = Zone.builder().zoneId(ZONE_ID).selfLink(ZONE_ID.toUrl()).build(); + compareZones(zone, Zone.fromPb(zone.toPb())); } private void compareZones(Zone expected, Zone value) { From feec3f1b7b6e33838a8a0c1e76c82520553af863 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 24 Feb 2016 12:19:22 +0100 Subject: [PATCH 277/375] Add matchesUrl method to identity objects. Add tests --- .../com/google/gcloud/compute/DiskTypeId.java | 12 ++++++++++++ .../com/google/gcloud/compute/LicenseId.java | 12 ++++++++++++ .../com/google/gcloud/compute/MachineTypeId.java | 12 ++++++++++++ .../java/com/google/gcloud/compute/RegionId.java | 11 ++++++++++- .../google/gcloud/compute/RegionResourceId.java | 1 + .../com/google/gcloud/compute/ResourceId.java | 2 ++ .../java/com/google/gcloud/compute/ZoneId.java | 11 ++++++++++- .../google/gcloud/compute/ZoneResourceId.java | 1 + .../google/gcloud/compute/DiskTypeIdTest.java | 16 ++++++++++++++++ .../com/google/gcloud/compute/LicenseIdTest.java | 16 ++++++++++++++++ .../google/gcloud/compute/MachineTypeIdTest.java | 16 ++++++++++++++++ .../com/google/gcloud/compute/RegionIdTest.java | 16 ++++++++++++++++ .../com/google/gcloud/compute/ZoneIdTest.java | 16 ++++++++++++++++ 13 files changed, 140 insertions(+), 2 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java index 93ec44b51acf..c338dfeb10f1 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java @@ -41,6 +41,7 @@ public String apply(DiskTypeId diskTypeId) { } }; + static final String REGEX = ZoneResourceId.REGEX + "diskTypes/[^/]+"; private static final long serialVersionUID = 7337881474103686219L; private final String diskType; @@ -112,7 +113,18 @@ public static DiskTypeId of(String project, String zone, String diskType) { return of(ZoneId.of(project, zone), diskType); } + /** + * Returns {@code true} if the provided string matches the expected format of a disk type URL. + * Returns {@code false} otherwise. + */ + static boolean matchesUrl(String url) { + return url.matches(REGEX); + } + static DiskTypeId fromUrl(String url) { + if (!matchesUrl(url)) { + throw new IllegalArgumentException(url + " is not a valid disk type URL"); + } int projectsIndex = url.indexOf("/projects/"); int zonesIndex = url.indexOf("/zones/"); int diskTypesIndex = url.indexOf("/diskTypes/"); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java index 2fd2b5eb3058..9bbeea639dc4 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java @@ -41,6 +41,7 @@ public String apply(LicenseId licenseId) { } }; + static final String REGEX = ResourceId.REGEX + "global/licenses/[^/]+"; private static final long serialVersionUID = -2239484554024469651L; private final String license; @@ -105,7 +106,18 @@ public static LicenseId of(String project, String license) { return new LicenseId(project, license); } + /** + * Returns {@code true} if the provided string matches the expected format of a license URL. + * Returns {@code false} otherwise. + */ + static boolean matchesUrl(String url) { + return url.matches(REGEX); + } + static LicenseId fromUrl(String url) { + if (!matchesUrl(url)) { + throw new IllegalArgumentException(url + " is not a valid license URL"); + } int projectsIndex = url.indexOf("/projects/"); int licensesIndex = url.indexOf("/global/licenses/"); String project = url.substring(projectsIndex + 10, licensesIndex); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java index 04073863b814..11428f700481 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java @@ -43,6 +43,7 @@ public String apply(MachineTypeId machineTypeId) { } }; + static final String REGEX = ZoneResourceId.REGEX + "machineTypes/[^/]+"; private static final long serialVersionUID = -5819598544478859608L; private final String machineType; @@ -101,7 +102,18 @@ public static MachineTypeId of(String project, String zone, String machineType) return new MachineTypeId(project, zone, machineType); } + /** + * Returns {@code true} if the provided string matches the expected format of a machine type URL. + * Returns {@code false} otherwise. + */ + static boolean matchesUrl(String url) { + return url.matches(REGEX); + } + static MachineTypeId fromUrl(String url) { + if (!matchesUrl(url)) { + throw new IllegalArgumentException(url + " is not a valid machine type URL"); + } int projectsIndex = url.indexOf("/projects/"); int zonesIndex = url.indexOf("/zones/"); int machineTypesIndex = url.indexOf("/machineTypes/"); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java index b172b0d46794..97d31ba09d99 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java @@ -41,6 +41,7 @@ public String apply(RegionId regionId) { } }; + static final String REGEX = ResourceId.REGEX + "regions/[^/]+"; private static final long serialVersionUID = 5569092266957249294L; private final String region; @@ -105,9 +106,17 @@ public static RegionId of(String region) { } /** - * Returns a new region identity given a region URL. + * Returns {@code true} if the provided string matches the expected format of a region URL. + * Returns {@code false} otherwise. */ + static boolean matchesUrl(String url) { + return url.matches(REGEX); + } + static RegionId fromUrl(String url) { + if (!matchesUrl(url)) { + throw new IllegalArgumentException(url + " is not a valid region URL"); + } int projectsIndex = url.indexOf("/projects/"); int regionsIndex = url.indexOf("/regions/"); String project = url.substring(projectsIndex + 10, regionsIndex); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionResourceId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionResourceId.java index 618ae0a9a4e1..63193f54833b 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionResourceId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionResourceId.java @@ -27,6 +27,7 @@ */ public abstract class RegionResourceId extends ResourceId { + static final String REGEX = ResourceId.REGEX + "regions/[^/]+/"; private static final long serialVersionUID = 5569092266957249294L; private final String region; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ResourceId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ResourceId.java index dc69d6ae53b4..aa25c4c2b589 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ResourceId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ResourceId.java @@ -26,6 +26,8 @@ */ public abstract class ResourceId implements Serializable { + static final String REGEX = + "(https?://(www|content).googleapis.com/compute/v1/)?projects/[^/]+/"; private static final long serialVersionUID = -8028734746870421573L; private String project; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java index 14e38c22cad7..bbf55a1c1062 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java @@ -41,6 +41,7 @@ public String apply(ZoneId zoneId) { } }; + static final String REGEX = ResourceId.REGEX + "zones/[^/]+"; private static final long serialVersionUID = -7635391994812946733L; private final String zone; @@ -100,9 +101,17 @@ public static ZoneId of(String zone) { } /** - * Returns a new zone identity given a zone URL. + * Returns {@code true} if the provided string matches the expected format of a zone URL. + * Returns {@code false} otherwise. */ + static boolean matchesUrl(String url) { + return url.matches(REGEX); + } + static ZoneId fromUrl(String url) { + if (!matchesUrl(url)) { + throw new IllegalArgumentException(url + " is not a valid zone URL"); + } int projectsIndex = url.indexOf("/projects/"); int zonesIndex = url.indexOf("/zones/"); String project = url.substring(projectsIndex + 10, zonesIndex); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneResourceId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneResourceId.java index 961ca7cd499b..576ae31aed0c 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneResourceId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneResourceId.java @@ -27,6 +27,7 @@ */ public abstract class ZoneResourceId extends ResourceId { + static final String REGEX = ResourceId.REGEX + "zones/[^/]+/"; private static final long serialVersionUID = -6249546895344926888L; private final String zone; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java index 0555f7c1d570..43be10eb31a3 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java @@ -17,10 +17,14 @@ package com.google.gcloud.compute; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; public class DiskTypeIdTest { @@ -30,6 +34,9 @@ public class DiskTypeIdTest { private static final String URL = "https://www.googleapis.com/compute/v1/projects/project/zones/zone/diskTypes/diskType"; + @Rule + public ExpectedException thrown = ExpectedException.none(); + @Test public void testOf() { DiskTypeId diskTypeId = DiskTypeId.of(PROJECT, ZONE, DISK_TYPE); @@ -48,6 +55,9 @@ public void testToAndFromUrl() { DiskTypeId diskTypeId = DiskTypeId.of(PROJECT, ZONE, DISK_TYPE); assertSame(diskTypeId, diskTypeId.setProjectId(PROJECT)); compareDiskTypeId(diskTypeId, DiskTypeId.fromUrl(diskTypeId.toUrl())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid disk type URL"); + diskTypeId = DiskTypeId.fromUrl("notMatchingUrl"); } @Test @@ -57,6 +67,12 @@ public void testSetProjectId() { compareDiskTypeId(diskTypeId, DiskTypeId.of(ZONE, DISK_TYPE).setProjectId(PROJECT)); } + @Test + public void testMatchesUrl() { + assertTrue(DiskTypeId.matchesUrl(DiskTypeId.of(PROJECT, ZONE, DISK_TYPE).toUrl())); + assertFalse(DiskTypeId.matchesUrl("notMatchingUrl")); + } + private void compareDiskTypeId(DiskTypeId expected, DiskTypeId value) { assertEquals(expected, value); assertEquals(expected.project(), expected.project()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java index eb5c40849956..d3632603b030 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java @@ -17,10 +17,14 @@ package com.google.gcloud.compute; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; public class LicenseIdTest { @@ -29,6 +33,9 @@ public class LicenseIdTest { private static final String URL = "https://www.googleapis.com/compute/v1/projects/project/global/licenses/license"; + @Rule + public ExpectedException thrown = ExpectedException.none(); + @Test public void testOf() { LicenseId licenseId = LicenseId.of(PROJECT, LICENSE); @@ -51,6 +58,15 @@ public void testSetProjectId() { LicenseId licenseId = LicenseId.of(PROJECT, LICENSE); assertSame(licenseId, licenseId.setProjectId(PROJECT)); compareLicenseId(licenseId, LicenseId.of(LICENSE).setProjectId(PROJECT)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid license URL"); + licenseId = LicenseId.fromUrl("notMatchingUrl"); + } + + @Test + public void testMatchesUrl() { + assertTrue(LicenseId.matchesUrl(LicenseId.of(PROJECT, LICENSE).toUrl())); + assertFalse(LicenseId.matchesUrl("notMatchingUrl")); } private void compareLicenseId(LicenseId expected, LicenseId value) { diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java index 34241fb9e3d1..bddb9c21f67a 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java @@ -17,10 +17,14 @@ package com.google.gcloud.compute; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; public class MachineTypeIdTest { @@ -30,6 +34,9 @@ public class MachineTypeIdTest { private static final String URL = "https://www.googleapis.com/compute/v1/projects/project/zones/zone/machineTypes/type"; + @Rule + public ExpectedException thrown = ExpectedException.none(); + @Test public void testOf() { MachineTypeId machineTypeId = MachineTypeId.of(PROJECT, ZONE, TYPE); @@ -47,6 +54,9 @@ public void testOf() { public void testToAndFromUrl() { MachineTypeId machineTypeId = MachineTypeId.of(PROJECT, ZONE, TYPE); compareMachineTypeId(machineTypeId, MachineTypeId.fromUrl(machineTypeId.toUrl())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid machine type URL"); + machineTypeId = MachineTypeId.fromUrl("notMatchingUrl"); } @Test @@ -56,6 +66,12 @@ public void testSetProjectId() { compareMachineTypeId(machineTypeId, MachineTypeId.of(ZONE, TYPE).setProjectId(PROJECT)); } + @Test + public void testMatchesUrl() { + assertTrue(MachineTypeId.matchesUrl(MachineTypeId.of(PROJECT, ZONE, TYPE).toUrl())); + assertFalse(MachineTypeId.matchesUrl("notMatchingUrl")); + } + private void compareMachineTypeId(MachineTypeId expected, MachineTypeId value) { assertEquals(expected, value); assertEquals(expected.project(), expected.project()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java index 74d08aa27ab6..adb94aee08fc 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java @@ -17,10 +17,14 @@ package com.google.gcloud.compute; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; public class RegionIdTest { @@ -29,6 +33,9 @@ public class RegionIdTest { private static final String URL = "https://www.googleapis.com/compute/v1/projects/project/regions/region"; + @Rule + public ExpectedException thrown = ExpectedException.none(); + @Test public void testOf() { RegionId regionId = RegionId.of(PROJECT, REGION); @@ -51,6 +58,15 @@ public void testSetProjectId() { RegionId regionId = RegionId.of(PROJECT, REGION); assertSame(regionId, regionId.setProjectId(PROJECT)); compareRegionId(regionId, RegionId.of(REGION).setProjectId(PROJECT)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid region URL"); + regionId = RegionId.fromUrl("notMatchingUrl"); + } + + @Test + public void testMatchesUrl() { + assertTrue(RegionId.matchesUrl(RegionId.of(PROJECT, REGION).toUrl())); + assertFalse(RegionId.matchesUrl("notMatchingUrl")); } private void compareRegionId(RegionId expected, RegionId value) { diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java index 5c3ccdac86d0..0583e454690d 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java @@ -17,10 +17,14 @@ package com.google.gcloud.compute; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; public class ZoneIdTest { @@ -29,6 +33,9 @@ public class ZoneIdTest { private static final String URL = "https://www.googleapis.com/compute/v1/projects/project/zones/zone"; + @Rule + public ExpectedException thrown = ExpectedException.none(); + @Test public void testOf() { ZoneId zoneId = ZoneId.of(PROJECT, ZONE); @@ -51,6 +58,15 @@ public void testSetProjectId() { ZoneId zoneId = ZoneId.of(PROJECT, ZONE); assertSame(zoneId, zoneId.setProjectId(PROJECT)); compareZoneId(zoneId, ZoneId.of(ZONE).setProjectId(PROJECT)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid zone URL"); + zoneId = ZoneId.fromUrl("notMatchingUrl"); + } + + @Test + public void testMatchesUrl() { + assertTrue(ZoneId.matchesUrl(ZoneId.of(PROJECT, ZONE).toUrl())); + assertFalse(ZoneId.matchesUrl("notMatchingUrl")); } private void compareZoneId(ZoneId expected, ZoneId value) { From 9bd877a2c34667df78a4df244a316d2ee791d86a Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 29 Feb 2016 16:42:46 +0100 Subject: [PATCH 278/375] Refactor Compute immutable resources' identities and classes - Use Pattern and Matcher to parse URLs into identities - Make REGEX private in identity classes - Remove non-necessary javadoc - Change timestamps' type from String to Long - Change id's type from Long to String --- .../gcloud/compute/DeprecationStatus.java | 61 ++++++------ .../com/google/gcloud/compute/DiskType.java | 59 +++++------ .../com/google/gcloud/compute/DiskTypeId.java | 38 +++---- .../com/google/gcloud/compute/License.java | 17 +--- .../com/google/gcloud/compute/LicenseId.java | 34 +++---- .../google/gcloud/compute/MachineType.java | 99 +++++++++---------- .../google/gcloud/compute/MachineTypeId.java | 30 +++--- .../com/google/gcloud/compute/Region.java | 66 ++++++------- .../com/google/gcloud/compute/RegionId.java | 26 ++--- .../gcloud/compute/RegionResourceId.java | 18 ++-- .../com/google/gcloud/compute/ResourceId.java | 19 ++-- .../java/com/google/gcloud/compute/Zone.java | 88 ++++++++--------- .../com/google/gcloud/compute/ZoneId.java | 24 ++--- .../google/gcloud/compute/ZoneResourceId.java | 18 ++-- .../gcloud/compute/DeprecationStatusTest.java | 6 +- .../google/gcloud/compute/DiskTypeIdTest.java | 10 +- .../google/gcloud/compute/DiskTypeTest.java | 18 ++-- .../google/gcloud/compute/LicenseIdTest.java | 10 +- .../google/gcloud/compute/LicenseTest.java | 5 +- .../gcloud/compute/MachineTypeIdTest.java | 10 +- .../gcloud/compute/MachineTypeTest.java | 33 +++---- .../google/gcloud/compute/RegionIdTest.java | 10 +- .../com/google/gcloud/compute/RegionTest.java | 15 ++- .../gcloud/compute/SerializationTest.java | 28 +++--- .../com/google/gcloud/compute/ZoneIdTest.java | 10 +- .../com/google/gcloud/compute/ZoneTest.java | 23 +++-- 26 files changed, 353 insertions(+), 422 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java index 1e8c5f98c7e6..20123d648598 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java @@ -16,6 +16,7 @@ package com.google.gcloud.compute; +import com.google.api.client.util.DateTime; import com.google.common.base.Function; import com.google.common.base.MoreObjects; @@ -24,14 +25,16 @@ /** * The deprecation status associated to a Google Compute Engine resource. + * + * @param The Google Compute Engine resource to which the deprecation status refers to. */ public final class DeprecationStatus implements Serializable { private static final long serialVersionUID = -2695077634793679794L; - private final String deleted; - private final String deprecated; - private final String obsolete; + private final Long deleted; + private final Long deprecated; + private final Long obsolete; private final T replacement; private final Status status; @@ -58,8 +61,7 @@ public enum Status { DELETED } - DeprecationStatus(String deleted, String deprecated, String obsolete, T replacement, - Status status) { + DeprecationStatus(Long deleted, Long deprecated, Long obsolete, T replacement, Status status) { this.deleted = deleted; this.deprecated = deprecated; this.obsolete = obsolete; @@ -68,32 +70,26 @@ public enum Status { } /** - * Returns an optional RFC3339 timestamp on or after which the deprecation state of this resource - * will be changed to {@link Status#DELETED}. - * - * @see RFC3339 + * Returns the timestamp on or after which the deprecation state of this resource will be changed + * to {@link Status#DELETED}. In milliseconds since epoch. */ - public String deleted() { + public Long deleted() { return deleted; } /** - * Returns an optional RFC3339 timestamp on or after which the deprecation state of this resource - * will be changed to {@link Status#DEPRECATED}. - * - * @see RFC3339 + * Returns the timestamp on or after which the deprecation state of this resource will be changed + * to {@link Status#DEPRECATED}. In milliseconds since epoch. */ - public String deprecated() { + public Long deprecated() { return deprecated; } /** - * Returns an optional RFC3339 timestamp on or after which the deprecation state of this resource - * will be changed to {@link Status#OBSOLETE}. - * - * @see RFC3339 + * Returns the timestamp on or after which the deprecation state of this resource will be changed + * to {@link Status#OBSOLETE}. In milliseconds since epoch. */ - public String obsolete() { + public Long obsolete() { return obsolete; } @@ -137,11 +133,17 @@ public boolean equals(Object obj) { com.google.api.services.compute.model.DeprecationStatus toPb() { com.google.api.services.compute.model.DeprecationStatus deprecationStatusPb = new com.google.api.services.compute.model.DeprecationStatus(); - deprecationStatusPb.setDeleted(deleted); - deprecationStatusPb.setDeprecated(deprecated); - deprecationStatusPb.setObsolete(obsolete); + if (deleted != null) { + deprecationStatusPb.setDeleted(new DateTime(deleted).toStringRfc3339()); + } + if (deprecated != null) { + deprecationStatusPb.setDeprecated(new DateTime(deprecated).toStringRfc3339()); + } + if (obsolete != null) { + deprecationStatusPb.setObsolete(new DateTime(obsolete).toStringRfc3339()); + } if (replacement != null) { - deprecationStatusPb.setReplacement(replacement.toUrl()); + deprecationStatusPb.setReplacement(replacement.selfLink()); } if (status() != null) { deprecationStatusPb.setState(status.name()); @@ -152,10 +154,13 @@ com.google.api.services.compute.model.DeprecationStatus toPb() { static DeprecationStatus fromPb( com.google.api.services.compute.model.DeprecationStatus deprecationStatusPb, Function fromUrl) { - return new DeprecationStatus( - deprecationStatusPb.getDeleted(), - deprecationStatusPb.getDeprecated(), - deprecationStatusPb.getObsolete(), + return new DeprecationStatus<>( + deprecationStatusPb.getDeleted() != null + ? DateTime.parseRfc3339(deprecationStatusPb.getDeleted()).getValue() : null, + deprecationStatusPb.getDeprecated() != null + ? DateTime.parseRfc3339(deprecationStatusPb.getDeprecated()).getValue() : null, + deprecationStatusPb.getObsolete() != null + ? DateTime.parseRfc3339(deprecationStatusPb.getObsolete()).getValue() : null, deprecationStatusPb.getReplacement() != null ? fromUrl.apply(deprecationStatusPb.getReplacement()) : null, deprecationStatusPb.getState() != null diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java index a9d12fc20813..f25aa3ac65a4 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java @@ -16,6 +16,7 @@ package com.google.gcloud.compute; +import com.google.api.client.util.DateTime; import com.google.common.base.Function; import com.google.common.base.MoreObjects; @@ -48,34 +49,32 @@ public com.google.api.services.compute.model.DiskType apply(DiskType diskType) { private static final long serialVersionUID = -944042261695072026L; - private final BigInteger id; + private final String id; private final DiskTypeId diskTypeId; - private final String creationTimestamp; + private final Long creationTimestamp; private final String description; private final String validDiskSize; - private final String selfLink; private final Long defaultDiskSizeGb; private final DeprecationStatus deprecationStatus; static final class Builder { - private BigInteger id; + private String id; private DiskTypeId diskTypeId; - private String creationTimestamp; + private Long creationTimestamp; private String description; private String validDiskSize; - private String selfLink; private Long defaultDiskSizeGb; private DeprecationStatus deprecationStatus; private Builder() {} - Builder id(BigInteger id) { + Builder id(String id) { this.id = id; return this; } - Builder creationTimestamp(String creationTimestamp) { + Builder creationTimestamp(Long creationTimestamp) { this.creationTimestamp = creationTimestamp; return this; } @@ -95,11 +94,6 @@ Builder validDiskSize(String validDiskSize) { return this; } - Builder selfLink(String selfLink) { - this.selfLink = selfLink; - return this; - } - Builder defaultDiskSizeGb(Long defaultDiskSizeGb) { this.defaultDiskSizeGb = defaultDiskSizeGb; return this; @@ -121,17 +115,14 @@ private DiskType(Builder builder) { this.diskTypeId = builder.diskTypeId; this.description = builder.description; this.validDiskSize = builder.validDiskSize; - this.selfLink = builder.selfLink; this.defaultDiskSizeGb = builder.defaultDiskSizeGb; this.deprecationStatus = builder.deprecationStatus; } /** - * Returns the creation timestamp in RFC3339 text format. - * - * @see RFC3339 + * Returns the creation timestamp in milliseconds since epoch. */ - public String creationTimestamp() { + public Long creationTimestamp() { return creationTimestamp; } @@ -145,7 +136,7 @@ public DiskTypeId diskTypeId() { /** * Returns an unique identifier for the disk type; defined by the service. */ - public BigInteger id() { + public String id() { return id; } @@ -163,13 +154,6 @@ public String validDiskSize() { return validDiskSize; } - /** - * Returns a service-defined URL for the disk type. - */ - public String selfLink() { - return selfLink; - } - /** * Returns the service-defined default disk size in GB. */ @@ -193,7 +177,6 @@ public String toString() { .add("creationTimestamp", creationTimestamp) .add("description", description) .add("validDiskSize", validDiskSize) - .add("selfLink", selfLink) .add("defaultDiskSizeGb", defaultDiskSizeGb) .add("deprecationStatus", deprecationStatus) .toString(); @@ -212,13 +195,17 @@ public boolean equals(Object obj) { com.google.api.services.compute.model.DiskType toPb() { com.google.api.services.compute.model.DiskType diskTypePb = new com.google.api.services.compute.model.DiskType(); - diskTypePb.setId(id); - diskTypePb.setCreationTimestamp(creationTimestamp); + if (id != null) { + diskTypePb.setId(new BigInteger(id)); + } + if (creationTimestamp != null) { + diskTypePb.setCreationTimestamp(new DateTime(creationTimestamp).toStringRfc3339()); + } diskTypePb.setDescription(description); diskTypePb.setValidDiskSize(validDiskSize); - diskTypePb.setSelfLink(selfLink); + diskTypePb.setSelfLink(diskTypeId.selfLink()); diskTypePb.setDefaultDiskSizeGb(defaultDiskSizeGb); - diskTypePb.setZone(diskTypeId.zoneId().toUrl()); + diskTypePb.setZone(diskTypeId.zoneId().selfLink()); if (deprecationStatus != null) { diskTypePb.setDeprecated(deprecationStatus.toPb()); } @@ -231,12 +218,16 @@ static Builder builder() { static DiskType fromPb(com.google.api.services.compute.model.DiskType diskTypePb) { Builder builder = builder(); - builder.id(diskTypePb.getId()); - builder.creationTimestamp(diskTypePb.getCreationTimestamp()); + if (diskTypePb.getId() != null) { + builder.id(diskTypePb.getId().toString()); + } + if (diskTypePb.getCreationTimestamp() != null) { + builder.creationTimestamp( + DateTime.parseRfc3339(diskTypePb.getCreationTimestamp()).getValue()); + } builder.diskTypeId(DiskTypeId.fromUrl(diskTypePb.getSelfLink())); builder.description(diskTypePb.getDescription()); builder.validDiskSize(diskTypePb.getValidDiskSize()); - builder.selfLink(diskTypePb.getSelfLink()); builder.defaultDiskSizeGb(diskTypePb.getDefaultDiskSizeGb()); if (diskTypePb.getDeprecated() != null) { builder.deprecationStatus( diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java index c338dfeb10f1..cdf1fd42eedc 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java @@ -22,6 +22,8 @@ import com.google.common.base.MoreObjects; import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Identity for a Google Compute Engine disk type. @@ -37,11 +39,12 @@ public DiskTypeId apply(String pb) { static final Function TO_URL_FUNCTION = new Function() { @Override public String apply(DiskTypeId diskTypeId) { - return diskTypeId.toUrl(); + return diskTypeId.selfLink(); } }; - static final String REGEX = ZoneResourceId.REGEX + "diskTypes/[^/]+"; + private static final String REGEX = ZoneResourceId.REGEX + "diskTypes/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); private static final long serialVersionUID = 7337881474103686219L; private final String diskType; @@ -52,21 +55,15 @@ private DiskTypeId(String project, String zone, String diskType) { } /** - * Returns the name of the disk type resource. The name must be 1-63 characters long, and comply - * with RFC1035. Specifically, the name must be 1-63 characters long and match the regular - * expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a - * lowercase letter, and all following characters must be a dash, lowercase letter, or digit, - * except the last character, which cannot be a dash. - * - * @see RFC1035 + * Returns the name of the disk type. */ public String diskType() { return diskType; } @Override - public String toUrl() { - return super.toUrl() + "/diskTypes/" + diskType; + public String selfLink() { + return super.selfLink() + "/diskTypes/" + diskType; } @Override @@ -76,12 +73,14 @@ MoreObjects.ToStringHelper toStringHelper() { @Override public int hashCode() { - return Objects.hash(super.hashCode(), diskType); + return Objects.hash(super.baseHashCode(), diskType); } @Override public boolean equals(Object obj) { - return obj instanceof DiskTypeId && baseEquals((DiskTypeId) obj); + return obj instanceof DiskTypeId + && baseEquals((DiskTypeId) obj) + && Objects.equals(diskType, ((DiskTypeId) obj).diskType); } @Override @@ -118,19 +117,14 @@ public static DiskTypeId of(String project, String zone, String diskType) { * Returns {@code false} otherwise. */ static boolean matchesUrl(String url) { - return url.matches(REGEX); + return PATTERN.matcher(url).matches(); } static DiskTypeId fromUrl(String url) { - if (!matchesUrl(url)) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { throw new IllegalArgumentException(url + " is not a valid disk type URL"); } - int projectsIndex = url.indexOf("/projects/"); - int zonesIndex = url.indexOf("/zones/"); - int diskTypesIndex = url.indexOf("/diskTypes/"); - String project = url.substring(projectsIndex + 10, zonesIndex); - String zone = url.substring(zonesIndex + 7, diskTypesIndex); - String diskType = url.substring(diskTypesIndex + 11, url.length()); - return DiskTypeId.of(project, zone, diskType); + return DiskTypeId.of(matcher.group(1), matcher.group(2), matcher.group(3)); } } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java index 5116761a0b2f..2c6cb4ac9422 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java @@ -35,12 +35,10 @@ public final class License implements Serializable { private final LicenseId licenseId; private final Boolean chargesUseFee; - private final String selfLink; - License(LicenseId licenseId, Boolean chargesUseFee, String selfLink) { + License(LicenseId licenseId, Boolean chargesUseFee) { this.licenseId = checkNotNull(licenseId); this.chargesUseFee = chargesUseFee; - this.selfLink = selfLink; } /** @@ -58,19 +56,11 @@ public Boolean chargesUseFee() { return chargesUseFee; } - /** - * Returns a service-defined URL for the license. - */ - public String selfLink() { - return selfLink; - } - @Override public String toString() { return MoreObjects.toStringHelper(this) .add("licenseId", licenseId) .add("chargesUseFee", chargesUseFee) - .add("selfLink", selfLink) .toString(); } @@ -89,12 +79,11 @@ com.google.api.services.compute.model.License toPb() { new com.google.api.services.compute.model.License(); licensePb.setName(licenseId.license()); licensePb.setChargesUseFee(chargesUseFee); - licensePb.setSelfLink(selfLink); + licensePb.setSelfLink(licenseId.selfLink()); return licensePb; } static License fromPb(com.google.api.services.compute.model.License licensePb) { - return new License(LicenseId.fromUrl(licensePb.getSelfLink()), licensePb.getChargesUseFee(), - licensePb.getSelfLink()); + return new License(LicenseId.fromUrl(licensePb.getSelfLink()), licensePb.getChargesUseFee()); } } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java index 9bbeea639dc4..36d3037bc41b 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java @@ -22,6 +22,8 @@ import com.google.common.base.MoreObjects; import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Identity for a Google Compute Engine license. @@ -37,11 +39,12 @@ public LicenseId apply(String pb) { static final Function TO_URL_FUNCTION = new Function() { @Override public String apply(LicenseId licenseId) { - return licenseId.toUrl(); + return licenseId.selfLink(); } }; - static final String REGEX = ResourceId.REGEX + "global/licenses/[^/]+"; + private static final String REGEX = ResourceId.REGEX + "global/licenses/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); private static final long serialVersionUID = -2239484554024469651L; private final String license; @@ -52,21 +55,15 @@ private LicenseId(String project, String license) { } /** - * Returns the name of the license. The name must be 1-63 characters long, and comply with - * RFC1035. Specifically, the name must be 1-63 characters long and match the regular expression - * {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a lowercase letter, - * and all following characters must be a dash, lowercase letter, or digit, except the last - * character, which cannot be a dash. - * - * @see RFC1035 + * Returns the name of the license. */ public String license() { return license; } @Override - public String toUrl() { - return super.toUrl() + "/global/licenses/" + license; + public String selfLink() { + return super.selfLink() + "/global/licenses/" + license; } @Override @@ -81,7 +78,9 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof LicenseId && baseEquals((LicenseId) obj); + return obj instanceof LicenseId + && baseEquals((LicenseId) obj) + && Objects.equals(license, ((LicenseId) obj).license); } @Override @@ -111,17 +110,14 @@ public static LicenseId of(String project, String license) { * Returns {@code false} otherwise. */ static boolean matchesUrl(String url) { - return url.matches(REGEX); + return PATTERN.matcher(url).matches(); } static LicenseId fromUrl(String url) { - if (!matchesUrl(url)) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { throw new IllegalArgumentException(url + " is not a valid license URL"); } - int projectsIndex = url.indexOf("/projects/"); - int licensesIndex = url.indexOf("/global/licenses/"); - String project = url.substring(projectsIndex + 10, licensesIndex); - String license = url.substring(licensesIndex + 17, url.length()); - return LicenseId.of(project, license); + return LicenseId.of(matcher.group(1), matcher.group(2)); } } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java index e8ac54094bf8..df0109afa1f5 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java @@ -16,6 +16,7 @@ package com.google.gcloud.compute; +import com.google.api.client.util.DateTime; import com.google.api.services.compute.model.MachineType.ScratchDisks; import com.google.common.base.Function; import com.google.common.base.MoreObjects; @@ -55,13 +56,12 @@ public com.google.api.services.compute.model.MachineType apply(MachineType type) private static final long serialVersionUID = -4210962597502860450L; private final MachineTypeId machineTypeId; - private final BigInteger id; - private final String creationTimestamp; + private final String id; + private final Long creationTimestamp; private final String description; - private final String selfLink; - private final Integer guestCpus; + private final Integer cpus; private final Integer memoryMb; - private final List scratchDisks; + private final List scratchDisksSizeGb; private final Integer maximumPersistentDisks; private final Long maximumPersistentDisksSizeGb; private final DeprecationStatus deprecationStatus; @@ -69,13 +69,12 @@ public com.google.api.services.compute.model.MachineType apply(MachineType type) static final class Builder { private MachineTypeId machineTypeId; - private BigInteger id; - private String creationTimestamp; + private String id; + private Long creationTimestamp; private String description; - private String selfLink; - private Integer guestCpus; + private Integer cpus; private Integer memoryMb; - private List scratchDisks; + private List scratchDisksSizeGb; private Integer maximumPersistentDisks; private Long maximumPersistentDisksSizeGb; private DeprecationStatus deprecationStatus; @@ -87,12 +86,12 @@ Builder machineTypeId(MachineTypeId machineTypeId) { return this; } - Builder id(BigInteger id) { + Builder id(String id) { this.id = id; return this; } - Builder creationTimestamp(String creationTimestamp) { + Builder creationTimestamp(Long creationTimestamp) { this.creationTimestamp = creationTimestamp; return this; } @@ -102,13 +101,8 @@ Builder description(String description) { return this; } - Builder selfLink(String selfLink) { - this.selfLink = selfLink; - return this; - } - - Builder guestCpus(Integer guestCpus) { - this.guestCpus = guestCpus; + Builder cpus(Integer cpus) { + this.cpus = cpus; return this; } @@ -117,8 +111,8 @@ Builder memoryMb(Integer memoryMb) { return this; } - Builder scratchDisks(List scratchDisks) { - this.scratchDisks = scratchDisks; + Builder scratchDisksSizeGb(List scratchDisksSizeGb) { + this.scratchDisksSizeGb = scratchDisksSizeGb; return this; } @@ -147,10 +141,9 @@ private MachineType(Builder builder) { this.id = builder.id; this.creationTimestamp = builder.creationTimestamp; this.description = builder.description; - this.selfLink = builder.selfLink; - this.guestCpus = builder.guestCpus; + this.cpus = builder.cpus; this.memoryMb = builder.memoryMb; - this.scratchDisks = builder.scratchDisks; + this.scratchDisksSizeGb = builder.scratchDisksSizeGb; this.maximumPersistentDisks = builder.maximumPersistentDisks; this.maximumPersistentDisksSizeGb = builder.maximumPersistentDisksSizeGb; this.deprecationStatus = builder.deprecationStatus; @@ -166,16 +159,14 @@ public MachineTypeId machineTypeId() { /** * Returns an unique identifier for the machine type; defined by the service. */ - public BigInteger id() { + public String id() { return id; } /** - * Returns the creation timestamp in RFC3339 text format. - * - * @see RFC3339 + * Returns the creation timestamp in milliseconds since epoch. */ - public String creationTimestamp() { + public Long creationTimestamp() { return creationTimestamp; } @@ -186,18 +177,11 @@ public String description() { return description; } - /** - * Returns a service-defined URL for the machine type. - */ - public String selfLink() { - return selfLink; - } - /** * Returns the number of virtual CPUs that are available to the instance. */ - public Integer guestCpus() { - return guestCpus; + public Integer cpus() { + return cpus; } /** @@ -210,8 +194,8 @@ public Integer memoryMb() { /** * Returns the size of all extended scratch disks assigned to the instance, defined in GB. */ - public List scratchDisks() { - return scratchDisks; + public List scratchDisksSizeGb() { + return scratchDisksSizeGb; } /** @@ -245,10 +229,9 @@ public String toString() { .add("id", id) .add("creationTimestamp", creationTimestamp) .add("description", description) - .add("selfLink", selfLink) - .add("guestCpus", guestCpus) + .add("cpus", cpus) .add("memoryMb", memoryMb) - .add("scratchDisks", scratchDisks) + .add("scratchDisksSizeGb", scratchDisksSizeGb) .add("maximumPersistentDisks", maximumPersistentDisks) .add("maximumPersistentDisksSizeGb", maximumPersistentDisksSizeGb) .add("deprecationStatus", deprecationStatus) @@ -268,15 +251,19 @@ public boolean equals(Object obj) { com.google.api.services.compute.model.MachineType toPb() { com.google.api.services.compute.model.MachineType machineTypePb = new com.google.api.services.compute.model.MachineType(); - machineTypePb.setId(id); - machineTypePb.setCreationTimestamp(creationTimestamp); + if (id != null) { + machineTypePb.setId(new BigInteger(id)); + } + if (creationTimestamp != null) { + machineTypePb.setCreationTimestamp(new DateTime(creationTimestamp).toStringRfc3339()); + } machineTypePb.setName(machineTypeId.machineType()); machineTypePb.setDescription(description); - machineTypePb.setSelfLink(selfLink); - machineTypePb.setGuestCpus(guestCpus); + machineTypePb.setSelfLink(machineTypeId.selfLink()); + machineTypePb.setGuestCpus(cpus); machineTypePb.setMemoryMb(memoryMb); - if (scratchDisks != null) { - machineTypePb.setScratchDisks(Lists.transform(scratchDisks, + if (scratchDisksSizeGb != null) { + machineTypePb.setScratchDisks(Lists.transform(scratchDisksSizeGb, new Function() { @Override public ScratchDisks apply(Integer diskSize) { @@ -300,14 +287,18 @@ static Builder builder() { static MachineType fromPb(com.google.api.services.compute.model.MachineType machineTypePb) { Builder builder = builder(); builder.machineTypeId(MachineTypeId.fromUrl(machineTypePb.getSelfLink())); - builder.id(machineTypePb.getId()); - builder.creationTimestamp(machineTypePb.getCreationTimestamp()); + if (machineTypePb.getId() != null) { + builder.id(machineTypePb.getId().toString()); + } + if (machineTypePb.getCreationTimestamp() != null) { + builder.creationTimestamp( + DateTime.parseRfc3339(machineTypePb.getCreationTimestamp()).getValue()); + } builder.description(machineTypePb.getDescription()); - builder.selfLink(machineTypePb.getSelfLink()); - builder.guestCpus(machineTypePb.getGuestCpus()); + builder.cpus(machineTypePb.getGuestCpus()); builder.memoryMb(machineTypePb.getMemoryMb()); if (machineTypePb.getScratchDisks() != null) { - builder.scratchDisks( + builder.scratchDisksSizeGb( Lists.transform(machineTypePb.getScratchDisks(), new Function() { @Override public Integer apply(ScratchDisks scratchDiskPb) { diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java index 11428f700481..1252719e05d7 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java @@ -22,6 +22,8 @@ import com.google.common.base.MoreObjects; import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Identity for a Google Compute Engine machine type. @@ -39,11 +41,12 @@ public MachineTypeId apply(String pb) { new Function() { @Override public String apply(MachineTypeId machineTypeId) { - return machineTypeId.toUrl(); + return machineTypeId.selfLink(); } }; - static final String REGEX = ZoneResourceId.REGEX + "machineTypes/[^/]+"; + private static final String REGEX = ZoneResourceId.REGEX + "machineTypes/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); private static final long serialVersionUID = -5819598544478859608L; private final String machineType; @@ -61,8 +64,8 @@ public String machineType() { } @Override - public String toUrl() { - return super.toUrl() + "/machineTypes/" + machineType; + public String selfLink() { + return super.selfLink() + "/machineTypes/" + machineType; } @Override @@ -72,12 +75,14 @@ MoreObjects.ToStringHelper toStringHelper() { @Override public int hashCode() { - return Objects.hash(super.hashCode(), machineType); + return Objects.hash(baseHashCode(), machineType); } @Override public boolean equals(Object obj) { - return obj instanceof MachineTypeId && baseEquals((MachineTypeId) obj); + return obj instanceof MachineTypeId + && baseEquals((MachineTypeId) obj) + && Objects.equals(machineType, ((MachineTypeId) obj).machineType); } @Override @@ -107,19 +112,14 @@ public static MachineTypeId of(String project, String zone, String machineType) * Returns {@code false} otherwise. */ static boolean matchesUrl(String url) { - return url.matches(REGEX); + return PATTERN.matcher(url).matches(); } static MachineTypeId fromUrl(String url) { - if (!matchesUrl(url)) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { throw new IllegalArgumentException(url + " is not a valid machine type URL"); } - int projectsIndex = url.indexOf("/projects/"); - int zonesIndex = url.indexOf("/zones/"); - int machineTypesIndex = url.indexOf("/machineTypes/"); - String project = url.substring(projectsIndex + 10, zonesIndex); - String zone = url.substring(zonesIndex + 7, machineTypesIndex); - String machineType = url.substring(machineTypesIndex + 14, url.length()); - return MachineTypeId.of(project, zone, machineType); + return MachineTypeId.of(matcher.group(1), matcher.group(2), matcher.group(3)); } } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java index 8edfd869a2b1..add58d8009b0 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java @@ -16,6 +16,7 @@ package com.google.gcloud.compute; +import com.google.api.client.util.DateTime; import com.google.common.base.Function; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; @@ -51,10 +52,9 @@ public com.google.api.services.compute.model.Region apply(Region region) { private static final long serialVersionUID = -3578710133393645135L; private final RegionId regionId; - private final BigInteger id; - private final String creationTimestamp; + private final String id; + private final Long creationTimestamp; private final String description; - private final String selfLink; private final Status status; private final List zones; private final List quotas; @@ -102,14 +102,23 @@ public com.google.api.services.compute.model.Quota apply(Quota quota) { this.usage = usage; } + /** + * Returns the name of the quota metric. + */ public String metric() { return metric; } + /** + * Returns the quota limit for this metric. + */ public double limit() { return limit; } + /** + * Returns the current usage for this quota. + */ public double usage() { return usage; } @@ -154,10 +163,10 @@ static Quota fromPb(com.google.api.services.compute.model.Quota quotaPb) { static final class Builder { private RegionId regionId; - private BigInteger id; - private String creationTimestamp; + private String id; + private Long creationTimestamp; private String description; - private String selfLink; + private Status status; private List zones; private List quotas; @@ -170,12 +179,12 @@ Builder regionId(RegionId regionId) { return this; } - Builder id(BigInteger id) { + Builder id(String id) { this.id = id; return this; } - Builder creationTimestamp(String creationTimestamp) { + Builder creationTimestamp(Long creationTimestamp) { this.creationTimestamp = creationTimestamp; return this; } @@ -185,11 +194,6 @@ Builder description(String description) { return this; } - Builder selfLink(String selfLink) { - this.selfLink = selfLink; - return this; - } - Builder status(Status status) { this.status = status; return this; @@ -220,7 +224,6 @@ private Region(Builder builder) { this.id = builder.id; this.creationTimestamp = builder.creationTimestamp; this.description = builder.description; - this.selfLink = builder.selfLink; this.status = builder.status; this.zones = builder.zones; this.quotas = builder.quotas; @@ -237,16 +240,14 @@ public RegionId regionId() { /** * Returns an unique identifier for the region; defined by the service. */ - public BigInteger id() { + public String id() { return id; } /** - * Returns the creation timestamp in RFC3339 text format. - * - * @see RFC3339 + * Returns the creation timestamp in milliseconds since epoch. */ - public String creationTimestamp() { + public Long creationTimestamp() { return creationTimestamp; } @@ -257,13 +258,6 @@ public String description() { return description; } - /** - * Returns a service-defined URL for the region. - */ - public String selfLink() { - return selfLink; - } - /** * Returns the status of the status. */ @@ -301,7 +295,6 @@ public String toString() { .add("id", id) .add("creationTimestamp", creationTimestamp) .add("description", description) - .add("selfLink", selfLink) .add("status", status) .add("zones", zones) .add("quotas", quotas) @@ -322,11 +315,15 @@ public boolean equals(Object obj) { com.google.api.services.compute.model.Region toPb() { com.google.api.services.compute.model.Region regionPb = new com.google.api.services.compute.model.Region(); - regionPb.setId(id); - regionPb.setCreationTimestamp(creationTimestamp); + if (id != null) { + regionPb.setId(new BigInteger(id)); + } + if (creationTimestamp != null) { + regionPb.setCreationTimestamp(new DateTime(creationTimestamp).toStringRfc3339()); + } regionPb.setName(regionId.region()); regionPb.setDescription(description); - regionPb.setSelfLink(selfLink); + regionPb.setSelfLink(regionId.selfLink()); if (status != null) { regionPb.setStatus(status.name()); } @@ -349,10 +346,13 @@ static Builder builder() { static Region fromPb(com.google.api.services.compute.model.Region regionPb) { Builder builder = builder(); builder.regionId(RegionId.fromUrl(regionPb.getSelfLink())); - builder.id(regionPb.getId()); - builder.creationTimestamp(regionPb.getCreationTimestamp()); + if (regionPb.getId() != null) { + builder.id(regionPb.getId().toString()); + } + if (regionPb.getCreationTimestamp() != null) { + builder.creationTimestamp(DateTime.parseRfc3339(regionPb.getCreationTimestamp()).getValue()); + } builder.description(regionPb.getDescription()); - builder.selfLink(regionPb.getSelfLink()); if (regionPb.getStatus() != null) { builder.status(Status.valueOf(regionPb.getStatus())); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java index 97d31ba09d99..403edd47ce48 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java @@ -22,6 +22,8 @@ import com.google.common.base.MoreObjects.ToStringHelper; import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * A Google Compute Engine region identity. @@ -37,11 +39,12 @@ public RegionId apply(String pb) { static final Function TO_URL_FUNCTION = new Function() { @Override public String apply(RegionId regionId) { - return regionId.toUrl(); + return regionId.selfLink(); } }; - static final String REGEX = ResourceId.REGEX + "regions/[^/]+"; + private static final String REGEX = ResourceId.REGEX + "regions/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); private static final long serialVersionUID = 5569092266957249294L; private final String region; @@ -64,8 +67,8 @@ public final String region() { } @Override - public String toUrl() { - return super.toUrl() + "/regions/" + region; + public String selfLink() { + return super.selfLink() + "/regions/" + region; } @Override @@ -80,7 +83,9 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof RegionId && baseEquals((RegionId) obj); + return obj instanceof RegionId + && baseEquals((RegionId) obj) + && Objects.equals(region, ((RegionId) obj).region); } @Override @@ -110,17 +115,14 @@ public static RegionId of(String region) { * Returns {@code false} otherwise. */ static boolean matchesUrl(String url) { - return url.matches(REGEX); + return PATTERN.matcher(url).matches(); } static RegionId fromUrl(String url) { - if (!matchesUrl(url)) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { throw new IllegalArgumentException(url + " is not a valid region URL"); } - int projectsIndex = url.indexOf("/projects/"); - int regionsIndex = url.indexOf("/regions/"); - String project = url.substring(projectsIndex + 10, regionsIndex); - String region = url.substring(regionsIndex + 9, url.length()); - return RegionId.of(project, region); + return RegionId.of(matcher.group(1), matcher.group(2)); } } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionResourceId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionResourceId.java index 63193f54833b..eeb288b07be1 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionResourceId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionResourceId.java @@ -27,7 +27,7 @@ */ public abstract class RegionResourceId extends ResourceId { - static final String REGEX = ResourceId.REGEX + "regions/[^/]+/"; + static final String REGEX = ResourceId.REGEX + "regions/([^/]+)/"; private static final long serialVersionUID = 5569092266957249294L; private final String region; @@ -57,8 +57,8 @@ public final RegionId regionId() { } @Override - public String toUrl() { - return super.toUrl() + "/regions/" + region; + public String selfLink() { + return super.selfLink() + "/regions/" + region; } @Override @@ -67,14 +67,14 @@ ToStringHelper toStringHelper() { } @Override - public int hashCode() { - return Objects.hash(baseHashCode(), region); + final int baseHashCode() { + return Objects.hash(super.baseHashCode(), region); } @Override - public boolean equals(Object obj) { - return obj != null - && obj.getClass().equals(RegionResourceId.class) - && baseEquals((RegionResourceId) obj); + final boolean baseEquals(ResourceId resourceId) { + return resourceId instanceof RegionResourceId + && super.baseEquals(resourceId) + && Objects.equals(region, ((RegionResourceId) resourceId).region); } } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ResourceId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ResourceId.java index aa25c4c2b589..38e0fe576ac8 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ResourceId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ResourceId.java @@ -26,25 +26,20 @@ */ public abstract class ResourceId implements Serializable { - static final String REGEX = - "(https?://(www|content).googleapis.com/compute/v1/)?projects/[^/]+/"; + static final String REGEX = ".*?projects/([^/]+)/"; + private static final String BASE_URL = "https://www.googleapis.com/compute/v1/projects/"; private static final long serialVersionUID = -8028734746870421573L; - private String project; + private final String project; ResourceId(String project) { this.project = project; } - /** - * Base URL for a resource URL. - */ - private static final String BASE_URL = "https://www.googleapis.com/compute/v1/projects/"; - /** * Returns a fully qualified URL to the entity. */ - public String toUrl() { + public String selfLink() { return BASE_URL + project; } @@ -64,12 +59,12 @@ public String toString() { return toStringHelper().toString(); } - final int baseHashCode() { + int baseHashCode() { return Objects.hash(project); } - final boolean baseEquals(ResourceId resourceId) { - return Objects.equals(toUrl(), resourceId.toUrl()); + boolean baseEquals(ResourceId resourceId) { + return Objects.equals(project, resourceId.project); } abstract ResourceId setProjectId(String projectId); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java index 073f7f624dae..48bb5412b605 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java @@ -16,6 +16,7 @@ package com.google.gcloud.compute; +import com.google.api.client.util.DateTime; import com.google.api.services.compute.model.Zone.MaintenanceWindows; import com.google.common.base.Function; import com.google.common.base.MoreObjects; @@ -51,10 +52,9 @@ public com.google.api.services.compute.model.Zone apply(Zone region) { private static final long serialVersionUID = 6113636504417213010L; private final ZoneId zoneId; - private final BigInteger id; - private final String creationTimestamp; + private final String id; + private final Long creationTimestamp; private final String description; - private final String selfLink; private final Status status; private final List maintenanceWindows; private final RegionId region; @@ -96,13 +96,13 @@ public MaintenanceWindows apply(MaintenanceWindow maintenanceWindow) { private final String name; private final String description; - private final String beginTime; - private final String endTime; + private final Long beginTime; + private final Long endTime; /** * Returns a zone maintenance window object. */ - MaintenanceWindow(String name, String description, String beginTime, String endTime) { + MaintenanceWindow(String name, String description, Long beginTime, Long endTime) { this.name = name; this.description = description; this.beginTime = beginTime; @@ -110,7 +110,7 @@ public MaintenanceWindows apply(MaintenanceWindow maintenanceWindow) { } /** - * Returns the disk of the maintanance window. + * Returns the name of the maintenance window. */ public String name() { return name; @@ -124,20 +124,16 @@ public String description() { } /** - * Returns the starting time of the maintenance window in RFC3339 text format. - * - * @see RFC3339 + * Returns the starting time of the maintenance window in milliseconds since epoch. */ - public String beginTime() { + public Long beginTime() { return beginTime; } /** - * Returns the ending time of the maintenance window in RFC3339 text format. - * - * @see RFC3339 + * Returns the ending time of the maintenance window in milliseconds since epoch. */ - public String endTime() { + public Long endTime() { return endTime; } @@ -166,23 +162,26 @@ MaintenanceWindows toPb() { return new MaintenanceWindows() .setName(name) .setDescription(description) - .setBeginTime(beginTime) - .setEndTime(endTime); + .setBeginTime(beginTime != null ? new DateTime(beginTime).toStringRfc3339() : null) + .setEndTime(endTime != null ? new DateTime(endTime).toStringRfc3339() : null); } static MaintenanceWindow fromPb(MaintenanceWindows windowPb) { return new MaintenanceWindow(windowPb.getName(), windowPb.getDescription(), - windowPb.getBeginTime(), windowPb.getEndTime()); + windowPb.getBeginTime() != null + ? DateTime.parseRfc3339(windowPb.getBeginTime()).getValue() : null, + windowPb.getEndTime() != null + ? DateTime.parseRfc3339(windowPb.getEndTime()).getValue() : null); } } static final class Builder { private ZoneId zoneId; - private BigInteger id; - private String creationTimestamp; + private String id; + private Long creationTimestamp; private String description; - private String selfLink; + private Status status; private List maintenanceWindows; private RegionId region; @@ -195,12 +194,12 @@ Builder zoneId(ZoneId zoneId) { return this; } - Builder id(BigInteger id) { + Builder id(String id) { this.id = id; return this; } - Builder creationTimestamp(String creationTimestamp) { + Builder creationTimestamp(Long creationTimestamp) { this.creationTimestamp = creationTimestamp; return this; } @@ -210,11 +209,6 @@ Builder description(String description) { return this; } - Builder selfLink(String selfLink) { - this.selfLink = selfLink; - return this; - } - Builder status(Status status) { this.status = status; return this; @@ -245,7 +239,6 @@ private Zone(Builder builder) { this.id = builder.id; this.creationTimestamp = builder.creationTimestamp; this.description = builder.description; - this.selfLink = builder.selfLink; this.status = builder.status; this.maintenanceWindows = builder.maintenanceWindows; this.region = builder.region; @@ -260,11 +253,9 @@ public ZoneId zoneId() { } /** - * Returns the creation timestamp in RFC3339 text format. - * - * @see RFC3339 + * Returns the creation timestamp in milliseconds since epoch. */ - public String creationTimestamp() { + public Long creationTimestamp() { return creationTimestamp; } @@ -278,17 +269,10 @@ public String description() { /** * Returns an unique identifier for the zone; defined by the service. */ - public BigInteger id() { + public String id() { return id; } - /** - * Returns a service-defined URL for the zone. - */ - public String selfLink() { - return selfLink; - } - /** * Returns the status of the zone. */ @@ -330,7 +314,6 @@ public String toString() { .add("id", id) .add("creationTimestamp", creationTimestamp) .add("description", description) - .add("selfLink", selfLink) .add("status", status) .add("maintenanceWindows", maintenanceWindows) .add("region", region) @@ -351,11 +334,15 @@ public boolean equals(Object obj) { com.google.api.services.compute.model.Zone toPb() { com.google.api.services.compute.model.Zone zonePb = new com.google.api.services.compute.model.Zone(); - zonePb.setId(id); - zonePb.setCreationTimestamp(creationTimestamp); + if (id != null) { + zonePb.setId(new BigInteger(id)); + } + if (creationTimestamp != null) { + zonePb.setCreationTimestamp(new DateTime(creationTimestamp).toStringRfc3339()); + } zonePb.setName(zoneId.zone()); zonePb.setDescription(description); - zonePb.setSelfLink(selfLink); + zonePb.setSelfLink(zoneId.selfLink()); if (status != null) { zonePb.setStatus(status.name()); } @@ -364,7 +351,7 @@ com.google.api.services.compute.model.Zone toPb() { Lists.transform(maintenanceWindows, MaintenanceWindow.TO_PB_FUNCTION)); } if (region != null) { - zonePb.setRegion(region.toUrl()); + zonePb.setRegion(region.selfLink()); } if (deprecationStatus != null) { zonePb.setDeprecated(deprecationStatus.toPb()); @@ -379,10 +366,13 @@ static Builder builder() { static Zone fromPb(com.google.api.services.compute.model.Zone zonePb) { Builder builder = builder(); builder.zoneId(ZoneId.fromUrl(zonePb.getSelfLink())); - builder.id(zonePb.getId()); - builder.creationTimestamp(zonePb.getCreationTimestamp()); + if (zonePb.getId() != null) { + builder.id(zonePb.getId().toString()); + } + if (zonePb.getCreationTimestamp() != null) { + builder.creationTimestamp(DateTime.parseRfc3339(zonePb.getCreationTimestamp()).getValue()); + } builder.description(zonePb.getDescription()); - builder.selfLink(zonePb.getSelfLink()); if (zonePb.getStatus() != null) { builder.status(Status.valueOf(zonePb.getStatus())); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java index bbf55a1c1062..74ac5be58201 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java @@ -22,6 +22,8 @@ import com.google.common.base.MoreObjects.ToStringHelper; import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * A Google Compute Engine zone identity. @@ -37,11 +39,12 @@ public ZoneId apply(String pb) { static final Function TO_URL_FUNCTION = new Function() { @Override public String apply(ZoneId zoneId) { - return zoneId.toUrl(); + return zoneId.selfLink(); } }; - static final String REGEX = ResourceId.REGEX + "zones/[^/]+"; + private static final String REGEX = ResourceId.REGEX + "zones/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); private static final long serialVersionUID = -7635391994812946733L; private final String zone; @@ -59,8 +62,8 @@ public final String zone() { } @Override - public String toUrl() { - return super.toUrl() + "/zones/" + zone; + public String selfLink() { + return super.selfLink() + "/zones/" + zone; } @Override @@ -75,7 +78,9 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof ZoneId && baseEquals((ZoneId) obj); + return obj instanceof ZoneId + && baseEquals((ZoneId) obj) + && Objects.equals(zone, ((ZoneId) obj).zone); } @Override @@ -109,13 +114,10 @@ static boolean matchesUrl(String url) { } static ZoneId fromUrl(String url) { - if (!matchesUrl(url)) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { throw new IllegalArgumentException(url + " is not a valid zone URL"); } - int projectsIndex = url.indexOf("/projects/"); - int zonesIndex = url.indexOf("/zones/"); - String project = url.substring(projectsIndex + 10, zonesIndex); - String zone = url.substring(zonesIndex + 7, url.length()); - return ZoneId.of(project, zone); + return ZoneId.of(matcher.group(1), matcher.group(2)); } } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneResourceId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneResourceId.java index 576ae31aed0c..60117684c056 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneResourceId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneResourceId.java @@ -27,7 +27,7 @@ */ public abstract class ZoneResourceId extends ResourceId { - static final String REGEX = ResourceId.REGEX + "zones/[^/]+/"; + static final String REGEX = ResourceId.REGEX + "zones/([^/]+)/"; private static final long serialVersionUID = -6249546895344926888L; private final String zone; @@ -57,8 +57,8 @@ public final ZoneId zoneId() { } @Override - public String toUrl() { - return super.toUrl() + "/zones/" + zone; + public String selfLink() { + return super.selfLink() + "/zones/" + zone; } @Override @@ -67,14 +67,14 @@ ToStringHelper toStringHelper() { } @Override - public int hashCode() { - return Objects.hash(baseHashCode(), zone); + final int baseHashCode() { + return Objects.hash(super.baseHashCode(), zone); } @Override - public boolean equals(Object obj) { - return obj != null - && obj.getClass().equals(ZoneResourceId.class) - && baseEquals((RegionResourceId) obj); + final boolean baseEquals(ResourceId resourceId) { + return resourceId instanceof ZoneResourceId + && super.baseEquals(resourceId) + && Objects.equals(zone, ((ZoneResourceId) resourceId).zone); } } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java index 2b7ec22e36bf..e8d29669da7b 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java @@ -24,9 +24,9 @@ public class DeprecationStatusTest { - private static final String DELETED = "2016-01-20T04:39:00.210-08:00"; - private static final String DEPRECATED = "2016-01-20T04:37:00.210-08:00"; - private static final String OBSOLETE = "2016-01-20T04:38:00.210-08:00"; + private static final Long DELETED = 1453293540000L; + private static final Long DEPRECATED = 1453293420000L; + private static final Long OBSOLETE = 1453293480000L; private static final DiskTypeId DISK_TYPE_ID = DiskTypeId.of("project", "zone", "diskType"); private static final MachineTypeId MACHINE_TYPE_ID = MachineTypeId.of("project", "zone", "machineType"); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java index 43be10eb31a3..5ff61d5777ba 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java @@ -43,7 +43,7 @@ public void testOf() { assertEquals(PROJECT, diskTypeId.project()); assertEquals(ZONE, diskTypeId.zone()); assertEquals(DISK_TYPE, diskTypeId.diskType()); - assertEquals(URL, diskTypeId.toUrl()); + assertEquals(URL, diskTypeId.selfLink()); diskTypeId = DiskTypeId.of(ZONE, DISK_TYPE); assertNull(diskTypeId.project()); assertEquals(ZONE, diskTypeId.zone()); @@ -54,10 +54,10 @@ public void testOf() { public void testToAndFromUrl() { DiskTypeId diskTypeId = DiskTypeId.of(PROJECT, ZONE, DISK_TYPE); assertSame(diskTypeId, diskTypeId.setProjectId(PROJECT)); - compareDiskTypeId(diskTypeId, DiskTypeId.fromUrl(diskTypeId.toUrl())); + compareDiskTypeId(diskTypeId, DiskTypeId.fromUrl(diskTypeId.selfLink())); thrown.expect(IllegalArgumentException.class); thrown.expectMessage("notMatchingUrl is not a valid disk type URL"); - diskTypeId = DiskTypeId.fromUrl("notMatchingUrl"); + DiskTypeId.fromUrl("notMatchingUrl"); } @Test @@ -69,7 +69,7 @@ public void testSetProjectId() { @Test public void testMatchesUrl() { - assertTrue(DiskTypeId.matchesUrl(DiskTypeId.of(PROJECT, ZONE, DISK_TYPE).toUrl())); + assertTrue(DiskTypeId.matchesUrl(DiskTypeId.of(PROJECT, ZONE, DISK_TYPE).selfLink())); assertFalse(DiskTypeId.matchesUrl("notMatchingUrl")); } @@ -78,7 +78,7 @@ private void compareDiskTypeId(DiskTypeId expected, DiskTypeId value) { assertEquals(expected.project(), expected.project()); assertEquals(expected.zone(), expected.zone()); assertEquals(expected.diskType(), expected.diskType()); - assertEquals(expected.toUrl(), expected.toUrl()); + assertEquals(expected.selfLink(), expected.selfLink()); assertEquals(expected.hashCode(), expected.hashCode()); } } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java index bbd3ad5207d3..7cacf256523a 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java @@ -24,15 +24,15 @@ public class DiskTypeTest { - private static final BigInteger ID = BigInteger.valueOf(42L); - private static final String CREATION_TIMESTAMP = "2016-01-20T04:39:00.210-08:00"; + private static final String ID = "42"; + private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final String DESCRIPTION = "description"; private static final String VALID_DISK_SIZE = "10GB-10TB"; private static final Long DEFAULT_DISK_SIZE_GB = 10L; private static final DiskTypeId DISK_TYPE_ID = DiskTypeId.of("project", "zone", "diskType"); - private static final String DELETED = "2016-01-20T04:39:00.210-08:00"; - private static final String DEPRECATED = "2016-01-20T04:37:00.210-08:00"; - private static final String OBSOLETE = "2016-01-20T04:38:00.210-08:00"; + private static final Long DELETED = 1453293540000L; + private static final Long DEPRECATED = 1453293420000L; + private static final Long OBSOLETE = 1453293480000L; private static final DeprecationStatus.Status STATUS = DeprecationStatus.Status.DELETED; private static final DeprecationStatus DEPRECATION_STATUS = new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, DISK_TYPE_ID, STATUS); @@ -42,7 +42,6 @@ public class DiskTypeTest { .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .validDiskSize(VALID_DISK_SIZE) - .selfLink(DISK_TYPE_ID.toUrl()) .defaultDiskSizeGb(DEFAULT_DISK_SIZE_GB) .deprecationStatus(DEPRECATION_STATUS) .build(); @@ -54,7 +53,6 @@ public void testBuilder() { assertEquals(CREATION_TIMESTAMP, DISK_TYPE.creationTimestamp()); assertEquals(DESCRIPTION, DISK_TYPE.description()); assertEquals(VALID_DISK_SIZE, DISK_TYPE.validDiskSize()); - assertEquals(DISK_TYPE_ID.toUrl(), DISK_TYPE.selfLink()); assertEquals(DEFAULT_DISK_SIZE_GB, DISK_TYPE.defaultDiskSizeGb()); assertEquals(DEPRECATION_STATUS, DISK_TYPE.deprecationStatus()); } @@ -62,10 +60,7 @@ public void testBuilder() { @Test public void testToPbAndFromPb() { compareDiskTypes(DISK_TYPE, DiskType.fromPb(DISK_TYPE.toPb())); - DiskType diskType = DiskType.builder() - .diskTypeId(DISK_TYPE_ID) - .selfLink(DISK_TYPE_ID.toUrl()) - .build(); + DiskType diskType = DiskType.builder().diskTypeId(DISK_TYPE_ID).build(); compareDiskTypes(diskType, DiskType.fromPb(diskType.toPb())); } @@ -76,7 +71,6 @@ private void compareDiskTypes(DiskType expected, DiskType value) { assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.description(), value.description()); assertEquals(expected.validDiskSize(), value.validDiskSize()); - assertEquals(expected.selfLink(), value.selfLink()); assertEquals(expected.defaultDiskSizeGb(), value.defaultDiskSizeGb()); assertEquals(expected.deprecationStatus(), value.deprecationStatus()); assertEquals(expected.hashCode(), value.hashCode()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java index d3632603b030..d06fd48cff9a 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java @@ -41,7 +41,7 @@ public void testOf() { LicenseId licenseId = LicenseId.of(PROJECT, LICENSE); assertEquals(PROJECT, licenseId.project()); assertEquals(LICENSE, licenseId.license()); - assertEquals(URL, licenseId.toUrl()); + assertEquals(URL, licenseId.selfLink()); licenseId = LicenseId.of(LICENSE); assertNull(licenseId.project()); assertEquals(LICENSE, licenseId.license()); @@ -50,7 +50,7 @@ public void testOf() { @Test public void testToAndFromUrl() { LicenseId licenseId = LicenseId.of(PROJECT, LICENSE); - compareLicenseId(licenseId, LicenseId.fromUrl(licenseId.toUrl())); + compareLicenseId(licenseId, LicenseId.fromUrl(licenseId.selfLink())); } @Test @@ -60,12 +60,12 @@ public void testSetProjectId() { compareLicenseId(licenseId, LicenseId.of(LICENSE).setProjectId(PROJECT)); thrown.expect(IllegalArgumentException.class); thrown.expectMessage("notMatchingUrl is not a valid license URL"); - licenseId = LicenseId.fromUrl("notMatchingUrl"); + LicenseId.fromUrl("notMatchingUrl"); } @Test public void testMatchesUrl() { - assertTrue(LicenseId.matchesUrl(LicenseId.of(PROJECT, LICENSE).toUrl())); + assertTrue(LicenseId.matchesUrl(LicenseId.of(PROJECT, LICENSE).selfLink())); assertFalse(LicenseId.matchesUrl("notMatchingUrl")); } @@ -73,7 +73,7 @@ private void compareLicenseId(LicenseId expected, LicenseId value) { assertEquals(expected, value); assertEquals(expected.project(), expected.project()); assertEquals(expected.license(), expected.license()); - assertEquals(expected.toUrl(), expected.toUrl()); + assertEquals(expected.selfLink(), expected.selfLink()); assertEquals(expected.hashCode(), expected.hashCode()); } } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseTest.java index 450979d8ecc8..c9fb95fab9c6 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseTest.java @@ -24,14 +24,12 @@ public class LicenseTest { private static final LicenseId LICENSE_ID = LicenseId.of("project", "license"); private static final Boolean CHARGES_USE_FEE = true; - private static final String SELF_LINK = LICENSE_ID.toUrl(); - private static final License LICENSE = new License(LICENSE_ID, CHARGES_USE_FEE, SELF_LINK); + private static final License LICENSE = new License(LICENSE_ID, CHARGES_USE_FEE); @Test public void testBuilder() { assertEquals(LICENSE_ID, LICENSE.licenseId()); assertEquals(CHARGES_USE_FEE, LICENSE.chargesUseFee()); - assertEquals(LICENSE_ID.toUrl(), LICENSE.selfLink()); } @Test @@ -46,7 +44,6 @@ private void compareLicenses(License expected, License value) { assertEquals(expected, value); assertEquals(expected.licenseId(), value.licenseId()); assertEquals(expected.chargesUseFee(), value.chargesUseFee()); - assertEquals(expected.selfLink(), value.selfLink()); assertEquals(expected.hashCode(), value.hashCode()); } } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java index bddb9c21f67a..7e3f4d7eae35 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java @@ -43,7 +43,7 @@ public void testOf() { assertEquals(PROJECT, machineTypeId.project()); assertEquals(ZONE, machineTypeId.zone()); assertEquals(TYPE, machineTypeId.machineType()); - assertEquals(URL, machineTypeId.toUrl()); + assertEquals(URL, machineTypeId.selfLink()); machineTypeId = MachineTypeId.of(ZONE, TYPE); assertNull(machineTypeId.project()); assertEquals(ZONE, machineTypeId.zone()); @@ -53,10 +53,10 @@ public void testOf() { @Test public void testToAndFromUrl() { MachineTypeId machineTypeId = MachineTypeId.of(PROJECT, ZONE, TYPE); - compareMachineTypeId(machineTypeId, MachineTypeId.fromUrl(machineTypeId.toUrl())); + compareMachineTypeId(machineTypeId, MachineTypeId.fromUrl(machineTypeId.selfLink())); thrown.expect(IllegalArgumentException.class); thrown.expectMessage("notMatchingUrl is not a valid machine type URL"); - machineTypeId = MachineTypeId.fromUrl("notMatchingUrl"); + MachineTypeId.fromUrl("notMatchingUrl"); } @Test @@ -68,7 +68,7 @@ public void testSetProjectId() { @Test public void testMatchesUrl() { - assertTrue(MachineTypeId.matchesUrl(MachineTypeId.of(PROJECT, ZONE, TYPE).toUrl())); + assertTrue(MachineTypeId.matchesUrl(MachineTypeId.of(PROJECT, ZONE, TYPE).selfLink())); assertFalse(MachineTypeId.matchesUrl("notMatchingUrl")); } @@ -77,7 +77,7 @@ private void compareMachineTypeId(MachineTypeId expected, MachineTypeId value) { assertEquals(expected.project(), expected.project()); assertEquals(expected.zone(), expected.zone()); assertEquals(expected.machineType(), expected.machineType()); - assertEquals(expected.toUrl(), expected.toUrl()); + assertEquals(expected.selfLink(), expected.selfLink()); assertEquals(expected.hashCode(), expected.hashCode()); } } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java index fffacf28f6e9..969b370ddce8 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java @@ -22,23 +22,22 @@ import org.junit.Test; -import java.math.BigInteger; import java.util.List; public class MachineTypeTest { - private static final BigInteger ID = BigInteger.valueOf(42L); - private static final String CREATION_TIMESTAMP = "2016-01-20T04:39:00.210-08:00"; + private static final String ID = "42"; + private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final String DESCRIPTION = "description"; private static final MachineTypeId MACHINE_TYPE_ID = MachineTypeId.of("project", "zone", "type"); - private static final Integer GUEST_CPUS = 1; + private static final Integer CPUS = 1; private static final Integer MEMORY_MB = 2; private static final List SCRATCH_DISKS = ImmutableList.of(3); private static final Integer MAXIMUM_PERSISTENT_DISKS = 4; private static final Long MAXIMUM_PERSISTENT_DISKS_SIZE_GB = 5L; - private static final String DELETED = "2016-01-20T04:39:00.210-08:00"; - private static final String DEPRECATED = "2016-01-20T04:37:00.210-08:00"; - private static final String OBSOLETE = "2016-01-20T04:38:00.210-08:00"; + private static final Long DELETED = 1453293540000L; + private static final Long DEPRECATED = 1453293420000L; + private static final Long OBSOLETE = 1453293480000L; private static final DeprecationStatus.Status STATUS = DeprecationStatus.Status.DELETED; private static final DeprecationStatus DEPRECATION_STATUS = new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, MACHINE_TYPE_ID, STATUS); @@ -47,10 +46,9 @@ public class MachineTypeTest { .machineTypeId(MACHINE_TYPE_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) - .selfLink(MACHINE_TYPE_ID.toUrl()) - .guestCpus(GUEST_CPUS) + .cpus(CPUS) .memoryMb(MEMORY_MB) - .scratchDisks(SCRATCH_DISKS) + .scratchDisksSizeGb(SCRATCH_DISKS) .maximumPersistentDisks(MAXIMUM_PERSISTENT_DISKS) .maximumPersistentDisksSizeGb(MAXIMUM_PERSISTENT_DISKS_SIZE_GB) .deprecationStatus(DEPRECATION_STATUS) @@ -62,10 +60,9 @@ public void testBuilder() { assertEquals(MACHINE_TYPE_ID, MACHINE_TYPE.machineTypeId()); assertEquals(CREATION_TIMESTAMP, MACHINE_TYPE.creationTimestamp()); assertEquals(DESCRIPTION, MACHINE_TYPE.description()); - assertEquals(MACHINE_TYPE_ID.toUrl(), MACHINE_TYPE.selfLink()); - assertEquals(GUEST_CPUS, MACHINE_TYPE.guestCpus()); + assertEquals(CPUS, MACHINE_TYPE.cpus()); assertEquals(MEMORY_MB, MACHINE_TYPE.memoryMb()); - assertEquals(SCRATCH_DISKS, MACHINE_TYPE.scratchDisks()); + assertEquals(SCRATCH_DISKS, MACHINE_TYPE.scratchDisksSizeGb()); assertEquals(MAXIMUM_PERSISTENT_DISKS, MACHINE_TYPE.maximumPersistentDisks()); assertEquals(MAXIMUM_PERSISTENT_DISKS_SIZE_GB, MACHINE_TYPE.maximumPersistentDisksSizeGb()); assertEquals(DEPRECATION_STATUS, MACHINE_TYPE.deprecationStatus()); @@ -74,10 +71,7 @@ public void testBuilder() { @Test public void testToPbAndFromPb() { compareMachineTypes(MACHINE_TYPE, MachineType.fromPb(MACHINE_TYPE.toPb())); - MachineType machineType = MachineType.builder() - .machineTypeId(MACHINE_TYPE_ID) - .selfLink(MACHINE_TYPE_ID.toUrl()) - .build(); + MachineType machineType = MachineType.builder().machineTypeId(MACHINE_TYPE_ID).build(); compareMachineTypes(machineType, MachineType.fromPb(machineType.toPb())); } @@ -87,10 +81,9 @@ private void compareMachineTypes(MachineType expected, MachineType value) { assertEquals(expected.id(), value.id()); assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.description(), value.description()); - assertEquals(expected.selfLink(), value.selfLink()); - assertEquals(expected.guestCpus(), value.guestCpus()); + assertEquals(expected.cpus(), value.cpus()); assertEquals(expected.memoryMb(), value.memoryMb()); - assertEquals(expected.scratchDisks(), value.scratchDisks()); + assertEquals(expected.scratchDisksSizeGb(), value.scratchDisksSizeGb()); assertEquals(expected.maximumPersistentDisks(), value.maximumPersistentDisks()); assertEquals(expected.maximumPersistentDisksSizeGb(), value.maximumPersistentDisksSizeGb()); assertEquals(expected.deprecationStatus(), value.deprecationStatus()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java index adb94aee08fc..3474a73c3030 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java @@ -41,7 +41,7 @@ public void testOf() { RegionId regionId = RegionId.of(PROJECT, REGION); assertEquals(PROJECT, regionId.project()); assertEquals(REGION, regionId.region()); - assertEquals(URL, regionId.toUrl()); + assertEquals(URL, regionId.selfLink()); regionId = RegionId.of(REGION); assertNull(regionId.project()); assertEquals(REGION, regionId.region()); @@ -50,7 +50,7 @@ public void testOf() { @Test public void testToAndFromUrl() { RegionId regionId = RegionId.of(PROJECT, REGION); - compareRegionId(regionId, RegionId.fromUrl(regionId.toUrl())); + compareRegionId(regionId, RegionId.fromUrl(regionId.selfLink())); } @Test @@ -60,12 +60,12 @@ public void testSetProjectId() { compareRegionId(regionId, RegionId.of(REGION).setProjectId(PROJECT)); thrown.expect(IllegalArgumentException.class); thrown.expectMessage("notMatchingUrl is not a valid region URL"); - regionId = RegionId.fromUrl("notMatchingUrl"); + RegionId.fromUrl("notMatchingUrl"); } @Test public void testMatchesUrl() { - assertTrue(RegionId.matchesUrl(RegionId.of(PROJECT, REGION).toUrl())); + assertTrue(RegionId.matchesUrl(RegionId.of(PROJECT, REGION).selfLink())); assertFalse(RegionId.matchesUrl("notMatchingUrl")); } @@ -73,7 +73,7 @@ private void compareRegionId(RegionId expected, RegionId value) { assertEquals(expected, value); assertEquals(expected.project(), expected.project()); assertEquals(expected.region(), expected.region()); - assertEquals(expected.toUrl(), expected.toUrl()); + assertEquals(expected.selfLink(), expected.selfLink()); assertEquals(expected.hashCode(), expected.hashCode()); } } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java index 94ca163f5b30..072823933110 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java @@ -28,8 +28,8 @@ public class RegionTest { private static final RegionId REGION_ID = RegionId.of("project", "region"); - private static final BigInteger ID = BigInteger.valueOf(42L); - private static final String CREATION_TIMESTAMP = "2016-01-20T04:39:00.210-08:00"; + private static final String ID = "42"; + private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final String DESCRIPTION = "description"; private static final Region.Status STATUS = Region.Status.DOWN; private static final ZoneId ZONE_ID1 = ZoneId.of("project", "zone1"); @@ -40,9 +40,9 @@ public class RegionTest { private static final Region.Quota QUOTA2 = new Region.Quota("METRIC2", 4, 3); private static final List QUOTAS = ImmutableList.of(QUOTA1, QUOTA2); - private static final String DELETED = "2016-01-20T04:39:00.210-08:00"; - private static final String DEPRECATED = "2016-01-20T04:37:00.210-08:00"; - private static final String OBSOLETE = "2016-01-20T04:38:00.210-08:00"; + private static final Long DELETED = 1453293540000L; + private static final Long DEPRECATED = 1453293420000L; + private static final Long OBSOLETE = 1453293480000L; private static final DeprecationStatus DEPRECATION_STATUS = new DeprecationStatus<>( DELETED, DEPRECATED, OBSOLETE, REGION_ID, DeprecationStatus.Status.DELETED); private static final Region REGION = Region.builder() @@ -50,7 +50,6 @@ public class RegionTest { .id(ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) - .selfLink(REGION_ID.toUrl()) .status(STATUS) .zones(ZONES) .quotas(QUOTAS) @@ -63,7 +62,6 @@ public void testBuilder() { assertEquals(ID, REGION.id()); assertEquals(CREATION_TIMESTAMP, REGION.creationTimestamp()); assertEquals(DESCRIPTION, REGION.description()); - assertEquals(REGION_ID.toUrl(), REGION.selfLink()); assertEquals(STATUS, REGION.status()); assertEquals(ZONES, REGION.zones()); assertEquals(QUOTAS, REGION.quotas()); @@ -76,7 +74,7 @@ public void testToAndFromPb() { compareRegions(REGION, region); assertEquals(REGION_ID.project(), region.regionId().project()); assertEquals(REGION_ID.region(), region.regionId().region()); - region = Region.builder().regionId(REGION_ID).selfLink(REGION_ID.toUrl()).build(); + region = Region.builder().regionId(REGION_ID).build(); compareRegions(region, Region.fromPb(region.toPb())); } @@ -86,7 +84,6 @@ private void compareRegions(Region expected, Region value) { assertEquals(expected.id(), value.id()); assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.description(), value.description()); - assertEquals(expected.selfLink(), value.selfLink()); assertEquals(expected.status(), value.status()); assertEquals(expected.zones(), value.zones()); assertEquals(expected.quotas(), value.quotas()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java index 04f52d9aea17..74c062fd6c27 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java @@ -32,13 +32,12 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; -import java.math.BigInteger; import java.util.List; public class SerializationTest { - private static final BigInteger ID = BigInteger.valueOf(42L); - private static final String CREATION_TIMESTAMP = "2016-01-20T04:39:00.210-08:00"; + private static final String ID = "42"; + private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final String DESCRIPTION = "description"; private static final String VALID_DISK_SIZE = "10GB-10TB"; private static final Long DEFAULT_DISK_SIZE_GB = 10L; @@ -49,7 +48,6 @@ public class SerializationTest { .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .validDiskSize(VALID_DISK_SIZE) - .selfLink(DISK_TYPE_ID.toUrl()) .defaultDiskSizeGb(DEFAULT_DISK_SIZE_GB) .build(); private static final MachineTypeId MACHINE_TYPE_ID = MachineTypeId.of("project", "zone", "type"); @@ -63,10 +61,9 @@ public class SerializationTest { .machineTypeId(MACHINE_TYPE_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) - .selfLink(MACHINE_TYPE_ID.toUrl()) - .guestCpus(GUEST_CPUS) + .cpus(GUEST_CPUS) .memoryMb(MEMORY_MB) - .scratchDisks(SCRATCH_DISKS) + .scratchDisksSizeGb(SCRATCH_DISKS) .maximumPersistentDisks(MAXIMUM_PERSISTENT_DISKS) .maximumPersistentDisksSizeGb(MAXIMUM_PERSISTENT_DISKS_SIZE_GB) .build(); @@ -85,38 +82,37 @@ public class SerializationTest { .id(ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) - .selfLink(REGION_ID.toUrl()) .status(REGION_STATUS) .zones(ZONES) .quotas(QUOTAS) .build(); private static final ZoneId ZONE_ID = ZoneId.of("project", "zone"); private static final Zone.Status ZONE_STATUS = Zone.Status.DOWN; + private static final Long BEGIN_TIME = 1453293420000L; + private static final Long END_TIME = 1453293480000L; private static final MaintenanceWindow WINDOW1 = new MaintenanceWindow("NAME1", "DESCRIPTION1", - "2016-01-20T04:39:00.210-08:00", "2016-01-21T04:39:00.210-08:00"); + BEGIN_TIME, END_TIME); private static final MaintenanceWindow WINDOW2 = new MaintenanceWindow("NAME2", "DESCRIPTION2", - "2016-01-21T04:39:00.210-08:00", "2016-01-22T04:39:00.210-08:00"); + BEGIN_TIME, END_TIME); private static final List WINDOWS = ImmutableList.of(WINDOW1, WINDOW2); private static final Zone ZONE = Zone.builder() .zoneId(ZONE_ID) .id(ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) - .selfLink(ZONE_ID.toUrl()) .status(ZONE_STATUS) .maintenanceWindows(WINDOWS) .region(REGION_ID) .build(); - private static final String DELETED = "2016-01-20T04:39:00.210-08:00"; - private static final String DEPRECATED = "2016-01-20T04:37:00.210-08:00"; - private static final String OBSOLETE = "2016-01-20T04:38:00.210-08:00"; + private static final Long DELETED = 1453293540000L; + private static final Long DEPRECATED = 1453293420000L; + private static final Long OBSOLETE = 1453293480000L; private static final DeprecationStatus DEPRECATION_STATUS = new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, MACHINE_TYPE_ID, DeprecationStatus.Status.DELETED); private static final LicenseId LICENSE_ID = LicenseId.of("project", "license"); private static final Boolean CHARGES_USE_FEE = true; - private static final String SELF_LINK = LICENSE_ID.toUrl(); - private static final License LICENSE = new License(LICENSE_ID, CHARGES_USE_FEE, SELF_LINK); + private static final License LICENSE = new License(LICENSE_ID, CHARGES_USE_FEE); @Test public void testServiceOptions() throws Exception { diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java index 0583e454690d..a147f0e21f63 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java @@ -41,7 +41,7 @@ public void testOf() { ZoneId zoneId = ZoneId.of(PROJECT, ZONE); assertEquals(PROJECT, zoneId.project()); assertEquals(ZONE, zoneId.zone()); - assertEquals(URL, zoneId.toUrl()); + assertEquals(URL, zoneId.selfLink()); zoneId = ZoneId.of(ZONE); assertNull(zoneId.project()); assertEquals(ZONE, zoneId.zone()); @@ -50,7 +50,7 @@ public void testOf() { @Test public void testToAndFromUrl() { ZoneId zoneId = ZoneId.of(PROJECT, ZONE); - compareZoneId(zoneId, ZoneId.fromUrl(zoneId.toUrl())); + compareZoneId(zoneId, ZoneId.fromUrl(zoneId.selfLink())); } @Test @@ -60,12 +60,12 @@ public void testSetProjectId() { compareZoneId(zoneId, ZoneId.of(ZONE).setProjectId(PROJECT)); thrown.expect(IllegalArgumentException.class); thrown.expectMessage("notMatchingUrl is not a valid zone URL"); - zoneId = ZoneId.fromUrl("notMatchingUrl"); + ZoneId.fromUrl("notMatchingUrl"); } @Test public void testMatchesUrl() { - assertTrue(ZoneId.matchesUrl(ZoneId.of(PROJECT, ZONE).toUrl())); + assertTrue(ZoneId.matchesUrl(ZoneId.of(PROJECT, ZONE).selfLink())); assertFalse(ZoneId.matchesUrl("notMatchingUrl")); } @@ -73,7 +73,7 @@ private void compareZoneId(ZoneId expected, ZoneId value) { assertEquals(expected, value); assertEquals(expected.project(), expected.project()); assertEquals(expected.zone(), expected.zone()); - assertEquals(expected.toUrl(), expected.toUrl()); + assertEquals(expected.selfLink(), expected.selfLink()); assertEquals(expected.hashCode(), expected.hashCode()); } } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java index 30cefd6b380a..bdc96d3d9069 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java @@ -30,18 +30,20 @@ public class ZoneTest { private static final ZoneId ZONE_ID = ZoneId.of("project", "zone"); private static final RegionId REGION_ID = RegionId.of("project", "region"); - private static final BigInteger ID = BigInteger.valueOf(42L); - private static final String CREATION_TIMESTAMP = "2016-01-20T04:39:00.210-08:00"; + private static final String ID = "42"; + private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final String DESCRIPTION = "description"; private static final Zone.Status STATUS = Zone.Status.DOWN; + private static final Long BEGIN_TIME = 1453293420000L; + private static final Long END_TIME = 1453293480000L; private static final MaintenanceWindow WINDOW1 = new MaintenanceWindow("NAME1", "DESCRIPTION1", - "2016-01-20T04:39:00.210-08:00", "2016-01-21T04:39:00.210-08:00"); + BEGIN_TIME, END_TIME); private static final MaintenanceWindow WINDOW2 = new MaintenanceWindow("NAME2", "DESCRIPTION2", - "2016-01-21T04:39:00.210-08:00", "2016-01-22T04:39:00.210-08:00"); + BEGIN_TIME, END_TIME); private static final List WINDOWS = ImmutableList.of(WINDOW1, WINDOW2); - private static final String DELETED = "2016-01-20T04:39:00.210-08:00"; - private static final String DEPRECATED = "2016-01-20T04:37:00.210-08:00"; - private static final String OBSOLETE = "2016-01-20T04:38:00.210-08:00"; + private static final Long DELETED = 1453293540000L; + private static final Long DEPRECATED = 1453293420000L; + private static final Long OBSOLETE = 1453293480000L; private static final DeprecationStatus DEPRECATION_STATUS = new DeprecationStatus<>( DELETED, DEPRECATED, OBSOLETE, ZONE_ID, DeprecationStatus.Status.DELETED); private static final Zone ZONE = Zone.builder() @@ -49,7 +51,6 @@ public class ZoneTest { .id(ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) - .selfLink(ZONE_ID.toUrl()) .status(STATUS) .maintenanceWindows(WINDOWS) .deprecationStatus(DEPRECATION_STATUS) @@ -62,7 +63,6 @@ public void testBuilder() { assertEquals(ID, ZONE.id()); assertEquals(CREATION_TIMESTAMP, ZONE.creationTimestamp()); assertEquals(DESCRIPTION, ZONE.description()); - assertEquals(ZONE_ID.toUrl(), ZONE.selfLink()); assertEquals(STATUS, ZONE.status()); assertEquals(WINDOWS, ZONE.maintenanceWindows()); assertEquals(REGION_ID, ZONE.region()); @@ -72,12 +72,12 @@ public void testBuilder() { @Test public void testToAndFromPb() { com.google.api.services.compute.model.Zone zonePb = ZONE.toPb(); - assertEquals(REGION_ID.toUrl(), zonePb.getRegion()); + assertEquals(REGION_ID.selfLink(), zonePb.getRegion()); Zone zone = Zone.fromPb(zonePb); compareZones(ZONE, zone); assertEquals(ZONE_ID.project(), zone.zoneId().project()); assertEquals(ZONE_ID.zone(), zone.zoneId().zone()); - zone = Zone.builder().zoneId(ZONE_ID).selfLink(ZONE_ID.toUrl()).build(); + zone = Zone.builder().zoneId(ZONE_ID).build(); compareZones(zone, Zone.fromPb(zone.toPb())); } @@ -87,7 +87,6 @@ private void compareZones(Zone expected, Zone value) { assertEquals(expected.id(), value.id()); assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.description(), value.description()); - assertEquals(expected.selfLink(), value.selfLink()); assertEquals(expected.status(), value.status()); assertEquals(expected.maintenanceWindows(), value.maintenanceWindows()); assertEquals(expected.region(), value.region()); From bf2a4084d1557876ad668d2e38eabcf79605dbaa Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 29 Feb 2016 19:50:42 +0100 Subject: [PATCH 279/375] Remove tab indentation from compute's pom.xml --- gcloud-java-compute/pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gcloud-java-compute/pom.xml b/gcloud-java-compute/pom.xml index 419c7c4780a2..5bf336e01a2f 100644 --- a/gcloud-java-compute/pom.xml +++ b/gcloud-java-compute/pom.xml @@ -27,10 +27,10 @@ v1-rev97-1.21.0 compile - - com.google.guava - guava-jdk5 - + + com.google.guava + guava-jdk5 + From 41f7ab7ace6f6d4e0e7944eddb5e6400948a40fc Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 1 Mar 2016 12:01:37 +0100 Subject: [PATCH 280/375] Replace com.google.api.client.util.DateTime with Joda formatter --- .../gcloud/compute/DeprecationStatus.java | 17 ++++++++++------- .../com/google/gcloud/compute/DiskType.java | 10 ++++++---- .../com/google/gcloud/compute/MachineType.java | 9 ++++++--- .../java/com/google/gcloud/compute/Region.java | 9 ++++++--- .../java/com/google/gcloud/compute/Zone.java | 17 ++++++++++------- 5 files changed, 38 insertions(+), 24 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java index 20123d648598..c80071dde10a 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java @@ -16,10 +16,12 @@ package com.google.gcloud.compute; -import com.google.api.client.util.DateTime; import com.google.common.base.Function; import com.google.common.base.MoreObjects; +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; + import java.io.Serializable; import java.util.Objects; @@ -31,6 +33,7 @@ public final class DeprecationStatus implements Serializable { private static final long serialVersionUID = -2695077634793679794L; + private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); private final Long deleted; private final Long deprecated; @@ -134,13 +137,13 @@ com.google.api.services.compute.model.DeprecationStatus toPb() { com.google.api.services.compute.model.DeprecationStatus deprecationStatusPb = new com.google.api.services.compute.model.DeprecationStatus(); if (deleted != null) { - deprecationStatusPb.setDeleted(new DateTime(deleted).toStringRfc3339()); + deprecationStatusPb.setDeleted(TIMESTAMP_FORMATTER.print(deleted)); } if (deprecated != null) { - deprecationStatusPb.setDeprecated(new DateTime(deprecated).toStringRfc3339()); + deprecationStatusPb.setDeprecated(TIMESTAMP_FORMATTER.print(deprecated)); } if (obsolete != null) { - deprecationStatusPb.setObsolete(new DateTime(obsolete).toStringRfc3339()); + deprecationStatusPb.setObsolete(TIMESTAMP_FORMATTER.print(obsolete)); } if (replacement != null) { deprecationStatusPb.setReplacement(replacement.selfLink()); @@ -156,11 +159,11 @@ static DeprecationStatus fromPb( Function fromUrl) { return new DeprecationStatus<>( deprecationStatusPb.getDeleted() != null - ? DateTime.parseRfc3339(deprecationStatusPb.getDeleted()).getValue() : null, + ? TIMESTAMP_FORMATTER.parseMillis(deprecationStatusPb.getDeleted()) : null, deprecationStatusPb.getDeprecated() != null - ? DateTime.parseRfc3339(deprecationStatusPb.getDeprecated()).getValue() : null, + ? TIMESTAMP_FORMATTER.parseMillis(deprecationStatusPb.getDeprecated()) : null, deprecationStatusPb.getObsolete() != null - ? DateTime.parseRfc3339(deprecationStatusPb.getObsolete()).getValue() : null, + ? TIMESTAMP_FORMATTER.parseMillis(deprecationStatusPb.getObsolete()) : null, deprecationStatusPb.getReplacement() != null ? fromUrl.apply(deprecationStatusPb.getReplacement()) : null, deprecationStatusPb.getState() != null diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java index f25aa3ac65a4..ce57067786c4 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java @@ -16,10 +16,12 @@ package com.google.gcloud.compute; -import com.google.api.client.util.DateTime; import com.google.common.base.Function; import com.google.common.base.MoreObjects; +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; + import java.io.Serializable; import java.math.BigInteger; import java.util.Objects; @@ -48,6 +50,7 @@ public com.google.api.services.compute.model.DiskType apply(DiskType diskType) { }; private static final long serialVersionUID = -944042261695072026L; + private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); private final String id; private final DiskTypeId diskTypeId; @@ -199,7 +202,7 @@ com.google.api.services.compute.model.DiskType toPb() { diskTypePb.setId(new BigInteger(id)); } if (creationTimestamp != null) { - diskTypePb.setCreationTimestamp(new DateTime(creationTimestamp).toStringRfc3339()); + diskTypePb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); } diskTypePb.setDescription(description); diskTypePb.setValidDiskSize(validDiskSize); @@ -222,8 +225,7 @@ static DiskType fromPb(com.google.api.services.compute.model.DiskType diskTypePb builder.id(diskTypePb.getId().toString()); } if (diskTypePb.getCreationTimestamp() != null) { - builder.creationTimestamp( - DateTime.parseRfc3339(diskTypePb.getCreationTimestamp()).getValue()); + builder.creationTimestamp(TIMESTAMP_FORMATTER.parseMillis(diskTypePb.getCreationTimestamp())); } builder.diskTypeId(DiskTypeId.fromUrl(diskTypePb.getSelfLink())); builder.description(diskTypePb.getDescription()); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java index df0109afa1f5..ee242c0d1ef0 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java @@ -16,12 +16,14 @@ package com.google.gcloud.compute; -import com.google.api.client.util.DateTime; import com.google.api.services.compute.model.MachineType.ScratchDisks; import com.google.common.base.Function; import com.google.common.base.MoreObjects; import com.google.common.collect.Lists; +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; + import java.io.Serializable; import java.math.BigInteger; import java.util.List; @@ -52,6 +54,7 @@ public com.google.api.services.compute.model.MachineType apply(MachineType type) return type.toPb(); } }; + private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); private static final long serialVersionUID = -4210962597502860450L; @@ -255,7 +258,7 @@ com.google.api.services.compute.model.MachineType toPb() { machineTypePb.setId(new BigInteger(id)); } if (creationTimestamp != null) { - machineTypePb.setCreationTimestamp(new DateTime(creationTimestamp).toStringRfc3339()); + machineTypePb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); } machineTypePb.setName(machineTypeId.machineType()); machineTypePb.setDescription(description); @@ -292,7 +295,7 @@ static MachineType fromPb(com.google.api.services.compute.model.MachineType mach } if (machineTypePb.getCreationTimestamp() != null) { builder.creationTimestamp( - DateTime.parseRfc3339(machineTypePb.getCreationTimestamp()).getValue()); + TIMESTAMP_FORMATTER.parseMillis(machineTypePb.getCreationTimestamp())); } builder.description(machineTypePb.getDescription()); builder.cpus(machineTypePb.getGuestCpus()); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java index add58d8009b0..38f79a691721 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java @@ -16,12 +16,14 @@ package com.google.gcloud.compute; -import com.google.api.client.util.DateTime; import com.google.common.base.Function; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; + import java.io.Serializable; import java.math.BigInteger; import java.util.List; @@ -50,6 +52,7 @@ public com.google.api.services.compute.model.Region apply(Region region) { }; private static final long serialVersionUID = -3578710133393645135L; + private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); private final RegionId regionId; private final String id; @@ -319,7 +322,7 @@ com.google.api.services.compute.model.Region toPb() { regionPb.setId(new BigInteger(id)); } if (creationTimestamp != null) { - regionPb.setCreationTimestamp(new DateTime(creationTimestamp).toStringRfc3339()); + regionPb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); } regionPb.setName(regionId.region()); regionPb.setDescription(description); @@ -350,7 +353,7 @@ static Region fromPb(com.google.api.services.compute.model.Region regionPb) { builder.id(regionPb.getId().toString()); } if (regionPb.getCreationTimestamp() != null) { - builder.creationTimestamp(DateTime.parseRfc3339(regionPb.getCreationTimestamp()).getValue()); + builder.creationTimestamp(TIMESTAMP_FORMATTER.parseMillis(regionPb.getCreationTimestamp())); } builder.description(regionPb.getDescription()); if (regionPb.getStatus() != null) { diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java index 48bb5412b605..20c64946d7ce 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java @@ -16,12 +16,14 @@ package com.google.gcloud.compute; -import com.google.api.client.util.DateTime; import com.google.api.services.compute.model.Zone.MaintenanceWindows; import com.google.common.base.Function; import com.google.common.base.MoreObjects; import com.google.common.collect.Lists; +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; + import java.io.Serializable; import java.math.BigInteger; import java.util.List; @@ -50,6 +52,7 @@ public com.google.api.services.compute.model.Zone apply(Zone region) { }; private static final long serialVersionUID = 6113636504417213010L; + private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); private final ZoneId zoneId; private final String id; @@ -162,16 +165,16 @@ MaintenanceWindows toPb() { return new MaintenanceWindows() .setName(name) .setDescription(description) - .setBeginTime(beginTime != null ? new DateTime(beginTime).toStringRfc3339() : null) - .setEndTime(endTime != null ? new DateTime(endTime).toStringRfc3339() : null); + .setBeginTime(beginTime != null ? TIMESTAMP_FORMATTER.print(beginTime) : null) + .setEndTime(endTime != null ? TIMESTAMP_FORMATTER.print(endTime) : null); } static MaintenanceWindow fromPb(MaintenanceWindows windowPb) { return new MaintenanceWindow(windowPb.getName(), windowPb.getDescription(), windowPb.getBeginTime() != null - ? DateTime.parseRfc3339(windowPb.getBeginTime()).getValue() : null, + ? TIMESTAMP_FORMATTER.parseMillis(windowPb.getBeginTime()) : null, windowPb.getEndTime() != null - ? DateTime.parseRfc3339(windowPb.getEndTime()).getValue() : null); + ? TIMESTAMP_FORMATTER.parseMillis(windowPb.getEndTime()) : null); } } @@ -338,7 +341,7 @@ com.google.api.services.compute.model.Zone toPb() { zonePb.setId(new BigInteger(id)); } if (creationTimestamp != null) { - zonePb.setCreationTimestamp(new DateTime(creationTimestamp).toStringRfc3339()); + zonePb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); } zonePb.setName(zoneId.zone()); zonePb.setDescription(description); @@ -370,7 +373,7 @@ static Zone fromPb(com.google.api.services.compute.model.Zone zonePb) { builder.id(zonePb.getId().toString()); } if (zonePb.getCreationTimestamp() != null) { - builder.creationTimestamp(DateTime.parseRfc3339(zonePb.getCreationTimestamp()).getValue()); + builder.creationTimestamp(TIMESTAMP_FORMATTER.parseMillis(zonePb.getCreationTimestamp())); } builder.description(zonePb.getDescription()); if (zonePb.getStatus() != null) { From 7fc133e11aa496add9a8ef5640fff57edf6f8c67 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 1 Mar 2016 16:15:12 +0100 Subject: [PATCH 281/375] Add service methods for immutable Compute resources --- .../com/google/gcloud/compute/Compute.java | 550 ++++++++++++++ .../google/gcloud/compute/ComputeImpl.java | 454 ++++++++++++ .../com/google/gcloud/compute/Option.java | 72 ++ .../com/google/gcloud/spi/ComputeRpc.java | 150 ++++ .../google/gcloud/spi/DefaultComputeRpc.java | 231 ++++++ .../gcloud/compute/ComputeImplTest.java | 674 ++++++++++++++++++ 6 files changed, 2131 insertions(+) create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/Option.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java index 4576f62f84b9..148e0bb88aad 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java @@ -16,7 +16,13 @@ package com.google.gcloud.compute; +import com.google.common.base.Joiner; +import com.google.common.collect.Sets; +import com.google.gcloud.Page; import com.google.gcloud.Service; +import com.google.gcloud.spi.ComputeRpc; + +import java.util.Set; /** * An interface for Google Cloud Compute Engine. @@ -24,4 +30,548 @@ * @see Google Cloud Compute Engine */ public interface Compute extends Service { + + /** + * Fields of a Compute Engine DiskType resource. + * + * @see Disk + * Type Resource + */ + enum DiskTypeField { + CREATION_TIMESTAMP("creationTimestamp"), + DEFAULT_DISK_SIZE_GB("defaultDiskSizeGb"), + DESCRIPTION("description"), + ID("id"), + NAME("name"), + SELF_LINK("selfLink"), + VALID_DISK_SIZE("validDiskSize"), + ZONE("zone"); + + private final String selector; + + DiskTypeField(String selector) { + this.selector = selector; + } + + public String selector() { + return selector; + } + + static String selector(DiskTypeField... fields) { + Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); + fieldStrings.add(SELF_LINK.selector()); + for (DiskTypeField field : fields) { + fieldStrings.add(field.selector()); + } + return Joiner.on(',').join(fieldStrings); + } + } + + /** + * Fields of a Compute Engine MachineType resource. + * + * @see + * Machine Type Resource + */ + enum MachineTypeField { + CREATION_TIMESTAMP("creationTimestamp"), + DESCRIPTION("description"), + GUEST_CPUS("cpus"), + ID("id"), + IMAGE_SPACE_GB("imageSpaceGb"), + MAXIMUM_PERSISTENT_DISKS("maximumPersistentDisks"), + MAXIMUM_PERSISTENT_DISKS_SIZE_GB("maximumPersistentDisksSizeGb"), + MEMORY_MB("memoryMb"), + NAME("name"), + SCRATCH_DISKS("scratchDisks"), + DISK_GB("diskGb"), + SELF_LINK("selfLink"), + ZONE("zone"); + + private final String selector; + + MachineTypeField(String selector) { + this.selector = selector; + } + + public String selector() { + return selector; + } + + static String selector(MachineTypeField... fields) { + Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); + fieldStrings.add(SELF_LINK.selector()); + for (MachineTypeField field : fields) { + fieldStrings.add(field.selector()); + } + return Joiner.on(',').join(fieldStrings); + } + } + + /** + * Fields of a Compute Engine Region resource. + * + * @see + * Region Resource + */ + enum RegionField { + CREATION_TIMESTAMP("creationTimestamp"), + DESCRIPTION("description"), + ID("id"), + NAME("name"), + QUOTAS("quotas"), + SELF_LINK("selfLink"), + STATUS("status"), + ZONES("zones"); + + private final String selector; + + RegionField(String selector) { + this.selector = selector; + } + + public String selector() { + return selector; + } + + static String selector(RegionField... fields) { + Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); + fieldStrings.add(SELF_LINK.selector()); + for (RegionField field : fields) { + fieldStrings.add(field.selector()); + } + return Joiner.on(',').join(fieldStrings); + } + } + + /** + * Fields of a Compute Engine Zone resource. + * + * @see Zone + * Resource + */ + enum ZoneField { + CREATION_TIMESTAMP("creationTimestamp"), + DESCRIPTION("description"), + ID("id"), + MAINTENANCE_WINDOWS("maintenanceWindows"), + NAME("name"), + REGION("region"), + SELF_LINK("selfLink"), + STATUS("status"); + + private final String selector; + + ZoneField(String selector) { + this.selector = selector; + } + + public String selector() { + return selector; + } + + static String selector(ZoneField... fields) { + Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); + fieldStrings.add(SELF_LINK.selector()); + for (ZoneField field : fields) { + fieldStrings.add(field.selector()); + } + return Joiner.on(',').join(fieldStrings); + } + } + + /** + * Fields of a Compute Engine License resource. + * + * @see License + * Resource + */ + enum LicenseField { + CHARGES_USE_FEE("chargesUseFee"), + NAME("name"), + SELF_LINK("selfLink"); + + private final String selector; + + LicenseField(String selector) { + this.selector = selector; + } + + public String selector() { + return selector; + } + + static String selector(LicenseField... fields) { + Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); + fieldStrings.add(SELF_LINK.selector()); + for (LicenseField field : fields) { + fieldStrings.add(field.selector()); + } + return Joiner.on(',').join(fieldStrings); + } + } + + /** + * Class for specifying disk type get options. + */ + class DiskTypeOption extends Option { + + private static final long serialVersionUID = 7349162455602991554L; + + private DiskTypeOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify the disk type's fields to be returned by the RPC call. If this + * option is not provided all disk type's fields are returned. {@code DiskTypeOption.fields} can + * be used to specify only the fields of interest. {@link DiskType#diskTypeId()} is always + * returned, even if not specified. + */ + public static DiskTypeOption fields(DiskTypeField... fields) { + return new DiskTypeOption(ComputeRpc.Option.FIELDS, DiskTypeField.selector(fields)); + } + } + + /** + * Class for specifying disk type list options. + */ + class DiskTypeListOption extends Option { + + private static final long serialVersionUID = 9051194230847610951L; + + private DiskTypeListOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify the maximum number of disk types to be returned. + */ + public static DiskTypeListOption maxResults(long maxResults) { + return new DiskTypeListOption(ComputeRpc.Option.MAX_RESULTS, maxResults); + } + + /** + * Returns an option to specify the page token from which to start listing disk types. + */ + public static DiskTypeListOption startPageToken(String pageToken) { + return new DiskTypeListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); + } + + /** + * Returns an option to specify the disk type's fields to be returned by the RPC call. If this + * option is not provided all disk type's fields are returned. {@code DiskTypeListOption.fields} + * can be used to specify only the fields of interest. {@link DiskType#diskTypeId()} is always + * returned, even if not specified. + */ + public static DiskTypeListOption fields(DiskTypeField... fields) { + StringBuilder builder = new StringBuilder(); + builder.append("items(").append(DiskTypeField.selector(fields)).append("),nextPageToken"); + return new DiskTypeListOption(ComputeRpc.Option.FIELDS, builder.toString()); + } + } + + /** + * Class for specifying machine type get options. + */ + class MachineTypeOption extends Option { + + private static final long serialVersionUID = 7349162455602991554L; + + private MachineTypeOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify the machine type's fields to be returned by the RPC call. If + * this option is not provided all machine type's fields are returned. + * {@code MachineTypeOption.fields} can be used to specify only the fields of interest. + * {@link MachineType#machineTypeId()} is always returned, even if not specified. + */ + public static MachineTypeOption fields(MachineTypeField... fields) { + return new MachineTypeOption(ComputeRpc.Option.FIELDS, MachineTypeField.selector(fields)); + } + } + + /** + * Class for specifying machine type list options. + */ + class MachineTypeListOption extends Option { + + private static final long serialVersionUID = -2974553049419897902L; + + private MachineTypeListOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify the maximum number of machine types to be returned. + */ + public static MachineTypeListOption maxResults(long maxResults) { + return new MachineTypeListOption(ComputeRpc.Option.MAX_RESULTS, maxResults); + } + + /** + * Returns an option to specify the page token from which to start listing machine types. + */ + public static MachineTypeListOption startPageToken(String pageToken) { + return new MachineTypeListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); + } + + /** + * Returns an option to specify the machine type's fields to be returned by the RPC call. If + * this option is not provided all machine type's fields are returned. + * {@code MachineTypeListOption.fields} can be used to specify only the fields of interest. + * {@link MachineType#machineTypeId()} is always returned, even if not specified. + */ + public static MachineTypeListOption fields(MachineTypeField... fields) { + StringBuilder builder = new StringBuilder(); + builder.append("items(").append(MachineTypeField.selector(fields)).append("),nextPageToken"); + return new MachineTypeListOption(ComputeRpc.Option.FIELDS, builder.toString()); + } + } + + /** + * Class for specifying region get options. + */ + class RegionOption extends Option { + + private static final long serialVersionUID = 2025084807788610826L; + + private RegionOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify the region's fields to be returned by the RPC call. If this + * option is not provided all region's fields are returned. {@code RegionOption.fields} can be + * used to specify only the fields of interest. {@link Region#regionId()} is always + * returned, even if not specified. + */ + public static RegionOption fields(RegionField... fields) { + return new RegionOption(ComputeRpc.Option.FIELDS, RegionField.selector(fields)); + } + } + + /** + * Class for specifying region list options. + */ + class RegionListOption extends Option { + + private static final long serialVersionUID = 3348089279267170211L; + + private RegionListOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify the maximum number of regions to be returned. + */ + public static RegionListOption maxResults(long maxResults) { + return new RegionListOption(ComputeRpc.Option.MAX_RESULTS, maxResults); + } + + /** + * Returns an option to specify the page token from which to start listing regions. + */ + public static RegionListOption startPageToken(String pageToken) { + return new RegionListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); + } + + /** + * Returns an option to specify the region's fields to be returned by the RPC call. If this + * option is not provided all region's fields are returned. {@code RegionListOption.fields} can + * be used to specify only the fields of interest. {@link Region#regionId()} is always + * returned, even if not specified. + */ + public static RegionListOption fields(RegionField... fields) { + StringBuilder builder = new StringBuilder(); + builder.append("items(").append(RegionField.selector(fields)).append("),nextPageToken"); + return new RegionListOption(ComputeRpc.Option.FIELDS, builder.toString()); + } + } + + /** + * Class for specifying zone get options. + */ + class ZoneOption extends Option { + + private static final long serialVersionUID = -2968652076389846258L; + + private ZoneOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify the zone's fields to be returned by the RPC call. If this option + * is not provided all zone's fields are returned. {@code ZoneOption.fields} can be used to + * specify only the fields of interest. {@link Zone#zoneId()} is always returned, even if + * not specified. + */ + public static ZoneOption fields(ZoneField... fields) { + return new ZoneOption(ComputeRpc.Option.FIELDS, ZoneField.selector(fields)); + } + } + + /** + * Class for specifying zone list options. + */ + class ZoneListOption extends Option { + + private static final long serialVersionUID = -4721971371200905764L; + + private ZoneListOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify the maximum number of zones to be returned. + */ + public static ZoneListOption maxResults(long maxResults) { + return new ZoneListOption(ComputeRpc.Option.MAX_RESULTS, maxResults); + } + + /** + * Returns an option to specify the page token from which to start listing zones. + */ + public static ZoneListOption startPageToken(String pageToken) { + return new ZoneListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); + } + + /** + * Returns an option to specify the zone's fields to be returned by the RPC call. If this option + * is not provided all zone's fields are returned. {@code ZoneListOption.fields} can be used to + * specify only the fields of interest. {@link Zone#zoneId()} is always returned, even if + * not specified. + */ + public static ZoneListOption fields(ZoneField... fields) { + StringBuilder builder = new StringBuilder(); + builder.append("items(").append(ZoneField.selector(fields)).append("),nextPageToken"); + return new ZoneListOption(ComputeRpc.Option.FIELDS, builder.toString()); + } + } + + /** + * Class for specifying license get options. + */ + class LicenseOption extends Option { + + private static final long serialVersionUID = -2968652076389846258L; + + private LicenseOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify the license's fields to be returned by the RPC call. If this + * option is not provided all license's fields are returned. {@code LicenseOption.fields} can be + * used to specify only the fields of interest. {@link License#licenseId()} is always returned, + * even if not specified. + */ + public static LicenseOption fields(LicenseField... fields) { + return new LicenseOption(ComputeRpc.Option.FIELDS, LicenseField.selector(fields)); + } + } + + /** + * Returns the requested disk type or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + DiskType getDiskType(DiskTypeId diskTypeId, DiskTypeOption... options) throws ComputeException; + + /** + * Returns the requested disk type or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + DiskType getDiskType(String zone, String diskType, DiskTypeOption... options) + throws ComputeException; + + /** + * Lists the disk types in the provided zone available to the current project. + * + * @throws ComputeException upon failure + */ + Page listDiskTypes(String zone, DiskTypeListOption... options) throws ComputeException; + + /** + * Lists all disk types available to the current project. + * + * @throws ComputeException upon failure + */ + Page listDiskTypes(DiskTypeListOption... options) throws ComputeException; + + /** + * Returns the requested machine type or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + MachineType getMachineType(MachineTypeId machineTypeId, MachineTypeOption... options) + throws ComputeException; + + /** + * Returns the requested machine type or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + MachineType getMachineType(String zone, String machineType, MachineTypeOption... options) + throws ComputeException; + + /** + * Lists the machine types in the provided zone available to the current project. + * + * @throws ComputeException upon failure + */ + Page listMachineTypes(String zone, MachineTypeListOption... options) + throws ComputeException; + + /** + * Lists all machine types available to the current project. + * + * @throws ComputeException upon failure + */ + Page listMachineTypes(MachineTypeListOption... options) throws ComputeException; + + /** + * Returns the requested region or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + Region getRegion(String region, RegionOption... options) throws ComputeException; + + /** + * Lists the regions available to the current project. + * + * @throws ComputeException upon failure + */ + Page listRegions(RegionListOption... options) throws ComputeException; + + /** + * Returns the requested zone or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + Zone getZone(String zone, ZoneOption... options) throws ComputeException; + + /** + * Lists the zones available to the current project. + * + * @throws ComputeException upon failure + */ + Page listZones(ZoneListOption... options) throws ComputeException; + + /** + * Returns the requested license or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + License getLicense(String license, LicenseOption... options) throws ComputeException; + + /** + * Returns the requested license or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + License getLicense(LicenseId license, LicenseOption... options) throws ComputeException; } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java index 8a3a82af8827..2aa54d55e90e 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java @@ -16,15 +16,469 @@ package com.google.gcloud.compute; +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.gcloud.RetryHelper.runWithRetries; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.common.collect.Maps; import com.google.gcloud.BaseService; +import com.google.gcloud.Page; +import com.google.gcloud.PageImpl; +import com.google.gcloud.PageImpl.NextPageFetcher; +import com.google.gcloud.RetryHelper; import com.google.gcloud.spi.ComputeRpc; +import java.util.Map; +import java.util.concurrent.Callable; + final class ComputeImpl extends BaseService implements Compute { + private static class DiskTypePageFetcher implements NextPageFetcher { + + private static final long serialVersionUID = -5253916264932522976L; + private final Map requestOptions; + private final ComputeOptions serviceOptions; + private final String zone; + + DiskTypePageFetcher(String zone, ComputeOptions serviceOptions, String cursor, + Map optionMap) { + this.requestOptions = + PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + this.zone = zone; + } + + @Override + public Page nextPage() { + return listDiskTypes(zone, serviceOptions, requestOptions); + } + } + + private static class AggregatedDiskTypePageFetcher implements NextPageFetcher { + + private static final long serialVersionUID = -1664743503750307996L; + private final Map requestOptions; + private final ComputeOptions serviceOptions; + + AggregatedDiskTypePageFetcher(ComputeOptions serviceOptions, String cursor, + Map optionMap) { + this.requestOptions = + PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + } + + @Override + public Page nextPage() { + return listDiskTypes(serviceOptions, requestOptions); + } + } + + private static class MachineTypePageFetcher implements NextPageFetcher { + + private static final long serialVersionUID = -5048133000517001933L; + private final Map requestOptions; + private final ComputeOptions serviceOptions; + private final String zone; + + MachineTypePageFetcher(String zone, ComputeOptions serviceOptions, String cursor, + Map optionMap) { + this.requestOptions = + PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + this.zone = zone; + } + + @Override + public Page nextPage() { + return listMachineTypes(zone, serviceOptions, requestOptions); + } + } + + private static class AggregatedMachineTypePageFetcher implements NextPageFetcher { + + private static final long serialVersionUID = 2919227789802660026L; + private final Map requestOptions; + private final ComputeOptions serviceOptions; + + AggregatedMachineTypePageFetcher(ComputeOptions serviceOptions, String cursor, + Map optionMap) { + this.requestOptions = + PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + } + + @Override + public Page nextPage() { + return listMachineTypes(serviceOptions, requestOptions); + } + } + + private static class RegionPageFetcher implements NextPageFetcher { + + private static final long serialVersionUID = 4180147045485258863L; + private final Map requestOptions; + private final ComputeOptions serviceOptions; + + RegionPageFetcher(ComputeOptions serviceOptions, String cursor, + Map optionMap) { + this.requestOptions = + PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + } + + @Override + public Page nextPage() { + return listRegions(serviceOptions, requestOptions); + } + } + + private static class ZonePageFetcher implements NextPageFetcher { + + private static final long serialVersionUID = -3946202621600687597L; + private final Map requestOptions; + private final ComputeOptions serviceOptions; + + ZonePageFetcher(ComputeOptions serviceOptions, String cursor, + Map optionMap) { + this.requestOptions = + PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + } + + @Override + public Page nextPage() { + return listZones(serviceOptions, requestOptions); + } + } + private final ComputeRpc computeRpc; ComputeImpl(ComputeOptions options) { super(options); computeRpc = options.rpc(); } + + @Override + public DiskType getDiskType(final DiskTypeId diskTypeId, DiskTypeOption... options) + throws ComputeException { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.DiskType answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.DiskType call() { + return computeRpc.getDiskType(diskTypeId.zone(), diskTypeId.diskType(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : DiskType.fromPb(answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public DiskType getDiskType(String zone, String diskType, DiskTypeOption... options) + throws ComputeException { + return getDiskType(DiskTypeId.of(zone, diskType), options); + } + + @Override + public Page listDiskTypes(String zone, DiskTypeListOption... options) + throws ComputeException { + return listDiskTypes(zone, options(), optionMap(options)); + } + + private static Page listDiskTypes(final String zone, + final ComputeOptions serviceOptions, final Map optionsMap) { + try { + ComputeRpc.Tuple> result = + runWithRetries(new Callable>>() { + @Override + public ComputeRpc.Tuple> call() { + return serviceOptions.rpc().listDiskTypes(zone, optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.x(); + Iterable diskTypes = Iterables.transform( + result.y() == null ? ImmutableList.of() + : result.y(), + new Function() { + @Override + public DiskType apply(com.google.api.services.compute.model.DiskType diskType) { + return DiskType.fromPb(diskType); + } + }); + return new PageImpl<>(new DiskTypePageFetcher(zone, serviceOptions, cursor, optionsMap), + cursor, diskTypes); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Page listDiskTypes(DiskTypeListOption... options) throws ComputeException { + return listDiskTypes(options(), optionMap(options)); + } + + private static Page listDiskTypes(final ComputeOptions serviceOptions, + final Map optionsMap) { + try { + ComputeRpc.Tuple> result = + runWithRetries(new Callable>>() { + @Override + public ComputeRpc.Tuple> call() { + return serviceOptions.rpc().listDiskTypes(optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.x(); + Iterable diskTypes = Iterables.transform(result.y(), + new Function() { + @Override + public DiskType apply(com.google.api.services.compute.model.DiskType diskType) { + return DiskType.fromPb(diskType); + } + }); + return new PageImpl<>(new AggregatedDiskTypePageFetcher(serviceOptions, cursor, optionsMap), + cursor, diskTypes); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public MachineType getMachineType(final MachineTypeId machineTypeId, MachineTypeOption... options) + throws ComputeException { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.MachineType answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.MachineType call() { + return computeRpc.getMachineType(machineTypeId.zone(), machineTypeId.machineType(), + optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : MachineType.fromPb(answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public MachineType getMachineType(String zone, String machineType, MachineTypeOption... options) + throws ComputeException { + return getMachineType(MachineTypeId.of(zone, machineType), options); + } + + @Override + public Page listMachineTypes(String zone, MachineTypeListOption... options) + throws ComputeException { + return listMachineTypes(zone, options(), optionMap(options)); + } + + private static Page listMachineTypes(final String zone, + final ComputeOptions serviceOptions, final Map optionsMap) { + try { + ComputeRpc.Tuple> result = + runWithRetries(new Callable>>() { + @Override + public ComputeRpc.Tuple> call() { + return serviceOptions.rpc().listMachineTypes(zone, optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.x(); + Iterable machineTypes = Iterables.transform( + result.y() == null ? ImmutableList.of() + : result.y(), + new Function() { + @Override + public MachineType apply( + com.google.api.services.compute.model.MachineType machineType) { + return MachineType.fromPb(machineType); + } + }); + return new PageImpl<>(new MachineTypePageFetcher(zone, serviceOptions, cursor, optionsMap), + cursor, machineTypes); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Page listMachineTypes(MachineTypeListOption... options) + throws ComputeException { + return listMachineTypes(options(), optionMap(options)); + } + + private static Page listMachineTypes(final ComputeOptions serviceOptions, + final Map optionsMap) { + try { + ComputeRpc.Tuple> result = + runWithRetries(new Callable>>() { + @Override + public ComputeRpc.Tuple> call() { + return serviceOptions.rpc().listMachineTypes(optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.x(); + Iterable machineTypes = Iterables.transform(result.y(), + new Function() { + @Override + public MachineType apply( + com.google.api.services.compute.model.MachineType machineType) { + return MachineType.fromPb(machineType); + } + }); + return new PageImpl<>( + new AggregatedMachineTypePageFetcher(serviceOptions, cursor, optionsMap), cursor, + machineTypes); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Region getRegion(final String region, RegionOption... options) throws ComputeException { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Region answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Region call() { + return computeRpc.getRegion(region, optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Region.fromPb(answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Page listRegions(RegionListOption... options) throws ComputeException { + return listRegions(options(), optionMap(options)); + } + + private static Page listRegions(final ComputeOptions serviceOptions, + final Map optionsMap) { + try { + ComputeRpc.Tuple> result = + runWithRetries(new Callable>>() { + @Override + public ComputeRpc.Tuple> call() { + return serviceOptions.rpc().listRegions(optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.x(); + Iterable regions = Iterables.transform( + result.y() == null ? ImmutableList.of() + : result.y(), + new Function() { + @Override + public Region apply(com.google.api.services.compute.model.Region region) { + return Region.fromPb(region); + } + }); + return new PageImpl<>(new RegionPageFetcher(serviceOptions, cursor, optionsMap), cursor, + regions); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Zone getZone(final String zone, ZoneOption... options) throws ComputeException { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Zone answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Zone call() { + return computeRpc.getZone(zone, optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Zone.fromPb(answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Page listZones(ZoneListOption... options) throws ComputeException { + return listZones(options(), optionMap(options)); + } + + private static Page listZones(final ComputeOptions serviceOptions, + final Map optionsMap) { + try { + ComputeRpc.Tuple> result = + runWithRetries(new Callable>>() { + @Override + public ComputeRpc.Tuple> call() { + return serviceOptions.rpc().listZones(optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.x(); + Iterable zones = Iterables.transform( + result.y() == null ? ImmutableList.of() + : result.y(), + new Function() { + @Override + public Zone apply(com.google.api.services.compute.model.Zone zone) { + return Zone.fromPb(zone); + } + }); + return new PageImpl<>(new ZonePageFetcher(serviceOptions, cursor, optionsMap), cursor, zones); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public License getLicense(String license, LicenseOption... options) + throws ComputeException { + return getLicense(LicenseId.of(license), options); + } + + @Override + public License getLicense(LicenseId license, LicenseOption... options) + throws ComputeException { + final LicenseId completeId = license.setProjectId(options().projectId()); + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.License answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.License call() { + return computeRpc.getLicense(completeId.project(), completeId.license(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : License.fromPb(answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + private Map optionMap(Option... options) { + Map optionMap = Maps.newEnumMap(ComputeRpc.Option.class); + for (Option option : options) { + Object prev = optionMap.put(option.rpcOption(), option.value()); + checkArgument(prev == null, "Duplicate option %s", option); + } + return optionMap; + } } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Option.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Option.java new file mode 100644 index 000000000000..ae100c9c9765 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Option.java @@ -0,0 +1,72 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; +import com.google.gcloud.spi.ComputeRpc; + +import java.io.Serializable; +import java.util.Objects; + +/** + * Base class for Compute operation option. + */ +class Option implements Serializable { + + private static final long serialVersionUID = 4116849309806774350L; + + private final ComputeRpc.Option rpcOption; + private final Object value; + + Option(ComputeRpc.Option rpcOption, Object value) { + this.rpcOption = checkNotNull(rpcOption); + this.value = value; + } + + ComputeRpc.Option rpcOption() { + return rpcOption; + } + + Object value() { + return value; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Option)) { + return false; + } + Option other = (Option) obj; + return Objects.equals(rpcOption, other.rpcOption) + && Objects.equals(value, other.value); + } + + @Override + public int hashCode() { + return Objects.hash(rpcOption, value); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("name", rpcOption.value()) + .add("value", value) + .toString(); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java index b7a59a9413c4..4668756e04cb 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java @@ -16,5 +16,155 @@ package com.google.gcloud.spi; +import com.google.api.services.compute.model.DiskType; +import com.google.api.services.compute.model.License; +import com.google.api.services.compute.model.MachineType; +import com.google.api.services.compute.model.Region; +import com.google.api.services.compute.model.Zone; +import com.google.gcloud.compute.ComputeException; + +import java.util.Map; + public interface ComputeRpc { + + // These options are part of the Google Compute Engine query parameters + enum Option { + FIELDS("fields"), + MAX_RESULTS("maxResults"), + PAGE_TOKEN("pageToken"), + FILTER("filter"); + + private final String value; + + Option(String value) { + this.value = value; + } + + public String value() { + return value; + } + + @SuppressWarnings("unchecked") + T get(Map options) { + return (T) options.get(this); + } + + String getString(Map options) { + return get(options); + } + + Long getLong(Map options) { + return get(options); + } + + Boolean getBoolean(Map options) { + return get(options); + } + } + + class Tuple { + + private final X x; + private final Y y; + + private Tuple(X x, Y y) { + this.x = x; + this.y = y; + } + + public static Tuple of(X x, Y y) { + return new Tuple<>(x, y); + } + + public X x() { + return x; + } + + public Y y() { + return y; + } + } + + /** + * Returns the requested disk type or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + DiskType getDiskType(String zone, String diskType, Map options) + throws ComputeException; + + /** + * Lists the disk types in the provided zone available to the current project. + * + * @throws ComputeException upon failure + */ + Tuple> listDiskTypes(String zone, Map options) + throws ComputeException; + + /** + * Lists all disk types available to the current project. + * + * @throws ComputeException upon failure + */ + Tuple> listDiskTypes(Map options) throws ComputeException; + + /** + * Returns the requested machine type or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + MachineType getMachineType(String zone, String diskType, Map options) + throws ComputeException; + + /** + * Lists the machine types in the provided zone available to the current project. + * + * @throws ComputeException upon failure + */ + Tuple> listMachineTypes(String zone, Map options) + throws ComputeException; + + /** + * Lists all machine types available to the current project. + * + * @throws ComputeException upon failure + */ + Tuple> listMachineTypes(Map options) + throws ComputeException; + + /** + * Returns the requested region or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + Region getRegion(String region, Map options) throws ComputeException; + + /** + * Lists the regions available to the current project. + * + * @throws ComputeException upon failure + */ + Tuple> listRegions(Map options) throws ComputeException; + + /** + * Returns the requested zone or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + Zone getZone(String zone, Map options) throws ComputeException; + + /** + * Lists the zones available to the current project. + * + * @throws ComputeException upon failure + */ + Tuple> listZones(Map options) throws ComputeException; + + /** + * Returns the requested license or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + License getLicense(String project, String license, Map options) + throws ComputeException; } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java index 6667588dd0ef..16e8464843fb 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java @@ -16,14 +16,35 @@ package com.google.gcloud.spi; +import static com.google.gcloud.spi.ComputeRpc.Option.FIELDS; +import static com.google.gcloud.spi.ComputeRpc.Option.FILTER; +import static com.google.gcloud.spi.ComputeRpc.Option.MAX_RESULTS; +import static com.google.gcloud.spi.ComputeRpc.Option.PAGE_TOKEN; +import static java.net.HttpURLConnection.HTTP_NOT_FOUND; + import com.google.api.client.http.HttpRequestInitializer; import com.google.api.client.http.HttpTransport; import com.google.api.client.json.jackson.JacksonFactory; import com.google.api.services.compute.Compute; +import com.google.api.services.compute.model.DiskType; +import com.google.api.services.compute.model.DiskTypeAggregatedList; +import com.google.api.services.compute.model.DiskTypeList; +import com.google.api.services.compute.model.DiskTypesScopedList; +import com.google.api.services.compute.model.License; +import com.google.api.services.compute.model.MachineType; +import com.google.api.services.compute.model.MachineTypeAggregatedList; +import com.google.api.services.compute.model.MachineTypeList; +import com.google.api.services.compute.model.MachineTypesScopedList; +import com.google.api.services.compute.model.Region; +import com.google.api.services.compute.model.RegionList; +import com.google.api.services.compute.model.Zone; +import com.google.api.services.compute.model.ZoneList; +import com.google.common.collect.ImmutableList; import com.google.gcloud.compute.ComputeException; import com.google.gcloud.compute.ComputeOptions; import java.io.IOException; +import java.util.Map; public class DefaultComputeRpc implements ComputeRpc { @@ -43,4 +64,214 @@ public DefaultComputeRpc(ComputeOptions options) { private static ComputeException translate(IOException exception) { return new ComputeException(exception); } + + @Override + public DiskType getDiskType(String zone, String diskType, Map options) + throws ComputeException { + try { + return compute.diskTypes() + .get(this.options.projectId(), zone, diskType) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + ComputeException serviceException = translate(ex); + if (serviceException.code() == HTTP_NOT_FOUND) { + return null; + } + throw serviceException; + } + } + + @Override + public Tuple> listDiskTypes(String zone, Map options) + throws ComputeException { + try { + DiskTypeList diskTypesList = compute.diskTypes() + .list(this.options.projectId(), zone) + .setFilter(FILTER.getString(options)) + .setMaxResults(MAX_RESULTS.getLong(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + .setFields(FIELDS.getString(options)) + .execute(); + Iterable diskTypes = diskTypesList.getItems(); + return Tuple.of(diskTypesList.getNextPageToken(), diskTypes); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Tuple> listDiskTypes(Map options) + throws ComputeException { + try { + DiskTypeAggregatedList aggregatedList = compute.diskTypes() + .aggregatedList(this.options.projectId()) + .setFilter(FILTER.getString(options)) + .setMaxResults(MAX_RESULTS.getLong(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + .setFields(FIELDS.getString(options)) + .execute(); + ImmutableList.Builder builder = ImmutableList.builder(); + Map scopedList = aggregatedList.getItems(); + if (scopedList != null) { + for (String key : scopedList.keySet()) { + DiskTypesScopedList diskTypesScopedList = scopedList.get(key); + if (diskTypesScopedList.getDiskTypes() != null) { + builder.addAll(diskTypesScopedList.getDiskTypes()); + } + } + } + return Tuple.>of(aggregatedList.getNextPageToken(), + builder.build()); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public MachineType getMachineType(String zone, String machineType, Map options) + throws ComputeException { + try { + return compute.machineTypes() + .get(this.options.projectId(), zone, machineType) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + ComputeException serviceException = translate(ex); + if (serviceException.code() == HTTP_NOT_FOUND) { + return null; + } + throw serviceException; + } + } + + @Override + public Tuple> listMachineTypes(String zone, Map options) + throws ComputeException { + try { + MachineTypeList machineTypesList = compute.machineTypes() + .list(this.options.projectId(), zone) + .setFilter(FILTER.getString(options)) + .setMaxResults(MAX_RESULTS.getLong(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + .setFields(FIELDS.getString(options)) + .execute(); + Iterable machineTypes = machineTypesList.getItems(); + return Tuple.of(machineTypesList.getNextPageToken(), machineTypes); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Tuple> listMachineTypes(Map options) + throws ComputeException { + try { + MachineTypeAggregatedList aggregatedList = compute.machineTypes() + .aggregatedList(this.options.projectId()) + .setFilter(FILTER.getString(options)) + .setMaxResults(MAX_RESULTS.getLong(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + .setFields(FIELDS.getString(options)) + .execute(); + ImmutableList.Builder builder = ImmutableList.builder(); + Map scopedList = aggregatedList.getItems(); + if (scopedList != null) { + for (String key : scopedList.keySet()) { + MachineTypesScopedList machineTypesScopedList = scopedList.get(key); + if (machineTypesScopedList.getMachineTypes() != null) { + builder.addAll(machineTypesScopedList.getMachineTypes()); + } + } + } + return Tuple.>of(aggregatedList.getNextPageToken(), + builder.build()); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Region getRegion(String region, Map options) throws ComputeException { + try { + return compute.regions() + .get(this.options.projectId(), region) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + ComputeException serviceException = translate(ex); + if (serviceException.code() == HTTP_NOT_FOUND) { + return null; + } + throw serviceException; + } + } + + @Override + public Tuple> listRegions(Map options) + throws ComputeException { + try { + RegionList regionsList = compute.regions() + .list(this.options.projectId()) + .setFilter(FILTER.getString(options)) + .setMaxResults(MAX_RESULTS.getLong(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + .setFields(FIELDS.getString(options)) + .execute(); + Iterable regions = regionsList.getItems(); + return Tuple.of(regionsList.getNextPageToken(), regions); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Zone getZone(String zone, Map options) throws ComputeException { + try { + return compute.zones() + .get(this.options.projectId(), zone) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + ComputeException serviceException = translate(ex); + if (serviceException.code() == HTTP_NOT_FOUND) { + return null; + } + throw serviceException; + } + } + + @Override + public Tuple> listZones(Map options) throws ComputeException { + try { + ZoneList zonesList = compute.zones() + .list(this.options.projectId()) + .setFilter(FILTER.getString(options)) + .setMaxResults(MAX_RESULTS.getLong(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + .setFields(FIELDS.getString(options)) + .execute(); + Iterable zones = zonesList.getItems(); + return Tuple.of(zonesList.getNextPageToken(), zones); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public License getLicense(String project, String license, Map options) + throws ComputeException { + try { + return compute.licenses() + .get(project, license) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + ComputeException serviceException = translate(ex); + if (serviceException.code() == HTTP_NOT_FOUND) { + return null; + } + throw serviceException; + } + } } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java new file mode 100644 index 000000000000..c1b44a26b51f --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java @@ -0,0 +1,674 @@ +/* + * Copyright 2015 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.easymock.EasyMock.capture; +import static org.easymock.EasyMock.eq; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; +import com.google.gcloud.Page; +import com.google.gcloud.RetryParams; +import com.google.gcloud.compute.Zone.MaintenanceWindow; +import com.google.gcloud.spi.ComputeRpc; +import com.google.gcloud.spi.ComputeRpc.Tuple; +import com.google.gcloud.spi.ComputeRpcFactory; + +import org.easymock.Capture; +import org.easymock.EasyMock; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import java.util.List; +import java.util.Map; + +public class ComputeImplTest { + + private static final String PROJECT = "project"; + private static final String ID = "42"; + private static final Long CREATION_TIMESTAMP = 1453293540000L; + private static final String DESCRIPTION = "description"; + private static final String VALID_DISK_SIZE = "10GB-10TB"; + private static final Long DEFAULT_DISK_SIZE_GB = 10L; + private static final DiskTypeId DISK_TYPE_ID = DiskTypeId.of("project", "zone", "diskType"); + private static final DiskType DISK_TYPE = DiskType.builder() + .id(ID) + .diskTypeId(DISK_TYPE_ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .validDiskSize(VALID_DISK_SIZE) + .defaultDiskSizeGb(DEFAULT_DISK_SIZE_GB) + .build(); + private static final MachineTypeId MACHINE_TYPE_ID = MachineTypeId.of("project", "zone", "type"); + private static final Integer GUEST_CPUS = 1; + private static final Integer MEMORY_MB = 2; + private static final List SCRATCH_DISKS = ImmutableList.of(3); + private static final Integer MAXIMUM_PERSISTENT_DISKS = 4; + private static final Long MAXIMUM_PERSISTENT_DISKS_SIZE_GB = 5L; + private static final MachineType MACHINE_TYPE = MachineType.builder() + .id(ID) + .machineTypeId(MACHINE_TYPE_ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .cpus(GUEST_CPUS) + .memoryMb(MEMORY_MB) + .scratchDisksSizeGb(SCRATCH_DISKS) + .maximumPersistentDisks(MAXIMUM_PERSISTENT_DISKS) + .maximumPersistentDisksSizeGb(MAXIMUM_PERSISTENT_DISKS_SIZE_GB) + .build(); + private static final RegionId REGION_ID = RegionId.of("project", "region"); + private static final Region.Status REGION_STATUS = Region.Status.DOWN; + private static final ZoneId ZONE_ID1 = ZoneId.of("project", "zone1"); + private static final ZoneId ZONE_ID2 = ZoneId.of("project", "zone2"); + private static final List ZONES = ImmutableList.of(ZONE_ID1, ZONE_ID2); + private static final Region.Quota QUOTA1 = + new Region.Quota("METRIC1", 2, 1); + private static final Region.Quota QUOTA2 = + new Region.Quota("METRIC2", 4, 3); + private static final List QUOTAS = ImmutableList.of(QUOTA1, QUOTA2); + private static final Region REGION = Region.builder() + .regionId(REGION_ID) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .status(REGION_STATUS) + .zones(ZONES) + .quotas(QUOTAS) + .build(); + private static final ZoneId ZONE_ID = ZoneId.of("project", "zone"); + private static final Zone.Status ZONE_STATUS = Zone.Status.DOWN; + private static final MaintenanceWindow WINDOW1 = new MaintenanceWindow("NAME1", "DESCRIPTION1", + 1453293420000L, 1453293480000L); + private static final MaintenanceWindow WINDOW2 = new MaintenanceWindow("NAME2", "DESCRIPTION2", + 1453293420000L, 1453293480000L); + private static final List WINDOWS = ImmutableList.of(WINDOW1, WINDOW2); + private static final Zone ZONE = Zone.builder() + .zoneId(ZONE_ID) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .status(ZONE_STATUS) + .maintenanceWindows(WINDOWS) + .region(REGION_ID) + .build(); + private static final LicenseId LICENSE_ID = LicenseId.of("project", "license"); + private static final Boolean CHARGES_USE_FEE = true; + private static final License LICENSE = new License(LICENSE_ID, CHARGES_USE_FEE); + + // Empty ComputeRpc options + private static final Map EMPTY_RPC_OPTIONS = ImmutableMap.of(); + + // DiskType options + private static final Compute.DiskTypeOption DISK_TYPE_OPTION_FIELDS = + Compute.DiskTypeOption.fields(Compute.DiskTypeField.ID, Compute.DiskTypeField.DESCRIPTION); + + // DiskType list options + private static final Compute.DiskTypeListOption DISK_TYPE_LIST_PAGE_TOKEN = + Compute.DiskTypeListOption.startPageToken("cursor"); + private static final Compute.DiskTypeListOption DISK_TYPE_LIST_MAX_RESULTS = + Compute.DiskTypeListOption.maxResults(42L); + private static final Map DISK_TYPE_LIST_OPTIONS = ImmutableMap.of( + ComputeRpc.Option.PAGE_TOKEN, "cursor", + ComputeRpc.Option.MAX_RESULTS, 42L); + + // MachineType options + private static final Compute.MachineTypeOption MACHINE_TYPE_OPTION_FIELDS = + Compute.MachineTypeOption.fields(Compute.MachineTypeField.ID, + Compute.MachineTypeField.DESCRIPTION); + + // MachineType list options + private static final Compute.MachineTypeListOption MACHINE_TYPE_LIST_PAGE_TOKEN = + Compute.MachineTypeListOption.startPageToken("cursor"); + private static final Compute.MachineTypeListOption MACHINE_TYPE_LIST_MAX_RESULTS = + Compute.MachineTypeListOption.maxResults(42L); + private static final Map MACHINE_TYPE_LIST_OPTIONS = ImmutableMap.of( + ComputeRpc.Option.PAGE_TOKEN, "cursor", + ComputeRpc.Option.MAX_RESULTS, 42L); + + // Region options + private static final Compute.RegionOption REGION_OPTION_FIELDS = + Compute.RegionOption.fields(Compute.RegionField.ID, Compute.RegionField.DESCRIPTION); + + // Region list options + private static final Compute.RegionListOption REGION_LIST_PAGE_TOKEN = + Compute.RegionListOption.startPageToken("cursor"); + private static final Compute.RegionListOption REGION_LIST_MAX_RESULTS = + Compute.RegionListOption.maxResults(42L); + private static final Map REGION_LIST_OPTIONS = ImmutableMap.of( + ComputeRpc.Option.PAGE_TOKEN, "cursor", + ComputeRpc.Option.MAX_RESULTS, 42L); + + // Zone options + private static final Compute.ZoneOption ZONE_OPTION_FIELDS = + Compute.ZoneOption.fields(Compute.ZoneField.ID, Compute.ZoneField.DESCRIPTION); + + // Zone list options + private static final Compute.ZoneListOption ZONE_LIST_PAGE_TOKEN = + Compute.ZoneListOption.startPageToken("cursor"); + private static final Compute.ZoneListOption ZONE_LIST_MAX_RESULTS = + Compute.ZoneListOption.maxResults(42L); + private static final Map ZONE_LIST_OPTIONS = ImmutableMap.of( + ComputeRpc.Option.PAGE_TOKEN, "cursor", + ComputeRpc.Option.MAX_RESULTS, 42L); + + // License options + private static final Compute.LicenseOption LICENSE_OPTION_FIELDS = + Compute.LicenseOption.fields(Compute.LicenseField.CHARGES_USE_FEE); + + private ComputeOptions options; + private ComputeRpcFactory rpcFactoryMock; + private ComputeRpc computeRpcMock; + private Compute compute; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Before + public void setUp() { + rpcFactoryMock = EasyMock.createMock(ComputeRpcFactory.class); + computeRpcMock = EasyMock.createMock(ComputeRpc.class); + EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(ComputeOptions.class))) + .andReturn(computeRpcMock).times(1); + EasyMock.replay(rpcFactoryMock); + options = ComputeOptions.builder() + .projectId(PROJECT) + .serviceRpcFactory(rpcFactoryMock) + .retryParams(RetryParams.noRetries()) + .build(); + } + + @After + public void tearDown() { + EasyMock.verify(rpcFactoryMock, computeRpcMock); + } + + @Test + public void testGetOptions() { + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertSame(options, compute.options()); + } + + @Test + public void testGetDiskType() { + EasyMock.expect( + computeRpcMock.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.diskType(), EMPTY_RPC_OPTIONS)) + .andReturn(DISK_TYPE.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + DiskType diskType = compute.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.diskType()); + assertEquals(DISK_TYPE, diskType); + } + + @Test + public void testGetDiskTypeFromDiskTypeId() { + EasyMock.expect( + computeRpcMock.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.diskType(), EMPTY_RPC_OPTIONS)) + .andReturn(DISK_TYPE.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + DiskType diskType = compute.getDiskType(DISK_TYPE_ID); + assertEquals(DISK_TYPE, diskType); + } + + @Test + public void testGetDiskTypeWithSelectedFields() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect( + computeRpcMock.getDiskType( + eq(DISK_TYPE_ID.zone()), eq(DISK_TYPE_ID.diskType()), capture(capturedOptions))) + .andReturn(DISK_TYPE.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + DiskType diskType = + compute.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.diskType(), DISK_TYPE_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(DISK_TYPE_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(DISK_TYPE, diskType); + } + + @Test + public void testListDiskTypes() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList diskTypeList = ImmutableList.of(DISK_TYPE, DISK_TYPE); + Tuple> result = + Tuple.of(cursor, Iterables.transform(diskTypeList, DiskType.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listDiskTypes(DISK_TYPE_ID.zone(), EMPTY_RPC_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listDiskTypes(DISK_TYPE_ID.zone()); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(diskTypeList.toArray(), Iterables.toArray(page.values(), DiskType.class)); + } + + @Test + public void testListEmptyDiskTypes() { + ImmutableList diskTypes = ImmutableList.of(); + Tuple> result = + Tuple.>of(null, diskTypes); + EasyMock.expect(computeRpcMock.listDiskTypes(DISK_TYPE_ID.zone(), EMPTY_RPC_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Page page = compute.listDiskTypes(DISK_TYPE_ID.zone()); + assertNull(page.nextPageCursor()); + assertArrayEquals(diskTypes.toArray(), Iterables.toArray(page.values(), DiskType.class)); + } + + @Test + public void testListDiskTypesWithOptions() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList diskTypeList = ImmutableList.of(DISK_TYPE, DISK_TYPE); + Tuple> result = + Tuple.of(cursor, Iterables.transform(diskTypeList, DiskType.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listDiskTypes(DISK_TYPE_ID.zone(), DISK_TYPE_LIST_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listDiskTypes(DISK_TYPE_ID.zone(), DISK_TYPE_LIST_MAX_RESULTS, + DISK_TYPE_LIST_PAGE_TOKEN); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(diskTypeList.toArray(), Iterables.toArray(page.values(), DiskType.class)); + } + + @Test + public void testAggregatedListDiskTypes() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList diskTypeList = ImmutableList.of(DISK_TYPE, DISK_TYPE); + Tuple> result = + Tuple.of(cursor, Iterables.transform(diskTypeList, DiskType.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listDiskTypes(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listDiskTypes(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(diskTypeList.toArray(), Iterables.toArray(page.values(), DiskType.class)); + } + + @Test + public void testAggregatedListEmptyDiskTypes() { + ImmutableList diskTypes = ImmutableList.of(); + Tuple> result = + Tuple.>of(null, diskTypes); + EasyMock.expect(computeRpcMock.listDiskTypes(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Page page = compute.listDiskTypes(); + assertNull(page.nextPageCursor()); + assertArrayEquals(diskTypes.toArray(), Iterables.toArray(page.values(), DiskType.class)); + } + + @Test + public void testAggregatedListDiskTypesWithOptions() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList diskTypeList = ImmutableList.of(DISK_TYPE, DISK_TYPE); + Tuple> result = + Tuple.of(cursor, Iterables.transform(diskTypeList, DiskType.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listDiskTypes(DISK_TYPE_LIST_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = + compute.listDiskTypes(DISK_TYPE_LIST_MAX_RESULTS, DISK_TYPE_LIST_PAGE_TOKEN); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(diskTypeList.toArray(), Iterables.toArray(page.values(), DiskType.class)); + } + + @Test + public void testGetMachineType() { + EasyMock.expect( + computeRpcMock.getMachineType( + MACHINE_TYPE_ID.zone(), MACHINE_TYPE_ID.machineType(), EMPTY_RPC_OPTIONS)) + .andReturn(MACHINE_TYPE.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + MachineType machineType = + compute.getMachineType(MACHINE_TYPE_ID.zone(), MACHINE_TYPE_ID.machineType()); + assertEquals(MACHINE_TYPE, machineType); + } + + @Test + public void testGetMachineTypeFromMachineTypeId() { + EasyMock.expect(computeRpcMock.getMachineType( + MACHINE_TYPE_ID.zone(), MACHINE_TYPE_ID.machineType(), EMPTY_RPC_OPTIONS)) + .andReturn(MACHINE_TYPE.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + MachineType machineType = compute.getMachineType(MACHINE_TYPE_ID); + assertEquals(MACHINE_TYPE, machineType); + } + + @Test + public void testGetMachineTypeWithSelectedFields() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect( + computeRpcMock.getMachineType(eq(MACHINE_TYPE_ID.zone()), eq(MACHINE_TYPE_ID.machineType()), + capture(capturedOptions))) + .andReturn(MACHINE_TYPE.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + MachineType machineType = compute.getMachineType(MACHINE_TYPE_ID.zone(), + MACHINE_TYPE_ID.machineType(), MACHINE_TYPE_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(DISK_TYPE_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(MACHINE_TYPE, machineType); + } + + @Test + public void testListMachineTypes() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList machineTypeList = ImmutableList.of(MACHINE_TYPE, MACHINE_TYPE); + Tuple> result = + Tuple.of(cursor, Iterables.transform(machineTypeList, MachineType.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listMachineTypes(MACHINE_TYPE_ID.zone(), EMPTY_RPC_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listMachineTypes(MACHINE_TYPE_ID.zone()); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(machineTypeList.toArray(), Iterables.toArray(page.values(), + MachineType.class)); + } + + @Test + public void testListEmptyMachineTypes() { + ImmutableList machineTypes = + ImmutableList.of(); + Tuple> result = + Tuple.>of(null, + machineTypes); + EasyMock.expect(computeRpcMock.listMachineTypes(MACHINE_TYPE_ID.zone(), EMPTY_RPC_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Page page = compute.listMachineTypes(MACHINE_TYPE_ID.zone()); + assertNull(page.nextPageCursor()); + assertArrayEquals(machineTypes.toArray(), Iterables.toArray(page.values(), MachineType.class)); + } + + @Test + public void testListMachineTypesWithOptions() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList machineTypeList = ImmutableList.of(MACHINE_TYPE, MACHINE_TYPE); + Tuple> result = + Tuple.of(cursor, Iterables.transform(machineTypeList, MachineType.TO_PB_FUNCTION)); + EasyMock.expect( + computeRpcMock.listMachineTypes(MACHINE_TYPE_ID.zone(), MACHINE_TYPE_LIST_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listMachineTypes(MACHINE_TYPE_ID.zone(), + MACHINE_TYPE_LIST_MAX_RESULTS, MACHINE_TYPE_LIST_PAGE_TOKEN); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(machineTypeList.toArray(), + Iterables.toArray(page.values(), MachineType.class)); + } + + @Test + public void testAggregatedListMachineTypes() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList machineTypeList = ImmutableList.of(MACHINE_TYPE, MACHINE_TYPE); + Tuple> result = + Tuple.of(cursor, Iterables.transform(machineTypeList, MachineType.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listMachineTypes(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listMachineTypes(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(machineTypeList.toArray(), Iterables.toArray(page.values(), + MachineType.class)); + } + + @Test + public void testAggregatedListEmptyMachineTypes() { + ImmutableList machineTypes = + ImmutableList.of(); + Tuple> result = + Tuple.>of(null, + machineTypes); + EasyMock.expect(computeRpcMock.listMachineTypes(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Page page = compute.listMachineTypes(); + assertNull(page.nextPageCursor()); + assertArrayEquals(machineTypes.toArray(), Iterables.toArray(page.values(), MachineType.class)); + } + + @Test + public void testAggregatedListMachineTypesWithOptions() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList machineTypeList = ImmutableList.of(MACHINE_TYPE, MACHINE_TYPE); + Tuple> result = + Tuple.of(cursor, Iterables.transform(machineTypeList, MachineType.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listMachineTypes(MACHINE_TYPE_LIST_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = + compute.listMachineTypes(MACHINE_TYPE_LIST_MAX_RESULTS, MACHINE_TYPE_LIST_PAGE_TOKEN); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(machineTypeList.toArray(), + Iterables.toArray(page.values(), MachineType.class)); + } + + @Test + public void testGetRegion() { + EasyMock.expect(computeRpcMock.getRegion(REGION_ID.region(), EMPTY_RPC_OPTIONS)) + .andReturn(REGION.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Region region = compute.getRegion(REGION_ID.region()); + assertEquals(REGION, region); + } + + @Test + public void testGetRegionWithSelectedFields() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.getRegion(eq(REGION_ID.region()), capture(capturedOptions))) + .andReturn(REGION.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Region region = compute.getRegion(REGION_ID.region(), REGION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(REGION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(REGION, region); + } + + @Test + public void testListRegions() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList regionList = ImmutableList.of(REGION, REGION); + Tuple> result = + Tuple.of(cursor, Iterables.transform(regionList, Region.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listRegions(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listRegions(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(regionList.toArray(), Iterables.toArray(page.values(), Region.class)); + } + + @Test + public void testListEmptyRegions() { + ImmutableList regions = ImmutableList.of(); + Tuple> result = + Tuple.>of(null, + regions); + EasyMock.expect(computeRpcMock.listRegions(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Page page = compute.listRegions(); + assertNull(page.nextPageCursor()); + assertArrayEquals(regions.toArray(), Iterables.toArray(page.values(), Region.class)); + } + + @Test + public void testListRegionsWithOptions() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList regionList = ImmutableList.of(REGION, REGION); + Tuple> result = + Tuple.of(cursor, Iterables.transform(regionList, Region.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listRegions(REGION_LIST_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listRegions(REGION_LIST_MAX_RESULTS, REGION_LIST_PAGE_TOKEN); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(regionList.toArray(), Iterables.toArray(page.values(), Region.class)); + } + + @Test + public void testGetZone() { + EasyMock.expect(computeRpcMock.getZone(ZONE_ID.zone(), EMPTY_RPC_OPTIONS)) + .andReturn(ZONE.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Zone zone = compute.getZone(ZONE_ID.zone()); + assertEquals(ZONE, zone); + } + + @Test + public void testGetZoneWithSelectedFields() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.getZone(eq(ZONE_ID.zone()), capture(capturedOptions))) + .andReturn(ZONE.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Zone zone = compute.getZone(ZONE_ID.zone(), ZONE_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(ZONE_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(ZONE, zone); + } + + @Test + public void testListZones() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList zoneList = ImmutableList.of(ZONE, ZONE); + Tuple> result = + Tuple.of(cursor, Iterables.transform(zoneList, Zone.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listZones(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listZones(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(zoneList.toArray(), Iterables.toArray(page.values(), Zone.class)); + } + + @Test + public void testListEmptyZones() { + ImmutableList zones = ImmutableList.of(); + Tuple> result = + Tuple.>of(null, zones); + EasyMock.expect(computeRpcMock.listZones(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Page page = compute.listZones(); + assertNull(page.nextPageCursor()); + assertArrayEquals(zones.toArray(), Iterables.toArray(page.values(), Zone.class)); + } + + @Test + public void testListZonesWithOptions() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList zoneList = ImmutableList.of(ZONE, ZONE); + Tuple> result = + Tuple.of(cursor, Iterables.transform(zoneList, Zone.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listZones(ZONE_LIST_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listZones(ZONE_LIST_MAX_RESULTS, ZONE_LIST_PAGE_TOKEN); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(zoneList.toArray(), Iterables.toArray(page.values(), Zone.class)); + } + + @Test + public void testGetLicenseFromString() { + EasyMock.expect(computeRpcMock.getLicense(PROJECT, LICENSE_ID.license(), EMPTY_RPC_OPTIONS)) + .andReturn(LICENSE.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + License license = compute.getLicense(LICENSE_ID.license()); + assertEquals(LICENSE, license); + } + + @Test + public void testGetLicenseFromStringWithOptions() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect( + computeRpcMock.getLicense(eq(PROJECT), eq(LICENSE_ID.license()), capture(capturedOptions))) + .andReturn(LICENSE.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + License license = compute.getLicense(LICENSE_ID.license(), LICENSE_OPTION_FIELDS); + assertEquals(LICENSE, license); + String selector = (String) capturedOptions.getValue().get(LICENSE_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("chargesUseFee")); + assertEquals(22, selector.length()); + assertEquals(LICENSE, license); + } + + @Test + public void testGetLicenseFromId() { + LicenseId licenseId = LicenseId.of("project2", "license2"); + EasyMock.expect( + computeRpcMock.getLicense(licenseId.project(), licenseId.license(), EMPTY_RPC_OPTIONS)) + .andReturn(LICENSE.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + License license = compute.getLicense(licenseId); + assertEquals(LICENSE, license); + } + + @Test + public void testGetLicenseFromIdWithOptions() { + Capture> capturedOptions = Capture.newInstance(); + LicenseId licenseId = LicenseId.of("project2", "license2"); + EasyMock.expect(computeRpcMock.getLicense(eq(licenseId.project()), eq(licenseId.license()), + capture(capturedOptions))) + .andReturn(LICENSE.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + License license = compute.getLicense(licenseId, LICENSE_OPTION_FIELDS); + assertEquals(LICENSE, license); + String selector = (String) capturedOptions.getValue().get(LICENSE_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("chargesUseFee")); + assertEquals(22, selector.length()); + assertEquals(LICENSE, license); + } +} From 566c581e32139dd525e6c228bdd818e9c8fdad28 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 1 Mar 2016 16:17:38 +0100 Subject: [PATCH 282/375] Add RemoteComputeHelper and integration tests --- .../compute/testing/RemoteComputeHelper.java | 117 ++++++ .../gcloud/compute/testing/package-info.java | 31 ++ .../gcloud/compute/it/ITComputeTest.java | 378 ++++++++++++++++++ 3 files changed, 526 insertions(+) create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/RemoteComputeHelper.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/package-info.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/RemoteComputeHelper.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/RemoteComputeHelper.java new file mode 100644 index 000000000000..266b31cd7c93 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/RemoteComputeHelper.java @@ -0,0 +1,117 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute.testing; + +import com.google.gcloud.AuthCredentials; +import com.google.gcloud.RetryParams; +import com.google.gcloud.compute.ComputeOptions; + +import java.io.IOException; +import java.io.InputStream; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Utility to create a remote Compute configuration for testing. Compute options can be obtained + * via the {@link #options()} method. Returned options have custom + * {@link ComputeOptions#retryParams()}: {@link RetryParams#retryMaxAttempts()} is {@code 10}, + * {@link RetryParams#retryMinAttempts()} is {@code 6}, {@link RetryParams#maxRetryDelayMillis()} is + * {@code 30000}, {@link RetryParams#totalRetryPeriodMillis()} is {@code 120000} and + * {@link RetryParams#initialRetryDelayMillis()} is {@code 250}. + * {@link ComputeOptions#connectTimeout()} and {@link ComputeOptions#readTimeout()} are both set to + * {@code 60000}. + */ +public class RemoteComputeHelper { + + private static final Logger log = Logger.getLogger(RemoteComputeHelper.class.getName()); + private final ComputeOptions options; + + private RemoteComputeHelper(ComputeOptions options) { + this.options = options; + } + + /** + * Returns a {@link ComputeOptions} object to be used for testing. + */ + public ComputeOptions options() { + return options; + } + + /** + * Creates a {@code RemoteComputeHelper} object for the given project id and JSON key input + * stream. + * + * @param projectId id of the project to be used for running the tests + * @param keyStream input stream for a JSON key + * @return A {@code RemoteComputeHelper} object for the provided options + * @throws ComputeHelperException if {@code keyStream} is not a valid JSON key stream + */ + public static RemoteComputeHelper create(String projectId, InputStream keyStream) + throws ComputeHelperException { + try { + ComputeOptions computeOptions = ComputeOptions.builder() + .authCredentials(AuthCredentials.createForJson(keyStream)) + .projectId(projectId) + .retryParams(retryParams()) + .connectTimeout(60000) + .readTimeout(60000) + .build(); + return new RemoteComputeHelper(computeOptions); + } catch (IOException ex) { + if (log.isLoggable(Level.WARNING)) { + log.log(Level.WARNING, ex.getMessage()); + } + throw ComputeHelperException.translate(ex); + } + } + + /** + * Creates a {@code RemoteComputeHelper} object using default project id and authentication + * credentials. + */ + public static RemoteComputeHelper create() { + ComputeOptions computeOptions = ComputeOptions.builder() + .retryParams(retryParams()) + .connectTimeout(60000) + .readTimeout(60000) + .build(); + return new RemoteComputeHelper(computeOptions); + } + + private static RetryParams retryParams() { + return RetryParams.builder() + .retryMaxAttempts(10) + .retryMinAttempts(6) + .maxRetryDelayMillis(30000) + .totalRetryPeriodMillis(120000) + .initialRetryDelayMillis(250) + .build(); + } + + public static class ComputeHelperException extends RuntimeException { + + private static final long serialVersionUID = -5747977015007639912L; + + public ComputeHelperException(String message, Throwable cause) { + super(message, cause); + } + + public static ComputeHelperException translate(Exception ex) { + return new ComputeHelperException(ex.getMessage(), ex); + } + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/package-info.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/package-info.java new file mode 100644 index 000000000000..86f1c2428cde --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/package-info.java @@ -0,0 +1,31 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +/** + * A testing helper for Google Compute Engine. + * + *

    A simple usage example: + * + *

    Before the test: + *

     {@code
    + * RemoteComputeHelper computeHelper = RemoteComputeHelper.create();
    + * Compute compute = computeHelper.options().service();
    + * } 
    + * + * @see + * gcloud-java tools for testing + */ +package com.google.gcloud.compute.testing; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java new file mode 100644 index 000000000000..15f3e1c05420 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java @@ -0,0 +1,378 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute.it; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import com.google.gcloud.Page; +import com.google.gcloud.compute.Compute; +import com.google.gcloud.compute.DiskType; +import com.google.gcloud.compute.License; +import com.google.gcloud.compute.LicenseId; +import com.google.gcloud.compute.MachineType; +import com.google.gcloud.compute.Region; +import com.google.gcloud.compute.Zone; +import com.google.gcloud.compute.testing.RemoteComputeHelper; + +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.Timeout; + +import java.util.Iterator; + +public class ITComputeTest { + + private static final String REGION = "us-central1"; + private static final String ZONE = "us-central1-a"; + private static final String DISK_TYPE = "local-ssd"; + private static final String MACHINE_TYPE = "f1-micro"; + private static final LicenseId LICENSE_ID = LicenseId.of("ubuntu-os-cloud", "ubuntu-1404-trusty"); + + private static Compute compute; + + @Rule + public Timeout globalTimeout = Timeout.seconds(300); + + @BeforeClass + public static void beforeClass() throws InterruptedException { + RemoteComputeHelper computeHelper = RemoteComputeHelper.create(); + compute = computeHelper.options().service(); + } + + @Test + public void testGetDiskType() { + DiskType diskType = compute.getDiskType(ZONE, DISK_TYPE); + // todo(mziccard): uncomment or remove once #695 is closed + // assertNotNull(diskType.id()); + assertEquals(ZONE, diskType.diskTypeId().zone()); + assertEquals(DISK_TYPE, diskType.diskTypeId().diskType()); + assertNotNull(diskType.creationTimestamp()); + assertNotNull(diskType.description()); + assertNotNull(diskType.validDiskSize()); + assertNotNull(diskType.defaultDiskSizeGb()); + } + + @Test + public void testGetDiskTypeWithSelectedFields() { + DiskType diskType = compute.getDiskType(ZONE, DISK_TYPE, + Compute.DiskTypeOption.fields(Compute.DiskTypeField.CREATION_TIMESTAMP)); + // todo(mziccard): uncomment or remove once #695 is closed + // assertNotNull(diskType.id()); + assertEquals(ZONE, diskType.diskTypeId().zone()); + assertEquals(DISK_TYPE, diskType.diskTypeId().diskType()); + assertNotNull(diskType.creationTimestamp()); + assertNull(diskType.description()); + assertNull(diskType.validDiskSize()); + assertNull(diskType.defaultDiskSizeGb()); + } + + @Test + public void testListDiskTypes() { + Page diskPage = compute.listDiskTypes(ZONE); + Iterator diskTypeIterator = diskPage.iterateAll(); + while(diskTypeIterator.hasNext()) { + DiskType diskType = diskTypeIterator.next(); + // todo(mziccard): uncomment or remove once #695 is closed + // assertNotNull(diskType.id()); + assertNotNull(diskType.diskTypeId()); + assertEquals(ZONE, diskType.diskTypeId().zone()); + assertNotNull(diskType.creationTimestamp()); + assertNotNull(diskType.description()); + assertNotNull(diskType.validDiskSize()); + assertNotNull(diskType.defaultDiskSizeGb()); + } + } + + @Test + public void testListDiskTypesWithSelectedFields() { + Page diskPage = compute.listDiskTypes(ZONE, + Compute.DiskTypeListOption.fields(Compute.DiskTypeField.CREATION_TIMESTAMP)); + Iterator diskTypeIterator = diskPage.iterateAll(); + while(diskTypeIterator.hasNext()) { + DiskType diskType = diskTypeIterator.next(); + assertNull(diskType.id()); + assertNotNull(diskType.diskTypeId()); + assertEquals(ZONE, diskType.diskTypeId().zone()); + assertNotNull(diskType.creationTimestamp()); + assertNull(diskType.description()); + assertNull(diskType.validDiskSize()); + assertNull(diskType.defaultDiskSizeGb()); + } + } + + @Test + public void testAggregatedListDiskTypes() { + Page diskPage = compute.listDiskTypes(); + Iterator diskTypeIterator = diskPage.iterateAll(); + while(diskTypeIterator.hasNext()) { + DiskType diskType = diskTypeIterator.next(); + // todo(mziccard): uncomment or remove once #695 is closed + // assertNotNull(diskType.id()); + assertNotNull(diskType.diskTypeId()); + assertNotNull(diskType.creationTimestamp()); + assertNotNull(diskType.description()); + assertNotNull(diskType.validDiskSize()); + assertNotNull(diskType.defaultDiskSizeGb()); + } + } + + @Test + public void testAggregatedListDiskTypesWithSelectedFields() { + Page diskPage = compute.listDiskTypes( + Compute.DiskTypeListOption.fields(Compute.DiskTypeField.CREATION_TIMESTAMP)); + Iterator diskTypeIterator = diskPage.iterateAll(); + while(diskTypeIterator.hasNext()) { + DiskType diskType = diskTypeIterator.next(); + assertNull(diskType.id()); + assertNotNull(diskType.diskTypeId()); + assertEquals(ZONE, diskType.diskTypeId().zone()); + assertNotNull(diskType.creationTimestamp()); + assertNull(diskType.description()); + assertNull(diskType.validDiskSize()); + assertNull(diskType.defaultDiskSizeGb()); + } + } + + @Test + public void testGetMachineType() { + MachineType machineType = compute.getMachineType(ZONE, MACHINE_TYPE); + assertEquals(ZONE, machineType.machineTypeId().zone()); + assertEquals(MACHINE_TYPE, machineType.machineTypeId().machineType()); + assertNotNull(machineType.id()); + assertNotNull(machineType.creationTimestamp()); + assertNotNull(machineType.description()); + assertNotNull(machineType.cpus()); + assertNotNull(machineType.memoryMb()); + assertNotNull(machineType.maximumPersistentDisks()); + assertNotNull(machineType.maximumPersistentDisksSizeGb()); + } + + @Test + public void testGetMachineTypeWithSelectedFields() { + MachineType machineType = compute.getMachineType(ZONE, MACHINE_TYPE, + Compute.MachineTypeOption.fields(Compute.MachineTypeField.ID)); + assertEquals(ZONE, machineType.machineTypeId().zone()); + assertEquals(MACHINE_TYPE, machineType.machineTypeId().machineType()); + assertNotNull(machineType.id()); + assertNull(machineType.creationTimestamp()); + assertNull(machineType.description()); + assertNull(machineType.cpus()); + assertNull(machineType.memoryMb()); + assertNull(machineType.maximumPersistentDisks()); + assertNull(machineType.maximumPersistentDisksSizeGb()); + } + + @Test + public void testListMachineTypes() { + Page machinePage = compute.listMachineTypes(ZONE); + Iterator machineTypeIterator = machinePage.iterateAll(); + while(machineTypeIterator.hasNext()) { + MachineType machineType = machineTypeIterator.next(); + assertNotNull(machineType.machineTypeId()); + assertEquals(ZONE, machineType.machineTypeId().zone()); + assertNotNull(machineType.id()); + assertNotNull(machineType.creationTimestamp()); + assertNotNull(machineType.description()); + assertNotNull(machineType.cpus()); + assertNotNull(machineType.memoryMb()); + assertNotNull(machineType.maximumPersistentDisks()); + assertNotNull(machineType.maximumPersistentDisksSizeGb()); + } + } + + @Test + public void testListMachineTypesWithSelectedFields() { + Page machinePage = compute.listMachineTypes(ZONE, + Compute.MachineTypeListOption.fields(Compute.MachineTypeField.CREATION_TIMESTAMP)); + Iterator machineTypeIterator = machinePage.iterateAll(); + while(machineTypeIterator.hasNext()) { + MachineType machineType = machineTypeIterator.next(); + assertNotNull(machineType.machineTypeId()); + assertEquals(ZONE, machineType.machineTypeId().zone()); + assertNull(machineType.id()); + assertNotNull(machineType.creationTimestamp()); + assertNull(machineType.description()); + assertNull(machineType.cpus()); + assertNull(machineType.memoryMb()); + assertNull(machineType.maximumPersistentDisks()); + assertNull(machineType.maximumPersistentDisksSizeGb()); + } + } + + @Test + public void testAggregatedListMachineTypes() { + Page machinePage = compute.listMachineTypes(); + Iterator machineTypeIterator = machinePage.iterateAll(); + while(machineTypeIterator.hasNext()) { + MachineType machineType = machineTypeIterator.next(); + assertNotNull(machineType.machineTypeId()); + assertNotNull(machineType.id()); + assertNotNull(machineType.creationTimestamp()); + assertNotNull(machineType.description()); + assertNotNull(machineType.cpus()); + assertNotNull(machineType.memoryMb()); + assertNotNull(machineType.maximumPersistentDisks()); + assertNotNull(machineType.maximumPersistentDisksSizeGb()); + } + } + + @Test + public void testAggregatedListMachineTypesWithSelectedFields() { + Page machinePage = compute.listMachineTypes( + Compute.MachineTypeListOption.fields(Compute.MachineTypeField.CREATION_TIMESTAMP)); + Iterator machineTypeIterator = machinePage.iterateAll(); + while(machineTypeIterator.hasNext()) { + MachineType machineType = machineTypeIterator.next(); + assertNotNull(machineType.machineTypeId()); + assertNull(machineType.id()); + assertNotNull(machineType.creationTimestamp()); + assertNull(machineType.description()); + assertNull(machineType.cpus()); + assertNull(machineType.memoryMb()); + assertNull(machineType.maximumPersistentDisks()); + assertNull(machineType.maximumPersistentDisksSizeGb()); + } + } + + @Test + public void testGetLicense() { + License license= compute.getLicense(LICENSE_ID); + assertEquals(LICENSE_ID, license.licenseId()); + assertNotNull(license.chargesUseFee()); + } + + @Test + public void testGetLicenseWithSelectedFields() { + License license = compute.getLicense(LICENSE_ID, Compute.LicenseOption.fields()); + assertEquals(LICENSE_ID, license.licenseId()); + assertNull(license.chargesUseFee()); + } + + @Test + public void testGetRegion() { + Region region = compute.getRegion(REGION); + assertEquals(REGION, region.regionId().region()); + assertNotNull(region.description()); + assertNotNull(region.creationTimestamp()); + assertNotNull(region.id()); + assertNotNull(region.quotas()); + assertNotNull(region.status()); + assertNotNull(region.zones()); + } + + @Test + public void testGetRegionWithSelectedFields() { + Region region = compute.getRegion(REGION, Compute.RegionOption.fields(Compute.RegionField.ID)); + assertEquals(REGION, region.regionId().region()); + assertNotNull(region.id()); + assertNull(region.description()); + assertNull(region.creationTimestamp()); + assertNull(region.quotas()); + assertNull(region.status()); + assertNull(region.zones()); + } + + @Test + public void testListRegions() { + Page regionPage = compute.listRegions(); + Iterator regionIterator = regionPage.iterateAll(); + while(regionIterator.hasNext()) { + Region region = regionIterator.next(); + assertNotNull(region.regionId()); + assertNotNull(region.description()); + assertNotNull(region.creationTimestamp()); + assertNotNull(region.id()); + assertNotNull(region.quotas()); + assertNotNull(region.status()); + assertNotNull(region.zones()); + } + } + + @Test + public void testListRegionsWithSelectedFields() { + Page regionPage = + compute.listRegions(Compute.RegionListOption.fields(Compute.RegionField.ID)); + Iterator regionIterator = regionPage.iterateAll(); + while(regionIterator.hasNext()) { + Region region = regionIterator.next(); + assertNotNull(region.regionId()); + assertNull(region.description()); + assertNull(region.creationTimestamp()); + assertNotNull(region.id()); + assertNull(region.quotas()); + assertNull(region.status()); + assertNull(region.zones()); + } + } + + @Test + public void testGetZone() { + Zone zone = compute.getZone(ZONE); + assertEquals(ZONE, zone.zoneId().zone()); + assertNotNull(zone.id()); + assertNotNull(zone.creationTimestamp()); + assertNotNull(zone.description()); + assertNotNull(zone.status()); + assertNotNull(zone.region()); + } + + @Test + public void testGetZoneWithSelectedFields() { + Zone zone = compute.getZone(ZONE, Compute.ZoneOption.fields(Compute.ZoneField.ID)); + assertEquals(ZONE, zone.zoneId().zone()); + assertNotNull(zone.id()); + assertNull(zone.creationTimestamp()); + assertNull(zone.description()); + assertNull(zone.status()); + assertNull(zone.maintenanceWindows()); + assertNull(zone.region()); + } + + @Test + public void testListZones() { + Page zonePage = compute.listZones(); + Iterator zoneIterator = zonePage.iterateAll(); + while(zoneIterator.hasNext()) { + Zone zone = zoneIterator.next(); + assertNotNull(zone.zoneId()); + assertNotNull(zone.id()); + assertNotNull(zone.creationTimestamp()); + assertNotNull(zone.description()); + assertNotNull(zone.status()); + assertNotNull(zone.region()); + } + } + + @Test + public void testListZonesWithSelectedFields() { + Page zonePage = compute.listZones( + Compute.ZoneListOption.fields(Compute.ZoneField.CREATION_TIMESTAMP)); + Iterator zoneIterator = zonePage.iterateAll(); + while(zoneIterator.hasNext()) { + Zone zone = zoneIterator.next(); + assertNotNull(zone.zoneId()); + assertNull(zone.id()); + assertNotNull(zone.creationTimestamp()); + assertNull(zone.description()); + assertNull(zone.status()); + assertNull(zone.region()); + } + } +} From c9add806ef64fd2ebe22d1d6fdb23d4c08b3939d Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 4 Mar 2016 09:54:37 +0100 Subject: [PATCH 283/375] Refactor compute service - Add missing resource fields and remove non-needed ones - Add selector classes and selector options - Add dedicated option classes for aggregated options - Remove unnecessary "throws" from method signature - Add static function to handle 404 exceptions --- .../com/google/gcloud/compute/Compute.java | 375 ++++++++++++++++-- .../google/gcloud/compute/ComputeImpl.java | 39 +- .../com/google/gcloud/spi/ComputeRpc.java | 40 +- .../google/gcloud/spi/DefaultComputeRpc.java | 87 ++-- .../gcloud/compute/ComputeImplTest.java | 64 ++- .../gcloud/compute/it/ITComputeTest.java | 106 ++++- 6 files changed, 555 insertions(+), 156 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java index 148e0bb88aad..eb96df0eaba9 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java @@ -16,12 +16,17 @@ package com.google.gcloud.compute; +import static com.google.common.base.Preconditions.checkNotNull; + import com.google.common.base.Joiner; +import com.google.common.base.MoreObjects; import com.google.common.collect.Sets; import com.google.gcloud.Page; import com.google.gcloud.Service; import com.google.gcloud.spi.ComputeRpc; +import java.io.Serializable; +import java.util.Objects; import java.util.Set; /** @@ -45,7 +50,8 @@ enum DiskTypeField { NAME("name"), SELF_LINK("selfLink"), VALID_DISK_SIZE("validDiskSize"), - ZONE("zone"); + ZONE("zone"), + DEPRECATED("deprecated"); private final String selector; @@ -76,7 +82,7 @@ static String selector(DiskTypeField... fields) { enum MachineTypeField { CREATION_TIMESTAMP("creationTimestamp"), DESCRIPTION("description"), - GUEST_CPUS("cpus"), + GUEST_CPUS("guestCpus"), ID("id"), IMAGE_SPACE_GB("imageSpaceGb"), MAXIMUM_PERSISTENT_DISKS("maximumPersistentDisks"), @@ -84,9 +90,9 @@ enum MachineTypeField { MEMORY_MB("memoryMb"), NAME("name"), SCRATCH_DISKS("scratchDisks"), - DISK_GB("diskGb"), SELF_LINK("selfLink"), - ZONE("zone"); + ZONE("zone"), + DEPRECATED("deprecated"); private final String selector; @@ -122,7 +128,8 @@ enum RegionField { QUOTAS("quotas"), SELF_LINK("selfLink"), STATUS("status"), - ZONES("zones"); + ZONES("zones"), + DEPRECATED("deprecated"); private final String selector; @@ -158,7 +165,8 @@ enum ZoneField { NAME("name"), REGION("region"), SELF_LINK("selfLink"), - STATUS("status"); + STATUS("status"), + DEPRECATED("deprecated"); private final String selector; @@ -211,6 +219,223 @@ static String selector(LicenseField... fields) { } } + /** + * Base class for list filters. + */ + abstract class ListFilter implements Serializable { + + private static final long serialVersionUID = -238638392811165127L; + + private final String field; + private final ComparisonOperator operator; + private final Object value; + + enum ComparisonOperator { + /** + * Defines an equality filter. + */ + EQ, + + /** + * Defines an inequality filter. + */ + NE + } + + ListFilter(String field, ComparisonOperator operator, Object value) { + this.field = field; + this.operator = operator; + this.value = value; + } + + @Override + public int hashCode() { + return Objects.hash(field, operator, value); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof ListFilter && toPb().equals(((ListFilter) obj).toPb()); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("field", field) + .add("operator", operator) + .add("value", value) + .toString(); + } + + String toPb() { + return field + ' ' + operator.name().toLowerCase() + ' ' + value.toString(); + } + } + + /** + * Class for filtering disk type lists. + */ + class DiskTypeFilter extends ListFilter { + + private static final long serialVersionUID = 4847837203592234453L; + + DiskTypeFilter(DiskTypeField field, ComparisonOperator operator, Object value) { + super(field.selector(), operator, value); + } + + /** + * Returns an equality filter for the given field and string value. For string fields, + * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must + * match the entire field. + * + * @see RE2 + */ + public static DiskTypeFilter equals(DiskTypeField field, String value) { + return new DiskTypeFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value)); + } + + /** + * Returns an equality filter for the given field and string value. For string fields, + * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must + * match the entire field. + * + * @see RE2 + */ + public static DiskTypeFilter notEquals(DiskTypeField field, String value) { + return new DiskTypeFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value)); + } + + /** + * Returns an equality filter for the given field and long value. + */ + public static DiskTypeFilter equals(DiskTypeField field, long value) { + return new DiskTypeFilter(checkNotNull(field), ComparisonOperator.EQ, value); + } + + /** + * Returns an inequality filter for the given field and long value. + */ + public static DiskTypeFilter notEquals(DiskTypeField field, long value) { + return new DiskTypeFilter(checkNotNull(field), ComparisonOperator.NE, value); + } + } + + /** + * Class for filtering machine type lists. + */ + class MachineTypeFilter extends ListFilter { + + private static final long serialVersionUID = 7346062041571853235L; + + MachineTypeFilter(MachineTypeField field, ComparisonOperator operator, Object value) { + super(field.selector(), operator, value); + } + + /** + * Returns an equality filter for the given field and string value. For string fields, + * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must + * match the entire field. + * + * @see RE2 + */ + public static MachineTypeFilter equals(MachineTypeField field, String value) { + return new MachineTypeFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value)); + } + + /** + * Returns an equality filter for the given field and string value. For string fields, + * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must + * match the entire field. + * + * @see RE2 + */ + public static MachineTypeFilter notEquals(MachineTypeField field, String value) { + return new MachineTypeFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value)); + } + + /** + * Returns an equality filter for the given field and long value. + */ + public static MachineTypeFilter equals(MachineTypeField field, long value) { + return new MachineTypeFilter(checkNotNull(field), ComparisonOperator.EQ, value); + } + + /** + * Returns an inequality filter for the given field and long value. + */ + public static MachineTypeFilter notEquals(MachineTypeField field, long value) { + return new MachineTypeFilter(checkNotNull(field), ComparisonOperator.NE, value); + } + } + + /** + * Class for filtering region lists. + */ + class RegionFilter extends ListFilter { + + private static final long serialVersionUID = 4464892812442567172L; + + RegionFilter(RegionField field, ComparisonOperator operator, Object value) { + super(field.selector(), operator, value); + } + + /** + * Returns an equality filter for the given field and string value. For string fields, + * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must + * match the entire field. + * + * @see RE2 + */ + public static RegionFilter equals(RegionField field, String value) { + return new RegionFilter(checkNotNull(field), ComparisonOperator.EQ, value); + } + + /** + * Returns an equality filter for the given field and string value. For string fields, + * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must + * match the entire field. + * + * @see RE2 + */ + public static RegionFilter notEquals(RegionField field, String value) { + return new RegionFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value)); + } + } + + /** + * Class for filtering zone lists. + */ + class ZoneFilter extends ListFilter { + + private static final long serialVersionUID = -3927428278548808737L; + + ZoneFilter(ZoneField field, ComparisonOperator operator, Object value) { + super(field.selector(), operator, value); + } + + /** + * Returns an equality filter for the given field and string value. For string fields, + * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must + * match the entire field. + * + * @see RE2 + */ + public static ZoneFilter equals(ZoneField field, String value) { + return new ZoneFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value)); + } + + /** + * Returns an equality filter for the given field and string value. For string fields, + * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must + * match the entire field. + * + * @see RE2 + */ + public static ZoneFilter notEquals(ZoneField field, String value) { + return new ZoneFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value)); + } + } + /** * Class for specifying disk type get options. */ @@ -244,6 +469,13 @@ private DiskTypeListOption(ComputeRpc.Option option, Object value) { super(option, value); } + /** + * Returns an option to specify a filter to the disk types being listed. + */ + public static DiskTypeListOption filter(DiskTypeFilter filter) { + return new DiskTypeListOption(ComputeRpc.Option.FILTER, filter.toPb()); + } + /** * Returns an option to specify the maximum number of disk types to be returned. */ @@ -271,6 +503,39 @@ public static DiskTypeListOption fields(DiskTypeField... fields) { } } + /** + * Class for specifying disk type aggregated list options. + */ + class DiskTypeAggregatedListOption extends Option { + + private static final long serialVersionUID = 7611137483018305170L; + + private DiskTypeAggregatedListOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify a filter to the disk types being listed. + */ + public static DiskTypeAggregatedListOption filter(DiskTypeFilter filter) { + return new DiskTypeAggregatedListOption(ComputeRpc.Option.FILTER, filter.toPb()); + } + + /** + * Returns an option to specify the maximum number of disk types to be returned. + */ + public static DiskTypeAggregatedListOption maxResults(long maxResults) { + return new DiskTypeAggregatedListOption(ComputeRpc.Option.MAX_RESULTS, maxResults); + } + + /** + * Returns an option to specify the page token from which to start listing disk types. + */ + public static DiskTypeAggregatedListOption startPageToken(String pageToken) { + return new DiskTypeAggregatedListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); + } + } + /** * Class for specifying machine type get options. */ @@ -304,6 +569,13 @@ private MachineTypeListOption(ComputeRpc.Option option, Object value) { super(option, value); } + /** + * Returns an option to specify a filter to the machine types being listed. + */ + public static MachineTypeListOption filter(MachineTypeFilter filter) { + return new MachineTypeListOption(ComputeRpc.Option.FILTER, filter.toPb()); + } + /** * Returns an option to specify the maximum number of machine types to be returned. */ @@ -331,6 +603,39 @@ public static MachineTypeListOption fields(MachineTypeField... fields) { } } + /** + * Class for specifying machine type aggregated list options. + */ + class MachineTypeAggregatedListOption extends Option { + + private static final long serialVersionUID = 8492257475500296057L; + + private MachineTypeAggregatedListOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify a filter to the machine types being listed. + */ + public static MachineTypeAggregatedListOption filter(MachineTypeFilter filter) { + return new MachineTypeAggregatedListOption(ComputeRpc.Option.FILTER, filter.toPb()); + } + + /** + * Returns an option to specify the maximum number of machine types to be returned. + */ + public static MachineTypeAggregatedListOption maxResults(long maxResults) { + return new MachineTypeAggregatedListOption(ComputeRpc.Option.MAX_RESULTS, maxResults); + } + + /** + * Returns an option to specify the page token from which to start listing machine types. + */ + public static MachineTypeAggregatedListOption startPageToken(String pageToken) { + return new MachineTypeAggregatedListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); + } + } + /** * Class for specifying region get options. */ @@ -364,6 +669,13 @@ private RegionListOption(ComputeRpc.Option option, Object value) { super(option, value); } + /** + * Returns an option to specify a filter to the regions being listed. + */ + public static RegionListOption filter(RegionFilter filter) { + return new RegionListOption(ComputeRpc.Option.FILTER, filter.toPb()); + } + /** * Returns an option to specify the maximum number of regions to be returned. */ @@ -424,6 +736,13 @@ private ZoneListOption(ComputeRpc.Option option, Object value) { super(option, value); } + /** + * Returns an option to specify a filter to the zones being listed. + */ + public static ZoneListOption filter(ZoneFilter filter) { + return new ZoneListOption(ComputeRpc.Option.FILTER, filter.toPb()); + } + /** * Returns an option to specify the maximum number of zones to be returned. */ @@ -478,100 +797,96 @@ public static LicenseOption fields(LicenseField... fields) { * * @throws ComputeException upon failure */ - DiskType getDiskType(DiskTypeId diskTypeId, DiskTypeOption... options) throws ComputeException; + DiskType getDiskType(DiskTypeId diskTypeId, DiskTypeOption... options); /** * Returns the requested disk type or {@code null} if not found. * * @throws ComputeException upon failure */ - DiskType getDiskType(String zone, String diskType, DiskTypeOption... options) - throws ComputeException; + DiskType getDiskType(String zone, String diskType, DiskTypeOption... options); /** - * Lists the disk types in the provided zone available to the current project. + * Lists the disk types in the provided zone. * * @throws ComputeException upon failure */ - Page listDiskTypes(String zone, DiskTypeListOption... options) throws ComputeException; + Page listDiskTypes(String zone, DiskTypeListOption... options); /** - * Lists all disk types available to the current project. + * Lists all disk types. * * @throws ComputeException upon failure */ - Page listDiskTypes(DiskTypeListOption... options) throws ComputeException; + Page listDiskTypes(DiskTypeAggregatedListOption... options); /** * Returns the requested machine type or {@code null} if not found. * * @throws ComputeException upon failure */ - MachineType getMachineType(MachineTypeId machineTypeId, MachineTypeOption... options) - throws ComputeException; + MachineType getMachineType(MachineTypeId machineTypeId, MachineTypeOption... options); /** * Returns the requested machine type or {@code null} if not found. * * @throws ComputeException upon failure */ - MachineType getMachineType(String zone, String machineType, MachineTypeOption... options) - throws ComputeException; + MachineType getMachineType(String zone, String machineType, MachineTypeOption... options); /** - * Lists the machine types in the provided zone available to the current project. + * Lists the machine types in the provided zone. * * @throws ComputeException upon failure */ - Page listMachineTypes(String zone, MachineTypeListOption... options) - throws ComputeException; + Page listMachineTypes(String zone, MachineTypeListOption... options); /** - * Lists all machine types available to the current project. + * Lists all machine types. * * @throws ComputeException upon failure */ - Page listMachineTypes(MachineTypeListOption... options) throws ComputeException; + Page listMachineTypes(MachineTypeAggregatedListOption... options); /** * Returns the requested region or {@code null} if not found. * * @throws ComputeException upon failure */ - Region getRegion(String region, RegionOption... options) throws ComputeException; + Region getRegion(String region, RegionOption... options); /** - * Lists the regions available to the current project. + * Lists the regions. * * @throws ComputeException upon failure */ - Page listRegions(RegionListOption... options) throws ComputeException; + Page listRegions(RegionListOption... options); /** * Returns the requested zone or {@code null} if not found. * * @throws ComputeException upon failure */ - Zone getZone(String zone, ZoneOption... options) throws ComputeException; + Zone getZone(String zone, ZoneOption... options); /** - * Lists the zones available to the current project. + * Lists the zones. * * @throws ComputeException upon failure */ - Page listZones(ZoneListOption... options) throws ComputeException; + Page listZones(ZoneListOption... options); /** * Returns the requested license or {@code null} if not found. * * @throws ComputeException upon failure */ - License getLicense(String license, LicenseOption... options) throws ComputeException; + License getLicense(String license, LicenseOption... options); /** * Returns the requested license or {@code null} if not found. * * @throws ComputeException upon failure */ - License getLicense(LicenseId license, LicenseOption... options) throws ComputeException; + License getLicense(LicenseId license, LicenseOption... options); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java index 2aa54d55e90e..2087e570a349 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java @@ -161,8 +161,7 @@ public Page nextPage() { } @Override - public DiskType getDiskType(final DiskTypeId diskTypeId, DiskTypeOption... options) - throws ComputeException { + public DiskType getDiskType(final DiskTypeId diskTypeId, DiskTypeOption... options) { final Map optionsMap = optionMap(options); try { com.google.api.services.compute.model.DiskType answer = @@ -179,14 +178,12 @@ public com.google.api.services.compute.model.DiskType call() { } @Override - public DiskType getDiskType(String zone, String diskType, DiskTypeOption... options) - throws ComputeException { + public DiskType getDiskType(String zone, String diskType, DiskTypeOption... options) { return getDiskType(DiskTypeId.of(zone, diskType), options); } @Override - public Page listDiskTypes(String zone, DiskTypeListOption... options) - throws ComputeException { + public Page listDiskTypes(String zone, DiskTypeListOption... options) { return listDiskTypes(zone, options(), optionMap(options)); } @@ -220,7 +217,7 @@ public DiskType apply(com.google.api.services.compute.model.DiskType diskType) { } @Override - public Page listDiskTypes(DiskTypeListOption... options) throws ComputeException { + public Page listDiskTypes(DiskTypeAggregatedListOption... options) { return listDiskTypes(options(), optionMap(options)); } @@ -252,15 +249,14 @@ public DiskType apply(com.google.api.services.compute.model.DiskType diskType) { } @Override - public MachineType getMachineType(final MachineTypeId machineTypeId, MachineTypeOption... options) - throws ComputeException { + public MachineType getMachineType(final MachineTypeId machineType, MachineTypeOption... options) { final Map optionsMap = optionMap(options); try { com.google.api.services.compute.model.MachineType answer = runWithRetries(new Callable() { @Override public com.google.api.services.compute.model.MachineType call() { - return computeRpc.getMachineType(machineTypeId.zone(), machineTypeId.machineType(), + return computeRpc.getMachineType(machineType.zone(), machineType.machineType(), optionsMap); } }, options().retryParams(), EXCEPTION_HANDLER); @@ -271,14 +267,12 @@ public com.google.api.services.compute.model.MachineType call() { } @Override - public MachineType getMachineType(String zone, String machineType, MachineTypeOption... options) - throws ComputeException { + public MachineType getMachineType(String zone, String machineType, MachineTypeOption... options) { return getMachineType(MachineTypeId.of(zone, machineType), options); } @Override - public Page listMachineTypes(String zone, MachineTypeListOption... options) - throws ComputeException { + public Page listMachineTypes(String zone, MachineTypeListOption... options) { return listMachineTypes(zone, options(), optionMap(options)); } @@ -313,8 +307,7 @@ public MachineType apply( } @Override - public Page listMachineTypes(MachineTypeListOption... options) - throws ComputeException { + public Page listMachineTypes(MachineTypeAggregatedListOption... options) { return listMachineTypes(options(), optionMap(options)); } @@ -348,7 +341,7 @@ public MachineType apply( } @Override - public Region getRegion(final String region, RegionOption... options) throws ComputeException { + public Region getRegion(final String region, RegionOption... options) { final Map optionsMap = optionMap(options); try { com.google.api.services.compute.model.Region answer = @@ -365,7 +358,7 @@ public com.google.api.services.compute.model.Region call() { } @Override - public Page listRegions(RegionListOption... options) throws ComputeException { + public Page listRegions(RegionListOption... options) { return listRegions(options(), optionMap(options)); } @@ -399,7 +392,7 @@ public Region apply(com.google.api.services.compute.model.Region region) { } @Override - public Zone getZone(final String zone, ZoneOption... options) throws ComputeException { + public Zone getZone(final String zone, ZoneOption... options) { final Map optionsMap = optionMap(options); try { com.google.api.services.compute.model.Zone answer = @@ -416,7 +409,7 @@ public com.google.api.services.compute.model.Zone call() { } @Override - public Page listZones(ZoneListOption... options) throws ComputeException { + public Page listZones(ZoneListOption... options) { return listZones(options(), optionMap(options)); } @@ -449,14 +442,12 @@ public Zone apply(com.google.api.services.compute.model.Zone zone) { } @Override - public License getLicense(String license, LicenseOption... options) - throws ComputeException { + public License getLicense(String license, LicenseOption... options) { return getLicense(LicenseId.of(license), options); } @Override - public License getLicense(LicenseId license, LicenseOption... options) - throws ComputeException { + public License getLicense(LicenseId license, LicenseOption... options) { final LicenseId completeId = license.setProjectId(options().projectId()); final Map optionsMap = optionMap(options); try { diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java index 4668756e04cb..35524e0c116d 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java @@ -90,81 +90,75 @@ public Y y() { * * @throws ComputeException upon failure */ - DiskType getDiskType(String zone, String diskType, Map options) - throws ComputeException; + DiskType getDiskType(String zone, String diskType, Map options); /** - * Lists the disk types in the provided zone available to the current project. + * Lists the disk types in the provided zone. * * @throws ComputeException upon failure */ - Tuple> listDiskTypes(String zone, Map options) - throws ComputeException; + Tuple> listDiskTypes(String zone, Map options); /** - * Lists all disk types available to the current project. + * Lists all disk types. * * @throws ComputeException upon failure */ - Tuple> listDiskTypes(Map options) throws ComputeException; + Tuple> listDiskTypes(Map options); /** * Returns the requested machine type or {@code null} if not found. * * @throws ComputeException upon failure */ - MachineType getMachineType(String zone, String diskType, Map options) - throws ComputeException; + MachineType getMachineType(String zone, String diskType, Map options); /** - * Lists the machine types in the provided zone available to the current project. + * Lists the machine types in the provided zone. * * @throws ComputeException upon failure */ - Tuple> listMachineTypes(String zone, Map options) - throws ComputeException; + Tuple> listMachineTypes(String zone, Map options); /** - * Lists all machine types available to the current project. + * Lists all machine types. * * @throws ComputeException upon failure */ - Tuple> listMachineTypes(Map options) - throws ComputeException; + Tuple> listMachineTypes(Map options); /** * Returns the requested region or {@code null} if not found. * * @throws ComputeException upon failure */ - Region getRegion(String region, Map options) throws ComputeException; + Region getRegion(String region, Map options); /** - * Lists the regions available to the current project. + * Lists the regions. * * @throws ComputeException upon failure */ - Tuple> listRegions(Map options) throws ComputeException; + Tuple> listRegions(Map options); /** * Returns the requested zone or {@code null} if not found. * * @throws ComputeException upon failure */ - Zone getZone(String zone, Map options) throws ComputeException; + Zone getZone(String zone, Map options); /** - * Lists the zones available to the current project. + * Lists the zones. * * @throws ComputeException upon failure */ - Tuple> listZones(Map options) throws ComputeException; + Tuple> listZones(Map options); /** * Returns the requested license or {@code null} if not found. * * @throws ComputeException upon failure */ - License getLicense(String project, String license, Map options) - throws ComputeException; + License getLicense(String project, String license, Map options); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java index 16e8464843fb..fe714acab502 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java @@ -66,25 +66,19 @@ private static ComputeException translate(IOException exception) { } @Override - public DiskType getDiskType(String zone, String diskType, Map options) - throws ComputeException { + public DiskType getDiskType(String zone, String diskType, Map options) { try { return compute.diskTypes() .get(this.options.projectId(), zone, diskType) .setFields(FIELDS.getString(options)) .execute(); } catch (IOException ex) { - ComputeException serviceException = translate(ex); - if (serviceException.code() == HTTP_NOT_FOUND) { - return null; - } - throw serviceException; + return nullForNotFound(ex); } } @Override - public Tuple> listDiskTypes(String zone, Map options) - throws ComputeException { + public Tuple> listDiskTypes(String zone, Map options) { try { DiskTypeList diskTypesList = compute.diskTypes() .list(this.options.projectId(), zone) @@ -101,21 +95,20 @@ public Tuple> listDiskTypes(String zone, Map> listDiskTypes(Map options) - throws ComputeException { + public Tuple> listDiskTypes(Map options) { try { DiskTypeAggregatedList aggregatedList = compute.diskTypes() .aggregatedList(this.options.projectId()) .setFilter(FILTER.getString(options)) .setMaxResults(MAX_RESULTS.getLong(options)) .setPageToken(PAGE_TOKEN.getString(options)) - .setFields(FIELDS.getString(options)) + // todo(mziccard): uncomment or remove once #711 is closed + // .setFields(FIELDS.getString(options)) .execute(); ImmutableList.Builder builder = ImmutableList.builder(); Map scopedList = aggregatedList.getItems(); if (scopedList != null) { - for (String key : scopedList.keySet()) { - DiskTypesScopedList diskTypesScopedList = scopedList.get(key); + for (DiskTypesScopedList diskTypesScopedList : scopedList.values()) { if (diskTypesScopedList.getDiskTypes() != null) { builder.addAll(diskTypesScopedList.getDiskTypes()); } @@ -129,25 +122,20 @@ public Tuple> listDiskTypes(Map options) } @Override - public MachineType getMachineType(String zone, String machineType, Map options) - throws ComputeException { + public MachineType getMachineType(String zone, String machineType, Map options) { try { return compute.machineTypes() .get(this.options.projectId(), zone, machineType) .setFields(FIELDS.getString(options)) .execute(); } catch (IOException ex) { - ComputeException serviceException = translate(ex); - if (serviceException.code() == HTTP_NOT_FOUND) { - return null; - } - throw serviceException; + return nullForNotFound(ex); } } @Override - public Tuple> listMachineTypes(String zone, Map options) - throws ComputeException { + public Tuple> listMachineTypes(String zone, + Map options) { try { MachineTypeList machineTypesList = compute.machineTypes() .list(this.options.projectId(), zone) @@ -164,21 +152,20 @@ public Tuple> listMachineTypes(String zone, Map> listMachineTypes(Map options) - throws ComputeException { + public Tuple> listMachineTypes(Map options) { try { MachineTypeAggregatedList aggregatedList = compute.machineTypes() .aggregatedList(this.options.projectId()) .setFilter(FILTER.getString(options)) .setMaxResults(MAX_RESULTS.getLong(options)) .setPageToken(PAGE_TOKEN.getString(options)) - .setFields(FIELDS.getString(options)) + // todo(mziccard): uncomment or remove once #711 is closed + // .setFields(FIELDS.getString(options)) .execute(); ImmutableList.Builder builder = ImmutableList.builder(); Map scopedList = aggregatedList.getItems(); if (scopedList != null) { - for (String key : scopedList.keySet()) { - MachineTypesScopedList machineTypesScopedList = scopedList.get(key); + for (MachineTypesScopedList machineTypesScopedList : scopedList.values()) { if (machineTypesScopedList.getMachineTypes() != null) { builder.addAll(machineTypesScopedList.getMachineTypes()); } @@ -192,24 +179,19 @@ public Tuple> listMachineTypes(Map opti } @Override - public Region getRegion(String region, Map options) throws ComputeException { + public Region getRegion(String region, Map options) { try { return compute.regions() .get(this.options.projectId(), region) .setFields(FIELDS.getString(options)) .execute(); } catch (IOException ex) { - ComputeException serviceException = translate(ex); - if (serviceException.code() == HTTP_NOT_FOUND) { - return null; - } - throw serviceException; + return nullForNotFound(ex); } } @Override - public Tuple> listRegions(Map options) - throws ComputeException { + public Tuple> listRegions(Map options) { try { RegionList regionsList = compute.regions() .list(this.options.projectId()) @@ -226,23 +208,19 @@ public Tuple> listRegions(Map options) } @Override - public Zone getZone(String zone, Map options) throws ComputeException { + public Zone getZone(String zone, Map options) { try { return compute.zones() .get(this.options.projectId(), zone) .setFields(FIELDS.getString(options)) .execute(); } catch (IOException ex) { - ComputeException serviceException = translate(ex); - if (serviceException.code() == HTTP_NOT_FOUND) { - return null; - } - throw serviceException; + return nullForNotFound(ex); } } @Override - public Tuple> listZones(Map options) throws ComputeException { + public Tuple> listZones(Map options) { try { ZoneList zonesList = compute.zones() .list(this.options.projectId()) @@ -259,19 +237,28 @@ public Tuple> listZones(Map options) throws Co } @Override - public License getLicense(String project, String license, Map options) - throws ComputeException { + public License getLicense(String project, String license, Map options) { try { return compute.licenses() .get(project, license) .setFields(FIELDS.getString(options)) .execute(); } catch (IOException ex) { - ComputeException serviceException = translate(ex); - if (serviceException.code() == HTTP_NOT_FOUND) { - return null; - } - throw serviceException; + return nullForNotFound(ex); + } + } + + /** + * This method returns {@code null} if the error code of {@code exception} was 404, re-throws the + * exception otherwise. + * + * @throws ComputeException if the error code of {@code exception} was not 404. + */ + private static T nullForNotFound(IOException exception) { + ComputeException serviceException = translate(exception); + if (serviceException.code() == HTTP_NOT_FOUND) { + return (T) null; } + throw serviceException; } } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java index c1b44a26b51f..5ef9b04ed446 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java @@ -126,13 +126,26 @@ public class ComputeImplTest { Compute.DiskTypeOption.fields(Compute.DiskTypeField.ID, Compute.DiskTypeField.DESCRIPTION); // DiskType list options + private static final Compute.DiskTypeFilter DISK_TYPE_FILTER = + Compute.DiskTypeFilter.equals(Compute.DiskTypeField.DESCRIPTION, "someDescription"); private static final Compute.DiskTypeListOption DISK_TYPE_LIST_PAGE_TOKEN = Compute.DiskTypeListOption.startPageToken("cursor"); private static final Compute.DiskTypeListOption DISK_TYPE_LIST_MAX_RESULTS = Compute.DiskTypeListOption.maxResults(42L); + private static final Compute.DiskTypeListOption DISK_TYPE_LIST_FILTER = + Compute.DiskTypeListOption.filter(DISK_TYPE_FILTER); private static final Map DISK_TYPE_LIST_OPTIONS = ImmutableMap.of( ComputeRpc.Option.PAGE_TOKEN, "cursor", - ComputeRpc.Option.MAX_RESULTS, 42L); + ComputeRpc.Option.MAX_RESULTS, 42L, + ComputeRpc.Option.FILTER, "description eq someDescription"); + + // DiskType aggregated list options + private static final Compute.DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_PAGE_TOKEN = + Compute.DiskTypeAggregatedListOption.startPageToken("cursor"); + private static final Compute.DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_MAX_RESULTS = + Compute.DiskTypeAggregatedListOption.maxResults(42L); + private static final Compute.DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_FILTER = + Compute.DiskTypeAggregatedListOption.filter(DISK_TYPE_FILTER); // MachineType options private static final Compute.MachineTypeOption MACHINE_TYPE_OPTION_FIELDS = @@ -140,39 +153,64 @@ public class ComputeImplTest { Compute.MachineTypeField.DESCRIPTION); // MachineType list options + private static final Compute.MachineTypeFilter MACHINE_TYPE_FILTER = + Compute.MachineTypeFilter.notEquals(Compute.MachineTypeField.MAXIMUM_PERSISTENT_DISKS, 42L); private static final Compute.MachineTypeListOption MACHINE_TYPE_LIST_PAGE_TOKEN = Compute.MachineTypeListOption.startPageToken("cursor"); private static final Compute.MachineTypeListOption MACHINE_TYPE_LIST_MAX_RESULTS = Compute.MachineTypeListOption.maxResults(42L); + private static final Compute.MachineTypeListOption MACHINE_TYPE_LIST_FILTER = + Compute.MachineTypeListOption.filter(MACHINE_TYPE_FILTER); private static final Map MACHINE_TYPE_LIST_OPTIONS = ImmutableMap.of( ComputeRpc.Option.PAGE_TOKEN, "cursor", - ComputeRpc.Option.MAX_RESULTS, 42L); + ComputeRpc.Option.MAX_RESULTS, 42L, + ComputeRpc.Option.FILTER, "maximumPersistentDisks ne 42"); + + // MachineType aggregated list options + private static final Compute.MachineTypeAggregatedListOption + MACHINE_TYPE_AGGREGATED_LIST_PAGE_TOKEN = + Compute.MachineTypeAggregatedListOption.startPageToken("cursor"); + private static final Compute.MachineTypeAggregatedListOption + MACHINE_TYPE_AGGREGATED_LIST_MAX_RESULTS = + Compute.MachineTypeAggregatedListOption.maxResults(42L); + private static final Compute.MachineTypeAggregatedListOption MACHINE_TYPE_AGGREGATED_LIST_FILTER = + Compute.MachineTypeAggregatedListOption.filter(MACHINE_TYPE_FILTER); // Region options private static final Compute.RegionOption REGION_OPTION_FIELDS = Compute.RegionOption.fields(Compute.RegionField.ID, Compute.RegionField.DESCRIPTION); // Region list options + private static final Compute.RegionFilter REGION_FILTER = + Compute.RegionFilter.equals(Compute.RegionField.ID, "someId"); private static final Compute.RegionListOption REGION_LIST_PAGE_TOKEN = Compute.RegionListOption.startPageToken("cursor"); private static final Compute.RegionListOption REGION_LIST_MAX_RESULTS = Compute.RegionListOption.maxResults(42L); + private static final Compute.RegionListOption REGION_LIST_FILTER = + Compute.RegionListOption.filter(REGION_FILTER); private static final Map REGION_LIST_OPTIONS = ImmutableMap.of( ComputeRpc.Option.PAGE_TOKEN, "cursor", - ComputeRpc.Option.MAX_RESULTS, 42L); + ComputeRpc.Option.MAX_RESULTS, 42L, + ComputeRpc.Option.FILTER, "id eq someId"); // Zone options private static final Compute.ZoneOption ZONE_OPTION_FIELDS = Compute.ZoneOption.fields(Compute.ZoneField.ID, Compute.ZoneField.DESCRIPTION); // Zone list options + private static final Compute.ZoneFilter ZONE_FILTER = + Compute.ZoneFilter.notEquals(Compute.ZoneField.NAME, "someName"); private static final Compute.ZoneListOption ZONE_LIST_PAGE_TOKEN = Compute.ZoneListOption.startPageToken("cursor"); private static final Compute.ZoneListOption ZONE_LIST_MAX_RESULTS = Compute.ZoneListOption.maxResults(42L); + private static final Compute.ZoneListOption ZONE_LIST_FILTER = + Compute.ZoneListOption.filter(ZONE_FILTER); private static final Map ZONE_LIST_OPTIONS = ImmutableMap.of( ComputeRpc.Option.PAGE_TOKEN, "cursor", - ComputeRpc.Option.MAX_RESULTS, 42L); + ComputeRpc.Option.MAX_RESULTS, 42L, + ComputeRpc.Option.FILTER, "name ne someName"); // License options private static final Compute.LicenseOption LICENSE_OPTION_FIELDS = @@ -293,7 +331,7 @@ public void testListDiskTypesWithOptions() { .andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listDiskTypes(DISK_TYPE_ID.zone(), DISK_TYPE_LIST_MAX_RESULTS, - DISK_TYPE_LIST_PAGE_TOKEN); + DISK_TYPE_LIST_PAGE_TOKEN, DISK_TYPE_LIST_FILTER); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(diskTypeList.toArray(), Iterables.toArray(page.values(), DiskType.class)); } @@ -334,8 +372,8 @@ public void testAggregatedListDiskTypesWithOptions() { Tuple.of(cursor, Iterables.transform(diskTypeList, DiskType.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listDiskTypes(DISK_TYPE_LIST_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); - Page page = - compute.listDiskTypes(DISK_TYPE_LIST_MAX_RESULTS, DISK_TYPE_LIST_PAGE_TOKEN); + Page page = compute.listDiskTypes(DISK_TYPE_AGGREGATED_LIST_MAX_RESULTS, + DISK_TYPE_AGGREGATED_LIST_PAGE_TOKEN, DISK_TYPE_AGGREGATED_LIST_FILTER); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(diskTypeList.toArray(), Iterables.toArray(page.values(), DiskType.class)); } @@ -427,7 +465,7 @@ public void testListMachineTypesWithOptions() { .andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listMachineTypes(MACHINE_TYPE_ID.zone(), - MACHINE_TYPE_LIST_MAX_RESULTS, MACHINE_TYPE_LIST_PAGE_TOKEN); + MACHINE_TYPE_LIST_MAX_RESULTS, MACHINE_TYPE_LIST_PAGE_TOKEN, MACHINE_TYPE_LIST_FILTER); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(machineTypeList.toArray(), Iterables.toArray(page.values(), MachineType.class)); @@ -473,8 +511,8 @@ public void testAggregatedListMachineTypesWithOptions() { EasyMock.expect(computeRpcMock.listMachineTypes(MACHINE_TYPE_LIST_OPTIONS)) .andReturn(result); EasyMock.replay(computeRpcMock); - Page page = - compute.listMachineTypes(MACHINE_TYPE_LIST_MAX_RESULTS, MACHINE_TYPE_LIST_PAGE_TOKEN); + Page page = compute.listMachineTypes(MACHINE_TYPE_AGGREGATED_LIST_MAX_RESULTS, + MACHINE_TYPE_AGGREGATED_LIST_PAGE_TOKEN, MACHINE_TYPE_AGGREGATED_LIST_FILTER); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(machineTypeList.toArray(), Iterables.toArray(page.values(), MachineType.class)); @@ -543,7 +581,8 @@ public void testListRegionsWithOptions() { Tuple.of(cursor, Iterables.transform(regionList, Region.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listRegions(REGION_LIST_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); - Page page = compute.listRegions(REGION_LIST_MAX_RESULTS, REGION_LIST_PAGE_TOKEN); + Page page = compute.listRegions(REGION_LIST_MAX_RESULTS, REGION_LIST_PAGE_TOKEN, + REGION_LIST_FILTER); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(regionList.toArray(), Iterables.toArray(page.values(), Region.class)); } @@ -610,7 +649,8 @@ public void testListZonesWithOptions() { Tuple.of(cursor, Iterables.transform(zoneList, Zone.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listZones(ZONE_LIST_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); - Page page = compute.listZones(ZONE_LIST_MAX_RESULTS, ZONE_LIST_PAGE_TOKEN); + Page page = + compute.listZones(ZONE_LIST_MAX_RESULTS, ZONE_LIST_PAGE_TOKEN, ZONE_LIST_FILTER); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(zoneList.toArray(), Iterables.toArray(page.values(), Zone.class)); } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java index 15f3e1c05420..5bc2589e6244 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java @@ -17,8 +17,11 @@ package com.google.gcloud.compute.it; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import com.google.gcloud.Page; import com.google.gcloud.compute.Compute; @@ -87,6 +90,7 @@ public void testGetDiskTypeWithSelectedFields() { public void testListDiskTypes() { Page diskPage = compute.listDiskTypes(ZONE); Iterator diskTypeIterator = diskPage.iterateAll(); + assertTrue(diskTypeIterator.hasNext()); while(diskTypeIterator.hasNext()) { DiskType diskType = diskTypeIterator.next(); // todo(mziccard): uncomment or remove once #695 is closed @@ -105,6 +109,7 @@ public void testListDiskTypesWithSelectedFields() { Page diskPage = compute.listDiskTypes(ZONE, Compute.DiskTypeListOption.fields(Compute.DiskTypeField.CREATION_TIMESTAMP)); Iterator diskTypeIterator = diskPage.iterateAll(); + assertTrue(diskTypeIterator.hasNext()); while(diskTypeIterator.hasNext()) { DiskType diskType = diskTypeIterator.next(); assertNull(diskType.id()); @@ -117,10 +122,30 @@ public void testListDiskTypesWithSelectedFields() { } } + @Test + public void testListDiskTypesWithFilter() { + Page diskPage = compute.listDiskTypes(ZONE, Compute.DiskTypeListOption.filter( + Compute.DiskTypeFilter.equals(Compute.DiskTypeField.DEFAULT_DISK_SIZE_GB, 375))); + Iterator diskTypeIterator = diskPage.iterateAll(); + assertTrue(diskTypeIterator.hasNext()); + while(diskTypeIterator.hasNext()) { + DiskType diskType = diskTypeIterator.next(); + // todo(mziccard): uncomment or remove once #695 is closed + // assertNotNull(diskType.id()); + assertNotNull(diskType.diskTypeId()); + assertEquals(ZONE, diskType.diskTypeId().zone()); + assertNotNull(diskType.creationTimestamp()); + assertNotNull(diskType.description()); + assertNotNull(diskType.validDiskSize()); + assertEquals(375, (long) diskType.defaultDiskSizeGb()); + } + } + @Test public void testAggregatedListDiskTypes() { Page diskPage = compute.listDiskTypes(); Iterator diskTypeIterator = diskPage.iterateAll(); + assertTrue(diskTypeIterator.hasNext()); while(diskTypeIterator.hasNext()) { DiskType diskType = diskTypeIterator.next(); // todo(mziccard): uncomment or remove once #695 is closed @@ -134,19 +159,20 @@ public void testAggregatedListDiskTypes() { } @Test - public void testAggregatedListDiskTypesWithSelectedFields() { - Page diskPage = compute.listDiskTypes( - Compute.DiskTypeListOption.fields(Compute.DiskTypeField.CREATION_TIMESTAMP)); + public void testAggregatedListDiskTypesWithFilter() { + Page diskPage = compute.listDiskTypes(Compute.DiskTypeAggregatedListOption.filter( + Compute.DiskTypeFilter.notEquals(Compute.DiskTypeField.DEFAULT_DISK_SIZE_GB, 375))); Iterator diskTypeIterator = diskPage.iterateAll(); + assertTrue(diskTypeIterator.hasNext()); while(diskTypeIterator.hasNext()) { DiskType diskType = diskTypeIterator.next(); - assertNull(diskType.id()); + // todo(mziccard): uncomment or remove once #695 is closed + // assertNotNull(diskType.id()); assertNotNull(diskType.diskTypeId()); - assertEquals(ZONE, diskType.diskTypeId().zone()); assertNotNull(diskType.creationTimestamp()); - assertNull(diskType.description()); - assertNull(diskType.validDiskSize()); - assertNull(diskType.defaultDiskSizeGb()); + assertNotNull(diskType.description()); + assertNotNull(diskType.validDiskSize()); + assertNotEquals(375, (long) diskType.defaultDiskSizeGb()); } } @@ -183,6 +209,7 @@ public void testGetMachineTypeWithSelectedFields() { public void testListMachineTypes() { Page machinePage = compute.listMachineTypes(ZONE); Iterator machineTypeIterator = machinePage.iterateAll(); + assertTrue(machineTypeIterator.hasNext()); while(machineTypeIterator.hasNext()) { MachineType machineType = machineTypeIterator.next(); assertNotNull(machineType.machineTypeId()); @@ -202,6 +229,7 @@ public void testListMachineTypesWithSelectedFields() { Page machinePage = compute.listMachineTypes(ZONE, Compute.MachineTypeListOption.fields(Compute.MachineTypeField.CREATION_TIMESTAMP)); Iterator machineTypeIterator = machinePage.iterateAll(); + assertTrue(machineTypeIterator.hasNext()); while(machineTypeIterator.hasNext()) { MachineType machineType = machineTypeIterator.next(); assertNotNull(machineType.machineTypeId()); @@ -216,10 +244,33 @@ public void testListMachineTypesWithSelectedFields() { } } + @Test + public void testListMachineTypesWithFilter() { + Page machinePage = compute.listMachineTypes(ZONE, + Compute.MachineTypeListOption.filter( + Compute.MachineTypeFilter.equals(Compute.MachineTypeField.GUEST_CPUS, 2))); + Iterator machineTypeIterator = machinePage.iterateAll(); + assertTrue(machineTypeIterator.hasNext()); + while(machineTypeIterator.hasNext()) { + MachineType machineType = machineTypeIterator.next(); + assertNotNull(machineType.machineTypeId()); + assertEquals(ZONE, machineType.machineTypeId().zone()); + assertNotNull(machineType.id()); + assertNotNull(machineType.creationTimestamp()); + assertNotNull(machineType.description()); + assertNotNull(machineType.cpus()); + assertEquals(2, (long) machineType.cpus()); + assertNotNull(machineType.memoryMb()); + assertNotNull(machineType.maximumPersistentDisks()); + assertNotNull(machineType.maximumPersistentDisksSizeGb()); + } + } + @Test public void testAggregatedListMachineTypes() { Page machinePage = compute.listMachineTypes(); Iterator machineTypeIterator = machinePage.iterateAll(); + assertTrue(machineTypeIterator.hasNext()); while(machineTypeIterator.hasNext()) { MachineType machineType = machineTypeIterator.next(); assertNotNull(machineType.machineTypeId()); @@ -234,20 +285,23 @@ public void testAggregatedListMachineTypes() { } @Test - public void testAggregatedListMachineTypesWithSelectedFields() { - Page machinePage = compute.listMachineTypes( - Compute.MachineTypeListOption.fields(Compute.MachineTypeField.CREATION_TIMESTAMP)); + public void testAggregatedListMachineTypesWithFilter() { + Page machinePage = + compute.listMachineTypes(Compute.MachineTypeAggregatedListOption.filter( + Compute.MachineTypeFilter.notEquals(Compute.MachineTypeField.GUEST_CPUS, 2))); Iterator machineTypeIterator = machinePage.iterateAll(); + assertTrue(machineTypeIterator.hasNext()); while(machineTypeIterator.hasNext()) { MachineType machineType = machineTypeIterator.next(); assertNotNull(machineType.machineTypeId()); - assertNull(machineType.id()); + assertNotNull(machineType.id()); assertNotNull(machineType.creationTimestamp()); - assertNull(machineType.description()); - assertNull(machineType.cpus()); - assertNull(machineType.memoryMb()); - assertNull(machineType.maximumPersistentDisks()); - assertNull(machineType.maximumPersistentDisksSizeGb()); + assertNotNull(machineType.description()); + assertNotNull(machineType.cpus()); + assertNotEquals(2, (long) machineType.cpus()); + assertNotNull(machineType.memoryMb()); + assertNotNull(machineType.maximumPersistentDisks()); + assertNotNull(machineType.maximumPersistentDisksSizeGb()); } } @@ -322,6 +376,15 @@ public void testListRegionsWithSelectedFields() { } } + @Test + public void testListRegionsWithFilter() { + Page regionPage = compute.listRegions(Compute.RegionListOption.filter( + Compute.RegionFilter.equals(Compute.RegionField.NAME, REGION))); + Iterator regionIterator = regionPage.iterateAll(); + assertEquals(REGION, regionIterator.next().regionId().region()); + assertFalse(regionIterator.hasNext()); + } + @Test public void testGetZone() { Zone zone = compute.getZone(ZONE); @@ -375,4 +438,13 @@ public void testListZonesWithSelectedFields() { assertNull(zone.region()); } } + + @Test + public void testListZonesWithFilter() { + Page zonePage = compute.listZones( + Compute.ZoneListOption.filter(Compute.ZoneFilter.equals(Compute.ZoneField.NAME, ZONE))); + Iterator zoneIterator = zonePage.iterateAll(); + assertEquals(ZONE, zoneIterator.next().zoneId().zone()); + assertFalse(zoneIterator.hasNext()); + } } From e1712e99c836c71b5ad20489cf7149ab53857833 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 8 Mar 2016 15:18:42 +0100 Subject: [PATCH 284/375] Add support for Compute's operations - Add RegionOperationId, ZoneOperationId, GlobalOperationId classes - Add functional methods for operations to Compute's service and rpc classes - Add Operation class (with functional methods) - Add unit and integration tests --- .../com/google/gcloud/compute/Compute.java | 220 +++++ .../google/gcloud/compute/ComputeImpl.java | 214 +++++ .../gcloud/compute/GlobalOperationId.java | 107 +++ .../com/google/gcloud/compute/Operation.java | 800 ++++++++++++++++++ .../google/gcloud/compute/OperationId.java | 38 + .../gcloud/compute/RegionOperationId.java | 112 +++ .../gcloud/compute/ZoneOperationId.java | 114 +++ .../com/google/gcloud/spi/ComputeRpc.java | 67 ++ .../google/gcloud/spi/DefaultComputeRpc.java | 123 ++- .../gcloud/compute/ComputeImplTest.java | 496 ++++++++++- .../gcloud/compute/OperationIdTest.java | 143 ++++ .../google/gcloud/compute/OperationTest.java | 489 +++++++++++ .../gcloud/compute/SerializationTest.java | 54 +- .../gcloud/compute/it/ITComputeTest.java | 193 ++++- 14 files changed, 3151 insertions(+), 19 deletions(-) create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalOperationId.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/OperationId.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionOperationId.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneOperationId.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationIdTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java index eb96df0eaba9..4acfab38addb 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java @@ -219,6 +219,61 @@ static String selector(LicenseField... fields) { } } + /** + * Fields of a Compute Engine Operation resource. + * + * @see + * GlobalOperation Resource + * @see + * RegionOperation Resource + * @see + * ZoneOperation Resource + */ + enum OperationField { + CLIENT_OPERATION_ID("clientOperationId"), + CREATION_TIMESTAMP("creationTimestamp"), + DESCRIPTION("description"), + END_TIME("endTime"), + ERROR("error"), + HTTP_ERROR_MESSAGE("httpErrorMessage"), + HTTP_ERROR_STATUS_CODE("httpErrorStatusCode"), + ID("id"), + INSERT_TIME("insertTime"), + NAME("name"), + OPERATION_TYPE("operationType"), + PROGRESS("progress"), + SELF_LINK("selfLink"), + START_TIME("startTime"), + STATUS("status"), + STATUS_MESSAGE("statusMessage"), + REGION("region"), + TARGET_ID("targetId"), + TARGET_LINK("targetLink"), + USER("user"), + WARNINGS("warnings"); + + private final String selector; + + OperationField(String selector) { + this.selector = selector; + } + + public String selector() { + return selector; + } + + static String selector(OperationField... fields) { + Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); + fieldStrings.add(SELF_LINK.selector()); + for (OperationField field : fields) { + fieldStrings.add(field.selector()); + } + return Joiner.on(',').join(fieldStrings); + } + } + /** * Base class for list filters. */ @@ -436,6 +491,68 @@ public static ZoneFilter notEquals(ZoneField field, String value) { } } + /** + * Class for filtering operation lists. + */ + class OperationFilter extends ListFilter { + + private static final long serialVersionUID = -3202249202748346427L; + + OperationFilter(OperationField field, ComparisonOperator operator, Object value) { + super(field.selector(), operator, value); + } + + /** + * Returns an equality filter for the given field and string value. For string fields, + * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must + * match the entire field. + * + * @see RE2 + */ + public static OperationFilter equals(OperationField field, String value) { + return new OperationFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value)); + } + + /** + * Returns an equality filter for the given field and string value. For string fields, + * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must + * match the entire field. + * + * @see RE2 + */ + public static OperationFilter notEquals(OperationField field, String value) { + return new OperationFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value)); + } + + /** + * Returns an equality filter for the given field and long value. + */ + public static OperationFilter equals(OperationField field, long value) { + return new OperationFilter(checkNotNull(field), ComparisonOperator.EQ, value); + } + + /** + * Returns an inequality filter for the given field and long value. + */ + public static OperationFilter notEquals(OperationField field, long value) { + return new OperationFilter(checkNotNull(field), ComparisonOperator.NE, value); + } + + /** + * Returns an equality filter for the given field and integer value. + */ + public static OperationFilter equals(OperationField field, int value) { + return new OperationFilter(checkNotNull(field), ComparisonOperator.EQ, value); + } + + /** + * Returns an inequality filter for the given field and integer value. + */ + public static OperationFilter notEquals(OperationField field, int value) { + return new OperationFilter(checkNotNull(field), ComparisonOperator.NE, value); + } + } + /** * Class for specifying disk type get options. */ @@ -792,6 +909,73 @@ public static LicenseOption fields(LicenseField... fields) { } } + /** + * Class for specifying operation get options. + */ + class OperationOption extends Option { + + private static final long serialVersionUID = -4572636917684779912L; + + private OperationOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify the operation's fields to be returned by the RPC call. If this + * option is not provided all operation's fields are returned. {@code OperationOption.fields} + * can be used to specify only the fields of interest. {@link Operation#operationId()} is + * always returned, even if not specified. + */ + public static OperationOption fields(OperationField... fields) { + return new OperationOption(ComputeRpc.Option.FIELDS, OperationField.selector(fields)); + } + } + + /** + * Class for specifying operation list options. + */ + class OperationListOption extends Option { + + private static final long serialVersionUID = -1509532420587265823L; + + private OperationListOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify a filter to the operations being listed. + */ + public static OperationListOption filter(OperationFilter filter) { + return new OperationListOption(ComputeRpc.Option.FILTER, filter.toPb()); + } + + /** + * Returns an option to specify the maximum number of operations to be returned. + */ + public static OperationListOption maxResults(long maxResults) { + return new OperationListOption(ComputeRpc.Option.MAX_RESULTS, maxResults); + } + + /** + * Returns an option to specify the page token from which to start listing operations. + */ + public static OperationListOption startPageToken(String pageToken) { + return new OperationListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); + } + + /** + * Returns an option to specify the operation's fields to be returned by the RPC call. If this + * option is not provided all operation's fields are returned. + * {@code OperationListOption.fields} can be used to specify only the fields of interest. + * {@link Operation#operationId()} is always returned, even if not specified. + */ + public static OperationListOption fields(OperationField... fields) { + StringBuilder builder = new StringBuilder(); + builder.append("items(").append(OperationField.selector(fields)).append("),nextPageToken"); + return new OperationListOption(ComputeRpc.Option.FIELDS, builder.toString()); + } + } + /** * Returns the requested disk type or {@code null} if not found. * @@ -889,4 +1073,40 @@ public static LicenseOption fields(LicenseField... fields) { * @throws ComputeException upon failure */ License getLicense(LicenseId license, LicenseOption... options); + + /** + * Returns the requested operation or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + Operation get(OperationId operationId, OperationOption... options); + + /** + * Lists the global operations. + * + * @throws ComputeException upon failure + */ + Page listGlobalOperations(OperationListOption... options); + + /** + * Lists the operations in the provided region. + * + * @throws ComputeException upon failure + */ + Page listRegionOperations(String region, OperationListOption... options); + + /** + * Lists the operations in the provided zone. + * + * @throws ComputeException upon failure + */ + Page listZoneOperations(String zone, OperationListOption... options); + + /** + * Deletes the requested operation. + * + * @return {@code true} if operation was deleted, {@code false} if it was not found + * @throws ComputeException upon failure + */ + boolean delete(OperationId operation); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java index 2087e570a349..13239d8209b6 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java @@ -35,6 +35,25 @@ final class ComputeImpl extends BaseService implements Compute { + private static class GlobalOperationPageFetcher implements NextPageFetcher { + + private static final long serialVersionUID = -2488912172182315364L; + private final Map requestOptions; + private final ComputeOptions serviceOptions; + + GlobalOperationPageFetcher(ComputeOptions serviceOptions, String cursor, + Map optionMap) { + this.requestOptions = + PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + } + + @Override + public Page nextPage() { + return listGlobalOperations(serviceOptions, requestOptions); + } + } + private static class DiskTypePageFetcher implements NextPageFetcher { private static final long serialVersionUID = -5253916264932522976L; @@ -153,6 +172,48 @@ public Page nextPage() { } } + private static class RegionOperationPageFetcher implements NextPageFetcher { + + private static final long serialVersionUID = 4111705358926164078L; + private final Map requestOptions; + private final ComputeOptions serviceOptions; + private final String region; + + RegionOperationPageFetcher(String region, ComputeOptions serviceOptions, String cursor, + Map optionMap) { + this.requestOptions = + PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + this.region = region; + } + + @Override + public Page nextPage() { + return listRegionOperations(region, serviceOptions, requestOptions); + } + } + + private static class ZoneOperationPageFetcher implements NextPageFetcher { + + private static final long serialVersionUID = 4111705358926164078L; + private final Map requestOptions; + private final ComputeOptions serviceOptions; + private final String zone; + + ZoneOperationPageFetcher(String zone, ComputeOptions serviceOptions, String cursor, + Map optionMap) { + this.requestOptions = + PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + this.zone = zone; + } + + @Override + public Page nextPage() { + return listZoneOperations(zone, serviceOptions, requestOptions); + } + } + private final ComputeRpc computeRpc; ComputeImpl(ComputeOptions options) { @@ -464,6 +525,159 @@ public com.google.api.services.compute.model.License call() { } } + @Override + public Operation get(final OperationId operationId, OperationOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + if (operationId instanceof RegionOperationId) { + RegionOperationId regionOperationId = (RegionOperationId) operationId; + return computeRpc.getRegionOperation(regionOperationId.region(), + regionOperationId.operation(), optionsMap); + } else if (operationId instanceof ZoneOperationId) { + ZoneOperationId zoneOperationId = (ZoneOperationId) operationId; + return computeRpc.getZoneOperation(zoneOperationId.zone(), + zoneOperationId.operation(), optionsMap); + } else { + return computeRpc.getGlobalOperation(operationId.operation(), optionsMap); + } + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Page listGlobalOperations(OperationListOption... options) { + return listGlobalOperations(options(), optionMap(options)); + } + + private static Page listGlobalOperations(final ComputeOptions serviceOptions, + final Map optionsMap) { + try { + ComputeRpc.Tuple> result = + runWithRetries(new Callable>>() { + @Override + public ComputeRpc.Tuple> call() { + return serviceOptions.rpc().listGlobalOperations(optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.x(); + Iterable operations = Iterables.transform( + result.y() == null ? ImmutableList.of() + : result.y(), + new Function() { + @Override + public Operation apply(com.google.api.services.compute.model.Operation operation) { + return Operation.fromPb(serviceOptions.service(), operation); + } + }); + return new PageImpl<>(new GlobalOperationPageFetcher(serviceOptions, cursor, optionsMap), + cursor, operations); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Page listRegionOperations(String region, OperationListOption... options) { + return listRegionOperations(region, options(), optionMap(options)); + } + + private static Page listRegionOperations(final String region, + final ComputeOptions serviceOptions, final Map optionsMap) { + try { + ComputeRpc.Tuple> result = + runWithRetries(new Callable>>() { + @Override + public ComputeRpc.Tuple> call() { + return serviceOptions.rpc().listRegionOperations(region, optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.x(); + Iterable operations = Iterables.transform( + result.y() == null ? ImmutableList.of() + : result.y(), + new Function() { + @Override + public Operation apply(com.google.api.services.compute.model.Operation operation) { + return Operation.fromPb(serviceOptions.service(), operation); + } + }); + return new PageImpl<>(new RegionOperationPageFetcher(region, serviceOptions, cursor, + optionsMap), cursor, operations); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Page listZoneOperations(String zone, OperationListOption... options) { + return listZoneOperations(zone, options(), optionMap(options)); + } + + private static Page listZoneOperations(final String zone, + final ComputeOptions serviceOptions, final Map optionsMap) { + try { + ComputeRpc.Tuple> result = + runWithRetries(new Callable>>() { + @Override + public ComputeRpc.Tuple> call() { + return serviceOptions.rpc().listZoneOperations(zone, optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.x(); + Iterable operations = Iterables.transform( + result.y() == null ? ImmutableList.of() + : result.y(), + new Function() { + @Override + public Operation apply(com.google.api.services.compute.model.Operation operation) { + return Operation.fromPb(serviceOptions.service(), operation); + } + }); + return new PageImpl<>(new ZoneOperationPageFetcher(zone, serviceOptions, cursor, optionsMap), + cursor, operations); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public boolean delete(final OperationId operation) { + try { + return runWithRetries(new Callable() { + @Override + public Boolean call() { + if (operation instanceof RegionOperationId) { + RegionOperationId regionOperationId = (RegionOperationId) operation; + return computeRpc.deleteRegionOperation(regionOperationId.region(), + regionOperationId.operation()); + } else if (operation instanceof ZoneOperationId) { + ZoneOperationId zoneOperationId = (ZoneOperationId) operation; + return computeRpc.deleteZoneOperation(zoneOperationId.zone(), + zoneOperationId.operation()); + } else { + return computeRpc.deleteGlobalOperation(operation.operation()); + } + } + }, options().retryParams(), EXCEPTION_HANDLER); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + private Map optionMap(Option... options) { Map optionMap = Maps.newEnumMap(ComputeRpc.Option.class); for (Option option : options) { diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalOperationId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalOperationId.java new file mode 100644 index 000000000000..3c1601e8c4d0 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalOperationId.java @@ -0,0 +1,107 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; + +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Identity for a Google Compute Engine global operation. + */ +public class GlobalOperationId extends ResourceId implements OperationId { + + private static final String REGEX = ResourceId.REGEX + "global/operations/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); + private static final long serialVersionUID = 3945756772641577962L; + + private final String operation; + + private GlobalOperationId(String project, String operation) { + super(project); + this.operation = checkNotNull(operation); + } + + @Override + public String operation() { + return operation; + } + + @Override + public String selfLink() { + return super.selfLink() + "/global/operations/" + operation; + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper().add("operation", operation); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), operation); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof GlobalOperationId + && baseEquals((GlobalOperationId) obj) + && Objects.equals(operation, ((GlobalOperationId) obj).operation); + } + + @Override + GlobalOperationId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return GlobalOperationId.of(projectId, operation); + } + + /** + * Returns a global operation identity given the operation name. + */ + public static GlobalOperationId of(String operation) { + return new GlobalOperationId(null, operation); + } + + /** + * Returns a global operation identity given project and operation names. + */ + public static GlobalOperationId of(String project, String operation) { + return new GlobalOperationId(project, operation); + } + + /** + * Returns {@code true} if the provided string matches the expected format of a global operation + * URL. Returns {@code false} otherwise. + */ + static boolean matchesUrl(String url) { + return PATTERN.matcher(url).matches(); + } + + static GlobalOperationId fromUrl(String url) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { + throw new IllegalArgumentException(url + " is not a valid global operation URL"); + } + return GlobalOperationId.of(matcher.group(1), matcher.group(2)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java new file mode 100644 index 000000000000..ac303843ebc4 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java @@ -0,0 +1,800 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +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 com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serializable; +import java.math.BigInteger; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * Google Compute Engine operations. Operation identity can be obtained via {@link #operationId()}. + * For global operations {@link #operationId()} returns an {@link GlobalOperationId}, for region + * operations {@link #operationId()} returns a {@link RegionOperationId}, for zone operations + * {@link #operationId()} returns a {@link ZoneOperationId}. To get an {@code Operation} object with + * the most recent information use {@link #reload(Compute.OperationOption...)}. + */ +public final class Operation implements Serializable { + + private static final long serialVersionUID = -8979001444590023899L; + private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); + + private transient Compute compute; + private final ComputeOptions options; + private final String id; + private final OperationId operationId; + private final Long creationTimestamp; + private final String clientOperationId; + private final String operationType; + private final String targetLink; + private final String targetId; + private final Status status; + private final String statusMessage; + private final String user; + private final Integer progress; + private final Long insertTime; + private final Long startTime; + private final Long endTime; + private final List errors; + private final List warnings; + private final Integer httpErrorStatusCode; + private final String httpErrorMessage; + private final String description; + + /** + * Types of operations. + */ + public enum Status { + PENDING, + RUNNING, + DONE + } + + /** + * An error that can occur during the processing of a Google Compute Engine operation. + */ + public static final class OperationError implements Serializable { + + static final Function FROM_PB_FUNCTION = new Function< + com.google.api.services.compute.model.Operation.Error.Errors, OperationError>() { + @Override + public OperationError apply( + com.google.api.services.compute.model.Operation.Error.Errors pb) { + return OperationError.fromPb(pb); + } + }; + static final Function TO_PB_FUNCTION = + new Function() { + @Override + public com.google.api.services.compute.model.Operation.Error.Errors apply( + OperationError operation) { + return operation.toPb(); + } + }; + + private static final long serialVersionUID = -1155314394806515873L; + + private final String code; + private final String location; + private final String message; + + OperationError(String code, String location, String message) { + this.code = code; + this.location = location; + this.message = message; + } + + /** + * Returns an error type identifier for this error. + */ + public String code() { + return code; + } + + /** + * Returns the field in the request which caused the error. Might be {@code null}. + */ + public String location() { + return location; + } + + /** + * Returns an optional, human-readable error message. + */ + public String message() { + return message; + } + + com.google.api.services.compute.model.Operation.Error.Errors toPb() { + return new com.google.api.services.compute.model.Operation.Error.Errors() + .setCode(code) + .setLocation(location) + .setMessage(message); + } + + static OperationError fromPb( + com.google.api.services.compute.model.Operation.Error.Errors errorPb) { + return new OperationError(errorPb.getCode(), errorPb.getLocation(), errorPb.getMessage()); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof OperationError + && Objects.equals(code, ((OperationError) obj).code) + && Objects.equals(message, ((OperationError) obj).message) + && Objects.equals(location, ((OperationError) obj).location); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("code", code) + .add("location", location) + .add("message", message) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(code, location, message); + } + } + + /** + * A warning message that is generated during the processing of a Google Compute Engine operation. + */ + public static final class OperationWarning implements Serializable { + + static final + Function + FROM_PB_FUNCTION = + new Function() { + @Override + public OperationWarning apply( + com.google.api.services.compute.model.Operation.Warnings pb) { + return OperationWarning.fromPb(pb); + } + }; + static final + Function + TO_PB_FUNCTION = + new Function() { + @Override + public com.google.api.services.compute.model.Operation.Warnings apply( + OperationWarning operation) { + return operation.toPb(); + } + }; + + private static final long serialVersionUID = 4917326627380228928L; + + private final String code; + private final String message; + private final Map metadata; + + OperationWarning(String code, String message, Map metadata) { + this.code = code; + this.metadata = metadata != null ? ImmutableMap.copyOf(metadata) : null; + this.message = message; + } + + /** + * Returns a warning identifier for this warning. + */ + public String code() { + return code; + } + + /** + * Returns a human-readable error message. + */ + public String message() { + return message; + } + + /** + * Returns metadata about this warning. + */ + public Map metadata() { + return metadata; + } + + com.google.api.services.compute.model.Operation.Warnings toPb() { + com.google.api.services.compute.model.Operation.Warnings warningPb = + new com.google.api.services.compute.model.Operation.Warnings() + .setCode(code) + .setMessage(message); + if (this.metadata != null) { + List metadataPb = + Lists.newArrayListWithCapacity(metadata.size()); + for (Map.Entry entry : metadata.entrySet()) { + metadataPb.add(new com.google.api.services.compute.model.Operation.Warnings.Data() + .setKey(entry.getKey()).setValue(entry.getValue())); + } + warningPb.setData(metadataPb); + } + return warningPb; + } + + static OperationWarning fromPb( + com.google.api.services.compute.model.Operation.Warnings warningPb) { + Map metadata = null; + if (warningPb.getData() != null) { + metadata = Maps.newHashMapWithExpectedSize(warningPb.getData().size()); + for (com.google.api.services.compute.model.Operation.Warnings.Data data + : warningPb.getData()) { + metadata.put(data.getKey(), data.getValue()); + } + } + return new OperationWarning(warningPb.getCode(), warningPb.getMessage(), metadata); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof OperationWarning + && Objects.equals(code, ((OperationWarning) obj).code) + && Objects.equals(message, ((OperationWarning) obj).message) + && Objects.equals(metadata, ((OperationWarning) obj).metadata); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("code", code) + .add("message", message) + .add("metadata", metadata) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(code, message, metadata); + } + } + + /** + * Builder for Compute Engine operations. + */ + static final class Builder { + + private Compute compute; + private String id; + private Long creationTimestamp; + private OperationId operationId; + private String clientOperationId; + private String operationType; + private String targetLink; + private String targetId; + private Status status; + private String statusMessage; + private String user; + private Integer progress; + private Long insertTime; + private Long startTime; + private Long endTime; + private List errors; + private List warnings; + private Integer httpErrorStatusCode; + private String httpErrorMessage; + + private String description; + + Builder(Compute compute) { + this.compute = compute; + } + + Builder(Compute compute, com.google.api.services.compute.model.Operation operationPb) { + this.compute = compute; + if (operationPb.getId() != null) { + id = operationPb.getId().toString(); + } + if (operationPb.getCreationTimestamp() != null) { + creationTimestamp = TIMESTAMP_FORMATTER.parseMillis(operationPb.getCreationTimestamp()); + } + if (RegionOperationId.matchesUrl(operationPb.getSelfLink())) { + operationId = RegionOperationId.fromUrl(operationPb.getSelfLink()); + } else if (ZoneOperationId.matchesUrl(operationPb.getSelfLink())) { + operationId = ZoneOperationId.fromUrl(operationPb.getSelfLink()); + } else { + operationId = GlobalOperationId.fromUrl(operationPb.getSelfLink()); + } + clientOperationId = operationPb.getClientOperationId(); + operationType = operationPb.getOperationType(); + targetLink = operationPb.getTargetLink(); + if (operationPb.getTargetId() != null) { + targetId = operationPb.getTargetId().toString(); + } + if (operationPb.getStatus() != null) { + status = Status.valueOf(operationPb.getStatus()); + } + statusMessage = operationPb.getStatusMessage(); + user = operationPb.getUser(); + progress = operationPb.getProgress(); + if (operationPb.getInsertTime() != null) { + insertTime = TIMESTAMP_FORMATTER.parseMillis(operationPb.getInsertTime()); + } + if (operationPb.getStartTime() != null) { + startTime = TIMESTAMP_FORMATTER.parseMillis(operationPb.getStartTime()); + } + if (operationPb.getEndTime() != null) { + endTime = TIMESTAMP_FORMATTER.parseMillis(operationPb.getEndTime()); + } + if (operationPb.getError() != null && operationPb.getError().getErrors() != null) { + errors = + Lists.transform(operationPb.getError().getErrors(), OperationError.FROM_PB_FUNCTION); + } + if (operationPb.getWarnings() != null) { + warnings = Lists.transform(operationPb.getWarnings(), OperationWarning.FROM_PB_FUNCTION); + } + httpErrorStatusCode = operationPb.getHttpErrorStatusCode(); + httpErrorMessage = operationPb.getHttpErrorMessage(); + description = operationPb.getDescription(); + } + + Builder id(String id) { + this.id = id; + return this; + } + + Builder creationTimestamp(Long creationTimestamp) { + this.creationTimestamp = creationTimestamp; + return this; + } + + Builder operationId(OperationId operationId) { + this.operationId = checkNotNull(operationId); + return this; + } + + Builder clientOperationId(String clientOperationId) { + this.clientOperationId = clientOperationId; + return this; + } + + Builder operationType(String operationType) { + this.operationType = operationType; + return this; + } + + Builder targetLink(String targetLink) { + this.targetLink = targetLink; + return this; + } + + Builder targetId(String targetId) { + this.targetId = targetId; + return this; + } + + Builder status(Status status) { + this.status = status; + return this; + } + + Builder statusMessage(String statusMessage) { + this.statusMessage = statusMessage; + return this; + } + + Builder user(String user) { + this.user = user; + return this; + } + + Builder progress(Integer progress) { + this.progress = progress; + return this; + } + + Builder insertTime(Long insertTime) { + this.insertTime = insertTime; + return this; + } + + Builder startTime(Long startTime) { + this.startTime = startTime; + return this; + } + + Builder endTime(Long endTime) { + this.endTime = endTime; + return this; + } + + Builder errors(List errors) { + this.errors = ImmutableList.copyOf(checkNotNull(errors)); + return this; + } + + Builder warnings(List warnings) { + this.warnings = ImmutableList.copyOf(checkNotNull(warnings)); + return this; + } + + Builder httpErrorStatusCode(Integer httpErrorStatusCode) { + this.httpErrorStatusCode = httpErrorStatusCode; + return this; + } + + Builder httpErrorMessage(String httpErrorMessage) { + this.httpErrorMessage = httpErrorMessage; + return this; + } + + Builder description(String description) { + this.description = description; + return this; + } + + /** + * Creates an object. + */ + public Operation build() { + return new Operation(this); + } + } + + private Operation(Builder builder) { + this.compute = checkNotNull(builder.compute); + this.options = compute.options(); + this.id = builder.id; + this.creationTimestamp = builder.creationTimestamp; + this.operationId = checkNotNull(builder.operationId); + this.clientOperationId = builder.clientOperationId; + this.operationType = builder.operationType; + this.targetLink = builder.targetLink; + this.targetId = builder.targetId; + this.status = builder.status; + this.statusMessage = builder.statusMessage; + this.user = builder.user; + this.progress = builder.progress; + this.insertTime = builder.insertTime; + this.startTime = builder.startTime; + this.endTime = builder.endTime; + this.errors = builder.errors != null ? ImmutableList.copyOf(builder.errors) : null; + this.warnings = builder.warnings != null ? ImmutableList.copyOf(builder.warnings) : null; + this.httpErrorStatusCode = builder.httpErrorStatusCode; + this.httpErrorMessage = builder.httpErrorMessage; + this.description = builder.description; + } + + /** + * Returns the operation's {@code Compute} object used to issue requests. + */ + public Compute compute() { + return compute; + } + + /** + * Returns the service-defined unique identifier for the operation. + */ + public String id() { + return id; + } + + /** + * Returns the creation timestamp in milliseconds since epoch. + */ + public Long creationTimestamp() { + return creationTimestamp; + } + + /** + * Returns the operation's identity. This method returns an {@link GlobalOperationId} for global + * operations, returns a {@link RegionOperationId} for region operations and returns a + * {@link ZoneOperationId} for zone operations. + * + * @see RFC1035 + */ + @SuppressWarnings("unchecked") + public T operationId() { + return (T) operationId; + } + + /** + * Reserved for future use. + */ + String clientOperationId() { + return clientOperationId; + } + + /** + * Returns the type of operation. + */ + public String operationType() { + return operationType; + } + + /** + * Returns the URL of the resource that the operation is modifying. + */ + public String targetLink() { + return targetLink; + } + + /** + * Returns the unique service-defined target ID, which identifies the resource that the operation + * is modifying. + */ + public String targetId() { + return targetId; + } + + /** + * Returns the status of the operation. + */ + public Status status() { + return status; + } + + /** + * Returns an optional textual description of the current status of the operation. + */ + public String statusMessage() { + return statusMessage; + } + + /** + * Returns the user who requested the operation, for example: {@code user@example.com}. + */ + public String user() { + return user; + } + + /** + * Returns an optional progress indicator that ranges from 0 to 100. There is no requirement that + * this be linear or support any granularity of operations. This should not be used to guess when + * the operation will be complete. This number should monotonically increase as the operation + * progresses. + */ + public Integer progress() { + return progress; + } + + /** + * Returns the time that this operation was requested. In milliseconds since epoch. + */ + public Long insertTime() { + return insertTime; + } + + /** + * Returns the time that this operation was started by the service. In milliseconds since epoch. + */ + public Long startTime() { + return startTime; + } + + /** + * Returns the time that this operation was completed. In milliseconds since epoch. + */ + public Long endTime() { + return endTime; + } + + /** + * Returns the errors encountered while processing this operation, if any. Returns {@code null} if + * no error occurred. + */ + public List errors() { + return errors; + } + + /** + * Returns the warnings encountered while processing this operation, if any. Returns {@code null} + * if no warning occurred. + */ + public List warnings() { + return warnings; + } + + /** + * Returns the HTTP error status code that was returned, if the operation failed. For example, a + * {@code 404} means the resource was not found. + */ + public Integer httpErrorStatusCode() { + return httpErrorStatusCode; + } + + /** + * Returns the the HTTP error message that was returned, if the operation failed. For example, a + * {@code NOT FOUND} message is returned if the resource was not found. + */ + public String httpErrorMessage() { + return httpErrorMessage; + } + + /** + * Returns an optional textual description of the operation. + */ + public String description() { + return description; + } + + /** + * Checks if this operation exists. + * + * @return {@code true} if this operation exists, {@code false} otherwise + * @throws ComputeException upon failure + */ + public boolean exists() throws ComputeException { + return reload(Compute.OperationOption.fields()) != null; + } + + /** + * Checks if this operation has completed its execution, either failing or succeeding. If the + * operation does not exist this method returns {@code false}. To correctly wait for operation's + * completion check that the operation exists first, using {@link #exists()}: + *
     {@code
    +   * if (operation.exists()) {
    +   *   while(!operation.isDone()) {
    +   *     Thread.sleep(1000L);
    +   *   }
    +   * }}
    + * + * @return {@code true} if this operation is in {@link Operation.Status#DONE} state, {@code false} + * if the state is not {@link Operation.Status#DONE} or the operation does not exist + * @throws ComputeException upon failure + */ + public boolean isDone() throws ComputeException { + Operation operation = + compute.get(operationId, Compute.OperationOption.fields(Compute.OperationField.STATUS)); + return operation != null && operation.status() == Status.DONE; + } + + /** + * Fetches current operation's latest information. Returns {@code null} if the operation does not + * exist. + * + * @param options operation options + * @return an {@code Operation} object with latest information or {@code null} if not found + * @throws ComputeException upon failure + */ + public Operation reload(Compute.OperationOption... options) throws ComputeException { + return compute.get(operationId, options); + } + + /** + * Deletes this operation. + * + * @return {@code true} if operation was deleted, {@code false} if it was not found + * @throws ComputeException upon failure + */ + public boolean delete() throws ComputeException { + return compute.delete(operationId); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id) + .add("operationsId", operationId) + .add("creationTimestamp", creationTimestamp) + .add("clientOperationId", clientOperationId) + .add("operationType", operationType) + .add("targetLink", targetLink) + .add("targetId", targetId) + .add("status", status) + .add("statusMessage", statusMessage) + .add("user", user) + .add("progress", progress) + .add("insertTime", insertTime) + .add("startTime", startTime) + .add("endTime", endTime) + .add("errors", errors) + .add("warnings", warnings) + .add("httpErrorStatusCode", httpErrorStatusCode) + .add("httpErrorMessage", httpErrorMessage) + .add("description", description) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(id); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof Operation + && Objects.equals(toPb(), ((Operation) obj).toPb()) + && Objects.equals(options, ((Operation) obj).options); + } + + com.google.api.services.compute.model.Operation toPb() { + com.google.api.services.compute.model.Operation operationPb = + new com.google.api.services.compute.model.Operation(); + if (id != null) { + operationPb.setId(new BigInteger(id)); + } + if (creationTimestamp != null) { + operationPb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); + } + operationPb.setName(operationId.operation()); + operationPb.setClientOperationId(clientOperationId); + if (operationId instanceof RegionOperationId) { + operationPb.setRegion(this.operationId().regionId().selfLink()); + } + if (operationId instanceof ZoneOperationId) { + operationPb.setZone(this.operationId().zoneId().selfLink()); + } + if (operationType != null) { + operationPb.setOperationType(operationType); + } + operationPb.setTargetLink(targetLink); + if (targetId != null) { + operationPb.setTargetId(new BigInteger(targetId)); + } + if (status != null) { + operationPb.setStatus(status.name()); + } + operationPb.setStatusMessage(statusMessage); + operationPb.setUser(user); + operationPb.setProgress(progress); + if (insertTime != null) { + operationPb.setInsertTime(TIMESTAMP_FORMATTER.print(insertTime)); + } + if (startTime != null) { + operationPb.setStartTime(TIMESTAMP_FORMATTER.print(startTime)); + } + if (endTime != null) { + operationPb.setEndTime(TIMESTAMP_FORMATTER.print(endTime)); + } + if (errors != null) { + operationPb.setError(new com.google.api.services.compute.model.Operation.Error().setErrors( + Lists.transform(errors, OperationError.TO_PB_FUNCTION))); + } + if (warnings != null) { + operationPb.setWarnings(Lists.transform(warnings, OperationWarning.TO_PB_FUNCTION)); + } + operationPb.setHttpErrorStatusCode(httpErrorStatusCode); + operationPb.setHttpErrorMessage(httpErrorMessage); + operationPb.setSelfLink(operationId.selfLink()); + operationPb.setDescription(description); + return operationPb; + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + this.compute = options.service(); + } + + static Operation fromPb(Compute compute, + com.google.api.services.compute.model.Operation operationPb) { + return new Builder(compute, operationPb).build(); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/OperationId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/OperationId.java new file mode 100644 index 000000000000..c7211e97ca2d --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/OperationId.java @@ -0,0 +1,38 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +/** + * Interface for Google Compute Engine operation identities. + */ +public interface OperationId { + + /** + * Returns the name of the project. + */ + String project(); + + /** + * Returns the name of the operation resource. + */ + String operation(); + + /** + * Returns a fully qualified URL to the entity. + */ + String selfLink(); +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionOperationId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionOperationId.java new file mode 100644 index 000000000000..acc23410d285 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionOperationId.java @@ -0,0 +1,112 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; + +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Identity for a Google Compute Engine region's operation. + */ +public final class RegionOperationId extends RegionResourceId implements OperationId { + + private static final String REGEX = RegionResourceId.REGEX + "operations/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); + private static final long serialVersionUID = 5816161906501886782L; + + private final String operation; + + private RegionOperationId(String project, String region, String operation) { + super(project, region); + this.operation = checkNotNull(operation); + } + + @Override + public String operation() { + return operation; + } + + @Override + public String selfLink() { + return super.selfLink() + "/operations/" + operation; + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return MoreObjects.toStringHelper(this).add("operation", operation); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), operation); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof RegionOperationId && baseEquals((RegionOperationId) obj); + } + + @Override + RegionOperationId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return RegionOperationId.of(projectId, region(), operation); + } + + /** + * Returns a region operation identity given the region identity and the operation name. + */ + public static RegionOperationId of(RegionId regionId, String operation) { + return new RegionOperationId(regionId.project(), regionId.region(), operation); + } + + /** + * Returns a region operation identity given the region and operation names. + */ + public static RegionOperationId of(String region, String operation) { + return new RegionOperationId(null, region, operation); + } + + /** + * Returns a region operation identity given project, region and operation names. + */ + public static RegionOperationId of(String project, String region, String operation) { + return new RegionOperationId(project, region, operation); + } + + /** + * Returns {@code true} if the provided string matches the expected format of a region operation + * URL. Returns {@code false} otherwise. + */ + static boolean matchesUrl(String url) { + return PATTERN.matcher(url).matches(); + } + + static RegionOperationId fromUrl(String url) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { + throw new IllegalArgumentException(url + " is not a valid region operation URL"); + } + return RegionOperationId.of(matcher.group(1), matcher.group(2), matcher.group(3)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneOperationId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneOperationId.java new file mode 100644 index 000000000000..c0364b0ead3f --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneOperationId.java @@ -0,0 +1,114 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; + +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Identity for a Google Compute Engine zone operation. + */ +public final class ZoneOperationId extends ZoneResourceId implements OperationId { + + private static final String REGEX = ZoneResourceId.REGEX + "operations/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); + private static final long serialVersionUID = 4910670262094017392L; + + private final String operation; + + private ZoneOperationId(String project, String zone, String operation) { + super(project, zone); + this.operation = checkNotNull(operation); + } + + @Override + public String operation() { + return operation; + } + + @Override + public String selfLink() { + return super.selfLink() + "/operations/" + operation; + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return MoreObjects.toStringHelper(this).add("operation", operation); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), operation); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof ZoneOperationId + && baseEquals((ZoneOperationId) obj) + && Objects.equals(operation, ((ZoneOperationId) obj).operation); + } + + @Override + ZoneOperationId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return ZoneOperationId.of(projectId, zone(), operation); + } + + /** + * Returns a zone operation identity given the zone identity and the operation name. + */ + public static ZoneOperationId of(ZoneId zoneId, String operation) { + return new ZoneOperationId(zoneId.project(), zoneId.zone(), operation); + } + + /** + * Returns a zone operation identity given the zone and operation names. + */ + public static ZoneOperationId of(String zone, String operation) { + return new ZoneOperationId(null, zone, operation); + } + + /** + * Returns a zone operation identity given project, zone and operation names. + */ + public static ZoneOperationId of(String project, String zone, String operation) { + return new ZoneOperationId(project, zone, operation); + } + + /** + * Returns {@code true} if the provided string matches the expected format of a zone operation + * URL. Returns {@code false} otherwise. + */ + static boolean matchesUrl(String url) { + return PATTERN.matcher(url).matches(); + } + + static ZoneOperationId fromUrl(String url) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { + throw new IllegalArgumentException(url + " is not a valid zone operation URL"); + } + return ZoneOperationId.of(matcher.group(1), matcher.group(2), matcher.group(3)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java index 35524e0c116d..13b391adb75e 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java @@ -19,6 +19,7 @@ import com.google.api.services.compute.model.DiskType; import com.google.api.services.compute.model.License; import com.google.api.services.compute.model.MachineType; +import com.google.api.services.compute.model.Operation; import com.google.api.services.compute.model.Region; import com.google.api.services.compute.model.Zone; import com.google.gcloud.compute.ComputeException; @@ -161,4 +162,70 @@ public Y y() { * @throws ComputeException upon failure */ License getLicense(String project, String license, Map options); + + /** + * Returns the requested global operation or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + Operation getGlobalOperation(String operation, Map options); + + /** + * Lists the global operations in the current project. + * + * @throws ComputeException upon failure + */ + Tuple> listGlobalOperations(Map options); + + /** + * Deletes the requested global operation. + * + * @return {@code true} if operation was deleted, {@code false} if it was not found + * @throws ComputeException upon failure + */ + boolean deleteGlobalOperation(String operation); + + /** + * Returns the requested region operation or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + Operation getRegionOperation(String region, String operation, Map options); + + /** + * Lists the region operations for the current project and region. + * + * @throws ComputeException upon failure + */ + Tuple> listRegionOperations(String region, Map options); + + /** + * Deletes the requested region operation. + * + * @return {@code true} if operation was deleted, {@code false} if it was not found + * @throws ComputeException upon failure + */ + boolean deleteRegionOperation(String region, String operation); + + /** + * Returns the requested zone operation or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + Operation getZoneOperation(String zone, String operation, Map options); + + /** + * Lists the zone operations for the current project and zone. + * + * @throws ComputeException upon failure + */ + Tuple> listZoneOperations(String zone, Map options); + + /** + * Deletes the requested zone operation. + * + * @return {@code true} if operation was deleted, {@code false} if it was not found + * @throws ComputeException upon failure + */ + boolean deleteZoneOperation(String zone, String operation); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java index fe714acab502..d54840e3fff0 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java @@ -35,6 +35,8 @@ import com.google.api.services.compute.model.MachineTypeAggregatedList; import com.google.api.services.compute.model.MachineTypeList; import com.google.api.services.compute.model.MachineTypesScopedList; +import com.google.api.services.compute.model.Operation; +import com.google.api.services.compute.model.OperationList; import com.google.api.services.compute.model.Region; import com.google.api.services.compute.model.RegionList; import com.google.api.services.compute.model.Zone; @@ -248,11 +250,130 @@ public License getLicense(String project, String license, Map options } } + @Override + public Operation getGlobalOperation(String operation, Map options) { + try { + return compute.globalOperations() + .get(this.options.projectId(), operation) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Tuple> listGlobalOperations(Map options) { + try { + OperationList operationsList = compute.globalOperations() + .list(this.options.projectId()) + .setFilter(FILTER.getString(options)) + .setMaxResults(MAX_RESULTS.getLong(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + .setFields(FIELDS.getString(options)) + .execute(); + Iterable operations = operationsList.getItems(); + return Tuple.of(operationsList.getNextPageToken(), operations); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public boolean deleteGlobalOperation(String operation) { + try { + compute.globalOperations().delete(this.options.projectId(), operation).execute(); + return true; + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Operation getRegionOperation(String region, String operation, Map options) { + try { + return compute.regionOperations() + .get(this.options.projectId(), region, operation) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Tuple> listRegionOperations(String region, + Map options) { + try { + OperationList operationsList = compute.regionOperations() + .list(this.options.projectId(), region) + .setFilter(FILTER.getString(options)) + .setMaxResults(MAX_RESULTS.getLong(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + .setFields(FIELDS.getString(options)) + .execute(); + Iterable operations = operationsList.getItems(); + return Tuple.of(operationsList.getNextPageToken(), operations); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public boolean deleteRegionOperation(String region, String operation) { + try { + compute.regionOperations().delete(this.options.projectId(), region, operation).execute(); + return true; + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Operation getZoneOperation(String zone, String operation, Map options) { + try { + return compute.zoneOperations() + .get(this.options.projectId(), zone, operation) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Tuple> listZoneOperations(String zone, + Map options) { + try { + OperationList operationsList = compute.zoneOperations() + .list(this.options.projectId(), zone) + .setFilter(FILTER.getString(options)) + .setMaxResults(MAX_RESULTS.getLong(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + .setFields(FIELDS.getString(options)) + .execute(); + Iterable operations = operationsList.getItems(); + return Tuple.of(operationsList.getNextPageToken(), operations); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public boolean deleteZoneOperation(String zone, String operation) { + try { + compute.zoneOperations().delete(this.options.projectId(), zone, operation).execute(); + return true; + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + /** * This method returns {@code null} if the error code of {@code exception} was 404, re-throws the * exception otherwise. * - * @throws ComputeException if the error code of {@code exception} was not 404. + * @throws ComputeException if the error code of {@code exception} was not 404 */ private static T nullForNotFound(IOException exception) { ComputeException serviceException = translate(exception); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java index 5ef9b04ed446..0d8461d611a7 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java @@ -20,10 +20,12 @@ import static org.easymock.EasyMock.eq; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import com.google.common.base.Function; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; @@ -117,6 +119,37 @@ public class ComputeImplTest { private static final LicenseId LICENSE_ID = LicenseId.of("project", "license"); private static final Boolean CHARGES_USE_FEE = true; private static final License LICENSE = new License(LICENSE_ID, CHARGES_USE_FEE); + private static final Operation.OperationError OPERATION_ERROR1 = + new Operation.OperationError("code1", "location1", "message1"); + private static final Operation.OperationError OPERATION_ERROR2 = + new Operation.OperationError("code2", "location2", "message2"); + private static final Operation.OperationWarning OPERATION_WARNING1 = + new Operation.OperationWarning("code1", "message1", ImmutableMap.of("k1", "v1")); + private static final Operation.OperationWarning OPERATION_WARNING2 = + new Operation.OperationWarning("code2", "location2", ImmutableMap.of("k2", "v2")); + private static final String CLIENT_OPERATION_ID = "clientOperationId"; + private static final String OPERATION_TYPE = "delete"; + private static final String TARGET_LINK = "targetLink"; + private static final String TARGET_ID = "42"; + private static final Operation.Status STATUS = Operation.Status.DONE; + private static final String STATUS_MESSAGE = "statusMessage"; + private static final String USER = "user"; + private static final Integer PROGRESS = 100; + private static final Long INSERT_TIME = 1453293540000L; + private static final Long START_TIME = 1453293420000L; + private static final Long END_TIME = 1453293480000L; + private static final List ERRORS = + ImmutableList.of(OPERATION_ERROR1, OPERATION_ERROR2); + private static final List WARNINGS = + ImmutableList.of(OPERATION_WARNING1, OPERATION_WARNING2); + private static final Integer HTTP_ERROR_STATUS_CODE = 404; + private static final String HTTP_ERROR_MESSAGE = "NOT FOUND"; + private static final GlobalOperationId GLOBAL_OPERATION_ID = + GlobalOperationId.of("project", "op"); + private static final ZoneOperationId ZONE_OPERATION_ID = + ZoneOperationId.of("project", "zone", "op"); + private static final RegionOperationId REGION_OPERATION_ID = + RegionOperationId.of("project", "region", "op"); // Empty ComputeRpc options private static final Map EMPTY_RPC_OPTIONS = ImmutableMap.of(); @@ -216,11 +249,33 @@ public class ComputeImplTest { private static final Compute.LicenseOption LICENSE_OPTION_FIELDS = Compute.LicenseOption.fields(Compute.LicenseField.CHARGES_USE_FEE); + // Operation options + private static final Compute.OperationOption OPERATION_OPTION_FIELDS = + Compute.OperationOption.fields(Compute.OperationField.ID, Compute.OperationField.DESCRIPTION); + + // Operation list options + private static final Compute.OperationFilter OPERATION_FILTER = + Compute.OperationFilter.notEquals(Compute.OperationField.PROGRESS, 0); + private static final Compute.OperationListOption OPERATION_LIST_PAGE_TOKEN = + Compute.OperationListOption.startPageToken("cursor"); + private static final Compute.OperationListOption OPERATION_LIST_MAX_RESULTS = + Compute.OperationListOption.maxResults(42L); + private static final Compute.OperationListOption OPERATION_LIST_FILTER = + Compute.OperationListOption.filter(OPERATION_FILTER); + private static final Map OPERATION_LIST_OPTIONS = ImmutableMap.of( + ComputeRpc.Option.PAGE_TOKEN, "cursor", + ComputeRpc.Option.MAX_RESULTS, 42L, + ComputeRpc.Option.FILTER, "progress ne 0"); + private ComputeOptions options; private ComputeRpcFactory rpcFactoryMock; private ComputeRpc computeRpcMock; private Compute compute; + private Operation globalOperation; + private Operation zoneOperation; + private Operation regionOperation; + @Rule public ExpectedException thrown = ExpectedException.none(); @@ -229,13 +284,77 @@ public void setUp() { rpcFactoryMock = EasyMock.createMock(ComputeRpcFactory.class); computeRpcMock = EasyMock.createMock(ComputeRpc.class); EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(ComputeOptions.class))) - .andReturn(computeRpcMock).times(1); + .andReturn(computeRpcMock).times(2); EasyMock.replay(rpcFactoryMock); options = ComputeOptions.builder() .projectId(PROJECT) .serviceRpcFactory(rpcFactoryMock) .retryParams(RetryParams.noRetries()) .build(); + Compute otherService = options.toBuilder().build().service(); + globalOperation = new Operation.Builder(otherService) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .operationId(GLOBAL_OPERATION_ID) + .clientOperationId(CLIENT_OPERATION_ID) + .operationType(OPERATION_TYPE) + .targetLink(TARGET_LINK) + .targetId(TARGET_ID) + .status(STATUS) + .statusMessage(STATUS_MESSAGE) + .user(USER) + .progress(PROGRESS) + .insertTime(INSERT_TIME) + .startTime(START_TIME) + .endTime(END_TIME) + .errors(ERRORS) + .warnings(WARNINGS) + .httpErrorStatusCode(HTTP_ERROR_STATUS_CODE) + .httpErrorMessage(HTTP_ERROR_MESSAGE) + .description(DESCRIPTION) + .build(); + zoneOperation = new Operation.Builder(otherService) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .operationId(ZONE_OPERATION_ID) + .clientOperationId(CLIENT_OPERATION_ID) + .operationType(OPERATION_TYPE) + .targetLink(TARGET_LINK) + .targetId(TARGET_ID) + .status(STATUS) + .statusMessage(STATUS_MESSAGE) + .user(USER) + .progress(PROGRESS) + .insertTime(INSERT_TIME) + .startTime(START_TIME) + .endTime(END_TIME) + .errors(ERRORS) + .warnings(WARNINGS) + .httpErrorStatusCode(HTTP_ERROR_STATUS_CODE) + .httpErrorMessage(HTTP_ERROR_MESSAGE) + .description(DESCRIPTION) + .build(); + regionOperation = new Operation.Builder(otherService) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .operationId(REGION_OPERATION_ID) + .clientOperationId(CLIENT_OPERATION_ID) + .operationType(OPERATION_TYPE) + .targetLink(TARGET_LINK) + .targetId(TARGET_ID) + .status(STATUS) + .statusMessage(STATUS_MESSAGE) + .user(USER) + .progress(PROGRESS) + .insertTime(INSERT_TIME) + .startTime(START_TIME) + .endTime(END_TIME) + .errors(ERRORS) + .warnings(WARNINGS) + .httpErrorStatusCode(HTTP_ERROR_STATUS_CODE) + .httpErrorMessage(HTTP_ERROR_MESSAGE) + .description(DESCRIPTION) + .build(); } @After @@ -682,6 +801,24 @@ public void testGetLicenseFromStringWithOptions() { assertEquals(LICENSE, license); } + @Test + public void testGetLicenseFromIdWithOptions() { + Capture> capturedOptions = Capture.newInstance(); + LicenseId licenseId = LicenseId.of("project2", "license2"); + EasyMock.expect(computeRpcMock.getLicense(eq(licenseId.project()), eq(licenseId.license()), + capture(capturedOptions))) + .andReturn(LICENSE.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + License license = compute.getLicense(licenseId, LICENSE_OPTION_FIELDS); + assertEquals(LICENSE, license); + String selector = (String) capturedOptions.getValue().get(LICENSE_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("chargesUseFee")); + assertEquals(22, selector.length()); + assertEquals(LICENSE, license); + } + @Test public void testGetLicenseFromId() { LicenseId licenseId = LicenseId.of("project2", "license2"); @@ -695,20 +832,355 @@ public void testGetLicenseFromId() { } @Test - public void testGetLicenseFromIdWithOptions() { + public void testGetGlobalOperation() { + EasyMock.expect( + computeRpcMock.getGlobalOperation(GLOBAL_OPERATION_ID.operation(), EMPTY_RPC_OPTIONS)) + .andReturn(globalOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.get(GLOBAL_OPERATION_ID); + assertEquals(globalOperation, operation); + } + + @Test + public void testGetGlobalOperationWithSelectedFields() { Capture> capturedOptions = Capture.newInstance(); - LicenseId licenseId = LicenseId.of("project2", "license2"); - EasyMock.expect(computeRpcMock.getLicense(eq(licenseId.project()), eq(licenseId.license()), - capture(capturedOptions))) - .andReturn(LICENSE.toPb()); + EasyMock.expect(computeRpcMock.getGlobalOperation( + eq(GLOBAL_OPERATION_ID.operation()), capture(capturedOptions))) + .andReturn(globalOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - License license = compute.getLicense(licenseId, LICENSE_OPTION_FIELDS); - assertEquals(LICENSE, license); - String selector = (String) capturedOptions.getValue().get(LICENSE_OPTION_FIELDS.rpcOption()); + Operation operation = compute.get(GLOBAL_OPERATION_ID, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); assertTrue(selector.contains("selfLink")); - assertTrue(selector.contains("chargesUseFee")); - assertEquals(22, selector.length()); - assertEquals(LICENSE, license); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(globalOperation, operation); + } + + @Test + public void testListGlobalOperations() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList operationList = ImmutableList.of(globalOperation, globalOperation); + Tuple> result = + Tuple.of(cursor, Iterables.transform(operationList, + new Function() { + @Override + public com.google.api.services.compute.model.Operation apply(Operation operation) { + return operation.toPb(); + } + })); + EasyMock.expect(computeRpcMock.listGlobalOperations(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listGlobalOperations(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(operationList.toArray(), Iterables.toArray(page.values(), Operation.class)); + } + + @Test + public void testListEmptyGlobalOperations() { + ImmutableList operations = ImmutableList.of(); + Tuple> result = + Tuple.>of(null, + operations); + EasyMock.expect(computeRpcMock.listGlobalOperations(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Page page = compute.listGlobalOperations(); + assertNull(page.nextPageCursor()); + assertArrayEquals(operations.toArray(), Iterables.toArray(page.values(), Operation.class)); + } + + @Test + public void testListGlobalOperationsWithOptions() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList operationList = ImmutableList.of(globalOperation, globalOperation); + Tuple> result = + Tuple.of(cursor, Iterables.transform(operationList, + new Function() { + @Override + public com.google.api.services.compute.model.Operation apply(Operation operation) { + return operation.toPb(); + } + })); + EasyMock.expect(computeRpcMock.listGlobalOperations(OPERATION_LIST_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listGlobalOperations(OPERATION_LIST_MAX_RESULTS, + OPERATION_LIST_PAGE_TOKEN, OPERATION_LIST_FILTER); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(operationList.toArray(), Iterables.toArray(page.values(), Operation.class)); + } + + @Test + public void testDeleteGlobalOperation_True() { + EasyMock.expect(computeRpcMock.deleteGlobalOperation(GLOBAL_OPERATION_ID.operation())) + .andReturn(true); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertTrue(compute.delete(GLOBAL_OPERATION_ID)); + } + + @Test + public void testDeleteGlobalOperation_False() { + EasyMock.expect(computeRpcMock.deleteGlobalOperation(GLOBAL_OPERATION_ID.operation())) + .andReturn(false); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertFalse(compute.delete(GLOBAL_OPERATION_ID)); + } + + @Test + public void testGetRegionOperation() { + EasyMock.expect(computeRpcMock.getRegionOperation(REGION_OPERATION_ID.region(), + REGION_OPERATION_ID.operation(), EMPTY_RPC_OPTIONS)) + .andReturn(regionOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.get(REGION_OPERATION_ID); + assertEquals(regionOperation, operation); + } + + @Test + public void testGetRegionOperationWithSelectedFields() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.getRegionOperation(eq(REGION_OPERATION_ID.region()), + eq(REGION_OPERATION_ID.operation()), capture(capturedOptions))) + .andReturn(regionOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.get(REGION_OPERATION_ID, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(regionOperation, operation); + } + + @Test + public void testListRegionOperations() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList operationList = ImmutableList.of(regionOperation, regionOperation); + Tuple> result = + Tuple.of(cursor, Iterables.transform(operationList, + new Function() { + @Override + public com.google.api.services.compute.model.Operation apply(Operation operation) { + return operation.toPb(); + } + })); + EasyMock.expect( + computeRpcMock.listRegionOperations(REGION_OPERATION_ID.region(), EMPTY_RPC_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listRegionOperations(REGION_OPERATION_ID.region()); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(operationList.toArray(), Iterables.toArray(page.values(), Operation.class)); + } + + @Test + public void testListEmptyRegionOperations() { + ImmutableList operations = ImmutableList.of(); + Tuple> result = + Tuple.>of(null, + operations); + EasyMock.expect( + computeRpcMock.listRegionOperations(REGION_OPERATION_ID.region(), EMPTY_RPC_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Page page = compute.listRegionOperations(REGION_OPERATION_ID.region()); + assertNull(page.nextPageCursor()); + assertArrayEquals(operations.toArray(), Iterables.toArray(page.values(), Operation.class)); + } + + @Test + public void testListRegionOperationsWithOptions() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList operationList = ImmutableList.of(regionOperation, regionOperation); + Tuple> result = + Tuple.of(cursor, Iterables.transform(operationList, + new Function() { + @Override + public com.google.api.services.compute.model.Operation apply(Operation operation) { + return operation.toPb(); + } + })); + EasyMock.expect( + computeRpcMock.listRegionOperations(REGION_OPERATION_ID.region(), OPERATION_LIST_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listRegionOperations(REGION_OPERATION_ID.region(), + OPERATION_LIST_MAX_RESULTS, OPERATION_LIST_PAGE_TOKEN, OPERATION_LIST_FILTER); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(operationList.toArray(), Iterables.toArray(page.values(), Operation.class)); + } + + @Test + public void testDeleteRegionOperation_True() { + EasyMock.expect(computeRpcMock.deleteRegionOperation(REGION_OPERATION_ID.region(), + REGION_OPERATION_ID.operation())).andReturn(true); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertTrue(compute.delete(REGION_OPERATION_ID)); + } + + @Test + public void testDeleteRegionOperation_False() { + EasyMock.expect(computeRpcMock.deleteRegionOperation(REGION_OPERATION_ID.region(), + REGION_OPERATION_ID.operation())).andReturn(false); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertFalse(compute.delete(REGION_OPERATION_ID)); + } + + @Test + public void testGetZoneOperation() { + EasyMock.expect(computeRpcMock.getZoneOperation(ZONE_OPERATION_ID.zone(), + ZONE_OPERATION_ID.operation(), EMPTY_RPC_OPTIONS)) + .andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.get(ZONE_OPERATION_ID); + assertEquals(zoneOperation, operation); + } + + @Test + public void testGetZoneOperationWithSelectedFields() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.getZoneOperation(eq(ZONE_OPERATION_ID.zone()), + eq(ZONE_OPERATION_ID.operation()), capture(capturedOptions))) + .andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.get(ZONE_OPERATION_ID, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(zoneOperation, operation); + } + + @Test + public void testListZoneOperations() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList operationList = ImmutableList.of(zoneOperation, zoneOperation); + Tuple> result = + Tuple.of(cursor, Iterables.transform(operationList, + new Function() { + @Override + public com.google.api.services.compute.model.Operation apply(Operation operation) { + return operation.toPb(); + } + })); + EasyMock.expect( + computeRpcMock.listZoneOperations(ZONE_OPERATION_ID.zone(), EMPTY_RPC_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listZoneOperations(ZONE_OPERATION_ID.zone()); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(operationList.toArray(), Iterables.toArray(page.values(), Operation.class)); + } + + @Test + public void testListEmptyZoneOperations() { + ImmutableList operations = ImmutableList.of(); + Tuple> result = + Tuple.>of(null, + operations); + EasyMock.expect( + computeRpcMock.listZoneOperations(ZONE_OPERATION_ID.zone(), EMPTY_RPC_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Page page = compute.listZoneOperations(ZONE_OPERATION_ID.zone()); + assertNull(page.nextPageCursor()); + assertArrayEquals(operations.toArray(), Iterables.toArray(page.values(), Operation.class)); + } + + @Test + public void testListZoneOperationsWithOptions() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList operationList = ImmutableList.of(zoneOperation, zoneOperation); + Tuple> result = + Tuple.of(cursor, Iterables.transform(operationList, + new Function() { + @Override + public com.google.api.services.compute.model.Operation apply(Operation operation) { + return operation.toPb(); + } + })); + EasyMock.expect( + computeRpcMock.listZoneOperations(ZONE_OPERATION_ID.zone(), OPERATION_LIST_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listZoneOperations(ZONE_OPERATION_ID.zone(), + OPERATION_LIST_MAX_RESULTS, OPERATION_LIST_PAGE_TOKEN, OPERATION_LIST_FILTER); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(operationList.toArray(), Iterables.toArray(page.values(), Operation.class)); + } + + @Test + public void testDeleteZoneOperation_True() { + EasyMock.expect(computeRpcMock.deleteZoneOperation(ZONE_OPERATION_ID.zone(), + ZONE_OPERATION_ID.operation())).andReturn(true); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertTrue(compute.delete(ZONE_OPERATION_ID)); + } + + @Test + public void testDeleteZoneOperation_False() { + EasyMock.expect(computeRpcMock.deleteZoneOperation(ZONE_OPERATION_ID.zone(), + ZONE_OPERATION_ID.operation())).andReturn(false); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertFalse(compute.delete(ZONE_OPERATION_ID)); + } + + @Test + public void testRetryableException() { + EasyMock.expect( + computeRpcMock.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.diskType(), EMPTY_RPC_OPTIONS)) + .andThrow(new ComputeException(500, "InternalError")) + .andReturn(DISK_TYPE.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.toBuilder().retryParams(RetryParams.defaultInstance()).build().service(); + DiskType diskType = compute.getDiskType(DISK_TYPE_ID); + assertEquals(DISK_TYPE, diskType); + } + + @Test + public void testNonRetryableException() { + String exceptionMessage = "Not Implemented"; + EasyMock.expect( + computeRpcMock.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.diskType(), EMPTY_RPC_OPTIONS)) + .andThrow(new ComputeException(501, exceptionMessage)); + EasyMock.replay(computeRpcMock); + compute = options.toBuilder().retryParams(RetryParams.defaultInstance()).build().service(); + thrown.expect(ComputeException.class); + thrown.expectMessage(exceptionMessage); + compute.getDiskType(DISK_TYPE_ID); + } + + @Test + public void testRuntimeException() { + String exceptionMessage = "Artificial runtime exception"; + EasyMock.expect( + computeRpcMock.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.diskType(), EMPTY_RPC_OPTIONS)) + .andThrow(new RuntimeException(exceptionMessage)); + EasyMock.replay(computeRpcMock); + compute = options.toBuilder().retryParams(RetryParams.defaultInstance()).build().service(); + thrown.expect(ComputeException.class); + thrown.expectMessage(exceptionMessage); + compute.getDiskType(DISK_TYPE_ID); } } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationIdTest.java new file mode 100644 index 000000000000..98430f0d1ad5 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationIdTest.java @@ -0,0 +1,143 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class OperationIdTest { + + private static final String PROJECT = "project"; + private static final String ZONE = "zone"; + private static final String REGION = "region"; + private static final String NAME = "op"; + private static final String GLOBAL_URL = + "https://www.googleapis.com/compute/v1/projects/project/global/operations/op"; + private static final String ZONE_URL = + "https://www.googleapis.com/compute/v1/projects/project/zones/zone/operations/op"; + private static final String REGION_URL = + "https://www.googleapis.com/compute/v1/projects/project/regions/region/operations/op"; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testOf() { + GlobalOperationId operationId = GlobalOperationId.of(PROJECT, NAME); + assertEquals(PROJECT, operationId.project()); + assertEquals(NAME, operationId.operation()); + assertEquals(GLOBAL_URL, operationId.selfLink()); + operationId = GlobalOperationId.of(NAME); + assertNull(operationId.project()); + assertEquals(NAME, operationId.operation()); + ZoneOperationId zoneOperationId = ZoneOperationId.of(PROJECT, ZONE, NAME); + assertEquals(PROJECT, zoneOperationId.project()); + assertEquals(ZONE, zoneOperationId.zone()); + assertEquals(NAME, zoneOperationId.operation()); + assertEquals(ZONE_URL, zoneOperationId.selfLink()); + zoneOperationId = ZoneOperationId.of(ZONE, NAME); + assertNull(zoneOperationId.project()); + assertEquals(ZONE, zoneOperationId.zone()); + assertEquals(NAME, zoneOperationId.operation()); + RegionOperationId regionOperationId = RegionOperationId.of(PROJECT, REGION, NAME); + assertEquals(PROJECT, regionOperationId.project()); + assertEquals(REGION, regionOperationId.region()); + assertEquals(NAME, regionOperationId.operation()); + assertEquals(REGION_URL, regionOperationId.selfLink()); + regionOperationId = RegionOperationId.of(REGION, NAME); + assertNull(regionOperationId.project()); + assertEquals(REGION, regionOperationId.region()); + assertEquals(NAME, regionOperationId.operation()); + } + + @Test + public void testToAndFromUrl() { + GlobalOperationId operationId = GlobalOperationId.of(PROJECT, NAME); + compareOperationId(operationId, GlobalOperationId.fromUrl(operationId.selfLink())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid global operation URL"); + GlobalOperationId.fromUrl("notMatchingUrl"); + ZoneOperationId zoneOperationId = ZoneOperationId.of(PROJECT, ZONE, NAME); + compareZoneOperationId(zoneOperationId, ZoneOperationId.fromUrl(zoneOperationId.selfLink())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid zone operation URL"); + ZoneOperationId.fromUrl("notMatchingUrl"); + RegionOperationId regionOperationId = RegionOperationId.of(PROJECT, REGION, NAME); + compareRegionOperationId(regionOperationId, + RegionOperationId.fromUrl(regionOperationId.selfLink())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid region operation URL"); + RegionOperationId.fromUrl("notMatchingUrl"); + } + + @Test + public void testSetProjectId() { + GlobalOperationId operationId = GlobalOperationId.of(PROJECT, NAME); + assertSame(operationId, operationId.setProjectId(PROJECT)); + compareOperationId(operationId, GlobalOperationId.of(NAME).setProjectId(PROJECT)); + ZoneOperationId zoneOperationId = ZoneOperationId.of(PROJECT, ZONE, NAME); + assertSame(zoneOperationId, zoneOperationId.setProjectId(PROJECT)); + compareZoneOperationId(zoneOperationId, ZoneOperationId.of(ZONE, NAME).setProjectId(PROJECT)); + RegionOperationId regionOperationId = RegionOperationId.of(PROJECT, REGION, NAME); + assertSame(regionOperationId, regionOperationId.setProjectId(PROJECT)); + compareRegionOperationId(regionOperationId, + RegionOperationId.of(REGION, NAME).setProjectId(PROJECT)); + } + + @Test + public void testMatchesUrl() { + assertTrue(GlobalOperationId.matchesUrl(GlobalOperationId.of(PROJECT, NAME).selfLink())); + assertFalse(GlobalOperationId.matchesUrl("notMatchingUrl")); + assertTrue(RegionOperationId.matchesUrl(RegionOperationId.of(PROJECT, REGION, NAME).selfLink())); + assertFalse(RegionOperationId.matchesUrl("notMatchingUrl")); + assertTrue(ZoneOperationId.matchesUrl(ZoneOperationId.of(PROJECT, REGION, NAME).selfLink())); + assertFalse(ZoneOperationId.matchesUrl("notMatchingUrl")); + } + + private void compareOperationId(GlobalOperationId expected, GlobalOperationId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.operation(), expected.operation()); + assertEquals(expected.selfLink(), expected.selfLink()); + assertEquals(expected.hashCode(), expected.hashCode()); + } + + private void compareZoneOperationId(ZoneOperationId expected, ZoneOperationId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.zone(), expected.zone()); + assertEquals(expected.operation(), expected.operation()); + assertEquals(expected.selfLink(), expected.selfLink()); + assertEquals(expected.hashCode(), expected.hashCode()); + } + + private void compareRegionOperationId(RegionOperationId expected, RegionOperationId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.region(), expected.region()); + assertEquals(expected.operation(), expected.operation()); + assertEquals(expected.selfLink(), expected.selfLink()); + assertEquals(expected.hashCode(), expected.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java new file mode 100644 index 000000000000..05daaacda636 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java @@ -0,0 +1,489 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.createStrictMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.gcloud.compute.Operation.OperationError; +import com.google.gcloud.compute.Operation.Status; +import com.google.gcloud.compute.Operation.OperationWarning; + +import org.junit.After; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.List; + +public class OperationTest { + + private static final OperationError OPERATION_ERROR1 = + new OperationError("code1", "location1", "message1"); + private static final OperationError OPERATION_ERROR2 = + new OperationError("code2", "location2", "message2"); + private static final OperationWarning OPERATION_WARNING1 = + new OperationWarning("code1", "message1", ImmutableMap.of("k1", "v1")); + private static final OperationWarning OPERATION_WARNING2 = + new OperationWarning("code2", "location2", ImmutableMap.of("k2", "v2")); + private static final String ID = "1"; + private static final Long CREATION_TIMESTAMP = 1453293540000L; + private static final String CLIENT_OPERATION_ID = "clientOperationId"; + private static final String OPERATION_TYPE = "delete"; + private static final String TARGET_LINK = "targetLink"; + private static final String TARGET_ID = "42"; + private static final Status STATUS = Status.DONE; + private static final String STATUS_MESSAGE = "statusMessage"; + private static final String USER = "user"; + private static final Integer PROGRESS = 100; + private static final Long INSERT_TIME = 1453293540000L; + private static final Long START_TIME = 1453293420000L; + private static final Long END_TIME = 1453293480000L; + private static final List ERRORS = + ImmutableList.of(OPERATION_ERROR1, OPERATION_ERROR2); + private static final List WARNINGS = + ImmutableList.of(OPERATION_WARNING1, OPERATION_WARNING2); + private static final Integer HTTP_ERROR_STATUS_CODE = 404; + private static final String HTTP_ERROR_MESSAGE = "NOT FOUND"; + private static final String DESCRIPTION = "description"; + private static final GlobalOperationId GLOBAL_OPERATION_ID = + GlobalOperationId.of("project", "op"); + private static final ZoneOperationId ZONE_OPERATION_ID = + ZoneOperationId.of("project", "zone", "op"); + private static final RegionOperationId REGION_OPERATION_ID = + RegionOperationId.of("project", "region", "op"); + + private Compute serviceMockReturnsOptions = createStrictMock(Compute.class); + private ComputeOptions mockOptions = createMock(ComputeOptions.class); + private Compute compute; + private Operation globalOperation; + private Operation regionOperation; + private Operation zoneOperation; + private Operation operation; + + private void initializeExpectedOperation(int optionsCalls) { + expect(serviceMockReturnsOptions.options()).andReturn(mockOptions).times(optionsCalls); + replay(serviceMockReturnsOptions); + globalOperation = new Operation.Builder(serviceMockReturnsOptions) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .operationId(GLOBAL_OPERATION_ID) + .clientOperationId(CLIENT_OPERATION_ID) + .operationType(OPERATION_TYPE) + .targetLink(TARGET_LINK) + .targetId(TARGET_ID) + .status(STATUS) + .statusMessage(STATUS_MESSAGE) + .user(USER) + .progress(PROGRESS) + .insertTime(INSERT_TIME) + .startTime(START_TIME) + .endTime(END_TIME) + .errors(ERRORS) + .warnings(WARNINGS) + .httpErrorStatusCode(HTTP_ERROR_STATUS_CODE) + .httpErrorMessage(HTTP_ERROR_MESSAGE) + .description(DESCRIPTION) + .build(); + zoneOperation = new Operation.Builder(serviceMockReturnsOptions) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .operationId(ZONE_OPERATION_ID) + .clientOperationId(CLIENT_OPERATION_ID) + .operationType(OPERATION_TYPE) + .targetLink(TARGET_LINK) + .targetId(TARGET_ID) + .status(STATUS) + .statusMessage(STATUS_MESSAGE) + .user(USER) + .progress(PROGRESS) + .insertTime(INSERT_TIME) + .startTime(START_TIME) + .endTime(END_TIME) + .errors(ERRORS) + .warnings(WARNINGS) + .httpErrorStatusCode(HTTP_ERROR_STATUS_CODE) + .httpErrorMessage(HTTP_ERROR_MESSAGE) + .description(DESCRIPTION) + .build(); + regionOperation = new Operation.Builder(serviceMockReturnsOptions) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .operationId(REGION_OPERATION_ID) + .clientOperationId(CLIENT_OPERATION_ID) + .operationType(OPERATION_TYPE) + .targetLink(TARGET_LINK) + .targetId(TARGET_ID) + .status(STATUS) + .statusMessage(STATUS_MESSAGE) + .user(USER) + .progress(PROGRESS) + .insertTime(INSERT_TIME) + .startTime(START_TIME) + .endTime(END_TIME) + .errors(ERRORS) + .warnings(WARNINGS) + .httpErrorStatusCode(HTTP_ERROR_STATUS_CODE) + .httpErrorMessage(HTTP_ERROR_MESSAGE) + .description(DESCRIPTION) + .build(); + compute = createStrictMock(Compute.class); + } + + private void initializeOperation() { + operation = new Operation.Builder(compute) + .id(ID) + .operationId(GLOBAL_OPERATION_ID) + .creationTimestamp(CREATION_TIMESTAMP) + .clientOperationId(CLIENT_OPERATION_ID) + .operationType(OPERATION_TYPE) + .targetLink(TARGET_LINK) + .targetId(TARGET_ID) + .status(STATUS) + .statusMessage(STATUS_MESSAGE) + .user(USER) + .progress(PROGRESS) + .insertTime(INSERT_TIME) + .startTime(START_TIME) + .endTime(END_TIME) + .errors(ERRORS) + .warnings(WARNINGS) + .httpErrorStatusCode(HTTP_ERROR_STATUS_CODE) + .httpErrorMessage(HTTP_ERROR_MESSAGE) + .description(DESCRIPTION) + .build(); + } + + @After + public void tearDown() throws Exception { + verify(serviceMockReturnsOptions); + } + + @Test + public void testBuilder() { + initializeExpectedOperation(6); + assertEquals(CREATION_TIMESTAMP, globalOperation.creationTimestamp()); + assertEquals(ID, globalOperation.id()); + assertEquals(GLOBAL_OPERATION_ID, globalOperation.operationId()); + assertEquals(CLIENT_OPERATION_ID, globalOperation.clientOperationId()); + assertEquals(OPERATION_TYPE, globalOperation.operationType()); + assertEquals(TARGET_LINK, globalOperation.targetLink()); + assertEquals(TARGET_ID, globalOperation.targetId()); + assertEquals(STATUS, globalOperation.status()); + assertEquals(STATUS_MESSAGE, globalOperation.statusMessage()); + assertEquals(USER, globalOperation.user()); + assertEquals(PROGRESS, globalOperation.progress()); + assertEquals(INSERT_TIME, globalOperation.insertTime()); + assertEquals(START_TIME, globalOperation.startTime()); + assertEquals(END_TIME, globalOperation.endTime()); + assertEquals(ERRORS, globalOperation.errors()); + assertEquals(WARNINGS, globalOperation.warnings()); + assertEquals(HTTP_ERROR_STATUS_CODE, globalOperation.httpErrorStatusCode()); + assertEquals(HTTP_ERROR_MESSAGE, globalOperation.httpErrorMessage()); + assertEquals(DESCRIPTION, globalOperation.description()); + assertSame(serviceMockReturnsOptions, globalOperation.compute()); + assertEquals(ID, regionOperation.id()); + assertEquals(CREATION_TIMESTAMP, regionOperation.creationTimestamp()); + assertEquals(REGION_OPERATION_ID, regionOperation.operationId()); + assertEquals(CLIENT_OPERATION_ID, regionOperation.clientOperationId()); + assertEquals(OPERATION_TYPE, regionOperation.operationType()); + assertEquals(TARGET_LINK, regionOperation.targetLink()); + assertEquals(TARGET_ID, regionOperation.targetId()); + assertEquals(STATUS, regionOperation.status()); + assertEquals(STATUS_MESSAGE, regionOperation.statusMessage()); + assertEquals(USER, regionOperation.user()); + assertEquals(PROGRESS, regionOperation.progress()); + assertEquals(INSERT_TIME, regionOperation.insertTime()); + assertEquals(START_TIME, regionOperation.startTime()); + assertEquals(END_TIME, regionOperation.endTime()); + assertEquals(ERRORS, regionOperation.errors()); + assertEquals(WARNINGS, regionOperation.warnings()); + assertEquals(HTTP_ERROR_STATUS_CODE, regionOperation.httpErrorStatusCode()); + assertEquals(HTTP_ERROR_MESSAGE, regionOperation.httpErrorMessage()); + assertEquals(DESCRIPTION, regionOperation.description()); + assertSame(serviceMockReturnsOptions, regionOperation.compute()); + assertEquals(ID, zoneOperation.id()); + assertEquals(CREATION_TIMESTAMP, zoneOperation.creationTimestamp()); + assertEquals(ZONE_OPERATION_ID, zoneOperation.operationId()); + assertEquals(CLIENT_OPERATION_ID, zoneOperation.clientOperationId()); + assertEquals(OPERATION_TYPE, zoneOperation.operationType()); + assertEquals(TARGET_LINK, zoneOperation.targetLink()); + assertEquals(TARGET_ID, zoneOperation.targetId()); + assertEquals(STATUS, zoneOperation.status()); + assertEquals(STATUS_MESSAGE, zoneOperation.statusMessage()); + assertEquals(USER, zoneOperation.user()); + assertEquals(PROGRESS, zoneOperation.progress()); + assertEquals(INSERT_TIME, zoneOperation.insertTime()); + assertEquals(START_TIME, zoneOperation.startTime()); + assertEquals(END_TIME, zoneOperation.endTime()); + assertEquals(ERRORS, zoneOperation.errors()); + assertEquals(WARNINGS, zoneOperation.warnings()); + assertEquals(HTTP_ERROR_STATUS_CODE, zoneOperation.httpErrorStatusCode()); + assertEquals(HTTP_ERROR_MESSAGE, zoneOperation.httpErrorMessage()); + assertEquals(DESCRIPTION, zoneOperation.description()); + assertSame(serviceMockReturnsOptions, zoneOperation.compute()); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(GLOBAL_OPERATION_ID) + .build(); + assertEquals(GLOBAL_OPERATION_ID, operation.operationId()); + assertSame(serviceMockReturnsOptions, operation.compute()); + assertNull(operation.creationTimestamp()); + assertNull(operation.id()); + assertNull(operation.clientOperationId()); + assertNull(operation.operationType()); + assertNull(operation.targetLink()); + assertNull(operation.targetId()); + assertNull(operation.status()); + assertNull(operation.statusMessage()); + assertNull(operation.user()); + assertNull(operation.progress()); + assertNull(operation.insertTime()); + assertNull(operation.startTime()); + assertNull(operation.endTime()); + assertNull(operation.errors()); + assertNull(operation.warnings()); + assertNull(operation.httpErrorStatusCode()); + assertNull(operation.httpErrorMessage()); + assertNull(operation.description()); + operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZONE_OPERATION_ID) + .build(); + assertSame(serviceMockReturnsOptions, operation.compute()); + assertEquals(ZONE_OPERATION_ID, operation.operationId()); + assertNull(operation.creationTimestamp()); + assertNull(operation.id()); + assertNull(operation.clientOperationId()); + assertNull(operation.operationType()); + assertNull(operation.targetLink()); + assertNull(operation.targetId()); + assertNull(operation.status()); + assertNull(operation.statusMessage()); + assertNull(operation.user()); + assertNull(operation.progress()); + assertNull(operation.insertTime()); + assertNull(operation.startTime()); + assertNull(operation.endTime()); + assertNull(operation.errors()); + assertNull(operation.warnings()); + assertNull(operation.httpErrorStatusCode()); + assertNull(operation.httpErrorMessage()); + assertNull(operation.description()); + operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(REGION_OPERATION_ID) + .build(); + assertSame(serviceMockReturnsOptions, operation.compute()); + assertEquals(REGION_OPERATION_ID, operation.operationId()); + assertNull(operation.creationTimestamp()); + assertNull(operation.id()); + assertNull(operation.clientOperationId()); + assertNull(operation.operationType()); + assertNull(operation.targetLink()); + assertNull(operation.targetId()); + assertNull(operation.status()); + assertNull(operation.statusMessage()); + assertNull(operation.user()); + assertNull(operation.progress()); + assertNull(operation.insertTime()); + assertNull(operation.startTime()); + assertNull(operation.endTime()); + assertNull(operation.errors()); + assertNull(operation.warnings()); + assertNull(operation.httpErrorStatusCode()); + assertNull(operation.httpErrorMessage()); + assertNull(operation.description()); + } + + @Test + public void testToAndFromPb() { + initializeExpectedOperation(24); + compareOperation(globalOperation, + Operation.fromPb(serviceMockReturnsOptions, globalOperation.toPb())); + assertNotNull(regionOperation.toPb().getRegion()); + compareOperation(regionOperation, + Operation.fromPb(serviceMockReturnsOptions, regionOperation.toPb())); + assertNotNull(zoneOperation.toPb().getZone()); + compareOperation(zoneOperation, + Operation.fromPb(serviceMockReturnsOptions, zoneOperation.toPb())); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(GLOBAL_OPERATION_ID) + .build(); + compareOperation(operation, Operation.fromPb(serviceMockReturnsOptions, operation.toPb())); + operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZONE_OPERATION_ID) + .build(); + compareOperation(operation, Operation.fromPb(serviceMockReturnsOptions, operation.toPb())); + operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(REGION_OPERATION_ID) + .build(); + compareOperation(operation, Operation.fromPb(serviceMockReturnsOptions, operation.toPb())); + } + + @Test + public void testDeleteTrue() { + initializeExpectedOperation(3); + expect(compute.options()).andReturn(mockOptions); + expect(compute.delete(GLOBAL_OPERATION_ID)).andReturn(true); + replay(compute); + initializeOperation(); + assertTrue(operation.delete()); + verify(compute); + } + + @Test + public void testDeleteFalse() { + initializeExpectedOperation(3); + expect(compute.options()).andReturn(mockOptions); + expect(compute.delete(GLOBAL_OPERATION_ID)).andReturn(false); + replay(compute); + initializeOperation(); + assertFalse(operation.delete()); + verify(compute); + } + + @Test + public void testExists_True() throws Exception { + initializeExpectedOperation(3); + Compute.OperationOption[] expectedOptions = {Compute.OperationOption.fields()}; + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(globalOperation); + replay(compute); + initializeOperation(); + assertTrue(operation.exists()); + verify(compute); + } + + @Test + public void testExists_False() throws Exception { + initializeExpectedOperation(3); + Compute.OperationOption[] expectedOptions = {Compute.OperationOption.fields()}; + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(null); + replay(compute); + initializeOperation(); + assertFalse(operation.exists()); + verify(compute); + } + + @Test + public void testIsDone_True() throws Exception { + initializeExpectedOperation(3); + Compute.OperationOption[] expectedOptions = + {Compute.OperationOption.fields(Compute.OperationField.STATUS)}; + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(globalOperation); + replay(compute); + initializeOperation(); + assertTrue(operation.isDone()); + verify(compute); + } + + @Test + public void testIsDone_False() throws Exception { + initializeExpectedOperation(4); + Compute.OperationOption[] expectedOptions = + {Compute.OperationOption.fields(Compute.OperationField.STATUS)}; + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(GLOBAL_OPERATION_ID, expectedOptions)).andReturn( + Operation.fromPb(serviceMockReturnsOptions, globalOperation.toPb().setStatus("PENDING"))); + replay(compute); + initializeOperation(); + assertFalse(operation.isDone()); + verify(compute); + } + @Test + public void testIsDone_NotExists() throws Exception { + initializeExpectedOperation(3); + Compute.OperationOption[] expectedOptions = + {Compute.OperationOption.fields(Compute.OperationField.STATUS)}; + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(globalOperation); + replay(compute); + initializeOperation(); + assertTrue(operation.isDone()); + verify(compute); + } + + @Test + public void testReload() throws Exception { + initializeExpectedOperation(5); + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(GLOBAL_OPERATION_ID)).andReturn(globalOperation); + replay(compute); + initializeOperation(); + Operation updatedOperation = operation.reload(); + compareOperation(globalOperation, updatedOperation); + verify(compute); + } + + @Test + public void testReloadNull() throws Exception { + initializeExpectedOperation(3); + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(GLOBAL_OPERATION_ID)).andReturn(null); + replay(compute); + initializeOperation(); + assertNull(operation.reload()); + verify(compute); + } + + @Test + public void testReloadWithOptions() throws Exception { + initializeExpectedOperation(5); + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(GLOBAL_OPERATION_ID, Compute.OperationOption.fields())) + .andReturn(globalOperation); + replay(compute); + initializeOperation(); + Operation updatedOperation = operation.reload(Compute.OperationOption.fields()); + compareOperation(globalOperation, updatedOperation); + verify(compute); + } + + private void compareOperation(Operation expected, Operation value) { + assertEquals(expected, value); + assertEquals(expected.compute().options(), value.compute().options()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.operationId(), value.operationId()); + assertEquals(expected.clientOperationId(), value.clientOperationId()); + assertEquals(expected.operationType(), value.operationType()); + assertEquals(expected.targetLink(), value.targetLink()); + assertEquals(expected.targetId(), value.targetId()); + assertEquals(expected.status(), value.status()); + assertEquals(expected.statusMessage(), value.statusMessage()); + assertEquals(expected.user(), value.user()); + assertEquals(expected.progress(), value.progress()); + assertEquals(expected.insertTime(), value.insertTime()); + assertEquals(expected.startTime(), value.startTime()); + assertEquals(expected.endTime(), value.endTime()); + assertEquals(expected.errors(), value.errors()); + assertEquals(expected.warnings(), value.warnings()); + assertEquals(expected.httpErrorStatusCode(), value.httpErrorStatusCode()); + assertEquals(expected.httpErrorMessage(), value.httpErrorMessage()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java index 74c062fd6c27..a73cf860810f 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java @@ -36,6 +36,7 @@ public class SerializationTest { + private static final Compute COMPUTE = ComputeOptions.builder().projectId("p").build().service(); private static final String ID = "42"; private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final String DESCRIPTION = "description"; @@ -113,7 +114,50 @@ public class SerializationTest { private static final LicenseId LICENSE_ID = LicenseId.of("project", "license"); private static final Boolean CHARGES_USE_FEE = true; private static final License LICENSE = new License(LICENSE_ID, CHARGES_USE_FEE); - + private static final GlobalOperationId GLOBAL_OPERATION_ID = + GlobalOperationId.of("project", "op"); + private static final ZoneOperationId ZONE_OPERATION_ID = + ZoneOperationId.of("project", "zone", "op"); + private static final RegionOperationId REGION_OPERATION_ID = + RegionOperationId.of("project", "region", "op"); + private static final Operation GLOBAL_OPERATION = + new Operation.Builder(COMPUTE).operationId(GLOBAL_OPERATION_ID).build(); + private static final Operation ZONE_OPERATION = + new Operation.Builder(COMPUTE).operationId(ZONE_OPERATION_ID).build(); + private static final Operation REGION_OPERATION = + new Operation.Builder(COMPUTE).operationId(REGION_OPERATION_ID).build(); + private static final Compute.DiskTypeOption DISK_TYPE_OPTION = + Compute.DiskTypeOption.fields(); + private static final Compute.DiskTypeFilter DISK_TYPE_FILTER = + Compute.DiskTypeFilter.equals(Compute.DiskTypeField.SELF_LINK, "selfLink"); + private static final Compute.DiskTypeListOption DISK_TYPE_LIST_OPTION = + Compute.DiskTypeListOption.filter(DISK_TYPE_FILTER); + private static final Compute.DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_OPTION = + Compute.DiskTypeAggregatedListOption.filter(DISK_TYPE_FILTER); + private static final Compute.MachineTypeOption MACHINE_TYPE_OPTION = + Compute.MachineTypeOption.fields(); + private static final Compute.MachineTypeFilter MACHINE_TYPE_FILTER = + Compute.MachineTypeFilter.equals(Compute.MachineTypeField.SELF_LINK, "selfLink"); + private static final Compute.MachineTypeListOption MACHINE_TYPE_LIST_OPTION = + Compute.MachineTypeListOption.filter(MACHINE_TYPE_FILTER); + private static final Compute.MachineTypeAggregatedListOption MACHINE_TYPE_AGGREGATED_LIST_OPTION = + Compute.MachineTypeAggregatedListOption.filter(MACHINE_TYPE_FILTER); + private static final Compute.RegionOption REGION_OPTION = Compute.RegionOption.fields(); + private static final Compute.RegionFilter REGION_FILTER = + Compute.RegionFilter.equals(Compute.RegionField.SELF_LINK, "selfLink"); + private static final Compute.RegionListOption REGION_LIST_OPTION = + Compute.RegionListOption.filter(REGION_FILTER); + private static final Compute.ZoneOption ZONE_OPTION = Compute.ZoneOption.fields(); + private static final Compute.ZoneFilter ZONE_FILTER = + Compute.ZoneFilter.equals(Compute.ZoneField.SELF_LINK, "selfLink"); + private static final Compute.ZoneListOption ZONE_LIST_OPTION = + Compute.ZoneListOption.filter(ZONE_FILTER); + private static final Compute.LicenseOption LICENSE_OPTION = Compute.LicenseOption.fields(); + private static final Compute.OperationOption OPERATION_OPTION = Compute.OperationOption.fields(); + private static final Compute.OperationFilter OPERATION_FILTER = + Compute.OperationFilter.equals(Compute.OperationField.SELF_LINK, "selfLink"); + private static final Compute.OperationListOption OPERATION_LIST_OPTION = + Compute.OperationListOption.filter(OPERATION_FILTER); @Test public void testServiceOptions() throws Exception { ComputeOptions options = ComputeOptions.builder() @@ -135,7 +179,13 @@ public void testServiceOptions() throws Exception { @Test public void testModelAndRequests() throws Exception { Serializable[] objects = {DISK_TYPE_ID, DISK_TYPE, MACHINE_TYPE_ID, MACHINE_TYPE, REGION_ID, - REGION, ZONE_ID, ZONE, LICENSE_ID, LICENSE, DEPRECATION_STATUS}; + REGION, ZONE_ID, ZONE, LICENSE_ID, LICENSE, DEPRECATION_STATUS, GLOBAL_OPERATION_ID, + REGION_OPERATION_ID, ZONE_OPERATION_ID, GLOBAL_OPERATION, REGION_OPERATION, ZONE_OPERATION, + DISK_TYPE_OPTION, DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, DISK_TYPE_AGGREGATED_LIST_OPTION, + MACHINE_TYPE_OPTION, MACHINE_TYPE_FILTER, MACHINE_TYPE_LIST_OPTION, + MACHINE_TYPE_AGGREGATED_LIST_OPTION, REGION_OPTION, REGION_FILTER, REGION_LIST_OPTION, + ZONE_OPTION, ZONE_FILTER, ZONE_LIST_OPTION, LICENSE_OPTION, OPERATION_OPTION, + OPERATION_FILTER, OPERATION_LIST_OPTION}; for (Serializable obj : objects) { Object copy = serializeAndDeserialize(obj); assertEquals(obj, obj); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java index 5bc2589e6244..ea316f521b29 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java @@ -29,8 +29,11 @@ import com.google.gcloud.compute.License; import com.google.gcloud.compute.LicenseId; import com.google.gcloud.compute.MachineType; +import com.google.gcloud.compute.Operation; import com.google.gcloud.compute.Region; +import com.google.gcloud.compute.RegionOperationId; import com.google.gcloud.compute.Zone; +import com.google.gcloud.compute.ZoneOperationId; import com.google.gcloud.compute.testing.RemoteComputeHelper; import org.junit.BeforeClass; @@ -62,7 +65,6 @@ public static void beforeClass() throws InterruptedException { @Test public void testGetDiskType() { DiskType diskType = compute.getDiskType(ZONE, DISK_TYPE); - // todo(mziccard): uncomment or remove once #695 is closed // assertNotNull(diskType.id()); assertEquals(ZONE, diskType.diskTypeId().zone()); assertEquals(DISK_TYPE, diskType.diskTypeId().diskType()); @@ -76,7 +78,6 @@ public void testGetDiskType() { public void testGetDiskTypeWithSelectedFields() { DiskType diskType = compute.getDiskType(ZONE, DISK_TYPE, Compute.DiskTypeOption.fields(Compute.DiskTypeField.CREATION_TIMESTAMP)); - // todo(mziccard): uncomment or remove once #695 is closed // assertNotNull(diskType.id()); assertEquals(ZONE, diskType.diskTypeId().zone()); assertEquals(DISK_TYPE, diskType.diskTypeId().diskType()); @@ -93,7 +94,6 @@ public void testListDiskTypes() { assertTrue(diskTypeIterator.hasNext()); while(diskTypeIterator.hasNext()) { DiskType diskType = diskTypeIterator.next(); - // todo(mziccard): uncomment or remove once #695 is closed // assertNotNull(diskType.id()); assertNotNull(diskType.diskTypeId()); assertEquals(ZONE, diskType.diskTypeId().zone()); @@ -148,7 +148,6 @@ public void testAggregatedListDiskTypes() { assertTrue(diskTypeIterator.hasNext()); while(diskTypeIterator.hasNext()) { DiskType diskType = diskTypeIterator.next(); - // todo(mziccard): uncomment or remove once #695 is closed // assertNotNull(diskType.id()); assertNotNull(diskType.diskTypeId()); assertNotNull(diskType.creationTimestamp()); @@ -447,4 +446,190 @@ public void testListZonesWithFilter() { assertEquals(ZONE, zoneIterator.next().zoneId().zone()); assertFalse(zoneIterator.hasNext()); } + + @Test + public void testListGlobalOperations() { + Page operationPage = compute.listGlobalOperations(); + Iterator operationIterator = operationPage.iterateAll(); + while(operationIterator.hasNext()) { + Operation operation = operationIterator.next(); + assertNotNull(operation.id()); + assertNotNull(operation.operationId()); + // todo(mziccard): uncomment or remove once #727 is closed + // assertNotNull(operation.creationTimestamp()); + assertNotNull(operation.operationType()); + assertNotNull(operation.status()); + assertNotNull(operation.user()); + } + } + + @Test + public void testListGlobalOperationsWithSelectedFields() { + Page operationPage = + compute.listGlobalOperations(Compute.OperationListOption.fields(Compute.OperationField.ID)); + Iterator operationIterator = operationPage.iterateAll(); + while(operationIterator.hasNext()) { + Operation operation = operationIterator.next(); + assertNotNull(operation.id()); + assertNotNull(operation.operationId()); + assertNull(operation.operationType()); + assertNull(operation.targetLink()); + assertNull(operation.targetId()); + assertNull(operation.creationTimestamp()); + assertNull(operation.operationType()); + assertNull(operation.status()); + assertNull(operation.statusMessage()); + assertNull(operation.user()); + assertNull(operation.progress()); + assertNull(operation.description()); + assertNull(operation.insertTime()); + assertNull(operation.startTime()); + assertNull(operation.endTime()); + assertNull(operation.warnings()); + assertNull(operation.httpErrorMessage()); + } + } + + @Test + public void testListGlobalOperationsWithFilter() { + Page operationPage = compute.listGlobalOperations(Compute.OperationListOption.filter( + Compute.OperationFilter.equals(Compute.OperationField.STATUS, "DONE"))); + Iterator operationIterator = operationPage.iterateAll(); + while(operationIterator.hasNext()) { + Operation operation = operationIterator.next(); + assertNotNull(operation.id()); + assertNotNull(operation.operationId()); + // todo(mziccard): uncomment or remove once #727 is closed + // assertNotNull(operation.creationTimestamp()); + assertNotNull(operation.operationType()); + assertEquals(Operation.Status.DONE, operation.status()); + assertNotNull(operation.user()); + } + } + + @Test + public void testListRegionOperations() { + Page operationPage = compute.listRegionOperations(REGION); + Iterator operationIterator = operationPage.iterateAll(); + while(operationIterator.hasNext()) { + Operation operation = operationIterator.next(); + assertNotNull(operation.id()); + assertNotNull(operation.operationId()); + assertEquals(REGION, operation.operationId().region()); + // assertNotNull(operation.creationTimestamp()); + assertNotNull(operation.operationType()); + assertNotNull(operation.status()); + assertNotNull(operation.user()); + } + } + + @Test + public void testListRegionOperationsWithSelectedFields() { + Page operationPage = compute.listRegionOperations(REGION, + Compute.OperationListOption.fields(Compute.OperationField.ID)); + Iterator operationIterator = operationPage.iterateAll(); + while(operationIterator.hasNext()) { + Operation operation = operationIterator.next(); + assertNotNull(operation.id()); + assertNotNull(operation.operationId()); + assertEquals(REGION, operation.operationId().region()); + assertNull(operation.operationType()); + assertNull(operation.targetLink()); + assertNull(operation.targetId()); + assertNull(operation.creationTimestamp()); + assertNull(operation.operationType()); + assertNull(operation.status()); + assertNull(operation.statusMessage()); + assertNull(operation.user()); + assertNull(operation.progress()); + assertNull(operation.description()); + assertNull(operation.insertTime()); + assertNull(operation.startTime()); + assertNull(operation.endTime()); + assertNull(operation.warnings()); + assertNull(operation.httpErrorMessage()); + } + } + + @Test + public void testListRegionOperationsWithFilter() { + Page operationPage = compute.listRegionOperations(REGION, + Compute.OperationListOption.filter(Compute.OperationFilter.equals( + Compute.OperationField.STATUS, "DONE"))); + Iterator operationIterator = operationPage.iterateAll(); + while(operationIterator.hasNext()) { + Operation operation = operationIterator.next(); + assertNotNull(operation.id()); + assertNotNull(operation.operationId()); + assertEquals(REGION, operation.operationId().region()); + // todo(mziccard): uncomment or remove once #727 is closed + // assertNotNull(operation.creationTimestamp()); + assertNotNull(operation.operationType()); + assertEquals(Operation.Status.DONE, operation.status()); + assertNotNull(operation.user()); + } + } + + @Test + public void testListZoneOperations() { + Page operationPage = compute.listZoneOperations(ZONE); + Iterator operationIterator = operationPage.iterateAll(); + while(operationIterator.hasNext()) { + Operation operation = operationIterator.next(); + assertNotNull(operation.id()); + assertNotNull(operation.operationId()); + assertEquals(ZONE, operation.operationId().zone()); + // assertNotNull(operation.creationTimestamp()); + assertNotNull(operation.operationType()); + assertNotNull(operation.status()); + assertNotNull(operation.user()); + } + } + + @Test + public void testListZoneOperationsWithSelectedFields() { + Page operationPage = compute.listZoneOperations(ZONE, + Compute.OperationListOption.fields(Compute.OperationField.ID)); + Iterator operationIterator = operationPage.iterateAll(); + while(operationIterator.hasNext()) { + Operation operation = operationIterator.next(); + assertNotNull(operation.id()); + assertNotNull(operation.operationId()); + assertEquals(ZONE, operation.operationId().zone()); + assertNull(operation.operationType()); + assertNull(operation.targetLink()); + assertNull(operation.targetId()); + assertNull(operation.creationTimestamp()); + assertNull(operation.operationType()); + assertNull(operation.status()); + assertNull(operation.statusMessage()); + assertNull(operation.user()); + assertNull(operation.progress()); + assertNull(operation.description()); + assertNull(operation.insertTime()); + assertNull(operation.startTime()); + assertNull(operation.endTime()); + assertNull(operation.warnings()); + assertNull(operation.httpErrorMessage()); + } + } + + @Test + public void testListZoneOperationsWithFilter() { + Page operationPage = compute.listZoneOperations(ZONE, + Compute.OperationListOption.filter(Compute.OperationFilter.equals( + Compute.OperationField.STATUS, "DONE"))); + Iterator operationIterator = operationPage.iterateAll(); + while(operationIterator.hasNext()) { + Operation operation = operationIterator.next(); + assertNotNull(operation.id()); + assertNotNull(operation.operationId()); + assertEquals(ZONE, operation.operationId().zone()); + // todo(mziccard): uncomment or remove once #727 is closed + // assertNotNull(operation.creationTimestamp()); + assertNotNull(operation.operationType()); + assertEquals(Operation.Status.DONE, operation.status()); + assertNotNull(operation.user()); + } + } } From 091d7a89b1d167d5e43bfc9ec69ca7876c3aac72 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 10 Mar 2016 10:07:53 +0100 Subject: [PATCH 285/375] Fix Compute operations issues - Fix javadoc errors - Fix OperationId and Operation tests - Fix RegionOperationId equals --- .../com/google/gcloud/compute/Compute.java | 71 ++++---- .../google/gcloud/compute/ComputeImpl.java | 2 +- .../com/google/gcloud/compute/Operation.java | 25 +-- .../google/gcloud/compute/OperationId.java | 2 +- .../gcloud/compute/RegionOperationId.java | 4 +- .../com/google/gcloud/spi/ComputeRpc.java | 6 +- .../gcloud/compute/ComputeImplTest.java | 171 ++++++++++-------- .../gcloud/compute/OperationIdTest.java | 31 +++- .../google/gcloud/compute/OperationTest.java | 147 +++++---------- .../gcloud/compute/it/ITComputeTest.java | 51 +++--- 10 files changed, 240 insertions(+), 270 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java index 4acfab38addb..f8e8359e8444 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java @@ -244,15 +244,16 @@ enum OperationField { NAME("name"), OPERATION_TYPE("operationType"), PROGRESS("progress"), + REGION("region"), SELF_LINK("selfLink"), START_TIME("startTime"), STATUS("status"), STATUS_MESSAGE("statusMessage"), - REGION("region"), TARGET_ID("targetId"), TARGET_LINK("targetLink"), USER("user"), - WARNINGS("warnings"); + WARNINGS("warnings"), + ZONE("zone"); private final String selector; @@ -292,7 +293,7 @@ enum ComparisonOperator { EQ, /** - * Defines an inequality filter. + * Defines a not-equals filter. */ NE } @@ -350,7 +351,7 @@ public static DiskTypeFilter equals(DiskTypeField field, String value) { } /** - * Returns an equality filter for the given field and string value. For string fields, + * Returns a not-equals filter for the given field and string value. For string fields, * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must * match the entire field. * @@ -368,7 +369,7 @@ public static DiskTypeFilter equals(DiskTypeField field, long value) { } /** - * Returns an inequality filter for the given field and long value. + * Returns a not-equals filter for the given field and long value. */ public static DiskTypeFilter notEquals(DiskTypeField field, long value) { return new DiskTypeFilter(checkNotNull(field), ComparisonOperator.NE, value); @@ -398,7 +399,7 @@ public static MachineTypeFilter equals(MachineTypeField field, String value) { } /** - * Returns an equality filter for the given field and string value. For string fields, + * Returns a not-equals filter for the given field and string value. For string fields, * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must * match the entire field. * @@ -416,7 +417,7 @@ public static MachineTypeFilter equals(MachineTypeField field, long value) { } /** - * Returns an inequality filter for the given field and long value. + * Returns a not-equals filter for the given field and long value. */ public static MachineTypeFilter notEquals(MachineTypeField field, long value) { return new MachineTypeFilter(checkNotNull(field), ComparisonOperator.NE, value); @@ -446,7 +447,7 @@ public static RegionFilter equals(RegionField field, String value) { } /** - * Returns an equality filter for the given field and string value. For string fields, + * Returns a not-equals filter for the given field and string value. For string fields, * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must * match the entire field. * @@ -480,7 +481,7 @@ public static ZoneFilter equals(ZoneField field, String value) { } /** - * Returns an equality filter for the given field and string value. For string fields, + * Returns a not-equals filter for the given field and string value. For string fields, * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must * match the entire field. * @@ -514,7 +515,7 @@ public static OperationFilter equals(OperationField field, String value) { } /** - * Returns an equality filter for the given field and string value. For string fields, + * Returns a not-equals filter for the given field and string value. For string fields, * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must * match the entire field. * @@ -532,7 +533,7 @@ public static OperationFilter equals(OperationField field, long value) { } /** - * Returns an inequality filter for the given field and long value. + * Returns a not-equals filter for the given field and long value. */ public static OperationFilter notEquals(OperationField field, long value) { return new OperationFilter(checkNotNull(field), ComparisonOperator.NE, value); @@ -546,7 +547,7 @@ public static OperationFilter equals(OperationField field, int value) { } /** - * Returns an inequality filter for the given field and integer value. + * Returns a not-equals filter for the given field and integer value. */ public static OperationFilter notEquals(OperationField field, int value) { return new OperationFilter(checkNotNull(field), ComparisonOperator.NE, value); @@ -566,8 +567,8 @@ private DiskTypeOption(ComputeRpc.Option option, Object value) { /** * Returns an option to specify the disk type's fields to be returned by the RPC call. If this - * option is not provided all disk type's fields are returned. {@code DiskTypeOption.fields} can - * be used to specify only the fields of interest. {@link DiskType#diskTypeId()} is always + * option is not provided, all disk type's fields are returned. {@code DiskTypeOption.fields} + * can be used to specify only the fields of interest. {@link DiskType#diskTypeId()} is always * returned, even if not specified. */ public static DiskTypeOption fields(DiskTypeField... fields) { @@ -587,7 +588,7 @@ private DiskTypeListOption(ComputeRpc.Option option, Object value) { } /** - * Returns an option to specify a filter to the disk types being listed. + * Returns an option to specify a filter on the disk types being listed. */ public static DiskTypeListOption filter(DiskTypeFilter filter) { return new DiskTypeListOption(ComputeRpc.Option.FILTER, filter.toPb()); @@ -609,9 +610,9 @@ public static DiskTypeListOption startPageToken(String pageToken) { /** * Returns an option to specify the disk type's fields to be returned by the RPC call. If this - * option is not provided all disk type's fields are returned. {@code DiskTypeListOption.fields} - * can be used to specify only the fields of interest. {@link DiskType#diskTypeId()} is always - * returned, even if not specified. + * option is not provided, all disk type's fields are returned. + * {@code DiskTypeListOption.fields} can be used to specify only the fields of interest. + * {@link DiskType#diskTypeId()} is always returned, even if not specified. */ public static DiskTypeListOption fields(DiskTypeField... fields) { StringBuilder builder = new StringBuilder(); @@ -632,7 +633,7 @@ private DiskTypeAggregatedListOption(ComputeRpc.Option option, Object value) { } /** - * Returns an option to specify a filter to the disk types being listed. + * Returns an option to specify a filter on the disk types being listed. */ public static DiskTypeAggregatedListOption filter(DiskTypeFilter filter) { return new DiskTypeAggregatedListOption(ComputeRpc.Option.FILTER, filter.toPb()); @@ -666,7 +667,7 @@ private MachineTypeOption(ComputeRpc.Option option, Object value) { /** * Returns an option to specify the machine type's fields to be returned by the RPC call. If - * this option is not provided all machine type's fields are returned. + * this option is not provided, all machine type's fields are returned. * {@code MachineTypeOption.fields} can be used to specify only the fields of interest. * {@link MachineType#machineTypeId()} is always returned, even if not specified. */ @@ -687,7 +688,7 @@ private MachineTypeListOption(ComputeRpc.Option option, Object value) { } /** - * Returns an option to specify a filter to the machine types being listed. + * Returns an option to specify a filter on the machine types being listed. */ public static MachineTypeListOption filter(MachineTypeFilter filter) { return new MachineTypeListOption(ComputeRpc.Option.FILTER, filter.toPb()); @@ -709,7 +710,7 @@ public static MachineTypeListOption startPageToken(String pageToken) { /** * Returns an option to specify the machine type's fields to be returned by the RPC call. If - * this option is not provided all machine type's fields are returned. + * this option is not provided, all machine type's fields are returned. * {@code MachineTypeListOption.fields} can be used to specify only the fields of interest. * {@link MachineType#machineTypeId()} is always returned, even if not specified. */ @@ -732,7 +733,7 @@ private MachineTypeAggregatedListOption(ComputeRpc.Option option, Object value) } /** - * Returns an option to specify a filter to the machine types being listed. + * Returns an option to specify a filter on the machine types being listed. */ public static MachineTypeAggregatedListOption filter(MachineTypeFilter filter) { return new MachineTypeAggregatedListOption(ComputeRpc.Option.FILTER, filter.toPb()); @@ -766,7 +767,7 @@ private RegionOption(ComputeRpc.Option option, Object value) { /** * Returns an option to specify the region's fields to be returned by the RPC call. If this - * option is not provided all region's fields are returned. {@code RegionOption.fields} can be + * option is not provided, all region's fields are returned. {@code RegionOption.fields} can be * used to specify only the fields of interest. {@link Region#regionId()} is always * returned, even if not specified. */ @@ -787,7 +788,7 @@ private RegionListOption(ComputeRpc.Option option, Object value) { } /** - * Returns an option to specify a filter to the regions being listed. + * Returns an option to specify a filter on the regions being listed. */ public static RegionListOption filter(RegionFilter filter) { return new RegionListOption(ComputeRpc.Option.FILTER, filter.toPb()); @@ -809,7 +810,7 @@ public static RegionListOption startPageToken(String pageToken) { /** * Returns an option to specify the region's fields to be returned by the RPC call. If this - * option is not provided all region's fields are returned. {@code RegionListOption.fields} can + * option is not provided, all region's fields are returned. {@code RegionListOption.fields} can * be used to specify only the fields of interest. {@link Region#regionId()} is always * returned, even if not specified. */ @@ -833,7 +834,7 @@ private ZoneOption(ComputeRpc.Option option, Object value) { /** * Returns an option to specify the zone's fields to be returned by the RPC call. If this option - * is not provided all zone's fields are returned. {@code ZoneOption.fields} can be used to + * is not provided, all zone's fields are returned. {@code ZoneOption.fields} can be used to * specify only the fields of interest. {@link Zone#zoneId()} is always returned, even if * not specified. */ @@ -854,7 +855,7 @@ private ZoneListOption(ComputeRpc.Option option, Object value) { } /** - * Returns an option to specify a filter to the zones being listed. + * Returns an option to specify a filter on the zones being listed. */ public static ZoneListOption filter(ZoneFilter filter) { return new ZoneListOption(ComputeRpc.Option.FILTER, filter.toPb()); @@ -876,7 +877,7 @@ public static ZoneListOption startPageToken(String pageToken) { /** * Returns an option to specify the zone's fields to be returned by the RPC call. If this option - * is not provided all zone's fields are returned. {@code ZoneListOption.fields} can be used to + * is not provided, all zone's fields are returned. {@code ZoneListOption.fields} can be used to * specify only the fields of interest. {@link Zone#zoneId()} is always returned, even if * not specified. */ @@ -900,9 +901,9 @@ private LicenseOption(ComputeRpc.Option option, Object value) { /** * Returns an option to specify the license's fields to be returned by the RPC call. If this - * option is not provided all license's fields are returned. {@code LicenseOption.fields} can be - * used to specify only the fields of interest. {@link License#licenseId()} is always returned, - * even if not specified. + * option is not provided, all license's fields are returned. {@code LicenseOption.fields} can + * be used to specify only the fields of interest. {@link License#licenseId()} is always + * returned, even if not specified. */ public static LicenseOption fields(LicenseField... fields) { return new LicenseOption(ComputeRpc.Option.FIELDS, LicenseField.selector(fields)); @@ -922,7 +923,7 @@ private OperationOption(ComputeRpc.Option option, Object value) { /** * Returns an option to specify the operation's fields to be returned by the RPC call. If this - * option is not provided all operation's fields are returned. {@code OperationOption.fields} + * option is not provided, all operation's fields are returned. {@code OperationOption.fields} * can be used to specify only the fields of interest. {@link Operation#operationId()} is * always returned, even if not specified. */ @@ -943,7 +944,7 @@ private OperationListOption(ComputeRpc.Option option, Object value) { } /** - * Returns an option to specify a filter to the operations being listed. + * Returns an option to specify a filter on the operations being listed. */ public static OperationListOption filter(OperationFilter filter) { return new OperationListOption(ComputeRpc.Option.FILTER, filter.toPb()); @@ -965,7 +966,7 @@ public static OperationListOption startPageToken(String pageToken) { /** * Returns an option to specify the operation's fields to be returned by the RPC call. If this - * option is not provided all operation's fields are returned. + * option is not provided, all operation's fields are returned. * {@code OperationListOption.fields} can be used to specify only the fields of interest. * {@link Operation#operationId()} is always returned, even if not specified. */ diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java index 13239d8209b6..453a0f5a8d53 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java @@ -195,7 +195,7 @@ public Page nextPage() { private static class ZoneOperationPageFetcher implements NextPageFetcher { - private static final long serialVersionUID = 4111705358926164078L; + private static final long serialVersionUID = -9012504536518197793L; private final Map requestOptions; private final ComputeOptions serviceOptions; private final String zone; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java index ac303843ebc4..baaa62eaae05 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java @@ -38,10 +38,10 @@ /** * Google Compute Engine operations. Operation identity can be obtained via {@link #operationId()}. - * For global operations {@link #operationId()} returns an {@link GlobalOperationId}, for region - * operations {@link #operationId()} returns a {@link RegionOperationId}, for zone operations - * {@link #operationId()} returns a {@link ZoneOperationId}. To get an {@code Operation} object with - * the most recent information use {@link #reload(Compute.OperationOption...)}. + * {@link #operationId()} returns {@link GlobalOperationId} for global operations, + * {@link RegionOperationId} for region operations, and {@link ZoneOperationId} for zone operations. + * To get an {@code Operation} object with the most recent information use + * {@link #reload(Compute.OperationOption...)}. */ public final class Operation implements Serializable { @@ -71,7 +71,7 @@ public final class Operation implements Serializable { private final String description; /** - * Types of operations. + * Status of an operation. */ public enum Status { PENDING, @@ -286,9 +286,6 @@ public int hashCode() { } } - /** - * Builder for Compute Engine operations. - */ static final class Builder { private Compute compute; @@ -310,7 +307,6 @@ static final class Builder { private List warnings; private Integer httpErrorStatusCode; private String httpErrorMessage; - private String description; Builder(Compute compute) { @@ -460,10 +456,7 @@ Builder description(String description) { return this; } - /** - * Creates an object. - */ - public Operation build() { + Operation build() { return new Operation(this); } } @@ -515,8 +508,8 @@ public Long creationTimestamp() { /** * Returns the operation's identity. This method returns an {@link GlobalOperationId} for global - * operations, returns a {@link RegionOperationId} for region operations and returns a - * {@link ZoneOperationId} for zone operations. + * operations, a {@link RegionOperationId} for region operations and a {@link ZoneOperationId} for + * zone operations. * * @see RFC1035 */ @@ -658,7 +651,7 @@ public boolean exists() throws ComputeException { /** * Checks if this operation has completed its execution, either failing or succeeding. If the * operation does not exist this method returns {@code false}. To correctly wait for operation's - * completion check that the operation exists first, using {@link #exists()}: + * completion, check that the operation exists first using {@link #exists()}: *
     {@code
        * if (operation.exists()) {
        *   while(!operation.isDone()) {
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/OperationId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/OperationId.java
    index c7211e97ca2d..eaaf7dee0ca4 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/OperationId.java
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/OperationId.java
    @@ -32,7 +32,7 @@ public interface OperationId {
       String operation();
     
       /**
    -   * Returns a fully qualified URL to the entity.
    +   * Returns a fully qualified URL to the operation.
        */
       String selfLink();
     }
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionOperationId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionOperationId.java
    index acc23410d285..e5c70bf23876 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionOperationId.java
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionOperationId.java
    @@ -62,7 +62,9 @@ public int hashCode() {
     
       @Override
       public boolean equals(Object obj) {
    -    return obj instanceof RegionOperationId && baseEquals((RegionOperationId) obj);
    +    return obj instanceof RegionOperationId
    +        && baseEquals((RegionOperationId) obj)
    +        && Objects.equals(operation, ((RegionOperationId) obj).operation);
       }
     
       @Override
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java
    index 13b391adb75e..740ad73b5b2e 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java
    @@ -171,7 +171,7 @@ public Y y() {
       Operation getGlobalOperation(String operation, Map options);
     
       /**
    -   * Lists the global operations in the current project.
    +   * Lists the global operations.
        *
        * @throws ComputeException upon failure
        */
    @@ -193,7 +193,7 @@ public Y y() {
       Operation getRegionOperation(String region, String operation, Map options);
     
       /**
    -   * Lists the region operations for the current project and region.
    +   * Lists the region operations for the provided region.
        *
        * @throws ComputeException upon failure
        */
    @@ -215,7 +215,7 @@ public Y y() {
       Operation getZoneOperation(String zone, String operation, Map options);
     
       /**
    -   * Lists the zone operations for the current project and zone.
    +   * Lists the zone operations for the provided zone.
        *
        * @throws ComputeException upon failure
        */
    diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java
    index 0d8461d611a7..e9e61dbf74f5 100644
    --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java
    +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java
    @@ -31,6 +31,27 @@
     import com.google.common.collect.Iterables;
     import com.google.gcloud.Page;
     import com.google.gcloud.RetryParams;
    +import com.google.gcloud.compute.Compute.DiskTypeAggregatedListOption;
    +import com.google.gcloud.compute.Compute.DiskTypeFilter;
    +import com.google.gcloud.compute.Compute.DiskTypeListOption;
    +import com.google.gcloud.compute.Compute.DiskTypeOption;
    +import com.google.gcloud.compute.Compute.LicenseOption;
    +import com.google.gcloud.compute.Compute.MachineTypeAggregatedListOption;
    +import com.google.gcloud.compute.Compute.MachineTypeFilter;
    +import com.google.gcloud.compute.Compute.MachineTypeListOption;
    +import com.google.gcloud.compute.Compute.MachineTypeOption;
    +import com.google.gcloud.compute.Compute.OperationFilter;
    +import com.google.gcloud.compute.Compute.OperationListOption;
    +import com.google.gcloud.compute.Compute.OperationOption;
    +import com.google.gcloud.compute.Compute.RegionFilter;
    +import com.google.gcloud.compute.Compute.RegionListOption;
    +import com.google.gcloud.compute.Compute.RegionOption;
    +import com.google.gcloud.compute.Compute.ZoneFilter;
    +import com.google.gcloud.compute.Compute.ZoneListOption;
    +import com.google.gcloud.compute.Compute.ZoneOption;
    +import com.google.gcloud.compute.Operation.OperationError;
    +import com.google.gcloud.compute.Operation.OperationWarning;
    +import com.google.gcloud.compute.Operation.Status;
     import com.google.gcloud.compute.Zone.MaintenanceWindow;
     import com.google.gcloud.spi.ComputeRpc;
     import com.google.gcloud.spi.ComputeRpc.Tuple;
    @@ -119,28 +140,28 @@ public class ComputeImplTest {
       private static final LicenseId LICENSE_ID = LicenseId.of("project", "license");
       private static final Boolean CHARGES_USE_FEE = true;
       private static final License LICENSE = new License(LICENSE_ID, CHARGES_USE_FEE);
    -  private static final Operation.OperationError OPERATION_ERROR1 =
    -      new Operation.OperationError("code1", "location1", "message1");
    -  private static final Operation.OperationError OPERATION_ERROR2 =
    -      new Operation.OperationError("code2", "location2", "message2");
    -  private static final Operation.OperationWarning OPERATION_WARNING1 =
    -      new Operation.OperationWarning("code1", "message1", ImmutableMap.of("k1", "v1"));
    -  private static final Operation.OperationWarning OPERATION_WARNING2 =
    -      new Operation.OperationWarning("code2", "location2", ImmutableMap.of("k2", "v2"));
    +  private static final OperationError OPERATION_ERROR1 =
    +      new OperationError("code1", "location1", "message1");
    +  private static final OperationError OPERATION_ERROR2 =
    +      new OperationError("code2", "location2", "message2");
    +  private static final OperationWarning OPERATION_WARNING1 =
    +      new OperationWarning("code1", "message1", ImmutableMap.of("k1", "v1"));
    +  private static final OperationWarning OPERATION_WARNING2 =
    +      new OperationWarning("code2", "location2", ImmutableMap.of("k2", "v2"));
       private static final String CLIENT_OPERATION_ID = "clientOperationId";
       private static final String OPERATION_TYPE = "delete";
       private static final String TARGET_LINK = "targetLink";
       private static final String TARGET_ID = "42";
    -  private static final Operation.Status STATUS = Operation.Status.DONE;
    +  private static final Status STATUS = Status.DONE;
       private static final String STATUS_MESSAGE = "statusMessage";
       private static final String USER = "user";
       private static final Integer PROGRESS = 100;
       private static final Long INSERT_TIME = 1453293540000L;
       private static final Long START_TIME = 1453293420000L;
       private static final Long END_TIME = 1453293480000L;
    -  private static final List ERRORS =
    +  private static final List ERRORS =
           ImmutableList.of(OPERATION_ERROR1, OPERATION_ERROR2);
    -  private static final List WARNINGS =
    +  private static final List WARNINGS =
           ImmutableList.of(OPERATION_WARNING1, OPERATION_WARNING2);
       private static final Integer HTTP_ERROR_STATUS_CODE = 404;
       private static final String HTTP_ERROR_MESSAGE = "NOT FOUND";
    @@ -155,113 +176,109 @@ public class ComputeImplTest {
       private static final Map EMPTY_RPC_OPTIONS = ImmutableMap.of();
     
       // DiskType options
    -  private static final Compute.DiskTypeOption DISK_TYPE_OPTION_FIELDS =
    -      Compute.DiskTypeOption.fields(Compute.DiskTypeField.ID, Compute.DiskTypeField.DESCRIPTION);
    +  private static final DiskTypeOption DISK_TYPE_OPTION_FIELDS =
    +      DiskTypeOption.fields(Compute.DiskTypeField.ID, Compute.DiskTypeField.DESCRIPTION);
     
       // DiskType list options
    -  private static final Compute.DiskTypeFilter DISK_TYPE_FILTER =
    -      Compute.DiskTypeFilter.equals(Compute.DiskTypeField.DESCRIPTION, "someDescription");
    -  private static final Compute.DiskTypeListOption DISK_TYPE_LIST_PAGE_TOKEN =
    -      Compute.DiskTypeListOption.startPageToken("cursor");
    -  private static final Compute.DiskTypeListOption DISK_TYPE_LIST_MAX_RESULTS =
    -      Compute.DiskTypeListOption.maxResults(42L);
    -  private static final Compute.DiskTypeListOption DISK_TYPE_LIST_FILTER =
    -      Compute.DiskTypeListOption.filter(DISK_TYPE_FILTER);
    +  private static final DiskTypeFilter DISK_TYPE_FILTER =
    +      DiskTypeFilter.equals(Compute.DiskTypeField.DESCRIPTION, "someDescription");
    +  private static final DiskTypeListOption DISK_TYPE_LIST_PAGE_TOKEN =
    +      DiskTypeListOption.startPageToken("cursor");
    +  private static final DiskTypeListOption DISK_TYPE_LIST_MAX_RESULTS =
    +      DiskTypeListOption.maxResults(42L);
    +  private static final DiskTypeListOption DISK_TYPE_LIST_FILTER =
    +      DiskTypeListOption.filter(DISK_TYPE_FILTER);
       private static final Map DISK_TYPE_LIST_OPTIONS = ImmutableMap.of(
           ComputeRpc.Option.PAGE_TOKEN, "cursor",
           ComputeRpc.Option.MAX_RESULTS, 42L,
           ComputeRpc.Option.FILTER, "description eq someDescription");
     
       // DiskType aggregated list options
    -  private static final Compute.DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_PAGE_TOKEN =
    -      Compute.DiskTypeAggregatedListOption.startPageToken("cursor");
    -  private static final Compute.DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_MAX_RESULTS =
    -      Compute.DiskTypeAggregatedListOption.maxResults(42L);
    -  private static final Compute.DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_FILTER =
    -      Compute.DiskTypeAggregatedListOption.filter(DISK_TYPE_FILTER);
    +  private static final DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_PAGE_TOKEN =
    +      DiskTypeAggregatedListOption.startPageToken("cursor");
    +  private static final DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_MAX_RESULTS =
    +      DiskTypeAggregatedListOption.maxResults(42L);
    +  private static final DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_FILTER =
    +      DiskTypeAggregatedListOption.filter(DISK_TYPE_FILTER);
     
       // MachineType options
    -  private static final Compute.MachineTypeOption MACHINE_TYPE_OPTION_FIELDS =
    -      Compute.MachineTypeOption.fields(Compute.MachineTypeField.ID,
    +  private static final MachineTypeOption MACHINE_TYPE_OPTION_FIELDS =
    +      MachineTypeOption.fields(Compute.MachineTypeField.ID,
               Compute.MachineTypeField.DESCRIPTION);
     
       // MachineType list options
    -  private static final Compute.MachineTypeFilter MACHINE_TYPE_FILTER =
    -      Compute.MachineTypeFilter.notEquals(Compute.MachineTypeField.MAXIMUM_PERSISTENT_DISKS, 42L);
    -  private static final Compute.MachineTypeListOption MACHINE_TYPE_LIST_PAGE_TOKEN =
    -      Compute.MachineTypeListOption.startPageToken("cursor");
    -  private static final Compute.MachineTypeListOption MACHINE_TYPE_LIST_MAX_RESULTS =
    -      Compute.MachineTypeListOption.maxResults(42L);
    -  private static final Compute.MachineTypeListOption MACHINE_TYPE_LIST_FILTER =
    -      Compute.MachineTypeListOption.filter(MACHINE_TYPE_FILTER);
    +  private static final MachineTypeFilter MACHINE_TYPE_FILTER =
    +      MachineTypeFilter.notEquals(Compute.MachineTypeField.MAXIMUM_PERSISTENT_DISKS, 42L);
    +  private static final MachineTypeListOption MACHINE_TYPE_LIST_PAGE_TOKEN =
    +      MachineTypeListOption.startPageToken("cursor");
    +  private static final MachineTypeListOption MACHINE_TYPE_LIST_MAX_RESULTS =
    +      MachineTypeListOption.maxResults(42L);
    +  private static final MachineTypeListOption MACHINE_TYPE_LIST_FILTER =
    +      MachineTypeListOption.filter(MACHINE_TYPE_FILTER);
       private static final Map MACHINE_TYPE_LIST_OPTIONS = ImmutableMap.of(
           ComputeRpc.Option.PAGE_TOKEN, "cursor",
           ComputeRpc.Option.MAX_RESULTS, 42L,
           ComputeRpc.Option.FILTER, "maximumPersistentDisks ne 42");
     
       // MachineType aggregated list options
    -  private static final Compute.MachineTypeAggregatedListOption
    -      MACHINE_TYPE_AGGREGATED_LIST_PAGE_TOKEN =
    -      Compute.MachineTypeAggregatedListOption.startPageToken("cursor");
    -  private static final Compute.MachineTypeAggregatedListOption
    -      MACHINE_TYPE_AGGREGATED_LIST_MAX_RESULTS =
    -      Compute.MachineTypeAggregatedListOption.maxResults(42L);
    -  private static final Compute.MachineTypeAggregatedListOption MACHINE_TYPE_AGGREGATED_LIST_FILTER =
    -      Compute.MachineTypeAggregatedListOption.filter(MACHINE_TYPE_FILTER);
    +  private static final MachineTypeAggregatedListOption MACHINE_TYPE_AGGREGATED_LIST_PAGE_TOKEN =
    +      MachineTypeAggregatedListOption.startPageToken("cursor");
    +  private static final MachineTypeAggregatedListOption MACHINE_TYPE_AGGREGATED_LIST_MAX_RESULTS =
    +      MachineTypeAggregatedListOption.maxResults(42L);
    +  private static final MachineTypeAggregatedListOption MACHINE_TYPE_AGGREGATED_LIST_FILTER =
    +      MachineTypeAggregatedListOption.filter(MACHINE_TYPE_FILTER);
     
       // Region options
    -  private static final Compute.RegionOption REGION_OPTION_FIELDS =
    -      Compute.RegionOption.fields(Compute.RegionField.ID, Compute.RegionField.DESCRIPTION);
    +  private static final RegionOption REGION_OPTION_FIELDS =
    +      RegionOption.fields(Compute.RegionField.ID, Compute.RegionField.DESCRIPTION);
     
       // Region list options
    -  private static final Compute.RegionFilter REGION_FILTER =
    -      Compute.RegionFilter.equals(Compute.RegionField.ID, "someId");
    -  private static final Compute.RegionListOption REGION_LIST_PAGE_TOKEN =
    -      Compute.RegionListOption.startPageToken("cursor");
    -  private static final Compute.RegionListOption REGION_LIST_MAX_RESULTS =
    -      Compute.RegionListOption.maxResults(42L);
    -  private static final Compute.RegionListOption REGION_LIST_FILTER =
    -      Compute.RegionListOption.filter(REGION_FILTER);
    +  private static final RegionFilter REGION_FILTER =
    +      RegionFilter.equals(Compute.RegionField.ID, "someId");
    +  private static final RegionListOption REGION_LIST_PAGE_TOKEN =
    +      RegionListOption.startPageToken("cursor");
    +  private static final RegionListOption REGION_LIST_MAX_RESULTS =
    +      RegionListOption.maxResults(42L);
    +  private static final RegionListOption REGION_LIST_FILTER =
    +      RegionListOption.filter(REGION_FILTER);
       private static final Map REGION_LIST_OPTIONS = ImmutableMap.of(
           ComputeRpc.Option.PAGE_TOKEN, "cursor",
           ComputeRpc.Option.MAX_RESULTS, 42L,
           ComputeRpc.Option.FILTER, "id eq someId");
     
       // Zone options
    -  private static final Compute.ZoneOption ZONE_OPTION_FIELDS =
    -      Compute.ZoneOption.fields(Compute.ZoneField.ID, Compute.ZoneField.DESCRIPTION);
    +  private static final ZoneOption ZONE_OPTION_FIELDS =
    +      ZoneOption.fields(Compute.ZoneField.ID, Compute.ZoneField.DESCRIPTION);
     
       // Zone list options
    -  private static final Compute.ZoneFilter ZONE_FILTER =
    -      Compute.ZoneFilter.notEquals(Compute.ZoneField.NAME, "someName");
    -  private static final Compute.ZoneListOption ZONE_LIST_PAGE_TOKEN =
    -      Compute.ZoneListOption.startPageToken("cursor");
    -  private static final Compute.ZoneListOption ZONE_LIST_MAX_RESULTS =
    -      Compute.ZoneListOption.maxResults(42L);
    -  private static final Compute.ZoneListOption ZONE_LIST_FILTER =
    -      Compute.ZoneListOption.filter(ZONE_FILTER);
    +  private static final ZoneFilter ZONE_FILTER =
    +      ZoneFilter.notEquals(Compute.ZoneField.NAME, "someName");
    +  private static final ZoneListOption ZONE_LIST_PAGE_TOKEN =
    +      ZoneListOption.startPageToken("cursor");
    +  private static final ZoneListOption ZONE_LIST_MAX_RESULTS = ZoneListOption.maxResults(42L);
    +  private static final ZoneListOption ZONE_LIST_FILTER = ZoneListOption.filter(ZONE_FILTER);
       private static final Map ZONE_LIST_OPTIONS = ImmutableMap.of(
           ComputeRpc.Option.PAGE_TOKEN, "cursor",
           ComputeRpc.Option.MAX_RESULTS, 42L,
           ComputeRpc.Option.FILTER, "name ne someName");
     
       // License options
    -  private static final Compute.LicenseOption LICENSE_OPTION_FIELDS =
    -      Compute.LicenseOption.fields(Compute.LicenseField.CHARGES_USE_FEE);
    +  private static final LicenseOption LICENSE_OPTION_FIELDS =
    +      LicenseOption.fields(Compute.LicenseField.CHARGES_USE_FEE);
     
       // Operation options
    -  private static final Compute.OperationOption OPERATION_OPTION_FIELDS =
    -      Compute.OperationOption.fields(Compute.OperationField.ID, Compute.OperationField.DESCRIPTION);
    +  private static final OperationOption OPERATION_OPTION_FIELDS =
    +      OperationOption.fields(Compute.OperationField.ID, Compute.OperationField.DESCRIPTION);
     
       // Operation list options
    -  private static final Compute.OperationFilter OPERATION_FILTER =
    -      Compute.OperationFilter.notEquals(Compute.OperationField.PROGRESS, 0);
    -  private static final Compute.OperationListOption OPERATION_LIST_PAGE_TOKEN =
    -      Compute.OperationListOption.startPageToken("cursor");
    -  private static final Compute.OperationListOption OPERATION_LIST_MAX_RESULTS =
    -      Compute.OperationListOption.maxResults(42L);
    -  private static final Compute.OperationListOption OPERATION_LIST_FILTER =
    -      Compute.OperationListOption.filter(OPERATION_FILTER);
    +  private static final OperationFilter OPERATION_FILTER =
    +      OperationFilter.notEquals(Compute.OperationField.PROGRESS, 0);
    +  private static final OperationListOption OPERATION_LIST_PAGE_TOKEN =
    +      OperationListOption.startPageToken("cursor");
    +  private static final OperationListOption OPERATION_LIST_MAX_RESULTS =
    +      OperationListOption.maxResults(42L);
    +  private static final OperationListOption OPERATION_LIST_FILTER =
    +      OperationListOption.filter(OPERATION_FILTER);
       private static final Map OPERATION_LIST_OPTIONS = ImmutableMap.of(
           ComputeRpc.Option.PAGE_TOKEN, "cursor",
           ComputeRpc.Option.MAX_RESULTS, 42L,
    diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationIdTest.java
    index 98430f0d1ad5..36ca5ef19090 100644
    --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationIdTest.java
    +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationIdTest.java
    @@ -60,6 +60,10 @@ public void testOf() {
         assertNull(zoneOperationId.project());
         assertEquals(ZONE, zoneOperationId.zone());
         assertEquals(NAME, zoneOperationId.operation());
    +    zoneOperationId = ZoneOperationId.of(ZoneId.of(PROJECT, ZONE), NAME);
    +    assertEquals(PROJECT, zoneOperationId.project());
    +    assertEquals(ZONE, zoneOperationId.zone());
    +    assertEquals(NAME, zoneOperationId.operation());
         RegionOperationId regionOperationId = RegionOperationId.of(PROJECT, REGION, NAME);
         assertEquals(PROJECT, regionOperationId.project());
         assertEquals(REGION, regionOperationId.region());
    @@ -69,20 +73,23 @@ public void testOf() {
         assertNull(regionOperationId.project());
         assertEquals(REGION, regionOperationId.region());
         assertEquals(NAME, regionOperationId.operation());
    +    regionOperationId = RegionOperationId.of(RegionId.of(PROJECT, REGION), NAME);
    +    assertEquals(PROJECT, regionOperationId.project());
    +    assertEquals(REGION, regionOperationId.region());
    +    assertEquals(NAME, regionOperationId.operation());
       }
     
       @Test
    -  public void testToAndFromUrl() {
    +  public void testToAndFromUrlGlobal() {
         GlobalOperationId operationId = GlobalOperationId.of(PROJECT, NAME);
         compareOperationId(operationId, GlobalOperationId.fromUrl(operationId.selfLink()));
         thrown.expect(IllegalArgumentException.class);
         thrown.expectMessage("notMatchingUrl is not a valid global operation URL");
         GlobalOperationId.fromUrl("notMatchingUrl");
    -    ZoneOperationId zoneOperationId = ZoneOperationId.of(PROJECT, ZONE, NAME);
    -    compareZoneOperationId(zoneOperationId, ZoneOperationId.fromUrl(zoneOperationId.selfLink()));
    -    thrown.expect(IllegalArgumentException.class);
    -    thrown.expectMessage("notMatchingUrl is not a valid zone operation URL");
    -    ZoneOperationId.fromUrl("notMatchingUrl");
    +  }
    +
    +  @Test
    +  public void testToAndFromUrlRegion() {
         RegionOperationId regionOperationId = RegionOperationId.of(PROJECT, REGION, NAME);
         compareRegionOperationId(regionOperationId,
             RegionOperationId.fromUrl(regionOperationId.selfLink()));
    @@ -91,6 +98,15 @@ public void testToAndFromUrl() {
         RegionOperationId.fromUrl("notMatchingUrl");
       }
     
    +  @Test
    +  public void testToAndFromUrlZone() {
    +    ZoneOperationId zoneOperationId = ZoneOperationId.of(PROJECT, ZONE, NAME);
    +    compareZoneOperationId(zoneOperationId, ZoneOperationId.fromUrl(zoneOperationId.selfLink()));
    +    thrown.expect(IllegalArgumentException.class);
    +    thrown.expectMessage("notMatchingUrl is not a valid zone operation URL");
    +    ZoneOperationId.fromUrl("notMatchingUrl");
    +  }
    +
       @Test
       public void testSetProjectId() {
         GlobalOperationId operationId = GlobalOperationId.of(PROJECT, NAME);
    @@ -109,7 +125,8 @@ public void testSetProjectId() {
       public void testMatchesUrl() {
         assertTrue(GlobalOperationId.matchesUrl(GlobalOperationId.of(PROJECT, NAME).selfLink()));
         assertFalse(GlobalOperationId.matchesUrl("notMatchingUrl"));
    -    assertTrue(RegionOperationId.matchesUrl(RegionOperationId.of(PROJECT, REGION, NAME).selfLink()));
    +    assertTrue(
    +        RegionOperationId.matchesUrl(RegionOperationId.of(PROJECT, REGION, NAME).selfLink()));
         assertFalse(RegionOperationId.matchesUrl("notMatchingUrl"));
         assertTrue(ZoneOperationId.matchesUrl(ZoneOperationId.of(PROJECT, REGION, NAME).selfLink()));
         assertFalse(ZoneOperationId.matchesUrl("notMatchingUrl"));
    diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java
    index 05daaacda636..9f08491a1632 100644
    --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java
    +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java
    @@ -31,13 +31,12 @@
     import com.google.common.collect.ImmutableList;
     import com.google.common.collect.ImmutableMap;
     import com.google.gcloud.compute.Operation.OperationError;
    -import com.google.gcloud.compute.Operation.Status;
     import com.google.gcloud.compute.Operation.OperationWarning;
    +import com.google.gcloud.compute.Operation.Status;
     
     import org.junit.After;
     import org.junit.Test;
     
    -import java.math.BigInteger;
     import java.util.List;
     
     public class OperationTest {
    @@ -183,74 +182,29 @@ public void tearDown() throws Exception {
         verify(serviceMockReturnsOptions);
       }
     
    -  @Test
    -  public void testBuilder() {
    -    initializeExpectedOperation(6);
    -    assertEquals(CREATION_TIMESTAMP, globalOperation.creationTimestamp());
    -    assertEquals(ID, globalOperation.id());
    -    assertEquals(GLOBAL_OPERATION_ID, globalOperation.operationId());
    -    assertEquals(CLIENT_OPERATION_ID, globalOperation.clientOperationId());
    -    assertEquals(OPERATION_TYPE, globalOperation.operationType());
    -    assertEquals(TARGET_LINK, globalOperation.targetLink());
    -    assertEquals(TARGET_ID, globalOperation.targetId());
    -    assertEquals(STATUS, globalOperation.status());
    -    assertEquals(STATUS_MESSAGE, globalOperation.statusMessage());
    -    assertEquals(USER, globalOperation.user());
    -    assertEquals(PROGRESS, globalOperation.progress());
    -    assertEquals(INSERT_TIME, globalOperation.insertTime());
    -    assertEquals(START_TIME, globalOperation.startTime());
    -    assertEquals(END_TIME, globalOperation.endTime());
    -    assertEquals(ERRORS, globalOperation.errors());
    -    assertEquals(WARNINGS, globalOperation.warnings());
    +  private void assertEqualsCommonFields(Operation operation) {
    +    assertEquals(CREATION_TIMESTAMP, operation.creationTimestamp());
    +    assertEquals(ID, operation.id());
    +    assertEquals(CLIENT_OPERATION_ID, operation.clientOperationId());
    +    assertEquals(OPERATION_TYPE, operation.operationType());
    +    assertEquals(TARGET_LINK, operation.targetLink());
    +    assertEquals(TARGET_ID, operation.targetId());
    +    assertEquals(STATUS, operation.status());
    +    assertEquals(STATUS_MESSAGE, operation.statusMessage());
    +    assertEquals(USER, operation.user());
    +    assertEquals(PROGRESS, operation.progress());
    +    assertEquals(INSERT_TIME, operation.insertTime());
    +    assertEquals(START_TIME, operation.startTime());
    +    assertEquals(END_TIME, operation.endTime());
    +    assertEquals(ERRORS, operation.errors());
    +    assertEquals(WARNINGS, operation.warnings());
         assertEquals(HTTP_ERROR_STATUS_CODE, globalOperation.httpErrorStatusCode());
         assertEquals(HTTP_ERROR_MESSAGE, globalOperation.httpErrorMessage());
         assertEquals(DESCRIPTION, globalOperation.description());
         assertSame(serviceMockReturnsOptions, globalOperation.compute());
    -    assertEquals(ID, regionOperation.id());
    -    assertEquals(CREATION_TIMESTAMP, regionOperation.creationTimestamp());
    -    assertEquals(REGION_OPERATION_ID, regionOperation.operationId());
    -    assertEquals(CLIENT_OPERATION_ID, regionOperation.clientOperationId());
    -    assertEquals(OPERATION_TYPE, regionOperation.operationType());
    -    assertEquals(TARGET_LINK, regionOperation.targetLink());
    -    assertEquals(TARGET_ID, regionOperation.targetId());
    -    assertEquals(STATUS, regionOperation.status());
    -    assertEquals(STATUS_MESSAGE, regionOperation.statusMessage());
    -    assertEquals(USER, regionOperation.user());
    -    assertEquals(PROGRESS, regionOperation.progress());
    -    assertEquals(INSERT_TIME, regionOperation.insertTime());
    -    assertEquals(START_TIME, regionOperation.startTime());
    -    assertEquals(END_TIME, regionOperation.endTime());
    -    assertEquals(ERRORS, regionOperation.errors());
    -    assertEquals(WARNINGS, regionOperation.warnings());
    -    assertEquals(HTTP_ERROR_STATUS_CODE, regionOperation.httpErrorStatusCode());
    -    assertEquals(HTTP_ERROR_MESSAGE, regionOperation.httpErrorMessage());
    -    assertEquals(DESCRIPTION, regionOperation.description());
    -    assertSame(serviceMockReturnsOptions, regionOperation.compute());
    -    assertEquals(ID, zoneOperation.id());
    -    assertEquals(CREATION_TIMESTAMP, zoneOperation.creationTimestamp());
    -    assertEquals(ZONE_OPERATION_ID, zoneOperation.operationId());
    -    assertEquals(CLIENT_OPERATION_ID, zoneOperation.clientOperationId());
    -    assertEquals(OPERATION_TYPE, zoneOperation.operationType());
    -    assertEquals(TARGET_LINK, zoneOperation.targetLink());
    -    assertEquals(TARGET_ID, zoneOperation.targetId());
    -    assertEquals(STATUS, zoneOperation.status());
    -    assertEquals(STATUS_MESSAGE, zoneOperation.statusMessage());
    -    assertEquals(USER, zoneOperation.user());
    -    assertEquals(PROGRESS, zoneOperation.progress());
    -    assertEquals(INSERT_TIME, zoneOperation.insertTime());
    -    assertEquals(START_TIME, zoneOperation.startTime());
    -    assertEquals(END_TIME, zoneOperation.endTime());
    -    assertEquals(ERRORS, zoneOperation.errors());
    -    assertEquals(WARNINGS, zoneOperation.warnings());
    -    assertEquals(HTTP_ERROR_STATUS_CODE, zoneOperation.httpErrorStatusCode());
    -    assertEquals(HTTP_ERROR_MESSAGE, zoneOperation.httpErrorMessage());
    -    assertEquals(DESCRIPTION, zoneOperation.description());
    -    assertSame(serviceMockReturnsOptions, zoneOperation.compute());
    -    Operation operation = new Operation.Builder(serviceMockReturnsOptions)
    -        .operationId(GLOBAL_OPERATION_ID)
    -        .build();
    -    assertEquals(GLOBAL_OPERATION_ID, operation.operationId());
    -    assertSame(serviceMockReturnsOptions, operation.compute());
    +  }
    +
    +  private void assertNullCommonFields(Operation operation) {
         assertNull(operation.creationTimestamp());
         assertNull(operation.id());
         assertNull(operation.clientOperationId());
    @@ -269,52 +223,33 @@ public void testBuilder() {
         assertNull(operation.httpErrorStatusCode());
         assertNull(operation.httpErrorMessage());
         assertNull(operation.description());
    +    assertSame(serviceMockReturnsOptions, operation.compute());
    +  }
    +
    +  @Test
    +  public void testBuilder() {
    +    initializeExpectedOperation(6);
    +    assertEqualsCommonFields(globalOperation);
    +    assertEquals(GLOBAL_OPERATION_ID, globalOperation.operationId());
    +    assertEqualsCommonFields(regionOperation);
    +    assertEquals(REGION_OPERATION_ID, regionOperation.operationId());
    +    assertEqualsCommonFields(zoneOperation);
    +    assertEquals(ZONE_OPERATION_ID, zoneOperation.operationId());
    +    Operation operation = new Operation.Builder(serviceMockReturnsOptions)
    +        .operationId(GLOBAL_OPERATION_ID)
    +        .build();
    +    assertNullCommonFields(operation);
    +    assertEquals(GLOBAL_OPERATION_ID, operation.operationId());
         operation = new Operation.Builder(serviceMockReturnsOptions)
             .operationId(ZONE_OPERATION_ID)
             .build();
    -    assertSame(serviceMockReturnsOptions, operation.compute());
    +    assertNullCommonFields(operation);
         assertEquals(ZONE_OPERATION_ID, operation.operationId());
    -    assertNull(operation.creationTimestamp());
    -    assertNull(operation.id());
    -    assertNull(operation.clientOperationId());
    -    assertNull(operation.operationType());
    -    assertNull(operation.targetLink());
    -    assertNull(operation.targetId());
    -    assertNull(operation.status());
    -    assertNull(operation.statusMessage());
    -    assertNull(operation.user());
    -    assertNull(operation.progress());
    -    assertNull(operation.insertTime());
    -    assertNull(operation.startTime());
    -    assertNull(operation.endTime());
    -    assertNull(operation.errors());
    -    assertNull(operation.warnings());
    -    assertNull(operation.httpErrorStatusCode());
    -    assertNull(operation.httpErrorMessage());
    -    assertNull(operation.description());
         operation = new Operation.Builder(serviceMockReturnsOptions)
             .operationId(REGION_OPERATION_ID)
             .build();
    -    assertSame(serviceMockReturnsOptions, operation.compute());
    +    assertNullCommonFields(operation);
         assertEquals(REGION_OPERATION_ID, operation.operationId());
    -    assertNull(operation.creationTimestamp());
    -    assertNull(operation.id());
    -    assertNull(operation.clientOperationId());
    -    assertNull(operation.operationType());
    -    assertNull(operation.targetLink());
    -    assertNull(operation.targetId());
    -    assertNull(operation.status());
    -    assertNull(operation.statusMessage());
    -    assertNull(operation.user());
    -    assertNull(operation.progress());
    -    assertNull(operation.insertTime());
    -    assertNull(operation.startTime());
    -    assertNull(operation.endTime());
    -    assertNull(operation.errors());
    -    assertNull(operation.warnings());
    -    assertNull(operation.httpErrorStatusCode());
    -    assertNull(operation.httpErrorMessage());
    -    assertNull(operation.description());
       }
     
       @Test
    @@ -420,10 +355,10 @@ public void testIsDone_NotExists() throws Exception {
         Compute.OperationOption[] expectedOptions =
             {Compute.OperationOption.fields(Compute.OperationField.STATUS)};
         expect(compute.options()).andReturn(mockOptions);
    -    expect(compute.get(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(globalOperation);
    +    expect(compute.get(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(null);
         replay(compute);
         initializeOperation();
    -    assertTrue(operation.isDone());
    +    assertFalse(operation.isDone());
         verify(compute);
       }
     
    diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java
    index ea316f521b29..da446821a088 100644
    --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java
    +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java
    @@ -65,6 +65,7 @@ public static void beforeClass() throws InterruptedException {
       @Test
       public void testGetDiskType() {
         DiskType diskType = compute.getDiskType(ZONE, DISK_TYPE);
    +    // todo(mziccard): uncomment or remove once #695 is closed
         // assertNotNull(diskType.id());
         assertEquals(ZONE, diskType.diskTypeId().zone());
         assertEquals(DISK_TYPE, diskType.diskTypeId().diskType());
    @@ -78,6 +79,7 @@ public void testGetDiskType() {
       public void testGetDiskTypeWithSelectedFields() {
         DiskType diskType = compute.getDiskType(ZONE, DISK_TYPE,
             Compute.DiskTypeOption.fields(Compute.DiskTypeField.CREATION_TIMESTAMP));
    +    // todo(mziccard): uncomment or remove once #695 is closed
         // assertNotNull(diskType.id());
         assertEquals(ZONE, diskType.diskTypeId().zone());
         assertEquals(DISK_TYPE, diskType.diskTypeId().diskType());
    @@ -92,8 +94,9 @@ public void testListDiskTypes() {
         Page diskPage = compute.listDiskTypes(ZONE);
         Iterator diskTypeIterator = diskPage.iterateAll();
         assertTrue(diskTypeIterator.hasNext());
    -    while(diskTypeIterator.hasNext()) {
    +    while (diskTypeIterator.hasNext()) {
           DiskType diskType = diskTypeIterator.next();
    +      // todo(mziccard): uncomment or remove once #695 is closed
           // assertNotNull(diskType.id());
           assertNotNull(diskType.diskTypeId());
           assertEquals(ZONE, diskType.diskTypeId().zone());
    @@ -110,7 +113,7 @@ public void testListDiskTypesWithSelectedFields() {
             Compute.DiskTypeListOption.fields(Compute.DiskTypeField.CREATION_TIMESTAMP));
         Iterator diskTypeIterator = diskPage.iterateAll();
         assertTrue(diskTypeIterator.hasNext());
    -    while(diskTypeIterator.hasNext()) {
    +    while (diskTypeIterator.hasNext()) {
           DiskType diskType = diskTypeIterator.next();
           assertNull(diskType.id());
           assertNotNull(diskType.diskTypeId());
    @@ -128,7 +131,7 @@ public void testListDiskTypesWithFilter() {
             Compute.DiskTypeFilter.equals(Compute.DiskTypeField.DEFAULT_DISK_SIZE_GB, 375)));
         Iterator diskTypeIterator = diskPage.iterateAll();
         assertTrue(diskTypeIterator.hasNext());
    -    while(diskTypeIterator.hasNext()) {
    +    while (diskTypeIterator.hasNext()) {
           DiskType diskType = diskTypeIterator.next();
           // todo(mziccard): uncomment or remove once #695 is closed
           // assertNotNull(diskType.id());
    @@ -146,7 +149,7 @@ public void testAggregatedListDiskTypes() {
         Page diskPage = compute.listDiskTypes();
         Iterator diskTypeIterator = diskPage.iterateAll();
         assertTrue(diskTypeIterator.hasNext());
    -    while(diskTypeIterator.hasNext()) {
    +    while (diskTypeIterator.hasNext()) {
           DiskType diskType = diskTypeIterator.next();
           // assertNotNull(diskType.id());
           assertNotNull(diskType.diskTypeId());
    @@ -163,7 +166,7 @@ public void testAggregatedListDiskTypesWithFilter() {
             Compute.DiskTypeFilter.notEquals(Compute.DiskTypeField.DEFAULT_DISK_SIZE_GB, 375)));
         Iterator diskTypeIterator = diskPage.iterateAll();
         assertTrue(diskTypeIterator.hasNext());
    -    while(diskTypeIterator.hasNext()) {
    +    while (diskTypeIterator.hasNext()) {
           DiskType diskType = diskTypeIterator.next();
           // todo(mziccard): uncomment or remove once #695 is closed
           // assertNotNull(diskType.id());
    @@ -209,7 +212,7 @@ public void testListMachineTypes() {
         Page machinePage = compute.listMachineTypes(ZONE);
         Iterator machineTypeIterator = machinePage.iterateAll();
         assertTrue(machineTypeIterator.hasNext());
    -    while(machineTypeIterator.hasNext()) {
    +    while (machineTypeIterator.hasNext()) {
           MachineType machineType = machineTypeIterator.next();
           assertNotNull(machineType.machineTypeId());
           assertEquals(ZONE, machineType.machineTypeId().zone());
    @@ -229,7 +232,7 @@ public void testListMachineTypesWithSelectedFields() {
             Compute.MachineTypeListOption.fields(Compute.MachineTypeField.CREATION_TIMESTAMP));
         Iterator machineTypeIterator = machinePage.iterateAll();
         assertTrue(machineTypeIterator.hasNext());
    -    while(machineTypeIterator.hasNext()) {
    +    while (machineTypeIterator.hasNext()) {
           MachineType machineType = machineTypeIterator.next();
           assertNotNull(machineType.machineTypeId());
           assertEquals(ZONE, machineType.machineTypeId().zone());
    @@ -250,7 +253,7 @@ public void testListMachineTypesWithFilter() {
                 Compute.MachineTypeFilter.equals(Compute.MachineTypeField.GUEST_CPUS, 2)));
         Iterator machineTypeIterator = machinePage.iterateAll();
         assertTrue(machineTypeIterator.hasNext());
    -    while(machineTypeIterator.hasNext()) {
    +    while (machineTypeIterator.hasNext()) {
           MachineType machineType = machineTypeIterator.next();
           assertNotNull(machineType.machineTypeId());
           assertEquals(ZONE, machineType.machineTypeId().zone());
    @@ -270,7 +273,7 @@ public void testAggregatedListMachineTypes() {
         Page machinePage = compute.listMachineTypes();
         Iterator machineTypeIterator = machinePage.iterateAll();
         assertTrue(machineTypeIterator.hasNext());
    -    while(machineTypeIterator.hasNext()) {
    +    while (machineTypeIterator.hasNext()) {
           MachineType machineType = machineTypeIterator.next();
           assertNotNull(machineType.machineTypeId());
           assertNotNull(machineType.id());
    @@ -290,7 +293,7 @@ public void testAggregatedListMachineTypesWithFilter() {
                 Compute.MachineTypeFilter.notEquals(Compute.MachineTypeField.GUEST_CPUS, 2)));
         Iterator machineTypeIterator = machinePage.iterateAll();
         assertTrue(machineTypeIterator.hasNext());
    -    while(machineTypeIterator.hasNext()) {
    +    while (machineTypeIterator.hasNext()) {
           MachineType machineType = machineTypeIterator.next();
           assertNotNull(machineType.machineTypeId());
           assertNotNull(machineType.id());
    @@ -346,7 +349,7 @@ public void testGetRegionWithSelectedFields() {
       public void testListRegions() {
         Page regionPage = compute.listRegions();
         Iterator regionIterator = regionPage.iterateAll();
    -    while(regionIterator.hasNext()) {
    +    while (regionIterator.hasNext()) {
           Region region = regionIterator.next();
           assertNotNull(region.regionId());
           assertNotNull(region.description());
    @@ -363,7 +366,7 @@ public void testListRegionsWithSelectedFields() {
         Page regionPage =
             compute.listRegions(Compute.RegionListOption.fields(Compute.RegionField.ID));
         Iterator regionIterator = regionPage.iterateAll();
    -    while(regionIterator.hasNext()) {
    +    while (regionIterator.hasNext()) {
           Region region = regionIterator.next();
           assertNotNull(region.regionId());
           assertNull(region.description());
    @@ -411,7 +414,7 @@ public void testGetZoneWithSelectedFields() {
       public void testListZones() {
         Page zonePage = compute.listZones();
         Iterator zoneIterator = zonePage.iterateAll();
    -    while(zoneIterator.hasNext()) {
    +    while (zoneIterator.hasNext()) {
           Zone zone = zoneIterator.next();
           assertNotNull(zone.zoneId());
           assertNotNull(zone.id());
    @@ -427,7 +430,7 @@ public void testListZonesWithSelectedFields() {
         Page zonePage = compute.listZones(
             Compute.ZoneListOption.fields(Compute.ZoneField.CREATION_TIMESTAMP));
         Iterator zoneIterator = zonePage.iterateAll();
    -    while(zoneIterator.hasNext()) {
    +    while (zoneIterator.hasNext()) {
           Zone zone = zoneIterator.next();
           assertNotNull(zone.zoneId());
           assertNull(zone.id());
    @@ -451,7 +454,7 @@ public void testListZonesWithFilter() {
       public void testListGlobalOperations() {
         Page operationPage = compute.listGlobalOperations();
         Iterator operationIterator = operationPage.iterateAll();
    -    while(operationIterator.hasNext()) {
    +    while (operationIterator.hasNext()) {
           Operation operation = operationIterator.next();
           assertNotNull(operation.id());
           assertNotNull(operation.operationId());
    @@ -468,7 +471,7 @@ public void testListGlobalOperationsWithSelectedFields() {
         Page operationPage =
             compute.listGlobalOperations(Compute.OperationListOption.fields(Compute.OperationField.ID));
         Iterator operationIterator = operationPage.iterateAll();
    -    while(operationIterator.hasNext()) {
    +    while (operationIterator.hasNext()) {
           Operation operation = operationIterator.next();
           assertNotNull(operation.id());
           assertNotNull(operation.operationId());
    @@ -495,7 +498,7 @@ public void testListGlobalOperationsWithFilter() {
         Page operationPage = compute.listGlobalOperations(Compute.OperationListOption.filter(
             Compute.OperationFilter.equals(Compute.OperationField.STATUS, "DONE")));
         Iterator operationIterator = operationPage.iterateAll();
    -    while(operationIterator.hasNext()) {
    +    while (operationIterator.hasNext()) {
           Operation operation = operationIterator.next();
           assertNotNull(operation.id());
           assertNotNull(operation.operationId());
    @@ -511,11 +514,12 @@ public void testListGlobalOperationsWithFilter() {
       public void testListRegionOperations() {
         Page operationPage = compute.listRegionOperations(REGION);
         Iterator operationIterator = operationPage.iterateAll();
    -    while(operationIterator.hasNext()) {
    +    while (operationIterator.hasNext()) {
           Operation operation = operationIterator.next();
           assertNotNull(operation.id());
           assertNotNull(operation.operationId());
           assertEquals(REGION, operation.operationId().region());
    +      // todo(mziccard): uncomment or remove once #727 is closed
           // assertNotNull(operation.creationTimestamp());
           assertNotNull(operation.operationType());
           assertNotNull(operation.status());
    @@ -528,7 +532,7 @@ public void testListRegionOperationsWithSelectedFields() {
         Page operationPage = compute.listRegionOperations(REGION,
             Compute.OperationListOption.fields(Compute.OperationField.ID));
         Iterator operationIterator = operationPage.iterateAll();
    -    while(operationIterator.hasNext()) {
    +    while (operationIterator.hasNext()) {
           Operation operation = operationIterator.next();
           assertNotNull(operation.id());
           assertNotNull(operation.operationId());
    @@ -557,7 +561,7 @@ public void testListRegionOperationsWithFilter() {
             Compute.OperationListOption.filter(Compute.OperationFilter.equals(
                 Compute.OperationField.STATUS, "DONE")));
         Iterator operationIterator = operationPage.iterateAll();
    -    while(operationIterator.hasNext()) {
    +    while (operationIterator.hasNext()) {
           Operation operation = operationIterator.next();
           assertNotNull(operation.id());
           assertNotNull(operation.operationId());
    @@ -574,11 +578,12 @@ public void testListRegionOperationsWithFilter() {
       public void testListZoneOperations() {
         Page operationPage = compute.listZoneOperations(ZONE);
         Iterator operationIterator = operationPage.iterateAll();
    -    while(operationIterator.hasNext()) {
    +    while (operationIterator.hasNext()) {
           Operation operation = operationIterator.next();
           assertNotNull(operation.id());
           assertNotNull(operation.operationId());
           assertEquals(ZONE, operation.operationId().zone());
    +      // todo(mziccard): uncomment or remove once #727 is closed
           // assertNotNull(operation.creationTimestamp());
           assertNotNull(operation.operationType());
           assertNotNull(operation.status());
    @@ -591,7 +596,7 @@ public void testListZoneOperationsWithSelectedFields() {
         Page operationPage = compute.listZoneOperations(ZONE,
             Compute.OperationListOption.fields(Compute.OperationField.ID));
         Iterator operationIterator = operationPage.iterateAll();
    -    while(operationIterator.hasNext()) {
    +    while (operationIterator.hasNext()) {
           Operation operation = operationIterator.next();
           assertNotNull(operation.id());
           assertNotNull(operation.operationId());
    @@ -620,7 +625,7 @@ public void testListZoneOperationsWithFilter() {
             Compute.OperationListOption.filter(Compute.OperationFilter.equals(
                 Compute.OperationField.STATUS, "DONE")));
         Iterator operationIterator = operationPage.iterateAll();
    -    while(operationIterator.hasNext()) {
    +    while (operationIterator.hasNext()) {
           Operation operation = operationIterator.next();
           assertNotNull(operation.id());
           assertNotNull(operation.operationId());
    
    From 29f2bad1d0e0a4cbad74688ed9e38625f598760b Mon Sep 17 00:00:00 2001
    From: Marco Ziccardi 
    Date: Sun, 13 Mar 2016 13:26:20 +0100
    Subject: [PATCH 286/375] Rename maxResults to pageSize, add tests for
     pagination
    
    ---
     .../com/google/gcloud/compute/Compute.java    |  28 +-
     .../com/google/gcloud/compute/Operation.java  |   2 +-
     .../gcloud/compute/ComputeImplTest.java       | 305 ++++++++++++++++--
     3 files changed, 298 insertions(+), 37 deletions(-)
    
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java
    index f8e8359e8444..faa890a1e982 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java
    @@ -597,8 +597,8 @@ public static DiskTypeListOption filter(DiskTypeFilter filter) {
         /**
          * Returns an option to specify the maximum number of disk types to be returned.
          */
    -    public static DiskTypeListOption maxResults(long maxResults) {
    -      return new DiskTypeListOption(ComputeRpc.Option.MAX_RESULTS, maxResults);
    +    public static DiskTypeListOption pageSize(long pageSize) {
    +      return new DiskTypeListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
         }
     
         /**
    @@ -642,8 +642,8 @@ public static DiskTypeAggregatedListOption filter(DiskTypeFilter filter) {
         /**
          * Returns an option to specify the maximum number of disk types to be returned.
          */
    -    public static DiskTypeAggregatedListOption maxResults(long maxResults) {
    -      return new DiskTypeAggregatedListOption(ComputeRpc.Option.MAX_RESULTS, maxResults);
    +    public static DiskTypeAggregatedListOption pageSize(long pageSize) {
    +      return new DiskTypeAggregatedListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
         }
     
         /**
    @@ -697,8 +697,8 @@ public static MachineTypeListOption filter(MachineTypeFilter filter) {
         /**
          * Returns an option to specify the maximum number of machine types to be returned.
          */
    -    public static MachineTypeListOption maxResults(long maxResults) {
    -      return new MachineTypeListOption(ComputeRpc.Option.MAX_RESULTS, maxResults);
    +    public static MachineTypeListOption pageSize(long pageSize) {
    +      return new MachineTypeListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
         }
     
         /**
    @@ -742,8 +742,8 @@ public static MachineTypeAggregatedListOption filter(MachineTypeFilter filter) {
         /**
          * Returns an option to specify the maximum number of machine types to be returned.
          */
    -    public static MachineTypeAggregatedListOption maxResults(long maxResults) {
    -      return new MachineTypeAggregatedListOption(ComputeRpc.Option.MAX_RESULTS, maxResults);
    +    public static MachineTypeAggregatedListOption pageSize(long pageSize) {
    +      return new MachineTypeAggregatedListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
         }
     
         /**
    @@ -797,8 +797,8 @@ public static RegionListOption filter(RegionFilter filter) {
         /**
          * Returns an option to specify the maximum number of regions to be returned.
          */
    -    public static RegionListOption maxResults(long maxResults) {
    -      return new RegionListOption(ComputeRpc.Option.MAX_RESULTS, maxResults);
    +    public static RegionListOption pageSize(long pageSize) {
    +      return new RegionListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
         }
     
         /**
    @@ -864,8 +864,8 @@ public static ZoneListOption filter(ZoneFilter filter) {
         /**
          * Returns an option to specify the maximum number of zones to be returned.
          */
    -    public static ZoneListOption maxResults(long maxResults) {
    -      return new ZoneListOption(ComputeRpc.Option.MAX_RESULTS, maxResults);
    +    public static ZoneListOption pageSize(long pageSize) {
    +      return new ZoneListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
         }
     
         /**
    @@ -953,8 +953,8 @@ public static OperationListOption filter(OperationFilter filter) {
         /**
          * Returns an option to specify the maximum number of operations to be returned.
          */
    -    public static OperationListOption maxResults(long maxResults) {
    -      return new OperationListOption(ComputeRpc.Option.MAX_RESULTS, maxResults);
    +    public static OperationListOption pageSize(long pageSize) {
    +      return new OperationListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
         }
     
         /**
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java
    index baaa62eaae05..6734de60804b 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java
    @@ -40,7 +40,7 @@
      * Google Compute Engine operations. Operation identity can be obtained via {@link #operationId()}.
      * {@link #operationId()} returns {@link GlobalOperationId} for global operations,
      * {@link RegionOperationId} for region operations, and {@link ZoneOperationId} for zone operations.
    - * To get an {@code Operation} object with the most recent information use
    + * To get an {@code Operation} object with the most recent information, use
      * {@link #reload(Compute.OperationOption...)}.
      */
     public final class Operation implements Serializable {
    diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java
    index e9e61dbf74f5..e1a81b5afe48 100644
    --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java
    +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java
    @@ -16,6 +16,9 @@
     
     package com.google.gcloud.compute;
     
    +import static com.google.gcloud.spi.ComputeRpc.Option.FILTER;
    +import static com.google.gcloud.spi.ComputeRpc.Option.MAX_RESULTS;
    +import static com.google.gcloud.spi.ComputeRpc.Option.PAGE_TOKEN;
     import static org.easymock.EasyMock.capture;
     import static org.easymock.EasyMock.eq;
     import static org.junit.Assert.assertArrayEquals;
    @@ -185,19 +188,19 @@ public class ComputeImplTest {
       private static final DiskTypeListOption DISK_TYPE_LIST_PAGE_TOKEN =
           DiskTypeListOption.startPageToken("cursor");
       private static final DiskTypeListOption DISK_TYPE_LIST_MAX_RESULTS =
    -      DiskTypeListOption.maxResults(42L);
    +      DiskTypeListOption.pageSize(42L);
       private static final DiskTypeListOption DISK_TYPE_LIST_FILTER =
           DiskTypeListOption.filter(DISK_TYPE_FILTER);
       private static final Map DISK_TYPE_LIST_OPTIONS = ImmutableMap.of(
    -      ComputeRpc.Option.PAGE_TOKEN, "cursor",
    -      ComputeRpc.Option.MAX_RESULTS, 42L,
    -      ComputeRpc.Option.FILTER, "description eq someDescription");
    +      PAGE_TOKEN, "cursor",
    +      MAX_RESULTS, 42L,
    +      FILTER, "description eq someDescription");
     
       // DiskType aggregated list options
       private static final DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_PAGE_TOKEN =
           DiskTypeAggregatedListOption.startPageToken("cursor");
       private static final DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_MAX_RESULTS =
    -      DiskTypeAggregatedListOption.maxResults(42L);
    +      DiskTypeAggregatedListOption.pageSize(42L);
       private static final DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_FILTER =
           DiskTypeAggregatedListOption.filter(DISK_TYPE_FILTER);
     
    @@ -212,19 +215,19 @@ public class ComputeImplTest {
       private static final MachineTypeListOption MACHINE_TYPE_LIST_PAGE_TOKEN =
           MachineTypeListOption.startPageToken("cursor");
       private static final MachineTypeListOption MACHINE_TYPE_LIST_MAX_RESULTS =
    -      MachineTypeListOption.maxResults(42L);
    +      MachineTypeListOption.pageSize(42L);
       private static final MachineTypeListOption MACHINE_TYPE_LIST_FILTER =
           MachineTypeListOption.filter(MACHINE_TYPE_FILTER);
       private static final Map MACHINE_TYPE_LIST_OPTIONS = ImmutableMap.of(
    -      ComputeRpc.Option.PAGE_TOKEN, "cursor",
    -      ComputeRpc.Option.MAX_RESULTS, 42L,
    -      ComputeRpc.Option.FILTER, "maximumPersistentDisks ne 42");
    +      PAGE_TOKEN, "cursor",
    +      MAX_RESULTS, 42L,
    +      FILTER, "maximumPersistentDisks ne 42");
     
       // MachineType aggregated list options
       private static final MachineTypeAggregatedListOption MACHINE_TYPE_AGGREGATED_LIST_PAGE_TOKEN =
           MachineTypeAggregatedListOption.startPageToken("cursor");
       private static final MachineTypeAggregatedListOption MACHINE_TYPE_AGGREGATED_LIST_MAX_RESULTS =
    -      MachineTypeAggregatedListOption.maxResults(42L);
    +      MachineTypeAggregatedListOption.pageSize(42L);
       private static final MachineTypeAggregatedListOption MACHINE_TYPE_AGGREGATED_LIST_FILTER =
           MachineTypeAggregatedListOption.filter(MACHINE_TYPE_FILTER);
     
    @@ -238,13 +241,13 @@ public class ComputeImplTest {
       private static final RegionListOption REGION_LIST_PAGE_TOKEN =
           RegionListOption.startPageToken("cursor");
       private static final RegionListOption REGION_LIST_MAX_RESULTS =
    -      RegionListOption.maxResults(42L);
    +      RegionListOption.pageSize(42L);
       private static final RegionListOption REGION_LIST_FILTER =
           RegionListOption.filter(REGION_FILTER);
       private static final Map REGION_LIST_OPTIONS = ImmutableMap.of(
    -      ComputeRpc.Option.PAGE_TOKEN, "cursor",
    -      ComputeRpc.Option.MAX_RESULTS, 42L,
    -      ComputeRpc.Option.FILTER, "id eq someId");
    +      PAGE_TOKEN, "cursor",
    +      MAX_RESULTS, 42L,
    +      FILTER, "id eq someId");
     
       // Zone options
       private static final ZoneOption ZONE_OPTION_FIELDS =
    @@ -255,12 +258,12 @@ public class ComputeImplTest {
           ZoneFilter.notEquals(Compute.ZoneField.NAME, "someName");
       private static final ZoneListOption ZONE_LIST_PAGE_TOKEN =
           ZoneListOption.startPageToken("cursor");
    -  private static final ZoneListOption ZONE_LIST_MAX_RESULTS = ZoneListOption.maxResults(42L);
    +  private static final ZoneListOption ZONE_LIST_MAX_RESULTS = ZoneListOption.pageSize(42L);
       private static final ZoneListOption ZONE_LIST_FILTER = ZoneListOption.filter(ZONE_FILTER);
       private static final Map ZONE_LIST_OPTIONS = ImmutableMap.of(
    -      ComputeRpc.Option.PAGE_TOKEN, "cursor",
    -      ComputeRpc.Option.MAX_RESULTS, 42L,
    -      ComputeRpc.Option.FILTER, "name ne someName");
    +      PAGE_TOKEN, "cursor",
    +      MAX_RESULTS, 42L,
    +      FILTER, "name ne someName");
     
       // License options
       private static final LicenseOption LICENSE_OPTION_FIELDS =
    @@ -276,13 +279,13 @@ public class ComputeImplTest {
       private static final OperationListOption OPERATION_LIST_PAGE_TOKEN =
           OperationListOption.startPageToken("cursor");
       private static final OperationListOption OPERATION_LIST_MAX_RESULTS =
    -      OperationListOption.maxResults(42L);
    +      OperationListOption.pageSize(42L);
       private static final OperationListOption OPERATION_LIST_FILTER =
           OperationListOption.filter(OPERATION_FILTER);
       private static final Map OPERATION_LIST_OPTIONS = ImmutableMap.of(
    -      ComputeRpc.Option.PAGE_TOKEN, "cursor",
    -      ComputeRpc.Option.MAX_RESULTS, 42L,
    -      ComputeRpc.Option.FILTER, "progress ne 0");
    +      PAGE_TOKEN, "cursor",
    +      MAX_RESULTS, 42L,
    +      FILTER, "progress ne 0");
     
       private ComputeOptions options;
       private ComputeRpcFactory rpcFactoryMock;
    @@ -442,6 +445,31 @@ public void testListDiskTypes() {
         assertArrayEquals(diskTypeList.toArray(), Iterables.toArray(page.values(), DiskType.class));
       }
     
    +  @Test
    +  public void testListDiskTypesNextPage() {
    +    String cursor = "cursor";
    +    String nextCursor = "nextCursor";
    +    compute = options.service();
    +    ImmutableList diskTypeList = ImmutableList.of(DISK_TYPE, DISK_TYPE);
    +    Tuple> result =
    +        Tuple.of(cursor, Iterables.transform(diskTypeList, DiskType.TO_PB_FUNCTION));
    +    ImmutableList nextDiskTypeList = ImmutableList.of(DISK_TYPE);
    +    Tuple> nextResult =
    +        Tuple.of(nextCursor, Iterables.transform(nextDiskTypeList, DiskType.TO_PB_FUNCTION));
    +    Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor);
    +    EasyMock.expect(computeRpcMock.listDiskTypes(DISK_TYPE_ID.zone(), EMPTY_RPC_OPTIONS))
    +        .andReturn(result);
    +    EasyMock.expect(computeRpcMock.listDiskTypes(DISK_TYPE_ID.zone(), nextOptions))
    +        .andReturn(nextResult);
    +    EasyMock.replay(computeRpcMock);
    +    Page page = compute.listDiskTypes(DISK_TYPE_ID.zone());
    +    assertEquals(cursor, page.nextPageCursor());
    +    assertArrayEquals(diskTypeList.toArray(), Iterables.toArray(page.values(), DiskType.class));
    +    page = page.nextPage();
    +    assertEquals(nextCursor, page.nextPageCursor());
    +    assertArrayEquals(nextDiskTypeList.toArray(), Iterables.toArray(page.values(), DiskType.class));
    +  }
    +
       @Test
       public void testListEmptyDiskTypes() {
         ImmutableList diskTypes = ImmutableList.of();
    @@ -486,6 +514,29 @@ public void testAggregatedListDiskTypes() {
         assertArrayEquals(diskTypeList.toArray(), Iterables.toArray(page.values(), DiskType.class));
       }
     
    +  @Test
    +  public void testAggregatedListDiskTypesNextPage() {
    +    String cursor = "cursor";
    +    String nextCursor = "nextCursor";
    +    compute = options.service();
    +    ImmutableList diskTypeList = ImmutableList.of(DISK_TYPE, DISK_TYPE);
    +    Tuple> result =
    +        Tuple.of(cursor, Iterables.transform(diskTypeList, DiskType.TO_PB_FUNCTION));
    +    ImmutableList nextDiskTypeList = ImmutableList.of(DISK_TYPE);
    +    Tuple> nextResult =
    +        Tuple.of(nextCursor, Iterables.transform(nextDiskTypeList, DiskType.TO_PB_FUNCTION));
    +    Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor);
    +    EasyMock.expect(computeRpcMock.listDiskTypes(EMPTY_RPC_OPTIONS)).andReturn(result);
    +    EasyMock.expect(computeRpcMock.listDiskTypes(nextOptions)).andReturn(nextResult);
    +    EasyMock.replay(computeRpcMock);
    +    Page page = compute.listDiskTypes();
    +    assertEquals(cursor, page.nextPageCursor());
    +    assertArrayEquals(diskTypeList.toArray(), Iterables.toArray(page.values(), DiskType.class));
    +    page = page.nextPage();
    +    assertEquals(nextCursor, page.nextPageCursor());
    +    assertArrayEquals(nextDiskTypeList.toArray(), Iterables.toArray(page.values(), DiskType.class));
    +  }
    +
       @Test
       public void testAggregatedListEmptyDiskTypes() {
         ImmutableList diskTypes = ImmutableList.of();
    @@ -573,6 +624,33 @@ public void testListMachineTypes() {
             MachineType.class));
       }
     
    +  @Test
    +  public void testListMachineTypesNextPage() {
    +    String cursor = "cursor";
    +    String nextCursor = "nextCursor";
    +    compute = options.service();
    +    ImmutableList machineTypeList = ImmutableList.of(MACHINE_TYPE, MACHINE_TYPE);
    +    Tuple> result =
    +        Tuple.of(cursor, Iterables.transform(machineTypeList, MachineType.TO_PB_FUNCTION));
    +    ImmutableList nextMachineTypeList = ImmutableList.of(MACHINE_TYPE);
    +    Tuple> nextResult =
    +        Tuple.of(nextCursor, Iterables.transform(nextMachineTypeList, MachineType.TO_PB_FUNCTION));
    +    Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor);
    +    EasyMock.expect(computeRpcMock.listMachineTypes(MACHINE_TYPE_ID.zone(), EMPTY_RPC_OPTIONS))
    +        .andReturn(result);
    +    EasyMock.expect(computeRpcMock.listMachineTypes(MACHINE_TYPE_ID.zone(), nextOptions))
    +        .andReturn(nextResult);
    +    EasyMock.replay(computeRpcMock);
    +    Page page = compute.listMachineTypes(MACHINE_TYPE_ID.zone());
    +    assertEquals(cursor, page.nextPageCursor());
    +    assertArrayEquals(machineTypeList.toArray(),
    +        Iterables.toArray(page.values(), MachineType.class));
    +    page = page.nextPage();
    +    assertEquals(nextCursor, page.nextPageCursor());
    +    assertArrayEquals(nextMachineTypeList.toArray(),
    +        Iterables.toArray(page.values(), MachineType.class));
    +  }
    +
       @Test
       public void testListEmptyMachineTypes() {
         ImmutableList machineTypes =
    @@ -622,6 +700,31 @@ public void testAggregatedListMachineTypes() {
             MachineType.class));
       }
     
    +  @Test
    +  public void testAggregatedListMachineTypesNextPage() {
    +    String cursor = "cursor";
    +    String nextCursor = "nextCursor";
    +    compute = options.service();
    +    ImmutableList machineTypeList = ImmutableList.of(MACHINE_TYPE, MACHINE_TYPE);
    +    Tuple> result =
    +        Tuple.of(cursor, Iterables.transform(machineTypeList, MachineType.TO_PB_FUNCTION));
    +    ImmutableList nextMachineTypeList = ImmutableList.of(MACHINE_TYPE);
    +    Tuple> nextResult =
    +        Tuple.of(nextCursor, Iterables.transform(nextMachineTypeList, MachineType.TO_PB_FUNCTION));
    +    Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor);
    +    EasyMock.expect(computeRpcMock.listMachineTypes(EMPTY_RPC_OPTIONS)).andReturn(result);
    +    EasyMock.expect(computeRpcMock.listMachineTypes(nextOptions)).andReturn(nextResult);
    +    EasyMock.replay(computeRpcMock);
    +    Page page = compute.listMachineTypes();
    +    assertEquals(cursor, page.nextPageCursor());
    +    assertArrayEquals(machineTypeList.toArray(),
    +        Iterables.toArray(page.values(), MachineType.class));
    +    page = page.nextPage();
    +    assertEquals(nextCursor, page.nextPageCursor());
    +    assertArrayEquals(nextMachineTypeList.toArray(),
    +        Iterables.toArray(page.values(), MachineType.class));
    +  }
    +
       @Test
       public void testAggregatedListEmptyMachineTypes() {
         ImmutableList machineTypes =
    @@ -694,6 +797,29 @@ public void testListRegions() {
         assertArrayEquals(regionList.toArray(), Iterables.toArray(page.values(), Region.class));
       }
     
    +  @Test
    +  public void testListRegionsNextPage() {
    +    String cursor = "cursor";
    +    String nextCursor = "nextCursor";
    +    compute = options.service();
    +    ImmutableList regionList = ImmutableList.of(REGION, REGION);
    +    ImmutableList nextRegionList = ImmutableList.of(REGION);
    +    Tuple> result =
    +        Tuple.of(cursor, Iterables.transform(regionList, Region.TO_PB_FUNCTION));
    +    Tuple> nextResult =
    +        Tuple.of(nextCursor, Iterables.transform(nextRegionList, Region.TO_PB_FUNCTION));
    +    Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor);
    +    EasyMock.expect(computeRpcMock.listRegions(EMPTY_RPC_OPTIONS)).andReturn(result);
    +    EasyMock.expect(computeRpcMock.listRegions(nextOptions)).andReturn(nextResult);
    +    EasyMock.replay(computeRpcMock);
    +    Page page = compute.listRegions();
    +    assertEquals(cursor, page.nextPageCursor());
    +    assertArrayEquals(regionList.toArray(), Iterables.toArray(page.values(), Region.class));
    +    page = page.nextPage();
    +    assertEquals(nextCursor, page.nextPageCursor());
    +    assertArrayEquals(nextRegionList.toArray(), Iterables.toArray(page.values(), Region.class));
    +  }
    +
       @Test
       public void testListEmptyRegions() {
         ImmutableList regions = ImmutableList.of();
    @@ -763,6 +889,29 @@ public void testListZones() {
         assertArrayEquals(zoneList.toArray(), Iterables.toArray(page.values(), Zone.class));
       }
     
    +  @Test
    +  public void testListZonesNextPage() {
    +    String cursor = "cursor";
    +    String nextCursor = "nextCursor";
    +    compute = options.service();
    +    ImmutableList zoneList = ImmutableList.of(ZONE, ZONE);
    +    ImmutableList nextZoneList = ImmutableList.of(ZONE);
    +    Tuple> result =
    +        Tuple.of(cursor, Iterables.transform(zoneList, Zone.TO_PB_FUNCTION));
    +    Tuple> nextResult =
    +        Tuple.of(nextCursor, Iterables.transform(nextZoneList, Zone.TO_PB_FUNCTION));
    +    Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor);
    +    EasyMock.expect(computeRpcMock.listZones(EMPTY_RPC_OPTIONS)).andReturn(result);
    +    EasyMock.expect(computeRpcMock.listZones(nextOptions)).andReturn(nextResult);
    +    EasyMock.replay(computeRpcMock);
    +    Page page = compute.listZones();
    +    assertEquals(cursor, page.nextPageCursor());
    +    assertArrayEquals(zoneList.toArray(), Iterables.toArray(page.values(), Zone.class));
    +    page = page.nextPage();
    +    assertEquals(nextCursor, page.nextPageCursor());
    +    assertArrayEquals(nextZoneList.toArray(), Iterables.toArray(page.values(), Zone.class));
    +  }
    +
       @Test
       public void testListEmptyZones() {
         ImmutableList zones = ImmutableList.of();
    @@ -896,6 +1045,42 @@ public com.google.api.services.compute.model.Operation apply(Operation operation
         assertArrayEquals(operationList.toArray(), Iterables.toArray(page.values(), Operation.class));
       }
     
    +  @Test
    +  public void testListGlobalOperationsNextPage() {
    +    String cursor = "cursor";
    +    String nextCursor = "nextCursor";
    +    compute = options.service();
    +    ImmutableList operationList = ImmutableList.of(globalOperation, globalOperation);
    +    ImmutableList nextOperationList = ImmutableList.of(globalOperation);
    +    Tuple> result =
    +        Tuple.of(cursor, Iterables.transform(operationList,
    +            new Function() {
    +              @Override
    +              public com.google.api.services.compute.model.Operation apply(Operation operation) {
    +                return operation.toPb();
    +              }
    +            }));
    +    Tuple> nextResult =
    +        Tuple.of(nextCursor, Iterables.transform(nextOperationList,
    +            new Function() {
    +              @Override
    +              public com.google.api.services.compute.model.Operation apply(Operation operation) {
    +                return operation.toPb();
    +              }
    +            }));
    +    Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor);
    +    EasyMock.expect(computeRpcMock.listGlobalOperations(EMPTY_RPC_OPTIONS)).andReturn(result);
    +    EasyMock.expect(computeRpcMock.listGlobalOperations(nextOptions)).andReturn(nextResult);
    +    EasyMock.replay(computeRpcMock);
    +    Page page = compute.listGlobalOperations();
    +    assertEquals(cursor, page.nextPageCursor());
    +    assertArrayEquals(operationList.toArray(), Iterables.toArray(page.values(), Operation.class));
    +    page = page.nextPage();
    +    assertEquals(nextCursor, page.nextPageCursor());
    +    assertArrayEquals(nextOperationList.toArray(),
    +        Iterables.toArray(page.values(), Operation.class));
    +  }
    +
       @Test
       public void testListEmptyGlobalOperations() {
         ImmutableList operations = ImmutableList.of();
    @@ -999,6 +1184,44 @@ public com.google.api.services.compute.model.Operation apply(Operation operation
         assertArrayEquals(operationList.toArray(), Iterables.toArray(page.values(), Operation.class));
       }
     
    +  @Test
    +  public void testListRegionOperationsNextPage() {
    +    String cursor = "cursor";
    +    String nextCursor = "nextCursor";
    +    compute = options.service();
    +    ImmutableList operationList = ImmutableList.of(regionOperation, regionOperation);
    +    ImmutableList nextOperationList = ImmutableList.of(regionOperation);
    +    Tuple> result =
    +        Tuple.of(cursor, Iterables.transform(operationList,
    +            new Function() {
    +              @Override
    +              public com.google.api.services.compute.model.Operation apply(Operation operation) {
    +                return operation.toPb();
    +              }
    +            }));
    +    Tuple> nextResult =
    +        Tuple.of(nextCursor, Iterables.transform(nextOperationList,
    +            new Function() {
    +              @Override
    +              public com.google.api.services.compute.model.Operation apply(Operation operation) {
    +                return operation.toPb();
    +              }
    +            }));
    +    Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor);
    +    EasyMock.expect(computeRpcMock.listRegionOperations(REGION_OPERATION_ID.region(),
    +        EMPTY_RPC_OPTIONS)).andReturn(result);
    +    EasyMock.expect(computeRpcMock.listRegionOperations(REGION_OPERATION_ID.region(),
    +        nextOptions)).andReturn(nextResult);
    +    EasyMock.replay(computeRpcMock);
    +    Page page = compute.listRegionOperations(REGION_OPERATION_ID.region());
    +    assertEquals(cursor, page.nextPageCursor());
    +    assertArrayEquals(operationList.toArray(), Iterables.toArray(page.values(), Operation.class));
    +    page = page.nextPage();
    +    assertEquals(nextCursor, page.nextPageCursor());
    +    assertArrayEquals(nextOperationList.toArray(),
    +        Iterables.toArray(page.values(), Operation.class));
    +  }
    +
       @Test
       public void testListEmptyRegionOperations() {
         ImmutableList operations = ImmutableList.of();
    @@ -1106,6 +1329,44 @@ public com.google.api.services.compute.model.Operation apply(Operation operation
         assertArrayEquals(operationList.toArray(), Iterables.toArray(page.values(), Operation.class));
       }
     
    +  @Test
    +  public void testListZoneOperationsNextPage() {
    +    String cursor = "cursor";
    +    String nextCursor = "nextCursor";
    +    compute = options.service();
    +    ImmutableList operationList = ImmutableList.of(zoneOperation, zoneOperation);
    +    ImmutableList nextOperationList = ImmutableList.of(zoneOperation);
    +    Tuple> result =
    +        Tuple.of(cursor, Iterables.transform(operationList,
    +            new Function() {
    +              @Override
    +              public com.google.api.services.compute.model.Operation apply(Operation operation) {
    +                return operation.toPb();
    +              }
    +            }));
    +    Tuple> nextResult =
    +        Tuple.of(nextCursor, Iterables.transform(nextOperationList,
    +            new Function() {
    +              @Override
    +              public com.google.api.services.compute.model.Operation apply(Operation operation) {
    +                return operation.toPb();
    +              }
    +            }));
    +    Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor);
    +    EasyMock.expect(computeRpcMock.listZoneOperations(ZONE_OPERATION_ID.zone(), EMPTY_RPC_OPTIONS))
    +        .andReturn(result);
    +    EasyMock.expect(computeRpcMock.listZoneOperations(ZONE_OPERATION_ID.zone(), nextOptions))
    +        .andReturn(nextResult);
    +    EasyMock.replay(computeRpcMock);
    +    Page page = compute.listZoneOperations(ZONE_OPERATION_ID.zone());
    +    assertEquals(cursor, page.nextPageCursor());
    +    assertArrayEquals(operationList.toArray(), Iterables.toArray(page.values(), Operation.class));
    +    page = page.nextPage();
    +    assertEquals(nextCursor, page.nextPageCursor());
    +    assertArrayEquals(nextOperationList.toArray(),
    +        Iterables.toArray(page.values(), Operation.class));
    +  }
    +
       @Test
       public void testListEmptyZoneOperations() {
         ImmutableList operations = ImmutableList.of();
    
    From 8fad79de23da5b7ef572d0822a101887aa978a55 Mon Sep 17 00:00:00 2001
    From: Marco Ziccardi 
    Date: Tue, 15 Mar 2016 13:00:43 +0100
    Subject: [PATCH 287/375] Refactor compute operations - Add Type enum to
     OperationId and type() getter - Replace instanceof with switch on type() -
     Add better javadoc to Operation - Remove final from Operation, make hashCode
     and equals final
    
    ---
     .../com/google/gcloud/compute/Compute.java    | 72 ++++++++-----------
     .../google/gcloud/compute/ComputeImpl.java    | 42 +++++------
     .../gcloud/compute/GlobalOperationId.java     |  5 ++
     .../com/google/gcloud/compute/Operation.java  | 36 ++++++----
     .../google/gcloud/compute/OperationId.java    | 26 +++++++
     .../gcloud/compute/RegionOperationId.java     |  5 ++
     .../gcloud/compute/ZoneOperationId.java       |  5 ++
     .../google/gcloud/spi/DefaultComputeRpc.java  |  2 +-
     .../gcloud/compute/OperationIdTest.java       |  9 +++
     .../gcloud/compute/it/ITComputeTest.java      |  2 +-
     10 files changed, 128 insertions(+), 76 deletions(-)
    
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java
    index faa890a1e982..935cf1fa9d7f 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java
    @@ -288,7 +288,7 @@ abstract class ListFilter implements Serializable {
     
         enum ComparisonOperator {
           /**
    -       * Defines an equality filter.
    +       * Defines an equals filter.
            */
           EQ,
     
    @@ -340,11 +340,11 @@ class DiskTypeFilter extends ListFilter {
         }
     
         /**
    -     * Returns an equality filter for the given field and string value. For string fields,
    +     * Returns an equals filter for the given field and string value. For string fields,
          * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
          * match the entire field.
          *
    -     * @see RE2
    +     * @see RE2
          */
         public static DiskTypeFilter equals(DiskTypeField field, String value) {
           return new DiskTypeFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value));
    @@ -355,14 +355,14 @@ public static DiskTypeFilter equals(DiskTypeField field, String value) {
          * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
          * match the entire field.
          *
    -     * @see RE2
    +     * @see RE2
          */
         public static DiskTypeFilter notEquals(DiskTypeField field, String value) {
           return new DiskTypeFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value));
         }
     
         /**
    -     * Returns an equality filter for the given field and long value.
    +     * Returns an equals filter for the given field and long value.
          */
         public static DiskTypeFilter equals(DiskTypeField field, long value) {
           return new DiskTypeFilter(checkNotNull(field), ComparisonOperator.EQ, value);
    @@ -388,11 +388,11 @@ class MachineTypeFilter extends ListFilter {
         }
     
         /**
    -     * Returns an equality filter for the given field and string value. For string fields,
    +     * Returns an equals filter for the given field and string value. For string fields,
          * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
          * match the entire field.
          *
    -     * @see RE2
    +     * @see RE2
          */
         public static MachineTypeFilter equals(MachineTypeField field, String value) {
           return new MachineTypeFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value));
    @@ -403,14 +403,14 @@ public static MachineTypeFilter equals(MachineTypeField field, String value) {
          * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
          * match the entire field.
          *
    -     * @see RE2
    +     * @see RE2
          */
         public static MachineTypeFilter notEquals(MachineTypeField field, String value) {
           return new MachineTypeFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value));
         }
     
         /**
    -     * Returns an equality filter for the given field and long value.
    +     * Returns an equals filter for the given field and long value.
          */
         public static MachineTypeFilter equals(MachineTypeField field, long value) {
           return new MachineTypeFilter(checkNotNull(field), ComparisonOperator.EQ, value);
    @@ -436,11 +436,11 @@ class RegionFilter extends ListFilter {
         }
     
         /**
    -     * Returns an equality filter for the given field and string value. For string fields,
    +     * Returns an equals filter for the given field and string value. For string fields,
          * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
          * match the entire field.
          *
    -     * @see RE2
    +     * @see RE2
          */
         public static RegionFilter equals(RegionField field, String value) {
           return new RegionFilter(checkNotNull(field), ComparisonOperator.EQ, value);
    @@ -451,7 +451,7 @@ public static RegionFilter equals(RegionField field, String value) {
          * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
          * match the entire field.
          *
    -     * @see RE2
    +     * @see RE2
          */
         public static RegionFilter notEquals(RegionField field, String value) {
           return new RegionFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value));
    @@ -470,11 +470,11 @@ class ZoneFilter extends ListFilter {
         }
     
         /**
    -     * Returns an equality filter for the given field and string value. For string fields,
    +     * Returns an equals filter for the given field and string value. For string fields,
          * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
          * match the entire field.
          *
    -     * @see RE2
    +     * @see RE2
          */
         public static ZoneFilter equals(ZoneField field, String value) {
           return new ZoneFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value));
    @@ -485,7 +485,7 @@ public static ZoneFilter equals(ZoneField field, String value) {
          * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
          * match the entire field.
          *
    -     * @see RE2
    +     * @see RE2
          */
         public static ZoneFilter notEquals(ZoneField field, String value) {
           return new ZoneFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value));
    @@ -504,11 +504,11 @@ class OperationFilter extends ListFilter {
         }
     
         /**
    -     * Returns an equality filter for the given field and string value. For string fields,
    +     * Returns an equals filter for the given field and string value. For string fields,
          * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
          * match the entire field.
          *
    -     * @see RE2
    +     * @see RE2
          */
         public static OperationFilter equals(OperationField field, String value) {
           return new OperationFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value));
    @@ -519,14 +519,14 @@ public static OperationFilter equals(OperationField field, String value) {
          * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
          * match the entire field.
          *
    -     * @see RE2
    +     * @see RE2
          */
         public static OperationFilter notEquals(OperationField field, String value) {
           return new OperationFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value));
         }
     
         /**
    -     * Returns an equality filter for the given field and long value.
    +     * Returns an equals filter for the given field and long value.
          */
         public static OperationFilter equals(OperationField field, long value) {
           return new OperationFilter(checkNotNull(field), ComparisonOperator.EQ, value);
    @@ -538,20 +538,6 @@ public static OperationFilter equals(OperationField field, long value) {
         public static OperationFilter notEquals(OperationField field, long value) {
           return new OperationFilter(checkNotNull(field), ComparisonOperator.NE, value);
         }
    -
    -    /**
    -     * Returns an equality filter for the given field and integer value.
    -     */
    -    public static OperationFilter equals(OperationField field, int value) {
    -      return new OperationFilter(checkNotNull(field), ComparisonOperator.EQ, value);
    -    }
    -
    -    /**
    -     * Returns a not-equals filter for the given field and integer value.
    -     */
    -    public static OperationFilter notEquals(OperationField field, int value) {
    -      return new OperationFilter(checkNotNull(field), ComparisonOperator.NE, value);
    -    }
       }
     
       /**
    @@ -595,7 +581,7 @@ public static DiskTypeListOption filter(DiskTypeFilter filter) {
         }
     
         /**
    -     * Returns an option to specify the maximum number of disk types to be returned.
    +     * Returns an option to specify the maximum number of disk types returned per page.
          */
         public static DiskTypeListOption pageSize(long pageSize) {
           return new DiskTypeListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
    @@ -640,7 +626,7 @@ public static DiskTypeAggregatedListOption filter(DiskTypeFilter filter) {
         }
     
         /**
    -     * Returns an option to specify the maximum number of disk types to be returned.
    +     * Returns an option to specify the maximum number of disk types returned per page.
          */
         public static DiskTypeAggregatedListOption pageSize(long pageSize) {
           return new DiskTypeAggregatedListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
    @@ -695,7 +681,7 @@ public static MachineTypeListOption filter(MachineTypeFilter filter) {
         }
     
         /**
    -     * Returns an option to specify the maximum number of machine types to be returned.
    +     * Returns an option to specify the maximum number of machine types returned per page.
          */
         public static MachineTypeListOption pageSize(long pageSize) {
           return new MachineTypeListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
    @@ -740,7 +726,7 @@ public static MachineTypeAggregatedListOption filter(MachineTypeFilter filter) {
         }
     
         /**
    -     * Returns an option to specify the maximum number of machine types to be returned.
    +     * Returns an option to specify the maximum number of machine types returned per page.
          */
         public static MachineTypeAggregatedListOption pageSize(long pageSize) {
           return new MachineTypeAggregatedListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
    @@ -795,7 +781,7 @@ public static RegionListOption filter(RegionFilter filter) {
         }
     
         /**
    -     * Returns an option to specify the maximum number of regions to be returned.
    +     * Returns an option to specify the maximum number of regions returned per page.
          */
         public static RegionListOption pageSize(long pageSize) {
           return new RegionListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
    @@ -862,7 +848,7 @@ public static ZoneListOption filter(ZoneFilter filter) {
         }
     
         /**
    -     * Returns an option to specify the maximum number of zones to be returned.
    +     * Returns an option to specify the maximum number of zones returned per page.
          */
         public static ZoneListOption pageSize(long pageSize) {
           return new ZoneListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
    @@ -951,7 +937,7 @@ public static OperationListOption filter(OperationFilter filter) {
         }
     
         /**
    -     * Returns an option to specify the maximum number of operations to be returned.
    +     * Returns an option to specify the maximum number of operations returned per page.
          */
         public static OperationListOption pageSize(long pageSize) {
           return new OperationListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
    @@ -1090,14 +1076,16 @@ public static OperationListOption fields(OperationField... fields) {
       Page listGlobalOperations(OperationListOption... options);
     
       /**
    -   * Lists the operations in the provided region.
    +   * Lists the operations for the provided region. These are operations that create/modify/delete
    +   * resources that live in a region (e.g. subnetworks).
        *
        * @throws ComputeException upon failure
        */
       Page listRegionOperations(String region, OperationListOption... options);
     
       /**
    -   * Lists the operations in the provided zone.
    +   * Lists the operations for the provided zone. These are operations that create/modify/delete
    +   * resources that live in a zone (e.g. instances).
        *
        * @throws ComputeException upon failure
        */
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java
    index 453a0f5a8d53..f3b866be5b77 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java
    @@ -533,16 +533,17 @@ public Operation get(final OperationId operationId, OperationOption... options)
               runWithRetries(new Callable() {
                 @Override
                 public com.google.api.services.compute.model.Operation call() {
    -              if (operationId instanceof RegionOperationId) {
    -                RegionOperationId regionOperationId = (RegionOperationId) operationId;
    -                return computeRpc.getRegionOperation(regionOperationId.region(),
    -                    regionOperationId.operation(), optionsMap);
    -              } else if (operationId instanceof ZoneOperationId) {
    -                ZoneOperationId zoneOperationId = (ZoneOperationId) operationId;
    -                return computeRpc.getZoneOperation(zoneOperationId.zone(),
    -                    zoneOperationId.operation(), optionsMap);
    -              } else {
    -                return computeRpc.getGlobalOperation(operationId.operation(), optionsMap);
    +              switch (operationId.type()) {
    +                case REGION:
    +                  RegionOperationId regionOperationId = (RegionOperationId) operationId;
    +                  return computeRpc.getRegionOperation(regionOperationId.region(),
    +                      regionOperationId.operation(), optionsMap);
    +                case ZONE:
    +                  ZoneOperationId zoneOperationId = (ZoneOperationId) operationId;
    +                  return computeRpc.getZoneOperation(zoneOperationId.zone(),
    +                      zoneOperationId.operation(), optionsMap);
    +                default:
    +                  return computeRpc.getGlobalOperation(operationId.operation(), optionsMap);
                   }
                 }
               }, options().retryParams(), EXCEPTION_HANDLER);
    @@ -660,16 +661,17 @@ public boolean delete(final OperationId operation) {
           return runWithRetries(new Callable() {
             @Override
             public Boolean call() {
    -          if (operation instanceof RegionOperationId) {
    -            RegionOperationId regionOperationId = (RegionOperationId) operation;
    -            return computeRpc.deleteRegionOperation(regionOperationId.region(),
    -                regionOperationId.operation());
    -          } else if (operation instanceof ZoneOperationId) {
    -            ZoneOperationId zoneOperationId = (ZoneOperationId) operation;
    -            return computeRpc.deleteZoneOperation(zoneOperationId.zone(),
    -                zoneOperationId.operation());
    -          } else {
    -            return computeRpc.deleteGlobalOperation(operation.operation());
    +          switch (operation.type()) {
    +            case REGION:
    +              RegionOperationId regionOperationId = (RegionOperationId) operation;
    +              return computeRpc.deleteRegionOperation(regionOperationId.region(),
    +                  regionOperationId.operation());
    +            case ZONE:
    +              ZoneOperationId zoneOperationId = (ZoneOperationId) operation;
    +              return computeRpc.deleteZoneOperation(zoneOperationId.zone(),
    +                  zoneOperationId.operation());
    +            default:
    +              return computeRpc.deleteGlobalOperation(operation.operation());
               }
             }
           }, options().retryParams(), EXCEPTION_HANDLER);
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalOperationId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalOperationId.java
    index 3c1601e8c4d0..c12e24c903cc 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalOperationId.java
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalOperationId.java
    @@ -40,6 +40,11 @@ private GlobalOperationId(String project, String operation) {
         this.operation = checkNotNull(operation);
       }
     
    +  @Override
    +  public Type type() {
    +    return Type.GLOBAL;
    +  }
    +
       @Override
       public String operation() {
         return operation;
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java
    index 6734de60804b..d857f90bc84f 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java
    @@ -17,6 +17,8 @@
     package com.google.gcloud.compute;
     
     import static com.google.common.base.Preconditions.checkNotNull;
    +import static com.google.gcloud.compute.OperationId.Type.REGION;
    +import static com.google.gcloud.compute.OperationId.Type.ZONE;
     
     import com.google.common.base.Function;
     import com.google.common.base.MoreObjects;
    @@ -43,7 +45,7 @@
      * To get an {@code Operation} object with the most recent information, use
      * {@link #reload(Compute.OperationOption...)}.
      */
    -public final class Operation implements Serializable {
    +public class Operation implements Serializable {
     
       private static final long serialVersionUID = -8979001444590023899L;
       private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime();
    @@ -124,7 +126,7 @@ public String code() {
         }
     
         /**
    -     * Returns the field in the request which caused the error. Might be {@code null}.
    +     * Returns the field in the request which caused the error. This value is optional.
          */
         public String location() {
           return location;
    @@ -213,7 +215,8 @@ public com.google.api.services.compute.model.Operation.Warnings apply(
         }
     
         /**
    -     * Returns a warning identifier for this warning.
    +     * Returns a warning identifier for this warning. For example, {@code NO_RESULTS_ON_PAGE} if
    +     * there are no results in the response.
          */
         public String code() {
           return code;
    @@ -227,7 +230,12 @@ public String message() {
         }
     
         /**
    -     * Returns metadata about this warning.
    +     * Returns metadata about this warning. Each key provides more detail on the warning being
    +     * returned. For example, for warnings where there are no results in a list request for a
    +     * particular zone, this key might be {@code scope} and the key's value might be the zone name.
    +     * Other examples might be a key indicating a deprecated resource, and a suggested replacement,
    +     * or a warning about invalid network settings (for example, if an instance attempts to perform
    +     * IP forwarding but is not enabled for IP forwarding).
          */
         public Map metadata() {
           return metadata;
    @@ -587,13 +595,15 @@ public Long insertTime() {
     
       /**
        * Returns the time that this operation was started by the service. In milliseconds since epoch.
    +   * This value will be {@code null} if the operation has not started yet.
        */
       public Long startTime() {
         return startTime;
       }
     
       /**
    -   * Returns the time that this operation was completed. In milliseconds since epoch.
    +   * Returns the time that this operation was completed. In milliseconds since epoch. This value
    +   * will be {@code null} if the operation has not finished yet.
        */
       public Long endTime() {
         return endTime;
    @@ -717,12 +727,12 @@ public String toString() {
       }
     
       @Override
    -  public int hashCode() {
    +  public final int hashCode() {
         return Objects.hash(id);
       }
     
       @Override
    -  public boolean equals(Object obj) {
    +  public final boolean equals(Object obj) {
         return obj instanceof Operation
             && Objects.equals(toPb(), ((Operation) obj).toPb())
             && Objects.equals(options, ((Operation) obj).options);
    @@ -739,11 +749,13 @@ com.google.api.services.compute.model.Operation toPb() {
         }
         operationPb.setName(operationId.operation());
         operationPb.setClientOperationId(clientOperationId);
    -    if (operationId instanceof RegionOperationId) {
    -      operationPb.setRegion(this.operationId().regionId().selfLink());
    -    }
    -    if (operationId instanceof ZoneOperationId) {
    -      operationPb.setZone(this.operationId().zoneId().selfLink());
    +    switch (operationId.type()) {
    +      case REGION:
    +        operationPb.setRegion(this.operationId().regionId().selfLink());
    +        break;
    +      case ZONE:
    +        operationPb.setZone(this.operationId().zoneId().selfLink());
    +        break;
         }
         if (operationType != null) {
           operationPb.setOperationType(operationType);
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/OperationId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/OperationId.java
    index eaaf7dee0ca4..7f9100aa61a2 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/OperationId.java
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/OperationId.java
    @@ -21,6 +21,32 @@
      */
     public interface OperationId {
     
    +  /**
    +   * Possible types for a Google Compute Engine operation identity.
    +   */
    +  enum Type {
    +    /**
    +     * Global operations are those operations that deal with global resources, such as global
    +     * addresses or snapshots.
    +     */
    +    GLOBAL,
    +    /**
    +     * Region operations are those operations that deal with resources that live in a region, such
    +     * as subnetworks.
    +     */
    +    REGION,
    +    /**
    +     * Zone operations are those operations that deal with resources that live in a zone, such as
    +     * disks and instances.
    +     */
    +    ZONE
    +  }
    +
    +  /**
    +   * Returns the type of this operation identity.
    +   */
    +  Type type();
    +
       /**
        * Returns the name of the project.
        */
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionOperationId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionOperationId.java
    index e5c70bf23876..96a772b5b9ea 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionOperationId.java
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionOperationId.java
    @@ -40,6 +40,11 @@ private RegionOperationId(String project, String region, String operation) {
         this.operation = checkNotNull(operation);
       }
     
    +  @Override
    +  public Type type() {
    +    return Type.REGION;
    +  }
    +
       @Override
       public String operation() {
         return operation;
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneOperationId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneOperationId.java
    index c0364b0ead3f..837ca6888c83 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneOperationId.java
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneOperationId.java
    @@ -40,6 +40,11 @@ private ZoneOperationId(String project, String zone, String operation) {
         this.operation = checkNotNull(operation);
       }
     
    +  @Override
    +  public Type type() {
    +    return Type.ZONE;
    +  }
    +
       @Override
       public String operation() {
         return operation;
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java
    index d54840e3fff0..3209084a5983 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java
    @@ -378,7 +378,7 @@ public boolean deleteZoneOperation(String zone, String operation) {
       private static  T nullForNotFound(IOException exception) {
         ComputeException serviceException = translate(exception);
         if (serviceException.code() == HTTP_NOT_FOUND) {
    -      return (T) null;
    +      return null;
         }
         throw serviceException;
       }
    diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationIdTest.java
    index 36ca5ef19090..76a53cdd1cd2 100644
    --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationIdTest.java
    +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationIdTest.java
    @@ -45,35 +45,43 @@ public class OperationIdTest {
       @Test
       public void testOf() {
         GlobalOperationId operationId = GlobalOperationId.of(PROJECT, NAME);
    +    assertEquals(OperationId.Type.GLOBAL, operationId.type());
         assertEquals(PROJECT, operationId.project());
         assertEquals(NAME, operationId.operation());
         assertEquals(GLOBAL_URL, operationId.selfLink());
         operationId = GlobalOperationId.of(NAME);
    +    assertEquals(OperationId.Type.GLOBAL, operationId.type());
         assertNull(operationId.project());
         assertEquals(NAME, operationId.operation());
         ZoneOperationId zoneOperationId = ZoneOperationId.of(PROJECT, ZONE, NAME);
    +    assertEquals(OperationId.Type.ZONE, zoneOperationId.type());
         assertEquals(PROJECT, zoneOperationId.project());
         assertEquals(ZONE, zoneOperationId.zone());
         assertEquals(NAME, zoneOperationId.operation());
         assertEquals(ZONE_URL, zoneOperationId.selfLink());
         zoneOperationId = ZoneOperationId.of(ZONE, NAME);
    +    assertEquals(OperationId.Type.ZONE, zoneOperationId.type());
         assertNull(zoneOperationId.project());
         assertEquals(ZONE, zoneOperationId.zone());
         assertEquals(NAME, zoneOperationId.operation());
         zoneOperationId = ZoneOperationId.of(ZoneId.of(PROJECT, ZONE), NAME);
    +    assertEquals(OperationId.Type.ZONE, zoneOperationId.type());
         assertEquals(PROJECT, zoneOperationId.project());
         assertEquals(ZONE, zoneOperationId.zone());
         assertEquals(NAME, zoneOperationId.operation());
         RegionOperationId regionOperationId = RegionOperationId.of(PROJECT, REGION, NAME);
    +    assertEquals(OperationId.Type.REGION, regionOperationId.type());
         assertEquals(PROJECT, regionOperationId.project());
         assertEquals(REGION, regionOperationId.region());
         assertEquals(NAME, regionOperationId.operation());
         assertEquals(REGION_URL, regionOperationId.selfLink());
         regionOperationId = RegionOperationId.of(REGION, NAME);
    +    assertEquals(OperationId.Type.REGION, regionOperationId.type());
         assertNull(regionOperationId.project());
         assertEquals(REGION, regionOperationId.region());
         assertEquals(NAME, regionOperationId.operation());
         regionOperationId = RegionOperationId.of(RegionId.of(PROJECT, REGION), NAME);
    +    assertEquals(OperationId.Type.REGION, regionOperationId.type());
         assertEquals(PROJECT, regionOperationId.project());
         assertEquals(REGION, regionOperationId.region());
         assertEquals(NAME, regionOperationId.operation());
    @@ -151,6 +159,7 @@ private void compareZoneOperationId(ZoneOperationId expected, ZoneOperationId va
     
       private void compareRegionOperationId(RegionOperationId expected, RegionOperationId value) {
         assertEquals(expected, value);
    +    assertEquals(expected.type(), value.type());
         assertEquals(expected.project(), expected.project());
         assertEquals(expected.region(), expected.region());
         assertEquals(expected.operation(), expected.operation());
    diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java
    index da446821a088..56960903d6c7 100644
    --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java
    +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java
    @@ -57,7 +57,7 @@ public class ITComputeTest {
       public Timeout globalTimeout = Timeout.seconds(300);
     
       @BeforeClass
    -  public static void beforeClass() throws InterruptedException {
    +  public static void beforeClass() {
         RemoteComputeHelper computeHelper = RemoteComputeHelper.create();
         compute = computeHelper.options().service();
       }
    
    From ba4fcf01983f61df06ab07734944c2408e6932f2 Mon Sep 17 00:00:00 2001
    From: Marco Ziccardi 
    Date: Tue, 15 Mar 2016 14:09:43 +0100
    Subject: [PATCH 288/375] Remove final from immutable resource classes
    
    ---
     .../src/main/java/com/google/gcloud/compute/DiskType.java   | 6 +++---
     .../src/main/java/com/google/gcloud/compute/License.java    | 6 +++---
     .../main/java/com/google/gcloud/compute/MachineType.java    | 6 +++---
     .../src/main/java/com/google/gcloud/compute/Region.java     | 6 +++---
     .../src/main/java/com/google/gcloud/compute/Zone.java       | 6 +++---
     5 files changed, 15 insertions(+), 15 deletions(-)
    
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java
    index ce57067786c4..0991a9d5d666 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java
    @@ -32,7 +32,7 @@
      *
      * @see Disk Types
      */
    -public final class DiskType implements Serializable {
    +public class DiskType implements Serializable {
     
       static final Function FROM_PB_FUNCTION =
           new Function() {
    @@ -186,12 +186,12 @@ public String toString() {
       }
     
       @Override
    -  public int hashCode() {
    +  public final int hashCode() {
         return Objects.hash(diskTypeId);
       }
     
       @Override
    -  public boolean equals(Object obj) {
    +  public final boolean equals(Object obj) {
         return obj instanceof DiskType && Objects.equals(toPb(), ((DiskType) obj).toPb());
       }
     
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java
    index 2c6cb4ac9422..d69c78d0bbf4 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java
    @@ -29,7 +29,7 @@
      *
      * @see Licenses
      */
    -public final class License implements Serializable {
    +public class License implements Serializable {
     
       private static final long serialVersionUID = 6907923910319640363L;
     
    @@ -65,12 +65,12 @@ public String toString() {
       }
     
       @Override
    -  public int hashCode() {
    +  public final int hashCode() {
         return Objects.hash(licenseId);
       }
     
       @Override
    -  public boolean equals(Object obj) {
    +  public final boolean equals(Object obj) {
         return obj instanceof License && Objects.equals(toPb(), ((License) obj).toPb());
       }
     
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java
    index ee242c0d1ef0..d9c446dddf72 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java
    @@ -36,7 +36,7 @@
      *
      * @see Machine Types
      */
    -public final class MachineType implements Serializable {
    +public class MachineType implements Serializable {
     
       static final Function
           FROM_PB_FUNCTION =
    @@ -242,12 +242,12 @@ public String toString() {
       }
     
       @Override
    -  public int hashCode() {
    +  public final int hashCode() {
         return Objects.hash(machineTypeId);
       }
     
       @Override
    -  public boolean equals(Object obj) {
    +  public final boolean equals(Object obj) {
         return obj instanceof MachineType && Objects.equals(toPb(), ((MachineType) obj).toPb());
       }
     
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java
    index 38f79a691721..470acf4e9061 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java
    @@ -34,7 +34,7 @@
      *
      * @see Region and Zones
      */
    -public final class Region implements Serializable {
    +public class Region implements Serializable {
     
       static final Function FROM_PB_FUNCTION =
           new Function() {
    @@ -306,12 +306,12 @@ public String toString() {
       }
     
       @Override
    -  public int hashCode() {
    +  public final int hashCode() {
         return Objects.hash(regionId);
       }
     
       @Override
    -  public boolean equals(Object obj) {
    +  public final boolean equals(Object obj) {
         return obj instanceof Region && Objects.equals(toPb(), ((Region) obj).toPb());
       }
     
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java
    index 20c64946d7ce..903f994118de 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java
    @@ -34,7 +34,7 @@
      *
      * @see Region and Zones
      */
    -public final class Zone implements Serializable {
    +public class Zone implements Serializable {
     
       static final Function FROM_PB_FUNCTION =
           new Function() {
    @@ -325,12 +325,12 @@ public String toString() {
       }
     
       @Override
    -  public int hashCode() {
    +  public final int hashCode() {
         return Objects.hash(zoneId);
       }
     
       @Override
    -  public boolean equals(Object obj) {
    +  public final boolean equals(Object obj) {
         return obj instanceof Zone && Objects.equals(toPb(), ((Zone) obj).toPb());
       }
     
    
    From de30a254b7e9e994bbf87644f5a0a0bf41ed97f4 Mon Sep 17 00:00:00 2001
    From: Marco Ziccardi 
    Date: Wed, 16 Mar 2016 09:52:22 +0100
    Subject: [PATCH 289/375] Operations: better javadoc for delete, stricter
     parsing of identities
    
    ---
     .../src/main/java/com/google/gcloud/compute/Compute.java  | 3 ++-
     .../main/java/com/google/gcloud/compute/ComputeImpl.java  | 8 ++++++--
     .../main/java/com/google/gcloud/compute/Operation.java    | 3 ++-
     3 files changed, 10 insertions(+), 4 deletions(-)
    
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java
    index 935cf1fa9d7f..8d707a598c32 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java
    @@ -1092,7 +1092,8 @@ public static OperationListOption fields(OperationField... fields) {
       Page listZoneOperations(String zone, OperationListOption... options);
     
       /**
    -   * Deletes the requested operation.
    +   * Deletes the requested operation. Delete is only possible for operations that have completed
    +   * their execution. Any attempt to delete a running operation will fail.
        *
        * @return {@code true} if operation was deleted, {@code false} if it was not found
        * @throws ComputeException upon failure
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java
    index f3b866be5b77..5e6c4bc869a6 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java
    @@ -542,8 +542,10 @@ public com.google.api.services.compute.model.Operation call() {
                       ZoneOperationId zoneOperationId = (ZoneOperationId) operationId;
                       return computeRpc.getZoneOperation(zoneOperationId.zone(),
                           zoneOperationId.operation(), optionsMap);
    -                default:
    +                case GLOBAL:
                       return computeRpc.getGlobalOperation(operationId.operation(), optionsMap);
    +                default:
    +                  throw new IllegalArgumentException("Unexpected operation identity type");
                   }
                 }
               }, options().retryParams(), EXCEPTION_HANDLER);
    @@ -670,8 +672,10 @@ public Boolean call() {
                   ZoneOperationId zoneOperationId = (ZoneOperationId) operation;
                   return computeRpc.deleteZoneOperation(zoneOperationId.zone(),
                       zoneOperationId.operation());
    -            default:
    +            case GLOBAL:
                   return computeRpc.deleteGlobalOperation(operation.operation());
    +            default:
    +              throw new IllegalArgumentException("Unexpected operation identity type");
               }
             }
           }, options().retryParams(), EXCEPTION_HANDLER);
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java
    index d857f90bc84f..7b8a888cf40c 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java
    @@ -692,7 +692,8 @@ public Operation reload(Compute.OperationOption... options) throws ComputeExcept
       }
     
       /**
    -   * Deletes this operation.
    +   * Deletes this operation. Delete is only possible for operations that have completed their
    +   * execution. Any attempt to delete a running operation will fail.
        *
        * @return {@code true} if operation was deleted, {@code false} if it was not found
        * @throws ComputeException upon failure
    
    From 3565376d4ce72e7a182e0c0a0ee91373ff700b61 Mon Sep 17 00:00:00 2001
    From: Marco Ziccardi 
    Date: Wed, 16 Mar 2016 16:45:38 +0100
    Subject: [PATCH 290/375] Add support for Compute's addresses - Add InstanceId,
     ForwardingRuleId and Global/RegionForwardingRuleId - Add AddressId,
     GlobalAddressId, RegionAddressId classes - Add functional methods for
     addresses to Compute's service and rpc classes - Add AddressInfo and Address
     classes - Add unit and integration tests
    
    ---
     .../com/google/gcloud/compute/Address.java    | 184 ++++++
     .../com/google/gcloud/compute/AddressId.java  |  63 ++
     .../google/gcloud/compute/AddressInfo.java    | 572 ++++++++++++++++++
     .../com/google/gcloud/compute/Compute.java    | 434 ++++++++++++-
     .../google/gcloud/compute/ComputeImpl.java    | 240 ++++++++
     .../gcloud/compute/ForwardingRuleId.java      |  65 ++
     .../gcloud/compute/GlobalAddressId.java       | 124 ++++
     .../compute/GlobalForwardingRuleId.java       | 140 +++++
     .../com/google/gcloud/compute/InstanceId.java | 154 +++++
     .../gcloud/compute/RegionAddressId.java       | 137 +++++
     .../compute/RegionForwardingRuleId.java       | 154 +++++
     .../compute/testing/RemoteComputeHelper.java  |   9 +
     .../com/google/gcloud/spi/ComputeRpc.java     |  76 +++
     .../google/gcloud/spi/DefaultComputeRpc.java  | 156 ++++-
     .../google/gcloud/compute/AddressIdTest.java  | 114 ++++
     .../gcloud/compute/AddressInfoTest.java       | 201 ++++++
     .../google/gcloud/compute/AddressTest.java    | 284 +++++++++
     .../gcloud/compute/ComputeImplTest.java       | 505 +++++++++++++++-
     .../gcloud/compute/ForwardingRuleIdTest.java  | 130 ++++
     .../google/gcloud/compute/InstanceIdTest.java |  88 +++
     .../gcloud/compute/SerializationTest.java     |  42 +-
     .../gcloud/compute/it/ITComputeTest.java      | 226 ++++++-
     22 files changed, 4066 insertions(+), 32 deletions(-)
     create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java
     create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressId.java
     create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressInfo.java
     create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/ForwardingRuleId.java
     create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalAddressId.java
     create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalForwardingRuleId.java
     create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceId.java
     create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionAddressId.java
     create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionForwardingRuleId.java
     create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressIdTest.java
     create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressInfoTest.java
     create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressTest.java
     create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/ForwardingRuleIdTest.java
     create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceIdTest.java
    
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java
    new file mode 100644
    index 000000000000..9950ff132303
    --- /dev/null
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java
    @@ -0,0 +1,184 @@
    +/*
    + * Copyright 2016 Google Inc. All Rights Reserved.
    + *
    + * 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.gcloud.compute;
    +
    +import static com.google.common.base.Preconditions.checkNotNull;
    +
    +import java.io.IOException;
    +import java.io.ObjectInputStream;
    +import java.util.Objects;
    +
    +/**
    + * A Google Compute Engine address. With Compute Engine you can create static external IP addresses
    + * that are assigned to your project and persists until you explicitly release them. A region
    + * address can be assigned to a Compute Engine instance or to a regional forwarding rule. Compute
    + * Engine also allows to create global addresses that are used for global forwarding rules. Both
    + * global addresses and global forwarding rules can only be used for HTTP load balancing.
    + * {@code Address} adds a layer of service-related functionality over {@link AddressInfo}. Objects
    + * of this class are immutable. To get an {@code Address} object with the most recent information
    + * use {@link #reload}.
    + *
    + * @see 
    + *     Static external IP addresses
    + * @see HTTP Load Balancing
    + */
    +public class Address extends AddressInfo {
    +
    +  private static final long serialVersionUID = 3457542817554062712L;
    +
    +  private final ComputeOptions options;
    +  private transient Compute compute;
    +
    +  /**
    +   * A builder for {@code Address} objects.
    +   */
    +  public static class Builder extends AddressInfo.Builder {
    +
    +    private final Compute compute;
    +    private final AddressInfo.BuilderImpl infoBuilder;
    +
    +    Builder(Compute compute, AddressId addressId) {
    +      this.compute = compute;
    +      this.infoBuilder = new AddressInfo.BuilderImpl();
    +      this.infoBuilder.addressId(addressId);
    +    }
    +
    +    Builder(Address address) {
    +      this.compute = address.compute;
    +      this.infoBuilder = new AddressInfo.BuilderImpl(address);
    +    }
    +
    +    @Override
    +    public Builder address(String address) {
    +      infoBuilder.address(address);
    +      return this;
    +    }
    +
    +    @Override
    +    Builder creationTimestamp(Long creationTimestamp) {
    +      infoBuilder.creationTimestamp(creationTimestamp);
    +      return this;
    +    }
    +
    +    @Override
    +    public Builder description(String description) {
    +      infoBuilder.description(description);
    +      return this;
    +    }
    +
    +    @Override
    +    Builder id(String id) {
    +      infoBuilder.id(id);
    +      return this;
    +    }
    +
    +    @Override
    +    Builder addressId(AddressId addressId) {
    +      infoBuilder.addressId(addressId);
    +      return this;
    +    }
    +
    +    @Override
    +    Builder status(Status status) {
    +      infoBuilder.status(status);
    +      return this;
    +    }
    +
    +    @Override
    +    Builder usage(Usage usage) {
    +      infoBuilder.usage(usage);
    +      return this;
    +    }
    +
    +    @Override
    +    public Address build() {
    +      return new Address(compute, infoBuilder);
    +    }
    +  }
    +
    +  Address(Compute compute, AddressInfo.BuilderImpl infoBuilder) {
    +    super(infoBuilder);
    +    this.compute = checkNotNull(compute);
    +    this.options = compute.options();
    +  }
    +
    +  /**
    +   * Checks if this address exists.
    +   *
    +   * @return {@code true} if this address exists, {@code false} otherwise
    +   * @throws ComputeException upon failure
    +   */
    +  public boolean exists() throws ComputeException  {
    +    return reload(Compute.AddressOption.fields()) != null;
    +  }
    +
    +  /**
    +   * Fetches current address' latest information. Returns {@code null} if the address does not
    +   * exist.
    +   *
    +   * @param options address options
    +   * @return an {@code Address} object with latest information or {@code null} if not found
    +   * @throws ComputeException upon failure
    +   */
    +  public Address reload(Compute.AddressOption... options) throws ComputeException {
    +    return compute.get(addressId(), options);
    +  }
    +
    +  /**
    +   * Deletes this address.
    +   *
    +   * @return an operation object if delete request was successfully sent, {@code null} if the
    +   *     address was not found
    +   * @throws ComputeException upon failure
    +   */
    +  public Operation delete(Compute.OperationOption... options) throws ComputeException {
    +    return compute.delete(addressId(), options);
    +  }
    +
    +  /**
    +   * Returns the address's {@code Compute} object used to issue requests.
    +   */
    +  public Compute compute() {
    +    return compute;
    +  }
    +
    +  @Override
    +  public Builder toBuilder() {
    +    return new Builder(this);
    +  }
    +
    +  @Override
    +  public final boolean equals(Object obj) {
    +    return obj instanceof Address
    +        && Objects.equals(toPb(), ((Address) obj).toPb())
    +        && Objects.equals(options, ((Address) obj).options);
    +  }
    +
    +  @Override
    +  public final int hashCode() {
    +    return Objects.hash(super.hashCode(), options);
    +  }
    +
    +  private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    +    in.defaultReadObject();
    +    this.compute = options.service();
    +  }
    +
    +  static Address fromPb(Compute compute, com.google.api.services.compute.model.Address addressPb) {
    +    return new Address(compute, new AddressInfo.BuilderImpl(addressPb));
    +  }
    +}
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressId.java
    new file mode 100644
    index 000000000000..01f163b867cd
    --- /dev/null
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressId.java
    @@ -0,0 +1,63 @@
    +/*
    + * Copyright 2016 Google Inc. All Rights Reserved.
    + *
    + * 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.gcloud.compute;
    +
    +/**
    + * Interface for Google Compute Engine address identities.
    + */
    +public interface AddressId {
    +
    +  /**
    +   * Possible types for a Google Compute Engine address identity.
    +   */
    +  enum Type {
    +    /**
    +     * Global static external IP addresses can be assigned to global forwarding rules.
    +     */
    +    GLOBAL,
    +    /**
    +     * Region static external IP addresses can be assigned to instances and region forwarding rules.
    +     */
    +    REGION
    +  }
    +
    +  /**
    +   * Returns the type of this address identity.
    +   */
    +  Type type();
    +
    +  /**
    +   * Returns the name of the project.
    +   */
    +  String project();
    +
    +  /**
    +   * Returns the name of the address resource. The name must be 1-63 characters long, and comply
    +   * with RFC1035. Specifically, the name must be 1-63 characters long and match the regular
    +   * expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a
    +   * lowercase letter, and all following characters must be a dash, lowercase letter, or digit,
    +   * except the last character, which cannot be a dash.
    +   *
    +   * @see RFC1035
    +   */
    +  String address();
    +
    +  /**
    +   * Returns a fully qualified URL to the entity.
    +   */
    +  String selfLink();
    +}
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressInfo.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressInfo.java
    new file mode 100644
    index 000000000000..eda874618801
    --- /dev/null
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressInfo.java
    @@ -0,0 +1,572 @@
    +/*
    + * Copyright 2016 Google Inc. All Rights Reserved.
    + *
    + * 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.gcloud.compute;
    +
    +import static com.google.common.base.Preconditions.checkNotNull;
    +
    +import com.google.api.services.compute.model.Address;
    +import com.google.common.base.Function;
    +import com.google.common.base.MoreObjects;
    +import com.google.common.collect.ImmutableList;
    +import com.google.common.collect.Lists;
    +
    +import org.joda.time.format.DateTimeFormatter;
    +import org.joda.time.format.ISODateTimeFormat;
    +
    +import java.io.Serializable;
    +import java.math.BigInteger;
    +import java.util.List;
    +import java.util.Objects;
    +
    +/**
    + * A Google Compute Engine address. With Compute Engine you can create static external IP addresses
    + * that are assigned to your project and persists until you explicitly release them. A region
    + * address can be assigned to a Compute Engine instance or to a regional forwarding rule. To create
    + * a region address use a {@link RegionAddressId} identity. Compute Engine also allows to create
    + * global addresses that are used for global forwarding rules. Both global addresses and global
    + * forwarding rules can only be used for HTTP load balancing. To create a global address use a
    + * {@link GlobalAddressId} identity.
    + *
    + * @see 
    + *     Static external IP addresses
    + * @see HTTP Load Balancing
    + */
    +public class AddressInfo implements Serializable {
    +
    +  static final Function FROM_PB_FUNCTION =
    +      new Function() {
    +        @Override
    +        public AddressInfo apply(Address pb) {
    +          return AddressInfo.fromPb(pb);
    +        }
    +      };
    +  static final Function TO_PB_FUNCTION =
    +      new Function() {
    +        @Override
    +        public Address apply(AddressInfo addressInfo) {
    +          return addressInfo.toPb();
    +        }
    +      };
    +
    +  private static final long serialVersionUID = 7678434703520207500L;
    +  private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime();
    +
    +  private final String address;
    +  private final Long creationTimestamp;
    +  private final String description;
    +  private final String id;
    +  private final AddressId addressId;
    +  private final Status status;
    +  private final Usage usage;
    +
    +  /**
    +   * The status of the address.
    +   */
    +  public enum Status {
    +
    +    /**
    +     * The address is reserved for the project and is available for use.
    +     */
    +    RESERVED,
    +
    +    /**
    +     * The address is currently being used and thus not available.
    +     */
    +    IN_USE
    +  }
    +
    +  /**
    +   * Base class for a Google Compute Engine address usage information. {@link InstanceUsage} is for
    +   * addresses assigned to a Google Compute Engine instance.
    +   */
    +  public abstract static class Usage implements Serializable {
    +
    +    private static final long serialVersionUID = -5028609518171408695L;
    +
    +    Usage() {}
    +
    +    /**
    +     * Returns the identities of resources currently using this address.
    +     */
    +    public abstract List users();
    +
    +    final boolean baseEquals(Usage usage) {
    +      return Objects.equals(toPb(), usage.toPb());
    +    }
    +
    +    Address toPb() {
    +      return new Address().setUsers(Lists.transform(users(), new Function() {
    +        @Override
    +        public String apply(ResourceId resourceId) {
    +          return resourceId.selfLink();
    +        }
    +      }));
    +    }
    +
    +    @SuppressWarnings("unchecked")
    +    static  T fromPb(Address addressPb) {
    +      String url = addressPb.getUsers().get(0);
    +      if (InstanceId.matchesUrl(url)) {
    +        return (T) InstanceUsage.fromPb(addressPb);
    +      } else if (RegionForwardingRuleId.matchesUrl(url)) {
    +        return (T) RegionForwardingUsage.fromPb(addressPb);
    +      } else {
    +        return (T) GlobalForwardingUsage.fromPb(addressPb);
    +      }
    +    }
    +  }
    +
    +  /**
    +   * Usage information for a Google Compute Engine region address assigned to a virtual machine
    +   * instance.
    +   */
    +  public static final class InstanceUsage extends Usage {
    +
    +    private static final long serialVersionUID = -5028609518171408695L;
    +
    +    private final InstanceId instance;
    +
    +    InstanceUsage(InstanceId instance) {
    +      this.instance = checkNotNull(instance);
    +    }
    +
    +    /**
    +     * Returns the identity of the instance using the address.
    +     */
    +    public InstanceId instance() {
    +      return instance;
    +    }
    +
    +    @Override
    +    public List users() {
    +      return ImmutableList.of(instance);
    +    }
    +
    +    @Override
    +    public String toString() {
    +      return MoreObjects.toStringHelper(this).add("instance", instance).toString();
    +    }
    +
    +    @Override
    +    public boolean equals(Object obj) {
    +      return obj instanceof InstanceUsage && baseEquals((InstanceUsage) obj);
    +    }
    +
    +    @Override
    +    public int hashCode() {
    +      return Objects.hash(instance);
    +    }
    +
    +    @SuppressWarnings("unchecked")
    +    static InstanceUsage fromPb(Address addressPb) {
    +      return new InstanceUsage(InstanceId.fromUrl(addressPb.getUsers().get(0)));
    +    }
    +  }
    +
    +  /**
    +   * Usage information for a Google Compute Engine region address assigned to one or more region
    +   * forwarding rules.
    +   */
    +  public static final class RegionForwardingUsage extends Usage {
    +
    +    private static final long serialVersionUID = -4255145869626427363L;
    +
    +    private final List forwardingRules;
    +
    +    RegionForwardingUsage(List forwardingRules) {
    +      this.forwardingRules = ImmutableList.copyOf(forwardingRules);
    +    }
    +
    +    /**
    +     * Returns a list of identities of region forwarding rules that are currently using the address.
    +     */
    +    public List forwardingRules() {
    +      return forwardingRules;
    +    }
    +
    +    @Override
    +    @SuppressWarnings("unchecked")
    +    public List users() {
    +      return (List) (List) forwardingRules;
    +    }
    +
    +    @Override
    +    public String toString() {
    +      return MoreObjects.toStringHelper(this).add("forwardingRules", forwardingRules).toString();
    +    }
    +
    +    @Override
    +    public boolean equals(Object obj) {
    +      return obj instanceof RegionForwardingUsage && baseEquals((RegionForwardingUsage) obj);
    +    }
    +
    +    @Override
    +    public int hashCode() {
    +      return Objects.hash(forwardingRules);
    +    }
    +
    +    @SuppressWarnings("unchecked")
    +    static RegionForwardingUsage fromPb(Address addressPb) {
    +      return new RegionForwardingUsage(
    +          Lists.transform(addressPb.getUsers(), RegionForwardingRuleId.FROM_URL_FUNCTION));
    +    }
    +  }
    +
    +  /**
    +   * Usage information for a Google Compute Engine global address assigned to one or more global
    +   * forwarding rules.
    +   */
    +  public static final class GlobalForwardingUsage extends Usage {
    +
    +    private static final long serialVersionUID = -2974154224319117433L;
    +
    +    private final List forwardingRules;
    +
    +    GlobalForwardingUsage(List forwardingRules) {
    +      this.forwardingRules = ImmutableList.copyOf(forwardingRules);
    +    }
    +
    +    /**
    +     * Returns a list of identities of global forwarding rules that are currently using the address.
    +     */
    +    public List forwardingRules() {
    +      return forwardingRules;
    +    }
    +
    +    @Override
    +    @SuppressWarnings("unchecked")
    +    public List users() {
    +      return (List) (List) forwardingRules;
    +    }
    +
    +    @Override
    +    public String toString() {
    +      return MoreObjects.toStringHelper(this).add("forwardingRules", forwardingRules).toString();
    +    }
    +
    +    @Override
    +    public boolean equals(Object obj) {
    +      return obj instanceof GlobalForwardingUsage && baseEquals((GlobalForwardingUsage) obj);
    +    }
    +
    +    @Override
    +    public int hashCode() {
    +      return Objects.hash(forwardingRules);
    +    }
    +
    +    @SuppressWarnings("unchecked")
    +    static GlobalForwardingUsage fromPb(Address addressPb) {
    +      return new GlobalForwardingUsage(
    +          Lists.transform(addressPb.getUsers(), GlobalForwardingRuleId.FROM_URL_FUNCTION));
    +    }
    +  }
    +
    +  /**
    +   * A builder for {@code AddressInfo} objects.
    +   */
    +  public abstract static class Builder {
    +
    +    /**
    +     * Sets the actual IP address.
    +     */
    +    public abstract Builder address(String address);
    +
    +    abstract Builder creationTimestamp(Long creationTimestamp);
    +
    +    /**
    +     * Sets an optional textual description of the address.
    +     */
    +    public abstract Builder description(String description);
    +
    +    abstract Builder id(String id);
    +
    +    abstract Builder addressId(AddressId addressId);
    +
    +    abstract Builder status(Status status);
    +
    +    abstract Builder usage(Usage usage);
    +
    +    /**
    +     * Creates an {@code AddressInfo} object.
    +     */
    +    public abstract AddressInfo build();
    +  }
    +
    +  static final class BuilderImpl extends Builder {
    +
    +    private String address;
    +    private Long creationTimestamp;
    +    private String description;
    +    private String id;
    +    private AddressId addressId;
    +    private Status status;
    +    private Usage usage;
    +
    +    BuilderImpl() {}
    +
    +    BuilderImpl(AddressInfo addressInfo) {
    +      this.address = addressInfo.address;
    +      this.creationTimestamp = addressInfo.creationTimestamp;
    +      this.description = addressInfo.description;
    +      this.id = addressInfo.id;
    +      this.addressId = addressInfo.addressId;
    +      this.status = addressInfo.status;
    +      this.usage = addressInfo.usage;
    +    }
    +
    +    BuilderImpl(Address addressPb) {
    +      if (RegionAddressId.matchesUrl(addressPb.getSelfLink())) {
    +        addressId = RegionAddressId.fromUrl(addressPb.getSelfLink());
    +      } else {
    +        addressId = GlobalAddressId.fromUrl(addressPb.getSelfLink());
    +      }
    +      address = addressPb.getAddress();
    +      if (addressPb.getCreationTimestamp() != null) {
    +        creationTimestamp = TIMESTAMP_FORMATTER.parseMillis(addressPb.getCreationTimestamp());
    +      }
    +      description = addressPb.getDescription();
    +      if (addressPb.getId() != null) {
    +        id = addressPb.getId().toString();
    +      }
    +      if (addressPb.getStatus() != null) {
    +        status = Status.valueOf(addressPb.getStatus());
    +      }
    +      if (addressPb.getUsers() != null && addressPb.getUsers().size() > 0) {
    +        usage = Usage.fromPb(addressPb);
    +      }
    +    }
    +
    +    @Override
    +    public BuilderImpl address(String address) {
    +      this.address = address;
    +      return this;
    +    }
    +
    +    @Override
    +    BuilderImpl creationTimestamp(Long creationTimestamp) {
    +      this.creationTimestamp = creationTimestamp;
    +      return this;
    +    }
    +
    +    @Override
    +    public BuilderImpl description(String description) {
    +      this.description = description;
    +      return this;
    +    }
    +
    +    @Override
    +    BuilderImpl id(String id) {
    +      this.id = id;
    +      return this;
    +    }
    +
    +    @Override
    +    BuilderImpl addressId(AddressId addressId) {
    +      this.addressId = checkNotNull(addressId);
    +      return this;
    +    }
    +
    +    @Override
    +    BuilderImpl status(Status status) {
    +      this.status = status;
    +      return this;
    +    }
    +
    +    @Override
    +    BuilderImpl usage(Usage usage) {
    +      this.usage = usage;
    +      return this;
    +    }
    +
    +    @Override
    +    public AddressInfo build() {
    +      return new AddressInfo(this);
    +    }
    +  }
    +
    +  AddressInfo(BuilderImpl builder) {
    +    address = builder.address;
    +    creationTimestamp = builder.creationTimestamp;
    +    description = builder.description;
    +    id = builder.id;
    +    addressId = checkNotNull(builder.addressId);
    +    status = builder.status;
    +    usage = builder.usage;
    +  }
    +
    +  /**
    +   * Returns the static external IP address represented by this object.
    +   */
    +  public String address() {
    +    return address;
    +  }
    +
    +  /**
    +   * Returns the creation timestamp in milliseconds since epoch.
    +   */
    +  public Long creationTimestamp() {
    +    return creationTimestamp;
    +  }
    +
    +  /**
    +   * Returns an optional textual description of the address.
    +   */
    +  public String description() {
    +    return description;
    +  }
    +
    +  /**
    +   * Returns an unique identifier for the address; defined by the service.
    +   */
    +  public String id() {
    +    return id;
    +  }
    +
    +  /**
    +   * Returns the address identity. Returns {@link GlobalAddressId} for a global address, returns
    +   * {@link RegionAddressId} for a region address.
    +   */
    +  @SuppressWarnings("unchecked")
    +  public  T addressId() {
    +    return (T) addressId;
    +  }
    +
    +  /**
    +   * Returns the status of the address.
    +   */
    +  public Status status() {
    +    return status;
    +  }
    +
    +  /**
    +   * Returns the usage information of the address. Returns a {@link InstanceUsage} object for region
    +   * addresses that are assigned to VM instances. Returns a {@link RegionForwardingUsage} object for
    +   * region addresses assigned to region forwarding rules. Returns a {@link GlobalForwardingUsage}
    +   * object for global addresses assigned to global forwarding rules. Returns {@code null} if the
    +   * address is not in use.
    +   */
    +  @SuppressWarnings("unchecked")
    +  public  T usage() {
    +    return (T) usage;
    +  }
    +
    +  /**
    +   * Returns a builder for the {@code AddressInfo} object.
    +   */
    +  public Builder toBuilder() {
    +    return new BuilderImpl(this);
    +  }
    +
    +  @Override
    +  public String toString() {
    +    return MoreObjects.toStringHelper(this)
    +        .add("address", address)
    +        .add("creationTimestamp", creationTimestamp)
    +        .add("description", description)
    +        .add("id", id)
    +        .add("addressId", addressId)
    +        .add("status", status)
    +        .add("usage", usage)
    +        .toString();
    +  }
    +
    +  @Override
    +  public int hashCode() {
    +    return Objects.hash(address, creationTimestamp, description, id, addressId, status, usage);
    +  }
    +
    +  @Override
    +  public boolean equals(Object obj) {
    +    return obj != null
    +        && obj.getClass().equals(AddressInfo.class)
    +        && Objects.equals(toPb(), ((AddressInfo) obj).toPb());
    +  }
    +
    +  AddressInfo setProjectId(String projectId) {
    +    Builder builder = toBuilder();
    +    AddressId addressIdWithProject;
    +    if (addressId instanceof RegionAddressId) {
    +      addressIdWithProject = this.addressId().setProjectId(projectId);
    +    } else {
    +      addressIdWithProject = this.addressId().setProjectId(projectId);
    +    }
    +    return builder.addressId(addressIdWithProject).build();
    +  }
    +
    +  Address toPb() {
    +    Address addressPb = usage != null ? usage.toPb() : new Address();
    +    addressPb.setAddress(address);
    +    if (creationTimestamp != null) {
    +      addressPb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp));
    +    }
    +    addressPb.setDescription(description);
    +    if (id != null) {
    +      addressPb.setId(new BigInteger(id));
    +    }
    +    addressPb.setName(addressId.address());
    +    if (addressId.type() == AddressId.Type.REGION) {
    +      addressPb.setRegion(this.addressId().regionId().selfLink());
    +    }
    +    if (status != null) {
    +      addressPb.setStatus(status.name());
    +    }
    +    addressPb.setSelfLink(addressId.selfLink());
    +    return addressPb;
    +  }
    +
    +  /**
    +   * Returns a builder for the AddressInfo object given it's identity.
    +   */
    +  public static BuilderImpl builder(AddressId addressId) {
    +    return new BuilderImpl().addressId(addressId);
    +  }
    +
    +  /**
    +   * Returns an AddressInfo object for the provided identity.
    +   */
    +  public static AddressInfo of(AddressId addressId) {
    +    return builder(addressId).build();
    +  }
    +
    +  /**
    +   * Returns an AddressInfo object for the provided name. Such an object corresponds to a global
    +   * address.
    +   */
    +  public static AddressInfo of(String name) {
    +    return of(GlobalAddressId.of(name));
    +  }
    +
    +  /**
    +   * Returns an AddressInfo object for the provided region identity and name. Such an object
    +   * corresponds to a region address.
    +   */
    +  public static AddressInfo of(RegionId regionId, String name) {
    +    return of(RegionAddressId.of(regionId, name));
    +  }
    +
    +  /**
    +   * Returns an AddressInfo object for the provided region and address names. Such an object
    +   * corresponds to a region address.
    +   */
    +  public static AddressInfo of(String region, String name) {
    +    return of(RegionAddressId.of(region, name));
    +  }
    +
    +  static AddressInfo fromPb(Address addressPb) {
    +    return new BuilderImpl(addressPb).build();
    +  }
    +}
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java
    index 8d707a598c32..ac881488f362 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java
    +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java
    @@ -275,6 +275,253 @@ static String selector(OperationField... fields) {
         }
       }
     
    +  /**
    +   * Fields of a Compute Engine Address resource.
    +   *
    +   * @see Region
    +   *     Address Resource
    +   * @see 
    +   *     Global Address Resource
    +   */
    +  enum AddressField {
    +    ADDRESS("address"),
    +    CREATION_TIMESTAMP("creationTimestamp"),
    +    DESCRIPTION("description"),
    +    ID("id"),
    +    NAME("name"),
    +    REGION("region"),
    +    SELF_LINK("selfLink"),
    +    STATUS("status"),
    +    USERS("users");
    +
    +    private final String selector;
    +
    +    AddressField(String selector) {
    +      this.selector = selector;
    +    }
    +
    +    public String selector() {
    +      return selector;
    +    }
    +
    +    static String selector(AddressField... fields) {
    +      Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1);
    +      fieldStrings.add(SELF_LINK.selector());
    +      for (AddressField field : fields) {
    +        fieldStrings.add(field.selector());
    +      }
    +      return Joiner.on(',').join(fieldStrings);
    +    }
    +  }
    +
    +  /**
    +   * Fields of a Compute Engine Disk resource.
    +   *
    +   * @see Disk
    +   *     Resource
    +   */
    +  enum DiskField {
    +    CREATION_TIMESTAMP("creationTimestamp"),
    +    DESCRIPTION("description"),
    +    ID("id"),
    +    LAST_ATTACH_TIMESTAMP("lastAttachTimestamp"),
    +    LAST_DETACH_TIMESTAMP("lastDetachTimestamp"),
    +    LICENSES("licenses"),
    +    NAME("name"),
    +    OPTIONS("options"),
    +    SELF_LINK("selfLink"),
    +    SIZE_GB("sizeGb"),
    +    SOURCE_IMAGE("sourceImage"),
    +    SOURCE_IMAGE_ID("sourceImageId"),
    +    SOURCE_SNAPSHOT("sourceSnapshot"),
    +    SOURCE_SNAPSHOT_ID("sourceSnapshotId"),
    +    STATUS("status"),
    +    TYPE("type"),
    +    USERS("users"),
    +    ZONE("zone");
    +
    +    private final String selector;
    +
    +    DiskField(String selector) {
    +      this.selector = selector;
    +    }
    +
    +    public String selector() {
    +      return selector;
    +    }
    +
    +    static String selector(DiskField... fields) {
    +      Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 4);
    +      fieldStrings.add(SELF_LINK.selector());
    +      fieldStrings.add(TYPE.selector());
    +      fieldStrings.add(SOURCE_IMAGE.selector());
    +      fieldStrings.add(SOURCE_SNAPSHOT.selector());
    +      for (DiskField field : fields) {
    +        fieldStrings.add(field.selector());
    +      }
    +      return Joiner.on(',').join(fieldStrings);
    +    }
    +  }
    +
    +  /**
    +   * Fields of a Compute Engine Snapshot resource.
    +   *
    +   * @see 
    +   *     Snapshot Resource
    +   */
    +  enum SnapshotField {
    +    CREATION_TIMESTAMP("creationTimestamp"),
    +    DESCRIPTION("description"),
    +    DISK_SIZE_GB("diskSizeGb"),
    +    ID("id"),
    +    LICENSES("licenses"),
    +    NAME("name"),
    +    SELF_LINK("selfLink"),
    +    SOURCE_DISK("sourceDisk"),
    +    SOURCE_DISK_ID("sourceDiskId"),
    +    STATUS("status"),
    +    STORAGE_BYTES("storageBytes"),
    +    STORAGE_BYTES_STATUS("storageBytesStatus");
    +
    +    private final String selector;
    +
    +    SnapshotField(String selector) {
    +      this.selector = selector;
    +    }
    +
    +    public String selector() {
    +      return selector;
    +    }
    +
    +    static String selector(SnapshotField... fields) {
    +      Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1);
    +      fieldStrings.add(SELF_LINK.selector());
    +      for (SnapshotField field : fields) {
    +        fieldStrings.add(field.selector());
    +      }
    +      return Joiner.on(',').join(fieldStrings);
    +    }
    +  }
    +
    +  /**
    +   * Fields of a Compute Engine Image resource.
    +   *
    +   * @see Image
    +   *     Resource
    +   */
    +  enum ImageField {
    +    ARCHIVE_SIZE_BYTES("archiveSizeBytes"),
    +    CREATION_TIMESTAMP("creationTimestamp"),
    +    DEPRECATED("deprecated"),
    +    DESCRIPTION("description"),
    +    DISK_SIZE_GB("diskSizeGb"),
    +    ID("id"),
    +    LICENSES("licenses"),
    +    NAME("name"),
    +    RAW_DISK("rawDisk"),
    +    SELF_LINK("selfLink"),
    +    SOURCE_DISK("sourceDisk"),
    +    SOURCE_DISK_ID("sourceDiskId"),
    +    SOURCE_TYPE("sourceType");
    +
    +    private final String selector;
    +
    +    ImageField(String selector) {
    +      this.selector = selector;
    +    }
    +
    +    public String selector() {
    +      return selector;
    +    }
    +
    +    static String selector(ImageField... fields) {
    +      Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 3);
    +      fieldStrings.add(SELF_LINK.selector());
    +      fieldStrings.add(SOURCE_DISK.selector());
    +      fieldStrings.add(RAW_DISK.selector());
    +      for (ImageField field : fields) {
    +        fieldStrings.add(field.selector());
    +      }
    +      return Joiner.on(',').join(fieldStrings);
    +    }
    +  }
    +
    +  /**
    +   * Fields of a Compute Engine Subnetwork resource.
    +   *
    +   * @see 
    +   *     Subnetwork Resource
    +   */
    +  enum SubnetworkField {
    +    CREATION_TIMESTAMP("creationTimestamp"),
    +    DESCRIPTION("description"),
    +    GATEWAY_ADDRESS("gatewayAddress"),
    +    ID("id"),
    +    IP_CIDR_RANGE("ipCidrRange"),
    +    NAME("name"),
    +    NETWORK("network"),
    +    REGION("region"),
    +    SELF_LINK("selfLink");
    +
    +    private final String selector;
    +
    +    SubnetworkField(String selector) {
    +      this.selector = selector;
    +    }
    +
    +    public String selector() {
    +      return selector;
    +    }
    +
    +    static String selector(SubnetworkField... fields) {
    +      Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1);
    +      fieldStrings.add(SELF_LINK.selector());
    +      for (SubnetworkField field : fields) {
    +        fieldStrings.add(field.selector());
    +      }
    +      return Joiner.on(',').join(fieldStrings);
    +    }
    +  }
    +
    +  /**
    +   * Fields of a Compute Engine Network resource.
    +   *
    +   * @see 
    +   *     Network Resource
    +   */
    +  enum NetworkField {
    +    IPV4_RANGE("IPv4Range"),
    +    AUTO_CREATE_SUBNETWORKS("autoCreateSubnetworks"),
    +    CREATION_TIMESTAMP("creationTimestamp"),
    +    DESCRIPTION("description"),
    +    GATEWAY_IPV4("gatewayIPv4"),
    +    ID("id"),
    +    NAME("name"),
    +    SELF_LINK("selfLink"),
    +    SUBNETWORKS("subnetworks");
    +
    +    private final String selector;
    +
    +    NetworkField(String selector) {
    +      this.selector = selector;
    +    }
    +
    +    public String selector() {
    +      return selector;
    +    }
    +
    +    static String selector(NetworkField... fields) {
    +      Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 3);
    +      fieldStrings.add(SELF_LINK.selector());
    +      fieldStrings.add(IPV4_RANGE.selector());
    +      fieldStrings.add(AUTO_CREATE_SUBNETWORKS.selector());
    +      for (NetworkField field : fields) {
    +        fieldStrings.add(field.selector());
    +      }
    +      return Joiner.on(',').join(fieldStrings);
    +    }
    +  }
    +
       /**
        * Base class for list filters.
        */
    @@ -540,6 +787,40 @@ public static OperationFilter notEquals(OperationField field, long value) {
         }
       }
     
    +  /**
    +   * Class for filtering address lists.
    +   */
    +  class AddressFilter extends ListFilter {
    +
    +    private static final long serialVersionUID = -227481644259653765L;
    +
    +    AddressFilter(AddressField field, ComparisonOperator operator, Object value) {
    +      super(field.selector(), operator, value);
    +    }
    +
    +    /**
    +     * Returns an equality filter for the given field and string value. For string fields,
    +     * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
    +     * match the entire field.
    +     *
    +     * @see RE2
    +     */
    +    public static AddressFilter equals(AddressField field, String value) {
    +      return new AddressFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value));
    +    }
    +
    +    /**
    +     * Returns a not-equals filter for the given field and string value. For string fields,
    +     * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must
    +     * match the entire field.
    +     *
    +     * @see RE2
    +     */
    +    public static AddressFilter notEquals(AddressField field, String value) {
    +      return new AddressFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value));
    +    }
    +  }
    +
       /**
        * Class for specifying disk type get options.
        */
    @@ -574,14 +855,14 @@ private DiskTypeListOption(ComputeRpc.Option option, Object value) {
         }
     
         /**
    -     * Returns an option to specify a filter on the disk types being listed.
    +     * Returns an option to specify a filter to the disk types being listed.
          */
         public static DiskTypeListOption filter(DiskTypeFilter filter) {
           return new DiskTypeListOption(ComputeRpc.Option.FILTER, filter.toPb());
         }
     
         /**
    -     * Returns an option to specify the maximum number of disk types returned per page.
    +     * Returns an option to specify the maximum number of disk types to be returned.
          */
         public static DiskTypeListOption pageSize(long pageSize) {
           return new DiskTypeListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
    @@ -619,14 +900,14 @@ private DiskTypeAggregatedListOption(ComputeRpc.Option option, Object value) {
         }
     
         /**
    -     * Returns an option to specify a filter on the disk types being listed.
    +     * Returns an option to specify a filter to the disk types being listed.
          */
         public static DiskTypeAggregatedListOption filter(DiskTypeFilter filter) {
           return new DiskTypeAggregatedListOption(ComputeRpc.Option.FILTER, filter.toPb());
         }
     
         /**
    -     * Returns an option to specify the maximum number of disk types returned per page.
    +     * Returns an option to specify the maximum number of disk types to be returned.
          */
         public static DiskTypeAggregatedListOption pageSize(long pageSize) {
           return new DiskTypeAggregatedListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
    @@ -963,6 +1244,106 @@ public static OperationListOption fields(OperationField... fields) {
         }
       }
     
    +  /**
    +   * Class for specifying address get options.
    +   */
    +  class AddressOption extends Option {
    +
    +    private static final long serialVersionUID = -5755491818692494389L;
    +
    +    private AddressOption(ComputeRpc.Option option, Object value) {
    +      super(option, value);
    +    }
    +
    +    /**
    +     * Returns an option to specify the address' fields to be returned by the RPC call. If this
    +     * option is not provided, all address' fields are returned. {@code AddressOption.fields} can be
    +     * used to specify only the fields of interest. {@link Address#addressId()} is always
    +     * returned, even if not specified.
    +     */
    +    public static AddressOption fields(AddressField... fields) {
    +      return new AddressOption(ComputeRpc.Option.FIELDS, AddressField.selector(fields));
    +    }
    +  }
    +
    +  /**
    +   * Class for specifying address list options.
    +   */
    +  class AddressListOption extends Option {
    +
    +    private static final long serialVersionUID = -4281322966374929346L;
    +
    +    private AddressListOption(ComputeRpc.Option option, Object value) {
    +      super(option, value);
    +    }
    +
    +    /**
    +     * Returns an option to specify a filter to the addresses being listed.
    +     */
    +    public static AddressListOption filter(AddressFilter filter) {
    +      return new AddressListOption(ComputeRpc.Option.FILTER, filter.toPb());
    +    }
    +
    +    /**
    +     * Returns an option to specify the maximum number of addresses returned per page.
    +     */
    +    public static AddressListOption pageSize(long pageSize) {
    +      return new AddressListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
    +    }
    +
    +    /**
    +     * Returns an option to specify the page token from which to start listing addresses.
    +     */
    +    public static AddressListOption startPageToken(String pageToken) {
    +      return new AddressListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken);
    +    }
    +
    +    /**
    +     * Returns an option to specify the address' fields to be returned by the RPC call. If this
    +     * option is not provided, all address' fields are returned. {@code AddressListOption.fields}
    +     * can be used to specify only the fields of interest. {@link Address#addressId()} is always
    +     * returned, even if not specified.
    +     */
    +    public static AddressListOption fields(AddressField... fields) {
    +      StringBuilder builder = new StringBuilder();
    +      builder.append("items(").append(AddressField.selector(fields)).append("),nextPageToken");
    +      return new AddressListOption(ComputeRpc.Option.FIELDS, builder.toString());
    +    }
    +  }
    +
    +  /**
    +   * Class for specifying address aggregated list options.
    +   */
    +  class AddressAggregatedListOption extends Option {
    +
    +    private static final long serialVersionUID = -95538941541279561L;
    +
    +    private AddressAggregatedListOption(ComputeRpc.Option option, Object value) {
    +      super(option, value);
    +    }
    +
    +    /**
    +     * Returns an option to specify a filter to the addresses being listed.
    +     */
    +    public static AddressAggregatedListOption filter(AddressFilter filter) {
    +      return new AddressAggregatedListOption(ComputeRpc.Option.FILTER, filter.toPb());
    +    }
    +
    +    /**
    +     * Returns an option to specify the maximum number of addresses returned per page.
    +     */
    +    public static AddressAggregatedListOption pageSize(long pageSize) {
    +      return new AddressAggregatedListOption(ComputeRpc.Option.MAX_RESULTS, pageSize);
    +    }
    +
    +    /**
    +     * Returns an option to specify the page token from which to start listing addresses.
    +     */
    +    public static AddressAggregatedListOption startPageToken(String pageToken) {
    +      return new AddressAggregatedListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken);
    +    }
    +  }
    +
       /**
        * Returns the requested disk type or {@code null} if not found.
        *
    @@ -1099,4 +1480,49 @@ public static OperationListOption fields(OperationField... fields) {
        * @throws ComputeException upon failure
        */
       boolean delete(OperationId operation);
    +
    +  /**
    +   * Returns the requested address or {@code null} if not found.
    +   *
    +   * @throws ComputeException upon failure
    +   */
    +  Address get(AddressId addressId, AddressOption... options);
    +
    +  /**
    +   * Creates a new address.
    +   *
    +   * @return an operation for address' creation
    +   * @throws ComputeException upon failure
    +   */
    +  Operation create(AddressInfo address, OperationOption... options);
    +
    +  /**
    +   * Lists the global addresses.
    +   *
    +   * @throws ComputeException upon failure
    +   */
    +  Page
    listGlobalAddresses(AddressListOption... options); + + /** + * Lists the region addresses for the provided region. + * + * @throws ComputeException upon failure + */ + Page
    listRegionAddresses(String region, AddressListOption... options); + + /** + * Lists all addresses. + * + * @throws ComputeException upon failure + */ + Page
    listAddresses(AddressAggregatedListOption... options); + + /** + * Deletes the requested address. + * + * @return an operation if request was issued correctly, {@code null} if the address was not + * found + * @throws ComputeException upon failure + */ + Operation delete(AddressId addressId, OperationOption... options); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java index 5e6c4bc869a6..001d0dd370de 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java @@ -214,6 +214,65 @@ public Page nextPage() { } } + private static class GlobalAddressPageFetcher implements NextPageFetcher
    { + + private static final long serialVersionUID = -3832055341507574454L; + private final Map requestOptions; + private final ComputeOptions serviceOptions; + + GlobalAddressPageFetcher(ComputeOptions serviceOptions, String cursor, + Map optionMap) { + this.requestOptions = + PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + } + + @Override + public Page
    nextPage() { + return listGlobalAddresses(serviceOptions, requestOptions); + } + } + + private static class RegionAddressPageFetcher implements NextPageFetcher
    { + + private static final long serialVersionUID = 7080596594494397027L; + private final Map requestOptions; + private final ComputeOptions serviceOptions; + private final String region; + + RegionAddressPageFetcher(String region, ComputeOptions serviceOptions, String cursor, + Map optionMap) { + this.requestOptions = + PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + this.region = region; + } + + @Override + public Page
    nextPage() { + return listRegionAddresses(region, serviceOptions, requestOptions); + } + } + + private static class AggregatedAddressPageFetcher implements NextPageFetcher
    { + + private static final long serialVersionUID = -5798942282919494950L; + private final Map requestOptions; + private final ComputeOptions serviceOptions; + + AggregatedAddressPageFetcher(ComputeOptions serviceOptions, String cursor, + Map optionMap) { + this.requestOptions = + PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + } + + @Override + public Page
    nextPage() { + return listAddresses(serviceOptions, requestOptions); + } + } + private final ComputeRpc computeRpc; ComputeImpl(ComputeOptions options) { @@ -684,6 +743,187 @@ public Boolean call() { } } + @Override + public Address get(final AddressId addressId, AddressOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Address answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Address call() { + switch (addressId.type()) { + case REGION: + RegionAddressId regionAddressId = (RegionAddressId) addressId; + return computeRpc.getRegionAddress(regionAddressId.region(), + regionAddressId.address(), optionsMap); + case GLOBAL: + return computeRpc.getGlobalAddress(addressId.address(), optionsMap); + default: + throw new IllegalArgumentException("Unexpected address identity type"); + } + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Address.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation create(final AddressInfo address, OperationOption... options) { + final com.google.api.services.compute.model.Address addressPb = + address.setProjectId(options().projectId()).toPb(); + final Map optionsMap = optionMap(options); + try { + return Operation.fromPb(this, + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + switch (address.addressId().type()) { + case REGION: + RegionAddressId regionAddressId = address.addressId(); + return computeRpc.createRegionAddress(regionAddressId.region(), addressPb, + optionsMap); + case GLOBAL: + return computeRpc.createGlobalAddress(addressPb, optionsMap); + default: + throw new IllegalArgumentException("Unexpected address identity type"); + } + } + }, options().retryParams(), EXCEPTION_HANDLER)); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Page
    listGlobalAddresses(AddressListOption... options) { + return listGlobalAddresses(options(), optionMap(options)); + } + + private static Page
    listGlobalAddresses(final ComputeOptions serviceOptions, + final Map optionsMap) { + try { + ComputeRpc.Tuple> result = + runWithRetries(new Callable>>() { + @Override + public ComputeRpc.Tuple> call() { + return serviceOptions.rpc().listGlobalAddresses(optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.x(); + Iterable
    operations = Iterables.transform( + result.y() == null ? ImmutableList.of() + : result.y(), + new Function() { + @Override + public Address apply(com.google.api.services.compute.model.Address address) { + return Address.fromPb(serviceOptions.service(), address); + } + }); + return new PageImpl<>(new GlobalAddressPageFetcher(serviceOptions, cursor, optionsMap), + cursor, operations); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Page
    listRegionAddresses(String region, AddressListOption... options) { + return listRegionAddresses(region, options(), optionMap(options)); + } + + private static Page
    listRegionAddresses(final String region, + final ComputeOptions serviceOptions, final Map optionsMap) { + try { + ComputeRpc.Tuple> result = + runWithRetries(new Callable>>() { + @Override + public ComputeRpc.Tuple> call() { + return serviceOptions.rpc().listRegionAddresses(region, optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.x(); + Iterable
    operations = Iterables.transform( + result.y() == null ? ImmutableList.of() + : result.y(), + new Function() { + @Override + public Address apply(com.google.api.services.compute.model.Address address) { + return Address.fromPb(serviceOptions.service(), address); + } + }); + return new PageImpl<>(new RegionAddressPageFetcher(region, serviceOptions, cursor, + optionsMap), cursor, operations); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Page
    listAddresses(AddressAggregatedListOption... options) { + return listAddresses(options(), optionMap(options)); + } + + private static Page
    listAddresses(final ComputeOptions serviceOptions, + final Map optionsMap) { + try { + ComputeRpc.Tuple> result = + runWithRetries(new Callable>>() { + @Override + public ComputeRpc.Tuple> call() { + return serviceOptions.rpc().listAddresses(optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.x(); + Iterable
    operations = Iterables.transform( + result.y() == null ? ImmutableList.of() + : result.y(), + new Function() { + @Override + public Address apply(com.google.api.services.compute.model.Address address) { + return Address.fromPb(serviceOptions.service(), address); + } + }); + return new PageImpl<>(new AggregatedAddressPageFetcher(serviceOptions, cursor, + optionsMap), cursor, operations); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation delete(final AddressId addressId, OperationOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + switch (addressId.type()) { + case REGION: + RegionAddressId regionAddressId = (RegionAddressId) addressId; + return computeRpc.deleteRegionAddress(regionAddressId.region(), + regionAddressId.address(), optionsMap); + case GLOBAL: + return computeRpc.deleteGlobalAddress(addressId.address(), optionsMap); + default: + throw new IllegalArgumentException("Unexpected address identity type"); + } + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + private Map optionMap(Option... options) { Map optionMap = Maps.newEnumMap(ComputeRpc.Option.class); for (Option option : options) { diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ForwardingRuleId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ForwardingRuleId.java new file mode 100644 index 000000000000..ab0920de1b61 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ForwardingRuleId.java @@ -0,0 +1,65 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +/** + * Interface for Google Compute Engine forwarding rule identities. + */ +public interface ForwardingRuleId { + + /** + * Possible types for a Google Compute Engine forwarding rule identity. + */ + enum Type { + /** + * Global forwarding rules are used to forward traffic to the correct load balancer for HTTP(S) + * load balancing. + */ + GLOBAL, + /** + * Region forwarding rules are used to forward traffic to the correct pool of target virtual + * machines. + */ + REGION + } + + /** + * Returns the type of this forwarding rule identity. + */ + Type type(); + + /** + * Returns the name of the project. + */ + String project(); + + /** + * Returns the name of the forwarding rule. The name must be 1-63 characters long, and comply with + * RFC1035. Specifically, the name must be 1-63 characters long and match the regular expression + * {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a lowercase letter, + * and all following characters must be a dash, lowercase letter, or digit, except the last + * character, which cannot be a dash. + * + * @see RFC1035 + */ + String rule(); + + /** + * Returns a fully qualified URL to the entity. + */ + String selfLink(); +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalAddressId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalAddressId.java new file mode 100644 index 000000000000..e7db4c56a5c3 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalAddressId.java @@ -0,0 +1,124 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects.ToStringHelper; + +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Identity for a Google Compute Engine global address. + */ +public final class GlobalAddressId extends ResourceId implements AddressId { + + private static final String REGEX = ResourceId.REGEX + "global/addresses/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); + private static final long serialVersionUID = -2950815290049218593L; + + private final String address; + + private GlobalAddressId(String project, String address) { + super(project); + this.address = checkNotNull(address); + } + + @Override + public Type type() { + return Type.GLOBAL; + } + + @Override + public String address() { + return address; + } + + @Override + public String selfLink() { + return super.selfLink() + "/global/addresses/" + address; + } + + @Override + public ToStringHelper toStringHelper() { + return super.toStringHelper().add("address", address); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), address); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof GlobalAddressId + && baseEquals((GlobalAddressId) obj) + && Objects.equals(address, ((GlobalAddressId) obj).address); + } + + @Override + GlobalAddressId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return GlobalAddressId.of(projectId, address); + } + + /** + * Returns an address identity given the address name. The address name must be 1-63 characters + * long, and comply with RFC1035. Specifically, the name must be 1-63 characters long and match + * the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must + * be a lowercase letter, and all following characters must be a dash, lowercase letter, or digit, + * except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public static GlobalAddressId of(String address) { + return new GlobalAddressId(null, address); + } + + /** + * Returns an address identity given project and address names. The address name must be 1-63 + * characters long, and comply with RFC1035. Specifically, the name must be 1-63 characters long + * and match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first + * character must be a lowercase letter, and all following characters must be a dash, lowercase + * letter, or digit, except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public static GlobalAddressId of(String project, String address) { + return new GlobalAddressId(project, address); + } + + /** + * Returns {@code true} if the provided string matches the expected format of a global address + * URL. Returns {@code false} otherwise. + */ + static boolean matchesUrl(String url) { + return PATTERN.matcher(url).matches(); + } + + static GlobalAddressId fromUrl(String url) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { + throw new IllegalArgumentException(url + " is not a valid global address URL"); + } + return GlobalAddressId.of(matcher.group(1), matcher.group(2)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalForwardingRuleId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalForwardingRuleId.java new file mode 100644 index 000000000000..bd902ad3d6e0 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalForwardingRuleId.java @@ -0,0 +1,140 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; + +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Identity for a Google Compute Engine global forwarding rule. + */ +public final class GlobalForwardingRuleId extends ResourceId implements ForwardingRuleId { + + static final Function FROM_URL_FUNCTION = + new Function() { + @Override + public GlobalForwardingRuleId apply(String pb) { + return GlobalForwardingRuleId.fromUrl(pb); + } + }; + static final Function TO_URL_FUNCTION = + new Function() { + @Override + public String apply(GlobalForwardingRuleId forwardingRuleId) { + return forwardingRuleId.selfLink(); + } + }; + + private static final String REGEX = ResourceId.REGEX + "global/forwardingRules/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); + private static final long serialVersionUID = -2648031793037534254L; + + private final String rule; + + private GlobalForwardingRuleId(String project, String rule) { + super(project); + this.rule = checkNotNull(rule); + } + + @Override + public Type type() { + return Type.GLOBAL; + } + + @Override + public String rule() { + return rule; + } + + @Override + public String selfLink() { + return super.selfLink() + "/global/forwardingRules/" + rule; + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper().add("rule", rule); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), rule); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof GlobalForwardingRuleId + && baseEquals((GlobalForwardingRuleId) obj) + && Objects.equals(rule, ((GlobalForwardingRuleId) obj).rule); + } + + @Override + GlobalForwardingRuleId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return GlobalForwardingRuleId.of(projectId, rule); + } + + /** + * Returns a forwarding rule identity given the rule name. The forwarding rule name must be 1-63 + * characters long, and comply with RFC1035. Specifically, the name must be 1-63 characters long + * and match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first + * character must be a lowercase letter, and all following characters must be a dash, lowercase + * letter, or digit, except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public static GlobalForwardingRuleId of(String rule) { + return new GlobalForwardingRuleId(null, rule); + } + + /** + * Returns a forwarding rule identity given the project rule names. The forwarding rule name must + * be 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 + * characters long and match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means + * the first character must be a lowercase letter, and all following characters must be a dash, + * lowercase letter, or digit, except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public static GlobalForwardingRuleId of(String project, String rule) { + return new GlobalForwardingRuleId(project, rule); + } + + /** + * Returns {@code true} if the provided string matches the expected format of a global forwarding + * rule URL. Returns {@code false} otherwise. + */ + static boolean matchesUrl(String url) { + return PATTERN.matcher(url).matches(); + } + + static GlobalForwardingRuleId fromUrl(String url) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { + throw new IllegalArgumentException(url + " is not a valid global forwarding rule URL"); + } + return GlobalForwardingRuleId.of(matcher.group(1), matcher.group(2)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceId.java new file mode 100644 index 000000000000..fc6d91ccb0b4 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceId.java @@ -0,0 +1,154 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; + +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Identity for a Google Compute Engine virtual machine instance. + */ +public final class InstanceId extends ZoneResourceId { + + static final Function FROM_URL_FUNCTION = new Function() { + @Override + public InstanceId apply(String pb) { + return InstanceId.fromUrl(pb); + } + }; + static final Function TO_URL_FUNCTION = new Function() { + @Override + public String apply(InstanceId instanceId) { + return instanceId.selfLink(); + } + }; + + private static final String REGEX = ZoneResourceId.REGEX + "instances/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); + private static final long serialVersionUID = -2787043125223159922L; + + private final String instance; + + private InstanceId(String project, String zone, String instance) { + super(project, zone); + this.instance = checkNotNull(instance); + } + + /** + * Returns the name of the instance. The instance name must be 1-63 characters long, and comply + * with RFC1035. Specifically, the name must be 1-63 characters long and match the regular + * expression [a-z]([-a-z0-9]*[a-z0-9])? which means the first character must be a lowercase + * letter, and all following characters must be a dash, lowercase letter, or digit, except the + * last character, which cannot be a dash. + * + * @see RFC1035 + */ + public String instance() { + return instance; + } + + @Override + public String selfLink() { + return super.selfLink() + "/instances/" + instance; + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return MoreObjects.toStringHelper(this).add("instance", instance); + } + + @Override + public int hashCode() { + return Objects.hash(super.baseHashCode(), instance); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof InstanceId + && baseEquals((InstanceId) obj) + && Objects.equals(instance, ((InstanceId) obj).instance); + } + + @Override + InstanceId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return InstanceId.of(projectId, zone(), instance); + } + + /** + * Returns an instance identity given the zone identity and the instance name. The instance name + * must be 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 + * characters long and match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means + * the first character must be a lowercase letter, and all following characters must be a dash, + * lowercase letter, or digit, except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public static InstanceId of(ZoneId zoneId, String instance) { + return new InstanceId(zoneId.project(), zoneId.zone(), instance); + } + + /** + * Returns an instance identity given the zone and instance names. The instance name must be 1-63 + * characters long, and comply with RFC1035. Specifically, the name must be 1-63 characters long + * and match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first + * character must be a lowercase letter, and all following characters must be a dash, lowercase + * letter, or digit, except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public static InstanceId of(String zone, String instance) { + return new InstanceId(null, zone, instance); + } + + /** + * Returns an instance identity given project, zone and instance names. The instance name must be + * 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 characters + * long and match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first + * character must be a lowercase letter, and all following characters must be a dash, lowercase + * letter, or digit, except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public static InstanceId of(String project, String zone, String instance) { + return new InstanceId(project, zone, instance); + } + + /** + * Returns {@code true} if the provided string matches the expected format of an instance URL. + * Returns {@code false} otherwise. + */ + static boolean matchesUrl(String url) { + return PATTERN.matcher(url).matches(); + } + + static InstanceId fromUrl(String url) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { + throw new IllegalArgumentException(url + " is not a valid instance URL"); + } + return InstanceId.of(matcher.group(1), matcher.group(2), matcher.group(3)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionAddressId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionAddressId.java new file mode 100644 index 000000000000..d3927affed29 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionAddressId.java @@ -0,0 +1,137 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; + +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Identity for a Google Compute Engine region address. + */ +public final class RegionAddressId extends RegionResourceId implements AddressId { + + private static final String REGEX = RegionResourceId.REGEX + "addresses/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); + private static final long serialVersionUID = 8170980880371085238L; + + private final String address; + + private RegionAddressId(String project, String region, String address) { + super(project, region); + this.address = checkNotNull(address); + } + + @Override + public Type type() { + return Type.REGION; + } + + @Override + public String address() { + return address; + } + + @Override + public String selfLink() { + return super.selfLink() + "/addresses/" + address; + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper().add("address", address); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), address); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof RegionAddressId + && baseEquals((RegionAddressId) obj) + && Objects.equals(address, ((RegionAddressId) obj).address); + } + + @Override + RegionAddressId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return RegionAddressId.of(projectId, region(), address); + } + + /** + * Returns a region address identity given the region identity and the address name. The address + * name must be 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 + * characters long and match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means + * the first character must be a lowercase letter, and all following characters must be a dash, + * lowercase letter, or digit, except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public static RegionAddressId of(RegionId regionId, String address) { + return new RegionAddressId(regionId.project(), regionId.region(), address); + } + + /** + * Returns a region address identity given the region and address names. The address name must be + * 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 characters + * long and match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first + * character must be a lowercase letter, and all following characters must be a dash, lowercase + * letter, or digit, except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public static RegionAddressId of(String region, String address) { + return new RegionAddressId(null, region, address); + } + + /** + * Returns a region address identity given project, region and address names. The address name + * must be 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 + * characters long and match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means + * the first character must be a lowercase letter, and all following characters must be a dash, + * lowercase letter, or digit, except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public static RegionAddressId of(String project, String region, String address) { + return new RegionAddressId(project, region, address); + } + + /** + * Returns {@code true} if the provided string matches the expected format of a region address + * URL. Returns {@code false} otherwise. + */ + static boolean matchesUrl(String url) { + return PATTERN.matcher(url).matches(); + } + + static RegionAddressId fromUrl(String url) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { + throw new IllegalArgumentException(url + " is not a valid region address URL"); + } + return RegionAddressId.of(matcher.group(1), matcher.group(2), matcher.group(3)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionForwardingRuleId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionForwardingRuleId.java new file mode 100644 index 000000000000..bbdf0720273e --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionForwardingRuleId.java @@ -0,0 +1,154 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; + +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Identity for a Google Compute Engine region's forwarding rule. + */ +public final class RegionForwardingRuleId extends RegionResourceId implements ForwardingRuleId { + + static final Function FROM_URL_FUNCTION = + new Function() { + @Override + public RegionForwardingRuleId apply(String pb) { + return RegionForwardingRuleId.fromUrl(pb); + } + }; + static final Function TO_URL_FUNCTION = + new Function() { + @Override + public String apply(RegionForwardingRuleId forwardingRuleId) { + return forwardingRuleId.selfLink(); + } + }; + + private static final String REGEX = RegionResourceId.REGEX + "forwardingRules/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); + private static final long serialVersionUID = 7885327931402904667L; + + private final String rule; + + private RegionForwardingRuleId(String project, String region, String rule) { + super(project, region); + this.rule = checkNotNull(rule); + } + + @Override + public Type type() { + return Type.REGION; + } + + @Override + public String rule() { + return rule; + } + + @Override + public String selfLink() { + return super.selfLink() + "/forwardingRules/" + rule; + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return MoreObjects.toStringHelper(this).add("rule", rule); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), rule); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof RegionForwardingRuleId + && baseEquals((RegionForwardingRuleId) obj) + && Objects.equals(rule, ((RegionForwardingRuleId) obj).rule); + } + + @Override + RegionForwardingRuleId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return RegionForwardingRuleId.of(projectId, region(), rule); + } + + /** + * Returns a region forwarding rule identity given the region identity and the rule name. The + * forwarding rule name must be 1-63 characters long, and comply with RFC1035. Specifically, the + * name must be 1-63 characters long and match the regular expression + * {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a lowercase letter, + * and all following characters must be a dash, lowercase letter, or digit, except the last + * character, which cannot be a dash. + * + * @see RFC1035 + */ + public static RegionForwardingRuleId of(RegionId regionId, String operation) { + return new RegionForwardingRuleId(regionId.project(), regionId.region(), operation); + } + + /** + * Returns a region forwarding rule identity given the region and rule names. The forwarding rule + * name must be 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 + * characters long and match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means + * the first character must be a lowercase letter, and all following characters must be a dash, + * lowercase letter, or digit, except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public static RegionForwardingRuleId of(String region, String operation) { + return new RegionForwardingRuleId(null, region, operation); + } + + /** + * Returns a region forwarding rule identity given project, region and rule names. The forwarding + * rule name must be 1-63 characters long, and comply with RFC1035. Specifically, the name must be + * 1-63 characters long and match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which + * means the first character must be a lowercase letter, and all following characters must be a + * dash, lowercase letter, or digit, except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public static RegionForwardingRuleId of(String project, String region, String operation) { + return new RegionForwardingRuleId(project, region, operation); + } + + /** + * Returns {@code true} if the provided string matches the expected format of a region forwarding + * rule URL. Returns {@code false} otherwise. + */ + static boolean matchesUrl(String url) { + return PATTERN.matcher(url).matches(); + } + + static RegionForwardingRuleId fromUrl(String url) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { + throw new IllegalArgumentException(url + " is not a valid region forwarding rule URL"); + } + return RegionForwardingRuleId.of(matcher.group(1), matcher.group(2), matcher.group(3)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/RemoteComputeHelper.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/RemoteComputeHelper.java index 266b31cd7c93..768650111b45 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/RemoteComputeHelper.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/RemoteComputeHelper.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.io.InputStream; +import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; @@ -51,6 +52,14 @@ public ComputeOptions options() { return options; } + /** + * Returns a base name for testing resources generated using a random UUID. This base name can be + * prepended to resource names to prevent name clashes. + */ + public static String baseResourceName() { + return "test-" + UUID.randomUUID().toString().replace("-", "").substring(0, 24) + "-"; + } + /** * Creates a {@code RemoteComputeHelper} object for the given project id and JSON key input * stream. diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java index 740ad73b5b2e..2f08c2702264 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java @@ -16,11 +16,18 @@ package com.google.gcloud.spi; +import com.google.api.services.compute.model.Address; +import com.google.api.services.compute.model.DeprecationStatus; +import com.google.api.services.compute.model.Disk; import com.google.api.services.compute.model.DiskType; +import com.google.api.services.compute.model.Image; import com.google.api.services.compute.model.License; import com.google.api.services.compute.model.MachineType; +import com.google.api.services.compute.model.Network; import com.google.api.services.compute.model.Operation; import com.google.api.services.compute.model.Region; +import com.google.api.services.compute.model.Snapshot; +import com.google.api.services.compute.model.Subnetwork; import com.google.api.services.compute.model.Zone; import com.google.gcloud.compute.ComputeException; @@ -228,4 +235,73 @@ public Y y() { * @throws ComputeException upon failure */ boolean deleteZoneOperation(String zone, String operation); + + /** + * Returns the requested global address or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + Address getGlobalAddress(String address, Map options); + + /** + * Creates a new global address. + * + * @return a global operation for global address' creation + * @throws ComputeException upon failure + */ + Operation createGlobalAddress(Address address, Map options); + + /** + * Lists the global addresses. + * + * @throws ComputeException upon failure + */ + Tuple> listGlobalAddresses(Map options); + + /** + * Deletes the requested global address. + * + * @return a global operation if request was issued correctly, {@code null} if the address was not + * found + * @throws ComputeException upon failure + */ + Operation deleteGlobalAddress(String address, Map options); + + /** + * Returns the requested region address or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + Address getRegionAddress(String region, String address, Map options); + + /** + * Creates a new region address. + * + * @return a region operation for region address' creation + * @throws ComputeException upon failure + */ + Operation createRegionAddress(String region, Address address, Map options); + + /** + * Lists the regions addresses for the provided region. + * + * @throws ComputeException upon failure + */ + Tuple> listRegionAddresses(String region, Map options); + + /** + * Lists all addressest. + * + * @throws ComputeException upon failure + */ + Tuple> listAddresses(Map options); + + /** + * Deletes the requested region address. + * + * @return a region operation if request was issued correctly, {@code null} if the address was not + * found + * @throws ComputeException upon failure + */ + Operation deleteRegionAddress(String region, String address, Map options); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java index 3209084a5983..78100f1c3c1f 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java @@ -26,6 +26,10 @@ import com.google.api.client.http.HttpTransport; import com.google.api.client.json.jackson.JacksonFactory; import com.google.api.services.compute.Compute; +import com.google.api.services.compute.model.Address; +import com.google.api.services.compute.model.AddressAggregatedList; +import com.google.api.services.compute.model.AddressList; +import com.google.api.services.compute.model.AddressesScopedList; import com.google.api.services.compute.model.DiskType; import com.google.api.services.compute.model.DiskTypeAggregatedList; import com.google.api.services.compute.model.DiskTypeList; @@ -285,7 +289,7 @@ public boolean deleteGlobalOperation(String operation) { compute.globalOperations().delete(this.options.projectId(), operation).execute(); return true; } catch (IOException ex) { - return nullForNotFound(ex); + return falseForNotFound(ex); } } @@ -325,7 +329,7 @@ public boolean deleteRegionOperation(String region, String operation) { compute.regionOperations().delete(this.options.projectId(), region, operation).execute(); return true; } catch (IOException ex) { - return nullForNotFound(ex); + return falseForNotFound(ex); } } @@ -364,6 +368,140 @@ public boolean deleteZoneOperation(String zone, String operation) { try { compute.zoneOperations().delete(this.options.projectId(), zone, operation).execute(); return true; + } catch (IOException ex) { + return falseForNotFound(ex); + } + } + + @Override + public Address getGlobalAddress(String address, Map options) { + try { + return compute.globalAddresses() + .get(this.options.projectId(), address) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Operation createGlobalAddress(Address address, Map options) { + try { + return compute.globalAddresses() + .insert(this.options.projectId(), address) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Tuple> listGlobalAddresses(Map options) { + try { + AddressList addressList = compute.globalAddresses() + .list(this.options.projectId()) + .setFilter(FILTER.getString(options)) + .setMaxResults(MAX_RESULTS.getLong(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + .setFields(FIELDS.getString(options)) + .execute(); + Iterable
    operations = addressList.getItems(); + return Tuple.of(addressList.getNextPageToken(), operations); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Operation deleteGlobalAddress(String address, Map options) { + try { + return compute.globalAddresses() + .delete(this.options.projectId(), address) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Address getRegionAddress(String region, String address, Map options) { + try { + return compute.addresses() + .get(this.options.projectId(), region, address) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Operation createRegionAddress(String region, Address address, Map options) { + try { + return compute.addresses() + .insert(this.options.projectId(), region, address) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Tuple> listRegionAddresses(String region, + Map options) { + try { + AddressList addressList = compute.addresses() + .list(this.options.projectId(), region) + .setFilter(FILTER.getString(options)) + .setMaxResults(MAX_RESULTS.getLong(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + .setFields(FIELDS.getString(options)) + .execute(); + Iterable
    operations = addressList.getItems(); + return Tuple.of(addressList.getNextPageToken(), operations); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Tuple> listAddresses(Map options) { + try { + AddressAggregatedList aggregatedList = compute.addresses() + .aggregatedList(this.options.projectId()) + .setFilter(FILTER.getString(options)) + .setMaxResults(MAX_RESULTS.getLong(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + // todo(mziccard): uncomment or remove once #711 is closed + // .setFields(FIELDS.getString(options)) + .execute(); + ImmutableList.Builder
    builder = ImmutableList.builder(); + Map scopedList = aggregatedList.getItems(); + if (scopedList != null) { + for (AddressesScopedList addressesScopedList : scopedList.values()) { + if (addressesScopedList.getAddresses() != null) { + builder.addAll(addressesScopedList.getAddresses()); + } + } + } + return Tuple.>of(aggregatedList.getNextPageToken(), + builder.build()); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Operation deleteRegionAddress(String region, String address, Map options) { + try { + return compute.addresses() + .delete(this.options.projectId(), region, address) + .setFields(FIELDS.getString(options)) + .execute(); } catch (IOException ex) { return nullForNotFound(ex); } @@ -382,4 +520,18 @@ private static T nullForNotFound(IOException exception) { } throw serviceException; } + + /** + * This method returns {@code false} if the error code of {@code exception} was 404, re-throws the + * exception otherwise. + * + * @throws ComputeException if the error code of {@code exception} was not 404 + */ + private static boolean falseForNotFound(IOException exception) { + ComputeException serviceException = translate(exception); + if (serviceException.code() == HTTP_NOT_FOUND) { + return false; + } + throw serviceException; + } } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressIdTest.java new file mode 100644 index 000000000000..2d3e1a63c613 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressIdTest.java @@ -0,0 +1,114 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class AddressIdTest { + + private static final String PROJECT = "project"; + private static final String REGION = "region"; + private static final String NAME = "addr"; + private static final String GLOBAL_URL = + "https://www.googleapis.com/compute/v1/projects/project/global/addresses/addr"; + private static final String REGION_URL = + "https://www.googleapis.com/compute/v1/projects/project/regions/region/addresses/addr"; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testOf() { + GlobalAddressId addressId = GlobalAddressId.of(PROJECT, NAME); + assertEquals(PROJECT, addressId.project()); + assertEquals(NAME, addressId.address()); + assertEquals(GLOBAL_URL, addressId.selfLink()); + addressId = GlobalAddressId.of(NAME); + assertNull(addressId.project()); + assertEquals(NAME, addressId.address()); + RegionAddressId regionAddressId = RegionAddressId.of(PROJECT, REGION, NAME); + assertEquals(PROJECT, regionAddressId.project()); + assertEquals(REGION, regionAddressId.region()); + assertEquals(NAME, regionAddressId.address()); + assertEquals(REGION_URL, regionAddressId.selfLink()); + regionAddressId = RegionAddressId.of(RegionId.of(PROJECT, REGION), NAME); + assertEquals(PROJECT, regionAddressId.project()); + assertEquals(REGION, regionAddressId.region()); + assertEquals(NAME, regionAddressId.address()); + assertEquals(REGION_URL, regionAddressId.selfLink()); + regionAddressId = RegionAddressId.of(REGION, NAME); + assertNull(regionAddressId.project()); + assertEquals(REGION, regionAddressId.region()); + assertEquals(NAME, regionAddressId.address()); + } + + @Test + public void testToAndFromUrl() { + GlobalAddressId addressId = GlobalAddressId.of(PROJECT, NAME); + compareAddressId(addressId, GlobalAddressId.fromUrl(addressId.selfLink())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid global address URL"); + GlobalAddressId.fromUrl("notMatchingUrl"); + RegionAddressId regionAddressId = RegionAddressId.of(PROJECT, REGION, NAME); + compareRegionAddressId(regionAddressId, RegionAddressId.fromUrl(regionAddressId.selfLink())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid global address URL"); + RegionAddressId.fromUrl("notMatchingUrl"); + } + + @Test + public void testSetProjectId() { + GlobalAddressId addressId = GlobalAddressId.of(PROJECT, NAME); + assertSame(addressId, addressId.setProjectId(PROJECT)); + compareAddressId(addressId, GlobalAddressId.of(NAME).setProjectId(PROJECT)); + RegionAddressId regionAddressId = RegionAddressId.of(PROJECT, REGION, NAME); + compareRegionAddressId(regionAddressId, RegionAddressId.of(REGION, NAME).setProjectId(PROJECT)); + } + + @Test + public void testMatchesUrl() { + assertTrue(GlobalAddressId.matchesUrl(GlobalAddressId.of(PROJECT, NAME).selfLink())); + assertFalse(GlobalAddressId.matchesUrl("notMatchingUrl")); + assertTrue(RegionAddressId.matchesUrl(RegionAddressId.of(PROJECT, REGION, NAME).selfLink())); + assertFalse(RegionAddressId.matchesUrl("notMatchingUrl")); + } + + private void compareAddressId(GlobalAddressId expected, GlobalAddressId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.address(), expected.address()); + assertEquals(expected.selfLink(), expected.selfLink()); + assertEquals(expected.hashCode(), expected.hashCode()); + } + + private void compareRegionAddressId(RegionAddressId expected, RegionAddressId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.region(), expected.region()); + assertEquals(expected.address(), expected.address()); + assertEquals(expected.selfLink(), expected.selfLink()); + assertEquals(expected.hashCode(), expected.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressInfoTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressInfoTest.java new file mode 100644 index 000000000000..cb4ba3678c30 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressInfoTest.java @@ -0,0 +1,201 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import com.google.common.collect.ImmutableList; +import com.google.gcloud.compute.AddressInfo.GlobalForwardingUsage; +import com.google.gcloud.compute.AddressInfo.InstanceUsage; +import com.google.gcloud.compute.AddressInfo.RegionForwardingUsage; + +import org.junit.Test; + +import java.util.List; + +public class AddressInfoTest { + + private static final String ADDRESS = "192.168.1.1"; + private static final Long CREATION_TIMESTAMP = 1452602400000L; + private static final String DESCRIPTION = "description"; + private static final String ID = "42"; + private static final GlobalAddressId GLOBAL_ADDRESS_ID = GlobalAddressId.of("project", "address"); + private static final RegionAddressId REGION_ADDRESS_ID = + RegionAddressId.of("project", "region", "address"); + private static final AddressInfo.Status STATUS = AddressInfo.Status.RESERVED; + private static final List GLOBAL_FORWARDING_RULES = + ImmutableList.of(GlobalForwardingRuleId.of("project", "forwardingRule1"), + GlobalForwardingRuleId.of("project", "forwardingRule2")); + private static final List REGION_FORWARDING_RULES = + ImmutableList.of(RegionForwardingRuleId.of("project", "region", "forwardingRule1"), + RegionForwardingRuleId.of("project", "region", "forwardingRule2")); + private static final InstanceUsage INSTANCE_USAGE = + new InstanceUsage(InstanceId.of("project", "zone", "instance1")); + private static final GlobalForwardingUsage GLOBAL_FORWARDING_USAGE = + new GlobalForwardingUsage(GLOBAL_FORWARDING_RULES); + private static final RegionForwardingUsage REGION_FORWARDING_USAGE = + new RegionForwardingUsage(REGION_FORWARDING_RULES); + private static final AddressInfo INSTANCE_ADDRESS_INFO = AddressInfo.builder(REGION_ADDRESS_ID) + .address(ADDRESS) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .id(ID) + .status(STATUS) + .usage(INSTANCE_USAGE) + .build(); + private static final AddressInfo GLOBAL_FORWARDING_ADDRESS_INFO = + AddressInfo.builder(GLOBAL_ADDRESS_ID) + .address(ADDRESS) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .id(ID) + .status(STATUS) + .usage(GLOBAL_FORWARDING_USAGE) + .build(); + private static final AddressInfo REGION_FORWARDING_ADDRESS_INFO = + AddressInfo.builder(REGION_ADDRESS_ID) + .address(ADDRESS) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .id(ID) + .status(STATUS) + .usage(REGION_FORWARDING_USAGE) + .build(); + + @Test + public void testToBuilder() { + compareAddressInfo(INSTANCE_ADDRESS_INFO, INSTANCE_ADDRESS_INFO.toBuilder().build()); + AddressInfo addressInfo = INSTANCE_ADDRESS_INFO.toBuilder() + .address("192.168.1.2") + .description("description2") + .build(); + assertEquals("description2", addressInfo.description()); + assertEquals("192.168.1.2", addressInfo.address()); + addressInfo = addressInfo.toBuilder() + .address("192.168.1.1") + .description("description") + .build(); + compareAddressInfo(INSTANCE_ADDRESS_INFO, addressInfo); + } + + @Test + public void testToBuilderIncomplete() { + AddressInfo addressInfo = AddressInfo.builder(GLOBAL_ADDRESS_ID).build(); + assertEquals(addressInfo, addressInfo.toBuilder().build()); + addressInfo = AddressInfo.builder(REGION_ADDRESS_ID).build(); + assertEquals(addressInfo, addressInfo.toBuilder().build()); + } + + @Test + public void testBuilder() { + assertEquals(ADDRESS, INSTANCE_ADDRESS_INFO.address()); + assertEquals(CREATION_TIMESTAMP, INSTANCE_ADDRESS_INFO.creationTimestamp()); + assertEquals(DESCRIPTION, INSTANCE_ADDRESS_INFO.description()); + assertEquals(ID, INSTANCE_ADDRESS_INFO.id()); + assertEquals(REGION_ADDRESS_ID, INSTANCE_ADDRESS_INFO.addressId()); + assertEquals(STATUS, INSTANCE_ADDRESS_INFO.status()); + assertEquals(INSTANCE_USAGE, INSTANCE_ADDRESS_INFO.usage()); + assertEquals(INSTANCE_USAGE.instance(), + INSTANCE_ADDRESS_INFO.usage().instance()); + assertEquals(ADDRESS, REGION_FORWARDING_ADDRESS_INFO.address()); + assertEquals(CREATION_TIMESTAMP, REGION_FORWARDING_ADDRESS_INFO.creationTimestamp()); + assertEquals(DESCRIPTION, REGION_FORWARDING_ADDRESS_INFO.description()); + assertEquals(ID, REGION_FORWARDING_ADDRESS_INFO.id()); + assertEquals(REGION_ADDRESS_ID, REGION_FORWARDING_ADDRESS_INFO.addressId()); + assertEquals(STATUS, REGION_FORWARDING_ADDRESS_INFO.status()); + assertEquals(REGION_FORWARDING_USAGE, REGION_FORWARDING_ADDRESS_INFO.usage()); + assertEquals(REGION_FORWARDING_RULES, + REGION_FORWARDING_ADDRESS_INFO.usage().forwardingRules()); + assertEquals(ADDRESS, GLOBAL_FORWARDING_ADDRESS_INFO.address()); + assertEquals(CREATION_TIMESTAMP, GLOBAL_FORWARDING_ADDRESS_INFO.creationTimestamp()); + assertEquals(DESCRIPTION, GLOBAL_FORWARDING_ADDRESS_INFO.description()); + assertEquals(ID, GLOBAL_FORWARDING_ADDRESS_INFO.id()); + assertEquals(GLOBAL_ADDRESS_ID, GLOBAL_FORWARDING_ADDRESS_INFO.addressId()); + assertEquals(STATUS, GLOBAL_FORWARDING_ADDRESS_INFO.status()); + assertEquals(GLOBAL_FORWARDING_USAGE, GLOBAL_FORWARDING_ADDRESS_INFO.usage()); + assertEquals(GLOBAL_FORWARDING_RULES, + GLOBAL_FORWARDING_ADDRESS_INFO.usage().forwardingRules()); + } + + @Test + public void testOf() { + AddressInfo addressInfo = AddressInfo.of("address"); + assertEquals(GlobalAddressId.of("address"), addressInfo.addressId()); + assertNull(addressInfo.address()); + assertNull(addressInfo.creationTimestamp()); + assertNull(addressInfo.description()); + assertNull(addressInfo.id()); + assertNull(addressInfo.status()); + assertNull(addressInfo.usage()); + addressInfo = AddressInfo.of(GLOBAL_ADDRESS_ID); + assertEquals(GLOBAL_ADDRESS_ID, addressInfo.addressId()); + assertNull(addressInfo.address()); + assertNull(addressInfo.creationTimestamp()); + assertNull(addressInfo.description()); + assertNull(addressInfo.id()); + assertNull(addressInfo.status()); + assertNull(addressInfo.usage()); + addressInfo = AddressInfo.of("region", "address"); + assertEquals(RegionAddressId.of("region", "address"), addressInfo.addressId()); + assertNull(addressInfo.address()); + assertNull(addressInfo.creationTimestamp()); + assertNull(addressInfo.description()); + assertNull(addressInfo.id()); + assertNull(addressInfo.status()); + assertNull(addressInfo.usage()); + addressInfo = AddressInfo.of(RegionId.of("region"), "address"); + assertEquals(RegionAddressId.of("region", "address"), addressInfo.addressId()); + assertNull(addressInfo.address()); + assertNull(addressInfo.creationTimestamp()); + assertNull(addressInfo.description()); + assertNull(addressInfo.id()); + assertNull(addressInfo.status()); + assertNull(addressInfo.usage()); + } + + @Test + public void testToPbAndFromPb() { + compareAddressInfo(INSTANCE_ADDRESS_INFO, AddressInfo.fromPb(INSTANCE_ADDRESS_INFO.toPb())); + compareAddressInfo(REGION_FORWARDING_ADDRESS_INFO, + AddressInfo.fromPb(REGION_FORWARDING_ADDRESS_INFO.toPb())); + compareAddressInfo(GLOBAL_FORWARDING_ADDRESS_INFO, + AddressInfo.fromPb(GLOBAL_FORWARDING_ADDRESS_INFO.toPb())); + AddressInfo addressInfo = AddressInfo.builder(GLOBAL_ADDRESS_ID).build(); + compareAddressInfo(addressInfo, AddressInfo.fromPb(addressInfo.toPb())); + } + + @Test + public void testSetProjectId() { + AddressInfo addressInfo = GLOBAL_FORWARDING_ADDRESS_INFO.toBuilder() + .addressId(GlobalAddressId.of(GLOBAL_ADDRESS_ID.address())) + .build(); + compareAddressInfo(GLOBAL_FORWARDING_ADDRESS_INFO, addressInfo.setProjectId("project")); + } + + private void compareAddressInfo(AddressInfo expected, AddressInfo value) { + assertEquals(expected, value); + assertEquals(expected.address(), value.address()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.id(), value.id()); + assertEquals(expected.addressId(), value.addressId()); + assertEquals(expected.usage(), value.usage()); + assertEquals(expected.status(), value.status()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressTest.java new file mode 100644 index 000000000000..d6082343b2d3 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressTest.java @@ -0,0 +1,284 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.createStrictMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import com.google.common.collect.ImmutableList; + +import org.junit.After; +import org.junit.Test; + +import java.math.BigInteger; +import java.util.List; + +public class AddressTest { + + private static final String ADDRESS = "192.168.1.1"; + private static final Long CREATION_TIMESTAMP = 1452602400000L; + private static final String DESCRIPTION = "description"; + private static final String ID = "42"; + private static final GlobalAddressId GLOBAL_ADDRESS_ID = GlobalAddressId.of("project", "address"); + private static final RegionAddressId REGION_ADDRESS_ID = + RegionAddressId.of("project", "region", "address"); + private static final AddressInfo.Status STATUS = AddressInfo.Status.RESERVED; + private static final List GLOBAL_FORWARDING_RULES = + ImmutableList.of(GlobalForwardingRuleId.of("project", "forwardingRule1"), + GlobalForwardingRuleId.of("project", "forwardingRule2")); + private static final List REGION_FORWARDING_RULES = + ImmutableList.of(RegionForwardingRuleId.of("project", "region", "forwardingRule1"), + RegionForwardingRuleId.of("project", "region", "forwardingRule2")); + private static final AddressInfo.InstanceUsage INSTANCE_USAGE = + new AddressInfo.InstanceUsage(InstanceId.of("project", "zone", "instance1")); + private static final AddressInfo.GlobalForwardingUsage GLOBAL_FORWARDING_USAGE = + new AddressInfo.GlobalForwardingUsage(GLOBAL_FORWARDING_RULES); + private static final AddressInfo.RegionForwardingUsage REGION_FORWARDING_USAGE = + new AddressInfo.RegionForwardingUsage(REGION_FORWARDING_RULES); + + private Compute serviceMockReturnsOptions = createStrictMock(Compute.class); + private ComputeOptions mockOptions = createMock(ComputeOptions.class); + private Compute compute; + private Address globalForwardingAddress; + private Address instanceAddress; + private Address regionForwardingAddress; + private Address address; + + private void initializeExpectedAddress(int optionsCalls) { + expect(serviceMockReturnsOptions.options()).andReturn(mockOptions).times(optionsCalls); + replay(serviceMockReturnsOptions); + instanceAddress = new Address.Builder(serviceMockReturnsOptions, REGION_ADDRESS_ID) + .address(ADDRESS) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .id(ID) + .status(STATUS) + .usage(INSTANCE_USAGE) + .build(); + globalForwardingAddress = new Address.Builder(serviceMockReturnsOptions, GLOBAL_ADDRESS_ID) + .address(ADDRESS) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .id(ID) + .status(STATUS) + .usage(GLOBAL_FORWARDING_USAGE) + .build(); + regionForwardingAddress = new Address.Builder(serviceMockReturnsOptions, REGION_ADDRESS_ID) + .address(ADDRESS) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .id(ID) + .status(STATUS) + .usage(REGION_FORWARDING_USAGE) + .build(); + compute = createStrictMock(Compute.class); + } + + private void initializeAddress() { + address = new Address.Builder(compute, REGION_ADDRESS_ID) + .address(ADDRESS) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .id(ID) + .status(STATUS) + .usage(REGION_FORWARDING_USAGE) + .build(); + } + + @After + public void tearDown() throws Exception { + verify(serviceMockReturnsOptions); + } + + @Test + public void testBuilder() { + initializeExpectedAddress(5); + assertEquals(ADDRESS, instanceAddress.address()); + assertEquals(CREATION_TIMESTAMP, instanceAddress.creationTimestamp()); + assertEquals(DESCRIPTION, instanceAddress.description()); + assertEquals(ID, instanceAddress.id()); + assertEquals(REGION_ADDRESS_ID, instanceAddress.addressId()); + assertEquals(STATUS, instanceAddress.status()); + assertEquals(INSTANCE_USAGE, instanceAddress.usage()); + assertSame(serviceMockReturnsOptions, instanceAddress.compute()); + assertEquals(ADDRESS, regionForwardingAddress.address()); + assertEquals(CREATION_TIMESTAMP, regionForwardingAddress.creationTimestamp()); + assertEquals(DESCRIPTION, regionForwardingAddress.description()); + assertEquals(ID, regionForwardingAddress.id()); + assertEquals(REGION_ADDRESS_ID, regionForwardingAddress.addressId()); + assertEquals(STATUS, regionForwardingAddress.status()); + assertEquals(REGION_FORWARDING_USAGE, regionForwardingAddress.usage()); + assertSame(serviceMockReturnsOptions, regionForwardingAddress.compute()); + assertEquals(ADDRESS, globalForwardingAddress.address()); + assertEquals(CREATION_TIMESTAMP, globalForwardingAddress.creationTimestamp()); + assertEquals(DESCRIPTION, globalForwardingAddress.description()); + assertEquals(ID, globalForwardingAddress.id()); + assertEquals(GLOBAL_ADDRESS_ID, globalForwardingAddress.addressId()); + assertEquals(STATUS, globalForwardingAddress.status()); + assertEquals(GLOBAL_FORWARDING_USAGE, globalForwardingAddress.usage()); + assertSame(serviceMockReturnsOptions, globalForwardingAddress.compute()); + Address address = new Address.Builder(serviceMockReturnsOptions, GLOBAL_ADDRESS_ID).build(); + assertEquals(GLOBAL_ADDRESS_ID, address.addressId()); + assertSame(serviceMockReturnsOptions, address.compute()); + assertNull(address.address()); + assertNull(address.creationTimestamp()); + assertNull(address.description()); + assertNull(address.id()); + assertNull(address.status()); + assertNull(address.usage()); + address = new Address.Builder(serviceMockReturnsOptions, REGION_ADDRESS_ID).build(); + assertEquals(REGION_ADDRESS_ID, address.addressId()); + assertSame(serviceMockReturnsOptions, address.compute()); + assertNull(address.address()); + assertNull(address.creationTimestamp()); + assertNull(address.description()); + assertNull(address.id()); + assertNull(address.status()); + assertNull(address.usage()); + } + + @Test + public void testToBuilder() { + initializeExpectedAddress(16); + compareAddress(instanceAddress, instanceAddress.toBuilder().build()); + compareAddress(globalForwardingAddress, globalForwardingAddress.toBuilder().build()); + compareAddress(regionForwardingAddress, regionForwardingAddress.toBuilder().build()); + Address newAddress = instanceAddress.toBuilder().description("newDescription").build(); + assertEquals("newDescription", newAddress.description()); + newAddress = newAddress.toBuilder().description("description").build(); + compareAddress(instanceAddress, newAddress); + } + + @Test + public void testToAndFromPb() { + initializeExpectedAddress(20); + compareAddress(globalForwardingAddress, + Address.fromPb(serviceMockReturnsOptions, globalForwardingAddress.toPb())); + compareAddress(regionForwardingAddress, + Address.fromPb(serviceMockReturnsOptions, regionForwardingAddress.toPb())); + compareAddress(instanceAddress, + Address.fromPb(serviceMockReturnsOptions, instanceAddress.toPb())); + Address address = new Address.Builder(serviceMockReturnsOptions, GLOBAL_ADDRESS_ID).build(); + compareAddress(address, Address.fromPb(serviceMockReturnsOptions, address.toPb())); + address = new Address.Builder(serviceMockReturnsOptions, REGION_ADDRESS_ID).build(); + compareAddress(address, Address.fromPb(serviceMockReturnsOptions, address.toPb())); + } + + @Test + public void testDeleteOperation() { + initializeExpectedAddress(4); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(GlobalOperationId.of("project", "op")) + .build(); + expect(compute.delete(REGION_ADDRESS_ID)).andReturn(operation); + replay(compute); + initializeAddress(); + assertSame(operation, address.delete()); + } + + @Test + public void testDeleteNull() { + initializeExpectedAddress(3); + expect(compute.options()).andReturn(mockOptions); + expect(compute.delete(REGION_ADDRESS_ID)).andReturn(null); + replay(compute); + initializeAddress(); + assertNull(address.delete()); + } + + @Test + public void testExists_True() throws Exception { + initializeExpectedAddress(3); + Compute.AddressOption[] expectedOptions = {Compute.AddressOption.fields()}; + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(REGION_ADDRESS_ID, expectedOptions)).andReturn(regionForwardingAddress); + replay(compute); + initializeAddress(); + assertTrue(address.exists()); + verify(compute); + } + + @Test + public void testExists_False() throws Exception { + initializeExpectedAddress(3); + Compute.AddressOption[] expectedOptions = {Compute.AddressOption.fields()}; + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(REGION_ADDRESS_ID, expectedOptions)).andReturn(null); + replay(compute); + initializeAddress(); + assertFalse(address.exists()); + verify(compute); + } + + @Test + public void testReload() throws Exception { + initializeExpectedAddress(5); + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(REGION_ADDRESS_ID)).andReturn(regionForwardingAddress); + replay(compute); + initializeAddress(); + Address updatedAddress = address.reload(); + compareAddress(regionForwardingAddress, updatedAddress); + verify(compute); + } + + @Test + public void testReloadNull() throws Exception { + initializeExpectedAddress(3); + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(REGION_ADDRESS_ID)).andReturn(null); + replay(compute); + initializeAddress(); + assertNull(address.reload()); + verify(compute); + } + + @Test + public void testReloadWithOptions() throws Exception { + initializeExpectedAddress(5); + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(REGION_ADDRESS_ID, Compute.AddressOption.fields())) + .andReturn(regionForwardingAddress); + replay(compute); + initializeAddress(); + Address updatedAddress = address.reload(Compute.AddressOption.fields()); + compareAddress(regionForwardingAddress, updatedAddress); + verify(compute); + } + + private void compareAddress(Address expected, Address value) { + assertEquals(expected, value); + assertEquals(expected.compute().options(), value.compute().options()); + assertEquals(expected.address(), value.address()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.id(), value.id()); + assertEquals(expected.addressId(), value.addressId()); + assertEquals(expected.usage(), value.usage()); + assertEquals(expected.status(), value.status()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java index e1a81b5afe48..3026bfcc8d40 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Google Inc. All Rights Reserved. + * Copyright 2016 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -174,6 +174,12 @@ public class ComputeImplTest { ZoneOperationId.of("project", "zone", "op"); private static final RegionOperationId REGION_OPERATION_ID = RegionOperationId.of("project", "region", "op"); + private static final RegionAddressId REGION_ADDRESS_ID = + RegionAddressId.of("project", "region", "address"); + private static final GlobalAddressId GLOBAL_ADDRESS_ID = + GlobalAddressId.of("project", "address"); + private static final AddressInfo REGION_ADDRESS = AddressInfo.builder(REGION_ADDRESS_ID).build(); + private static final AddressInfo GLOBAL_ADDRESS = AddressInfo.builder(GLOBAL_ADDRESS_ID).build(); // Empty ComputeRpc options private static final Map EMPTY_RPC_OPTIONS = ImmutableMap.of(); @@ -187,7 +193,7 @@ public class ComputeImplTest { DiskTypeFilter.equals(Compute.DiskTypeField.DESCRIPTION, "someDescription"); private static final DiskTypeListOption DISK_TYPE_LIST_PAGE_TOKEN = DiskTypeListOption.startPageToken("cursor"); - private static final DiskTypeListOption DISK_TYPE_LIST_MAX_RESULTS = + private static final DiskTypeListOption DISK_TYPE_LIST_PAGE_SIZE = DiskTypeListOption.pageSize(42L); private static final DiskTypeListOption DISK_TYPE_LIST_FILTER = DiskTypeListOption.filter(DISK_TYPE_FILTER); @@ -199,7 +205,7 @@ public class ComputeImplTest { // DiskType aggregated list options private static final DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_PAGE_TOKEN = DiskTypeAggregatedListOption.startPageToken("cursor"); - private static final DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_MAX_RESULTS = + private static final DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_PAGE_SIZE = DiskTypeAggregatedListOption.pageSize(42L); private static final DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_FILTER = DiskTypeAggregatedListOption.filter(DISK_TYPE_FILTER); @@ -214,7 +220,7 @@ public class ComputeImplTest { MachineTypeFilter.notEquals(Compute.MachineTypeField.MAXIMUM_PERSISTENT_DISKS, 42L); private static final MachineTypeListOption MACHINE_TYPE_LIST_PAGE_TOKEN = MachineTypeListOption.startPageToken("cursor"); - private static final MachineTypeListOption MACHINE_TYPE_LIST_MAX_RESULTS = + private static final MachineTypeListOption MACHINE_TYPE_LIST_PAGE_SIZE = MachineTypeListOption.pageSize(42L); private static final MachineTypeListOption MACHINE_TYPE_LIST_FILTER = MachineTypeListOption.filter(MACHINE_TYPE_FILTER); @@ -226,7 +232,7 @@ public class ComputeImplTest { // MachineType aggregated list options private static final MachineTypeAggregatedListOption MACHINE_TYPE_AGGREGATED_LIST_PAGE_TOKEN = MachineTypeAggregatedListOption.startPageToken("cursor"); - private static final MachineTypeAggregatedListOption MACHINE_TYPE_AGGREGATED_LIST_MAX_RESULTS = + private static final MachineTypeAggregatedListOption MACHINE_TYPE_AGGREGATED_LIST_PAGE_SIZE = MachineTypeAggregatedListOption.pageSize(42L); private static final MachineTypeAggregatedListOption MACHINE_TYPE_AGGREGATED_LIST_FILTER = MachineTypeAggregatedListOption.filter(MACHINE_TYPE_FILTER); @@ -240,7 +246,7 @@ public class ComputeImplTest { RegionFilter.equals(Compute.RegionField.ID, "someId"); private static final RegionListOption REGION_LIST_PAGE_TOKEN = RegionListOption.startPageToken("cursor"); - private static final RegionListOption REGION_LIST_MAX_RESULTS = + private static final RegionListOption REGION_LIST_PAGE_SIZE = RegionListOption.pageSize(42L); private static final RegionListOption REGION_LIST_FILTER = RegionListOption.filter(REGION_FILTER); @@ -258,7 +264,7 @@ public class ComputeImplTest { ZoneFilter.notEquals(Compute.ZoneField.NAME, "someName"); private static final ZoneListOption ZONE_LIST_PAGE_TOKEN = ZoneListOption.startPageToken("cursor"); - private static final ZoneListOption ZONE_LIST_MAX_RESULTS = ZoneListOption.pageSize(42L); + private static final ZoneListOption ZONE_LIST_PAGE_SIZE = ZoneListOption.pageSize(42L); private static final ZoneListOption ZONE_LIST_FILTER = ZoneListOption.filter(ZONE_FILTER); private static final Map ZONE_LIST_OPTIONS = ImmutableMap.of( PAGE_TOKEN, "cursor", @@ -278,7 +284,7 @@ public class ComputeImplTest { OperationFilter.notEquals(Compute.OperationField.PROGRESS, 0); private static final OperationListOption OPERATION_LIST_PAGE_TOKEN = OperationListOption.startPageToken("cursor"); - private static final OperationListOption OPERATION_LIST_MAX_RESULTS = + private static final OperationListOption OPERATION_LIST_PAGE_SIZE = OperationListOption.pageSize(42L); private static final OperationListOption OPERATION_LIST_FILTER = OperationListOption.filter(OPERATION_FILTER); @@ -287,6 +293,32 @@ public class ComputeImplTest { MAX_RESULTS, 42L, FILTER, "progress ne 0"); + // Address options + private static final Compute.AddressOption ADDRESS_OPTION_FIELDS = + Compute.AddressOption.fields(Compute.AddressField.ID, Compute.AddressField.DESCRIPTION); + + // Address list options + private static final Compute.AddressFilter ADDRESS_FILTER = + Compute.AddressFilter.notEquals(Compute.AddressField.REGION, "someRegion"); + private static final Compute.AddressListOption ADDRESS_LIST_PAGE_TOKEN = + Compute.AddressListOption.startPageToken("cursor"); + private static final Compute.AddressListOption ADDRESS_LIST_PAGE_SIZE = + Compute.AddressListOption.pageSize(42L); + private static final Compute.AddressListOption ADDRESS_LIST_FILTER = + Compute.AddressListOption.filter(ADDRESS_FILTER); + private static final Map ADDRESS_LIST_OPTIONS = ImmutableMap.of( + PAGE_TOKEN, "cursor", + MAX_RESULTS, 42L, + FILTER, "region ne someRegion"); + + // Address aggregated list options + private static final Compute.AddressAggregatedListOption ADDRESS_AGGREGATED_LIST_PAGE_TOKEN = + Compute.AddressAggregatedListOption.startPageToken("cursor"); + private static final Compute.AddressAggregatedListOption ADDRESS_AGGREGATED_LIST_PAGE_SIZE = + Compute.AddressAggregatedListOption.pageSize(42L); + private static final Compute.AddressAggregatedListOption ADDRESS_AGGREGATED_LIST_FILTER = + Compute.AddressAggregatedListOption.filter(ADDRESS_FILTER); + private ComputeOptions options; private ComputeRpcFactory rpcFactoryMock; private ComputeRpc computeRpcMock; @@ -494,7 +526,7 @@ public void testListDiskTypesWithOptions() { EasyMock.expect(computeRpcMock.listDiskTypes(DISK_TYPE_ID.zone(), DISK_TYPE_LIST_OPTIONS)) .andReturn(result); EasyMock.replay(computeRpcMock); - Page page = compute.listDiskTypes(DISK_TYPE_ID.zone(), DISK_TYPE_LIST_MAX_RESULTS, + Page page = compute.listDiskTypes(DISK_TYPE_ID.zone(), DISK_TYPE_LIST_PAGE_SIZE, DISK_TYPE_LIST_PAGE_TOKEN, DISK_TYPE_LIST_FILTER); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(diskTypeList.toArray(), Iterables.toArray(page.values(), DiskType.class)); @@ -559,7 +591,7 @@ public void testAggregatedListDiskTypesWithOptions() { Tuple.of(cursor, Iterables.transform(diskTypeList, DiskType.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listDiskTypes(DISK_TYPE_LIST_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); - Page page = compute.listDiskTypes(DISK_TYPE_AGGREGATED_LIST_MAX_RESULTS, + Page page = compute.listDiskTypes(DISK_TYPE_AGGREGATED_LIST_PAGE_SIZE, DISK_TYPE_AGGREGATED_LIST_PAGE_TOKEN, DISK_TYPE_AGGREGATED_LIST_FILTER); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(diskTypeList.toArray(), Iterables.toArray(page.values(), DiskType.class)); @@ -679,7 +711,7 @@ public void testListMachineTypesWithOptions() { .andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listMachineTypes(MACHINE_TYPE_ID.zone(), - MACHINE_TYPE_LIST_MAX_RESULTS, MACHINE_TYPE_LIST_PAGE_TOKEN, MACHINE_TYPE_LIST_FILTER); + MACHINE_TYPE_LIST_PAGE_SIZE, MACHINE_TYPE_LIST_PAGE_TOKEN, MACHINE_TYPE_LIST_FILTER); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(machineTypeList.toArray(), Iterables.toArray(page.values(), MachineType.class)); @@ -750,7 +782,7 @@ public void testAggregatedListMachineTypesWithOptions() { EasyMock.expect(computeRpcMock.listMachineTypes(MACHINE_TYPE_LIST_OPTIONS)) .andReturn(result); EasyMock.replay(computeRpcMock); - Page page = compute.listMachineTypes(MACHINE_TYPE_AGGREGATED_LIST_MAX_RESULTS, + Page page = compute.listMachineTypes(MACHINE_TYPE_AGGREGATED_LIST_PAGE_SIZE, MACHINE_TYPE_AGGREGATED_LIST_PAGE_TOKEN, MACHINE_TYPE_AGGREGATED_LIST_FILTER); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(machineTypeList.toArray(), @@ -843,7 +875,7 @@ public void testListRegionsWithOptions() { Tuple.of(cursor, Iterables.transform(regionList, Region.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listRegions(REGION_LIST_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); - Page page = compute.listRegions(REGION_LIST_MAX_RESULTS, REGION_LIST_PAGE_TOKEN, + Page page = compute.listRegions(REGION_LIST_PAGE_SIZE, REGION_LIST_PAGE_TOKEN, REGION_LIST_FILTER); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(regionList.toArray(), Iterables.toArray(page.values(), Region.class)); @@ -935,7 +967,7 @@ public void testListZonesWithOptions() { EasyMock.expect(computeRpcMock.listZones(ZONE_LIST_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = - compute.listZones(ZONE_LIST_MAX_RESULTS, ZONE_LIST_PAGE_TOKEN, ZONE_LIST_FILTER); + compute.listZones(ZONE_LIST_PAGE_SIZE, ZONE_LIST_PAGE_TOKEN, ZONE_LIST_FILTER); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(zoneList.toArray(), Iterables.toArray(page.values(), Zone.class)); } @@ -1110,7 +1142,7 @@ public com.google.api.services.compute.model.Operation apply(Operation operation })); EasyMock.expect(computeRpcMock.listGlobalOperations(OPERATION_LIST_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); - Page page = compute.listGlobalOperations(OPERATION_LIST_MAX_RESULTS, + Page page = compute.listGlobalOperations(OPERATION_LIST_PAGE_SIZE, OPERATION_LIST_PAGE_TOKEN, OPERATION_LIST_FILTER); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(operationList.toArray(), Iterables.toArray(page.values(), Operation.class)); @@ -1256,7 +1288,7 @@ public com.google.api.services.compute.model.Operation apply(Operation operation .andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listRegionOperations(REGION_OPERATION_ID.region(), - OPERATION_LIST_MAX_RESULTS, OPERATION_LIST_PAGE_TOKEN, OPERATION_LIST_FILTER); + OPERATION_LIST_PAGE_SIZE, OPERATION_LIST_PAGE_TOKEN, OPERATION_LIST_FILTER); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(operationList.toArray(), Iterables.toArray(page.values(), Operation.class)); } @@ -1401,7 +1433,7 @@ public com.google.api.services.compute.model.Operation apply(Operation operation .andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listZoneOperations(ZONE_OPERATION_ID.zone(), - OPERATION_LIST_MAX_RESULTS, OPERATION_LIST_PAGE_TOKEN, OPERATION_LIST_FILTER); + OPERATION_LIST_PAGE_SIZE, OPERATION_LIST_PAGE_TOKEN, OPERATION_LIST_FILTER); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(operationList.toArray(), Iterables.toArray(page.values(), Operation.class)); } @@ -1424,6 +1456,445 @@ public void testDeleteZoneOperation_False() { assertFalse(compute.delete(ZONE_OPERATION_ID)); } + @Test + public void testGetGlobalAddress() { + EasyMock.expect( + computeRpcMock.getGlobalAddress(GLOBAL_ADDRESS_ID.address(), EMPTY_RPC_OPTIONS)) + .andReturn(GLOBAL_ADDRESS.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Address address = compute.get(GLOBAL_ADDRESS_ID); + assertEquals(new Address(compute, new AddressInfo.BuilderImpl(GLOBAL_ADDRESS)), address); + } + + @Test + public void testGetGlobalAddressWithSelectedFields() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.getGlobalAddress( + eq(GLOBAL_ADDRESS_ID.address()), capture(capturedOptions))) + .andReturn(GLOBAL_ADDRESS.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Address address = compute.get(GLOBAL_ADDRESS_ID, ADDRESS_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(ADDRESS_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(new Address(compute, new AddressInfo.BuilderImpl(GLOBAL_ADDRESS)), address); + } + + @Test + public void testGetRegionAddress() { + EasyMock.expect(computeRpcMock.getRegionAddress(REGION_ADDRESS_ID.region(), + REGION_ADDRESS_ID.address(), EMPTY_RPC_OPTIONS)).andReturn(REGION_ADDRESS.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Address address = compute.get(REGION_ADDRESS_ID); + assertEquals(new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS)), address); + } + + @Test + public void testGetRegionAddressWithSelectedFields() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.getRegionAddress(eq(REGION_ADDRESS_ID.region()), + eq(REGION_ADDRESS_ID.address()), capture(capturedOptions))) + .andReturn(REGION_ADDRESS.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Address address = compute.get(REGION_ADDRESS_ID, ADDRESS_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(ADDRESS_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS)), address); + } + + @Test + public void testDeleteGlobalAddress_Operation() { + EasyMock + .expect(computeRpcMock.deleteGlobalAddress(GLOBAL_ADDRESS_ID.address(), EMPTY_RPC_OPTIONS)) + .andReturn(globalOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(globalOperation, compute.delete(GLOBAL_ADDRESS_ID)); + } + + @Test + public void testDeleteGlobalAddressWithSelectedFields_Operation() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.deleteGlobalAddress(eq(GLOBAL_ADDRESS_ID.address()), + capture(capturedOptions))).andReturn(globalOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.delete(GLOBAL_ADDRESS_ID, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(globalOperation, operation); + } + + @Test + public void testDeleteGlobalAddress_Null() { + EasyMock + .expect(computeRpcMock.deleteGlobalAddress(GLOBAL_ADDRESS_ID.address(), EMPTY_RPC_OPTIONS)) + .andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.delete(GLOBAL_ADDRESS_ID)); + } + + @Test + public void testDeleteRegionAddress_Operation() { + EasyMock.expect(computeRpcMock.deleteRegionAddress(REGION_ADDRESS_ID.region(), + REGION_ADDRESS_ID.address(), EMPTY_RPC_OPTIONS)).andReturn(regionOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(regionOperation, compute.delete(REGION_ADDRESS_ID)); + } + + @Test + public void testDeleteRegionAddressWithSelectedFields_Operation() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.deleteRegionAddress(eq(REGION_ADDRESS_ID.region()), + eq(REGION_ADDRESS_ID.address()), capture(capturedOptions))) + .andReturn(globalOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.delete(REGION_ADDRESS_ID, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(globalOperation, operation); + } + + @Test + public void testDeleteRegionAddress_Null() { + EasyMock.expect(computeRpcMock.deleteRegionAddress(REGION_ADDRESS_ID.region(), + REGION_ADDRESS_ID.address(), EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.delete(REGION_ADDRESS_ID)); + } + + @Test + public void testListGlobalAddresses() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList
    addressList = ImmutableList.of( + new Address(compute, new AddressInfo.BuilderImpl(GLOBAL_ADDRESS)), + new Address(compute, new AddressInfo.BuilderImpl(GLOBAL_ADDRESS))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listGlobalAddresses(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page
    page = compute.listGlobalAddresses(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(addressList.toArray(), Iterables.toArray(page.values(), Address.class)); + } + + @Test + public void testListGlobalAddressesNextPage() { + String cursor = "cursor"; + String nextCursor = "nextCursor"; + compute = options.service(); + ImmutableList
    addressList = ImmutableList.of( + new Address(compute, new AddressInfo.BuilderImpl(GLOBAL_ADDRESS)), + new Address(compute, new AddressInfo.BuilderImpl(GLOBAL_ADDRESS))); + ImmutableList
    nextAddressList = ImmutableList.of( + new Address(compute, new AddressInfo.BuilderImpl(GLOBAL_ADDRESS))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(addressList, + new Function() { + @Override + public com.google.api.services.compute.model.Address apply(Address address) { + return address.toPb(); + } + })); + Tuple> nextResult = + Tuple.of(nextCursor, Iterables.transform(nextAddressList, + new Function() { + @Override + public com.google.api.services.compute.model.Address apply(Address address) { + return address.toPb(); + } + })); + Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + EasyMock.expect(computeRpcMock.listGlobalAddresses(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.expect(computeRpcMock.listGlobalAddresses(nextOptions)).andReturn(nextResult); + EasyMock.replay(computeRpcMock); + Page
    page = compute.listGlobalAddresses(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(addressList.toArray(), Iterables.toArray(page.values(), Address.class)); + page = page.nextPage(); + assertEquals(nextCursor, page.nextPageCursor()); + assertArrayEquals(nextAddressList.toArray(), Iterables.toArray(page.values(), Address.class)); + } + + @Test + public void testListEmptyGlobalAddresses() { + ImmutableList addresses = ImmutableList.of(); + Tuple> result = + Tuple.>of(null, addresses); + EasyMock.expect(computeRpcMock.listGlobalAddresses(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Page
    page = compute.listGlobalAddresses(); + assertNull(page.nextPageCursor()); + assertArrayEquals(addresses.toArray(), Iterables.toArray(page.values(), Address.class)); + } + + @Test + public void testListGlobalAddressesWithOptions() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList
    addressList = ImmutableList.of( + new Address(compute, new AddressInfo.BuilderImpl(GLOBAL_ADDRESS)), + new Address(compute, new AddressInfo.BuilderImpl(GLOBAL_ADDRESS))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listGlobalAddresses(ADDRESS_LIST_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page
    page = compute.listGlobalAddresses(ADDRESS_LIST_PAGE_SIZE, + ADDRESS_LIST_PAGE_TOKEN, ADDRESS_LIST_FILTER); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(addressList.toArray(), Iterables.toArray(page.values(), Address.class)); + } + + @Test + public void testListRegionAddresses() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList
    addressList = ImmutableList.of( + new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS)), + new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(addressList, + new Function() { + @Override + public com.google.api.services.compute.model.Address apply(Address address) { + return address.toPb(); + } + })); + EasyMock.expect( + computeRpcMock.listRegionAddresses(REGION_ADDRESS_ID.region(), EMPTY_RPC_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + Page
    page = compute.listRegionAddresses(REGION_ADDRESS_ID.region()); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(addressList.toArray(), Iterables.toArray(page.values(), Address.class)); + } + + @Test + public void testListRegionAddressesNextPage() { + String cursor = "cursor"; + String nextCursor = "nextCursor"; + compute = options.service(); + ImmutableList
    addressList = ImmutableList.of( + new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS)), + new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS))); + ImmutableList
    nextAddressList = ImmutableList.of( + new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(addressList, + new Function() { + @Override + public com.google.api.services.compute.model.Address apply(Address address) { + return address.toPb(); + } + })); + Tuple> nextResult = + Tuple.of(nextCursor, Iterables.transform(nextAddressList, + new Function() { + @Override + public com.google.api.services.compute.model.Address apply(Address address) { + return address.toPb(); + } + })); + Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + EasyMock.expect( + computeRpcMock.listRegionAddresses(REGION_ADDRESS_ID.region(), EMPTY_RPC_OPTIONS)) + .andReturn(result); + EasyMock.expect( + computeRpcMock.listRegionAddresses(REGION_ADDRESS_ID.region(), nextOptions)) + .andReturn(nextResult); + EasyMock.replay(computeRpcMock); + Page
    page = compute.listRegionAddresses(REGION_ADDRESS_ID.region()); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(addressList.toArray(), Iterables.toArray(page.values(), Address.class)); + page = page.nextPage(); + assertEquals(nextCursor, page.nextPageCursor()); + assertArrayEquals(nextAddressList.toArray(), Iterables.toArray(page.values(), Address.class)); + } + + @Test + public void testListEmptyRegionAddresses() { + ImmutableList addresses = ImmutableList.of(); + Tuple> result = + Tuple.>of(null, addresses); + EasyMock.expect( + computeRpcMock.listRegionAddresses(REGION_ADDRESS_ID.region(), EMPTY_RPC_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Page
    page = compute.listRegionAddresses(REGION_ADDRESS_ID.region()); + assertNull(page.nextPageCursor()); + assertArrayEquals(addresses.toArray(), Iterables.toArray(page.values(), Address.class)); + } + + @Test + public void testListRegionAddressesWithOptions() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList
    addressList = ImmutableList.of( + new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS)), + new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); + EasyMock.expect( + computeRpcMock.listRegionAddresses(REGION_ADDRESS_ID.region(), ADDRESS_LIST_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + Page
    page = compute.listRegionAddresses(REGION_ADDRESS_ID.region(), + ADDRESS_LIST_PAGE_SIZE, ADDRESS_LIST_PAGE_TOKEN, ADDRESS_LIST_FILTER); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(addressList.toArray(), Iterables.toArray(page.values(), Address.class)); + } + + @Test + public void testAggregatedListAddresses() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList
    addressList = ImmutableList.of( + new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS)), + new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listAddresses(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page
    page = compute.listAddresses(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(addressList.toArray(), Iterables.toArray(page.values(), Address.class)); + } + + @Test + public void testAggregatedListAddressesNextPage() { + String cursor = "cursor"; + String nextCursor = "nextCursor"; + compute = options.service(); + ImmutableList
    addressList = ImmutableList.of( + new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS)), + new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS))); + ImmutableList
    nextAddressList = ImmutableList.of( + new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); + Tuple> nextResult = + Tuple.of(nextCursor, Iterables.transform(nextAddressList, AddressInfo.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + EasyMock.expect(computeRpcMock.listAddresses(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.expect(computeRpcMock.listAddresses(nextOptions)).andReturn(nextResult); + EasyMock.replay(computeRpcMock); + Page
    page = compute.listAddresses(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(addressList.toArray(), Iterables.toArray(page.values(), Address.class)); + page = page.nextPage(); + assertEquals(nextCursor, page.nextPageCursor()); + assertArrayEquals(nextAddressList.toArray(), Iterables.toArray(page.values(), Address.class)); + } + + @Test + public void testAggregatedListEmptyAddresses() { + ImmutableList addresses = ImmutableList.of(); + Tuple> result = + Tuple.>of(null, addresses); + EasyMock.expect(computeRpcMock.listAddresses(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Page
    page = compute.listAddresses(); + assertNull(page.nextPageCursor()); + assertArrayEquals(addresses.toArray(), Iterables.toArray(page.values(), Address.class)); + } + + @Test + public void testAggregatedListAddressesWithOptions() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList
    addressList = ImmutableList.of( + new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS)), + new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listAddresses(ADDRESS_LIST_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page
    page = compute.listAddresses(ADDRESS_AGGREGATED_LIST_PAGE_SIZE, + ADDRESS_AGGREGATED_LIST_PAGE_TOKEN, ADDRESS_AGGREGATED_LIST_FILTER); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(addressList.toArray(), Iterables.toArray(page.values(), Address.class)); + } + + @Test + public void testCreateGlobalAddress() { + EasyMock.expect(computeRpcMock.createGlobalAddress(GLOBAL_ADDRESS.toPb(), EMPTY_RPC_OPTIONS)) + .andReturn(globalOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + AddressId incompleteId = GlobalAddressId.of("address"); + Operation operation = + compute.create(GLOBAL_ADDRESS.toBuilder().addressId(incompleteId).build()); + assertEquals(globalOperation, operation); + } + + @Test + public void testCreateGlobalAddressWithOptions() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect( + computeRpcMock.createGlobalAddress(eq(GLOBAL_ADDRESS.toPb()), capture(capturedOptions))) + .andReturn(globalOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.create(GLOBAL_ADDRESS, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(globalOperation, operation); + } + + @Test + public void testCreateRegionAddress() { + EasyMock.expect(computeRpcMock.createRegionAddress(REGION_ADDRESS_ID.region(), + REGION_ADDRESS.toPb(), EMPTY_RPC_OPTIONS)).andReturn(regionOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + AddressId incompleteId = RegionAddressId.of("region", "address"); + Operation operation = + compute.create(REGION_ADDRESS.toBuilder().addressId(incompleteId).build()); + assertEquals(regionOperation, operation); + } + + @Test + public void testCreateRegionAddressWithOptions() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.createRegionAddress(eq(REGION_ADDRESS_ID.region()), + eq(REGION_ADDRESS.toPb()), capture(capturedOptions))).andReturn(regionOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.create(REGION_ADDRESS, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(regionOperation, operation); + } + @Test public void testRetryableException() { EasyMock.expect( diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ForwardingRuleIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ForwardingRuleIdTest.java new file mode 100644 index 000000000000..e15059623fa7 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ForwardingRuleIdTest.java @@ -0,0 +1,130 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class ForwardingRuleIdTest { + + private static final String PROJECT = "project"; + private static final String REGION = "region"; + private static final String NAME = "rule"; + private static final String GLOBAL_URL = + "https://www.googleapis.com/compute/v1/projects/project/global/forwardingRules/rule"; + private static final String REGION_URL = "https://www.googleapis.com/compute/v1/projects/" + + "project/regions/region/forwardingRules/rule"; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testOf() { + GlobalForwardingRuleId forwardingRuleId = GlobalForwardingRuleId.of(PROJECT, NAME); + assertEquals(PROJECT, forwardingRuleId.project()); + assertEquals(NAME, forwardingRuleId.rule()); + assertEquals(GLOBAL_URL, forwardingRuleId.selfLink()); + assertEquals(ForwardingRuleId.Type.GLOBAL, forwardingRuleId.type()); + forwardingRuleId = GlobalForwardingRuleId.of(NAME); + assertNull(forwardingRuleId.project()); + assertEquals(NAME, forwardingRuleId.rule()); + assertEquals(ForwardingRuleId.Type.GLOBAL, forwardingRuleId.type()); + RegionForwardingRuleId regionForwardingRuleId = + RegionForwardingRuleId.of(PROJECT, REGION, NAME); + assertEquals(PROJECT, regionForwardingRuleId.project()); + assertEquals(REGION, regionForwardingRuleId.region()); + assertEquals(NAME, regionForwardingRuleId.rule()); + assertEquals(REGION_URL, regionForwardingRuleId.selfLink()); + assertEquals(ForwardingRuleId.Type.REGION, regionForwardingRuleId.type()); + regionForwardingRuleId = RegionForwardingRuleId.of(RegionId.of(PROJECT, REGION), NAME); + assertEquals(PROJECT, regionForwardingRuleId.project()); + assertEquals(REGION, regionForwardingRuleId.region()); + assertEquals(NAME, regionForwardingRuleId.rule()); + assertEquals(REGION_URL, regionForwardingRuleId.selfLink()); + assertEquals(ForwardingRuleId.Type.REGION, regionForwardingRuleId.type()); + regionForwardingRuleId = RegionForwardingRuleId.of(REGION, NAME); + assertNull(regionForwardingRuleId.project()); + assertEquals(REGION, regionForwardingRuleId.region()); + assertEquals(NAME, regionForwardingRuleId.rule()); + assertEquals(ForwardingRuleId.Type.REGION, regionForwardingRuleId.type()); + } + + @Test + public void testToAndFromUrl() { + GlobalForwardingRuleId forwardingRuleId = GlobalForwardingRuleId.of(PROJECT, NAME); + compareGlobalForwardingRuleId(forwardingRuleId, + GlobalForwardingRuleId.fromUrl(forwardingRuleId.selfLink())); + RegionForwardingRuleId regionForwardingRuleId = + RegionForwardingRuleId.of(PROJECT, REGION, NAME); + compareRegionForwardingRuleId(regionForwardingRuleId, + RegionForwardingRuleId.fromUrl(regionForwardingRuleId.selfLink())); + } + + @Test + public void testSetProjectId() { + GlobalForwardingRuleId forwardingRuleId = GlobalForwardingRuleId.of(PROJECT, NAME); + assertSame(forwardingRuleId, forwardingRuleId.setProjectId(PROJECT)); + compareGlobalForwardingRuleId(forwardingRuleId, + GlobalForwardingRuleId.of(NAME).setProjectId(PROJECT)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid global forwarding rule URL"); + GlobalForwardingRuleId.fromUrl("notMatchingUrl"); + RegionForwardingRuleId regionForwardingRuleId = + RegionForwardingRuleId.of(PROJECT, REGION, NAME); + assertSame(regionForwardingRuleId, regionForwardingRuleId.setProjectId(PROJECT)); + compareRegionForwardingRuleId(regionForwardingRuleId, + RegionForwardingRuleId.of(REGION, NAME).setProjectId(PROJECT)); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid region forwarding rule URL"); + RegionForwardingRuleId.fromUrl("notMatchingUrl"); + } + + @Test + public void testMatchesUrl() { + assertTrue(GlobalForwardingRuleId.matchesUrl(GlobalForwardingRuleId.of(PROJECT, NAME).selfLink())); + assertFalse(GlobalForwardingRuleId.matchesUrl("notMatchingUrl")); + assertTrue(RegionForwardingRuleId.matchesUrl( + RegionForwardingRuleId.of(PROJECT, REGION, NAME).selfLink())); + assertFalse(RegionForwardingRuleId.matchesUrl("notMatchingUrl")); + } + + private void compareGlobalForwardingRuleId(GlobalForwardingRuleId expected, + GlobalForwardingRuleId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.rule(), expected.rule()); + assertEquals(expected.selfLink(), expected.selfLink()); + assertEquals(expected.hashCode(), expected.hashCode()); + } + + private void compareRegionForwardingRuleId(RegionForwardingRuleId expected, + RegionForwardingRuleId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.region(), expected.region()); + assertEquals(expected.rule(), expected.rule()); + assertEquals(expected.selfLink(), expected.selfLink()); + assertEquals(expected.hashCode(), expected.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceIdTest.java new file mode 100644 index 000000000000..782c8eb4ec31 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceIdTest.java @@ -0,0 +1,88 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class InstanceIdTest { + + private static final String PROJECT = "project"; + private static final String ZONE = "zone"; + private static final String NAME = "instance"; + private static final String URL = + "https://www.googleapis.com/compute/v1/projects/project/zones/zone/instances/instance"; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testOf() { + InstanceId instanceId = InstanceId.of(PROJECT, ZONE, NAME); + assertEquals(PROJECT, instanceId.project()); + assertEquals(ZONE, instanceId.zone()); + assertEquals(NAME, instanceId.instance()); + assertEquals(URL, instanceId.selfLink()); + instanceId = InstanceId.of(ZoneId.of(PROJECT, ZONE), NAME); + assertEquals(PROJECT, instanceId.project()); + assertEquals(ZONE, instanceId.zone()); + assertEquals(NAME, instanceId.instance()); + assertEquals(URL, instanceId.selfLink()); + instanceId = InstanceId.of(ZONE, NAME); + assertNull(instanceId.project()); + assertEquals(ZONE, instanceId.zone()); + assertEquals(NAME, instanceId.instance()); + } + + @Test + public void testToAndFromUrl() { + InstanceId instanceId = InstanceId.of(PROJECT, ZONE, NAME); + compareInstanceId(instanceId, InstanceId.fromUrl(instanceId.selfLink())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid instance URL"); + InstanceId.fromUrl("notMatchingUrl"); + } + + @Test + public void testSetProjectId() { + InstanceId instanceId = InstanceId.of(PROJECT, ZONE, NAME); + assertSame(instanceId, instanceId.setProjectId(PROJECT)); + compareInstanceId(instanceId, InstanceId.of(ZONE, NAME).setProjectId(PROJECT)); + } + + @Test + public void testMatchesUrl() { + assertTrue(InstanceId.matchesUrl(InstanceId.of(PROJECT, ZONE, NAME).selfLink())); + assertFalse(InstanceId.matchesUrl("notMatchingUrl")); + } + + private void compareInstanceId(InstanceId expected, InstanceId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.zone(), expected.zone()); + assertEquals(expected.instance(), expected.instance()); + assertEquals(expected.selfLink(), expected.selfLink()); + assertEquals(expected.hashCode(), expected.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java index a73cf860810f..81afee4acf50 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java @@ -126,6 +126,27 @@ public class SerializationTest { new Operation.Builder(COMPUTE).operationId(ZONE_OPERATION_ID).build(); private static final Operation REGION_OPERATION = new Operation.Builder(COMPUTE).operationId(REGION_OPERATION_ID).build(); + private static final InstanceId INSTANCE_ID = InstanceId.of("project", "zone", "instance"); + private static final GlobalForwardingRuleId GLOBAL_FORWARDING_RULE_ID = + GlobalForwardingRuleId.of("project", "rule"); + private static final RegionForwardingRuleId REGION_FORWARDING_RULE_ID = + RegionForwardingRuleId.of("project", "region", "rule"); + private static final GlobalAddressId GLOBAL_ADDRESS_ID = GlobalAddressId.of("project", "address"); + private static final RegionAddressId REGION_ADDRESS_ID = + RegionAddressId.of("project", "region", "address"); + private static final AddressInfo.InstanceUsage INSTANCE_USAGE = + new AddressInfo.InstanceUsage(INSTANCE_ID); + private static final AddressInfo.GlobalForwardingUsage GLOBAL_FORWARDING_USAGE = + new AddressInfo.GlobalForwardingUsage(ImmutableList.of(GLOBAL_FORWARDING_RULE_ID)); + private static final AddressInfo.RegionForwardingUsage REGION_FORWARDING_USAGE = + new AddressInfo.RegionForwardingUsage(ImmutableList.of(REGION_FORWARDING_RULE_ID)); + private static final AddressInfo ADDRESS_INFO = AddressInfo.builder(REGION_ADDRESS_ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .id(ID) + .usage(INSTANCE_USAGE) + .build(); + private static final Address ADDRESS = new Address.Builder(COMPUTE, REGION_ADDRESS_ID).build(); private static final Compute.DiskTypeOption DISK_TYPE_OPTION = Compute.DiskTypeOption.fields(); private static final Compute.DiskTypeFilter DISK_TYPE_FILTER = @@ -158,6 +179,14 @@ public class SerializationTest { Compute.OperationFilter.equals(Compute.OperationField.SELF_LINK, "selfLink"); private static final Compute.OperationListOption OPERATION_LIST_OPTION = Compute.OperationListOption.filter(OPERATION_FILTER); + private static final Compute.AddressOption ADDRESS_OPTION = Compute.AddressOption.fields(); + private static final Compute.AddressFilter ADDRESS_FILTER = + Compute.AddressFilter.equals(Compute.AddressField.SELF_LINK, "selfLink"); + private static final Compute.AddressListOption ADDRESS_LIST_OPTION = + Compute.AddressListOption.filter(ADDRESS_FILTER); + private static final Compute.AddressAggregatedListOption ADDRESS_AGGREGATED_LIST_OPTION = + Compute.AddressAggregatedListOption.filter(ADDRESS_FILTER); + @Test public void testServiceOptions() throws Exception { ComputeOptions options = ComputeOptions.builder() @@ -181,11 +210,14 @@ public void testModelAndRequests() throws Exception { Serializable[] objects = {DISK_TYPE_ID, DISK_TYPE, MACHINE_TYPE_ID, MACHINE_TYPE, REGION_ID, REGION, ZONE_ID, ZONE, LICENSE_ID, LICENSE, DEPRECATION_STATUS, GLOBAL_OPERATION_ID, REGION_OPERATION_ID, ZONE_OPERATION_ID, GLOBAL_OPERATION, REGION_OPERATION, ZONE_OPERATION, - DISK_TYPE_OPTION, DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, DISK_TYPE_AGGREGATED_LIST_OPTION, - MACHINE_TYPE_OPTION, MACHINE_TYPE_FILTER, MACHINE_TYPE_LIST_OPTION, - MACHINE_TYPE_AGGREGATED_LIST_OPTION, REGION_OPTION, REGION_FILTER, REGION_LIST_OPTION, - ZONE_OPTION, ZONE_FILTER, ZONE_LIST_OPTION, LICENSE_OPTION, OPERATION_OPTION, - OPERATION_FILTER, OPERATION_LIST_OPTION}; + INSTANCE_ID, REGION_FORWARDING_RULE_ID, GLOBAL_FORWARDING_RULE_ID, GLOBAL_ADDRESS_ID, + REGION_ADDRESS_ID, INSTANCE_USAGE, GLOBAL_FORWARDING_USAGE, REGION_FORWARDING_USAGE, + ADDRESS_INFO, ADDRESS, DISK_TYPE_OPTION, DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, + DISK_TYPE_AGGREGATED_LIST_OPTION, MACHINE_TYPE_OPTION, MACHINE_TYPE_FILTER, + MACHINE_TYPE_LIST_OPTION, MACHINE_TYPE_AGGREGATED_LIST_OPTION, REGION_OPTION, REGION_FILTER, + REGION_LIST_OPTION, ZONE_OPTION, ZONE_FILTER, ZONE_LIST_OPTION, LICENSE_OPTION, + OPERATION_OPTION, OPERATION_FILTER, OPERATION_LIST_OPTION, ADDRESS_OPTION, ADDRESS_FILTER, + ADDRESS_LIST_OPTION, ADDRESS_AGGREGATED_LIST_OPTION}; for (Serializable obj : objects) { Object copy = serializeAndDeserialize(obj); assertEquals(obj, obj); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java index 56960903d6c7..666fe8500704 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java @@ -23,14 +23,20 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import com.google.common.collect.ImmutableSet; import com.google.gcloud.Page; +import com.google.gcloud.compute.Address; +import com.google.gcloud.compute.AddressId; +import com.google.gcloud.compute.AddressInfo; import com.google.gcloud.compute.Compute; import com.google.gcloud.compute.DiskType; +import com.google.gcloud.compute.GlobalAddressId; import com.google.gcloud.compute.License; import com.google.gcloud.compute.LicenseId; import com.google.gcloud.compute.MachineType; import com.google.gcloud.compute.Operation; import com.google.gcloud.compute.Region; +import com.google.gcloud.compute.RegionAddressId; import com.google.gcloud.compute.RegionOperationId; import com.google.gcloud.compute.Zone; import com.google.gcloud.compute.ZoneOperationId; @@ -42,6 +48,7 @@ import org.junit.rules.Timeout; import java.util.Iterator; +import java.util.Set; public class ITComputeTest { @@ -50,6 +57,7 @@ public class ITComputeTest { private static final String DISK_TYPE = "local-ssd"; private static final String MACHINE_TYPE = "f1-micro"; private static final LicenseId LICENSE_ID = LicenseId.of("ubuntu-os-cloud", "ubuntu-1404-trusty"); + private static final String BASE_RESOURCE_NAME = RemoteComputeHelper.baseResourceName(); private static Compute compute; @@ -65,7 +73,6 @@ public static void beforeClass() { @Test public void testGetDiskType() { DiskType diskType = compute.getDiskType(ZONE, DISK_TYPE); - // todo(mziccard): uncomment or remove once #695 is closed // assertNotNull(diskType.id()); assertEquals(ZONE, diskType.diskTypeId().zone()); assertEquals(DISK_TYPE, diskType.diskTypeId().diskType()); @@ -79,7 +86,6 @@ public void testGetDiskType() { public void testGetDiskTypeWithSelectedFields() { DiskType diskType = compute.getDiskType(ZONE, DISK_TYPE, Compute.DiskTypeOption.fields(Compute.DiskTypeField.CREATION_TIMESTAMP)); - // todo(mziccard): uncomment or remove once #695 is closed // assertNotNull(diskType.id()); assertEquals(ZONE, diskType.diskTypeId().zone()); assertEquals(DISK_TYPE, diskType.diskTypeId().diskType()); @@ -96,7 +102,6 @@ public void testListDiskTypes() { assertTrue(diskTypeIterator.hasNext()); while (diskTypeIterator.hasNext()) { DiskType diskType = diskTypeIterator.next(); - // todo(mziccard): uncomment or remove once #695 is closed // assertNotNull(diskType.id()); assertNotNull(diskType.diskTypeId()); assertEquals(ZONE, diskType.diskTypeId().zone()); @@ -309,7 +314,7 @@ public void testAggregatedListMachineTypesWithFilter() { @Test public void testGetLicense() { - License license= compute.getLicense(LICENSE_ID); + License license = compute.getLicense(LICENSE_ID); assertEquals(LICENSE_ID, license.licenseId()); assertNotNull(license.chargesUseFee()); } @@ -637,4 +642,217 @@ public void testListZoneOperationsWithFilter() { assertNotNull(operation.user()); } } + + @Test + public void testCreateGetAndDeleteRegionAddress() throws InterruptedException { + String name = BASE_RESOURCE_NAME + "create-and-get-region-address"; + AddressId addressId = RegionAddressId.of(REGION, name); + AddressInfo addressInfo = AddressInfo.of(addressId); + Operation operation = compute.create(addressInfo); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + // test get + Address remoteAddress = compute.get(addressId); + assertNotNull(remoteAddress); + assertTrue(remoteAddress.addressId() instanceof RegionAddressId); + assertEquals(REGION, remoteAddress.addressId().region()); + assertEquals(addressId.address(), remoteAddress.addressId().address()); + assertNotNull(remoteAddress.address()); + assertNotNull(remoteAddress.creationTimestamp()); + assertNotNull(remoteAddress.id()); + assertNotNull(remoteAddress.status()); + // test get with selected fields + remoteAddress = compute.get(addressId, Compute.AddressOption.fields()); + assertNotNull(remoteAddress); + assertTrue(remoteAddress.addressId() instanceof RegionAddressId); + assertEquals(REGION, remoteAddress.addressId().region()); + assertEquals(addressId.address(), remoteAddress.addressId().address()); + assertNull(remoteAddress.address()); + assertNull(remoteAddress.creationTimestamp()); + assertNull(remoteAddress.id()); + operation = remoteAddress.delete(); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + assertNull(compute.get(addressId)); + } + + @Test + public void testListRegionAddresses() throws InterruptedException { + String prefix = BASE_RESOURCE_NAME + "list-region-address"; + String[] addressNames = {prefix + "1", prefix + "2"}; + AddressId firstAddressId = RegionAddressId.of(REGION, addressNames[0]); + AddressId secondAddressId = RegionAddressId.of(REGION, addressNames[1]); + Operation firstOperation = compute.create(AddressInfo.of(firstAddressId)); + Operation secondOperation = compute.create(AddressInfo.of(secondAddressId)); + while (!firstOperation.isDone()) { + Thread.sleep(1000L); + } + while (!secondOperation.isDone()) { + Thread.sleep(1000L); + } + Set addressSet = ImmutableSet.copyOf(addressNames); + // test list + Compute.AddressFilter filter = + Compute.AddressFilter.equals(Compute.AddressField.NAME, prefix + "\\d"); + Page
    addressPage = + compute.listRegionAddresses(REGION, Compute.AddressListOption.filter(filter)); + Iterator
    addressIterator = addressPage.iterateAll(); + int count = 0; + while (addressIterator.hasNext()) { + Address address = addressIterator.next(); + assertNotNull(address.addressId()); + assertTrue(address.addressId() instanceof RegionAddressId); + assertEquals(REGION, address.addressId().region()); + assertTrue(addressSet.contains(address.addressId().address())); + assertNotNull(address.address()); + assertNotNull(address.creationTimestamp()); + assertNotNull(address.id()); + count++; + } + assertEquals(2, count); + // test list with selected fields + count = 0; + addressPage = compute.listRegionAddresses(REGION, Compute.AddressListOption.filter(filter), + Compute.AddressListOption.fields(Compute.AddressField.ADDRESS)); + addressIterator = addressPage.iterateAll(); + while (addressIterator.hasNext()) { + Address address = addressIterator.next(); + assertTrue(address.addressId() instanceof RegionAddressId); + assertEquals(REGION, address.addressId().region()); + assertTrue(addressSet.contains(address.addressId().address())); + assertNotNull(address.address()); + assertNull(address.creationTimestamp()); + assertNull(address.id()); + assertNull(address.status()); + assertNull(address.usage()); + count++; + } + assertEquals(2, count); + compute.delete(firstAddressId); + compute.delete(secondAddressId); + } + + @Test + public void testAggregatedListAddresses() throws InterruptedException { + String prefix = BASE_RESOURCE_NAME + "aggregated-list-address"; + String[] addressNames = {prefix + "1", prefix + "2"}; + AddressId firstAddressId = RegionAddressId.of(REGION, addressNames[0]); + AddressId secondAddressId = GlobalAddressId.of(REGION, addressNames[1]); + Operation firstOperation = compute.create(AddressInfo.of(firstAddressId)); + Operation secondOperation = compute.create(AddressInfo.of(secondAddressId)); + while (!firstOperation.isDone()) { + Thread.sleep(1000L); + } + while (!secondOperation.isDone()) { + Thread.sleep(1000L); + } + Set addressSet = ImmutableSet.copyOf(addressNames); + Compute.AddressFilter filter = + Compute.AddressFilter.equals(Compute.AddressField.NAME, prefix + "\\d"); + Page
    addressPage = + compute.listAddresses(Compute.AddressAggregatedListOption.filter(filter)); + Iterator
    addressIterator = addressPage.iterateAll(); + int count = 0; + while (addressIterator.hasNext()) { + Address address = addressIterator.next(); + assertNotNull(address.addressId()); + assertTrue(addressSet.contains(address.addressId().address())); + assertNotNull(address.address()); + assertNotNull(address.creationTimestamp()); + assertNotNull(address.id()); + count++; + } + assertEquals(2, count); + compute.delete(firstAddressId); + compute.delete(secondAddressId); + } + + @Test + public void testCreateGetAndDeleteGlobalAddress() throws InterruptedException { + String name = BASE_RESOURCE_NAME + "create-and-get-global-address"; + AddressId addressId = GlobalAddressId.of(name); + AddressInfo addressInfo = AddressInfo.of(addressId); + Operation operation = compute.create(addressInfo); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + // test get + Address remoteAddress = compute.get(addressId); + assertNotNull(remoteAddress); + assertTrue(remoteAddress.addressId() instanceof GlobalAddressId); + assertEquals(addressId.address(), remoteAddress.addressId().address()); + assertNotNull(remoteAddress.address()); + assertNotNull(remoteAddress.creationTimestamp()); + assertNotNull(remoteAddress.id()); + assertNotNull(remoteAddress.status()); + // test get with selected fields + remoteAddress = compute.get(addressId, Compute.AddressOption.fields()); + assertNotNull(remoteAddress); + assertTrue(remoteAddress.addressId() instanceof GlobalAddressId); + assertEquals(addressId.address(), remoteAddress.addressId().address()); + assertNull(remoteAddress.address()); + assertNull(remoteAddress.creationTimestamp()); + assertNull(remoteAddress.id()); + operation = remoteAddress.delete(); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + assertNull(compute.get(addressId)); + } + + @Test + public void testListGlobalAddresses() throws InterruptedException { + String prefix = BASE_RESOURCE_NAME + "list-global-address"; + String[] addressNames = {prefix + "1", prefix + "2"}; + AddressId firstAddressId = GlobalAddressId.of(addressNames[0]); + AddressId secondAddressId = GlobalAddressId.of(addressNames[1]); + Operation firstOperation = compute.create(AddressInfo.of(firstAddressId)); + Operation secondOperation = compute.create(AddressInfo.of(secondAddressId)); + while (!firstOperation.isDone()) { + Thread.sleep(1000L); + } + while (!secondOperation.isDone()) { + Thread.sleep(1000L); + } + Set addressSet = ImmutableSet.copyOf(addressNames); + // test list + Compute.AddressFilter filter = + Compute.AddressFilter.equals(Compute.AddressField.NAME, prefix + "\\d"); + Page
    addressPage = + compute.listGlobalAddresses(Compute.AddressListOption.filter(filter)); + Iterator
    addressIterator = addressPage.iterateAll(); + int count = 0; + while (addressIterator.hasNext()) { + Address address = addressIterator.next(); + assertNotNull(address.addressId()); + assertTrue(address.addressId() instanceof GlobalAddressId); + assertTrue(addressSet.contains(address.addressId().address())); + assertNotNull(address.address()); + assertNotNull(address.creationTimestamp()); + assertNotNull(address.id()); + count++; + } + assertEquals(2, count); + // test list with selected fields + count = 0; + addressPage = compute.listGlobalAddresses(Compute.AddressListOption.filter(filter), + Compute.AddressListOption.fields(Compute.AddressField.ADDRESS)); + addressIterator = addressPage.iterateAll(); + while (addressIterator.hasNext()) { + Address address = addressIterator.next(); + assertTrue(address.addressId() instanceof GlobalAddressId); + assertTrue(addressSet.contains(address.addressId().address())); + assertNotNull(address.address()); + assertNull(address.creationTimestamp()); + assertNull(address.id()); + assertNull(address.status()); + assertNull(address.usage()); + count++; + } + assertEquals(2, count); + compute.delete(firstAddressId); + compute.delete(secondAddressId); + } } From f3c30f108ce5b25e5157484520cc81677b53af90 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 17 Mar 2016 10:59:05 +0100 Subject: [PATCH 291/375] Provide better javadoc to address related classes --- .../com/google/gcloud/compute/Address.java | 4 ++-- .../google/gcloud/compute/AddressInfo.java | 20 +++++++++++-------- .../com/google/gcloud/compute/Compute.java | 14 ++++++------- .../com/google/gcloud/spi/ComputeRpc.java | 10 +++++----- 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java index 9950ff132303..44a526b09241 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java @@ -141,8 +141,8 @@ public Address reload(Compute.AddressOption... options) throws ComputeException /** * Deletes this address. * - * @return an operation object if delete request was successfully sent, {@code null} if the - * address was not found + * @return an {@code Operation} object if delete request was successfully sent, {@code null} if + * the address was not found * @throws ComputeException upon failure */ public Operation delete(Compute.OperationOption... options) throws ComputeException { diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressInfo.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressInfo.java index eda874618801..18554ea7f241 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressInfo.java @@ -90,8 +90,12 @@ public enum Status { } /** - * Base class for a Google Compute Engine address usage information. {@link InstanceUsage} is for - * addresses assigned to a Google Compute Engine instance. + * Base class for a Google Compute Engine address's usage information. Implementations of this + * class represent different possible usages of a Compute Engine address. {@link InstanceUsage} + * contains information for region addresses assigned to a Google Compute Engine instance. + * {@link RegionForwardingUsage} contains information for region addresses assigned to one or more + * region forwarding rule. {@link GlobalForwardingUsage} contains information for global addresses + * assigned to one or more global forwarding rule. */ public abstract static class Usage implements Serializable { @@ -430,7 +434,7 @@ public String description() { } /** - * Returns an unique identifier for the address; defined by the service. + * Returns the unique identifier for the address; defined by the service. */ public String id() { return id; @@ -529,21 +533,21 @@ Address toPb() { } /** - * Returns a builder for the AddressInfo object given it's identity. + * Returns a builder for the {@code AddressInfo} object given it's identity. */ public static BuilderImpl builder(AddressId addressId) { return new BuilderImpl().addressId(addressId); } /** - * Returns an AddressInfo object for the provided identity. + * Returns an {@code AddressInfo} object for the provided identity. */ public static AddressInfo of(AddressId addressId) { return builder(addressId).build(); } /** - * Returns an AddressInfo object for the provided name. Such an object corresponds to a global + * Returns an {@code AddressInfo} object for the provided name. The object corresponds to a global * address. */ public static AddressInfo of(String name) { @@ -551,7 +555,7 @@ public static AddressInfo of(String name) { } /** - * Returns an AddressInfo object for the provided region identity and name. Such an object + * Returns an {@code AddressInfo} object for the provided region identity and name. The object * corresponds to a region address. */ public static AddressInfo of(RegionId regionId, String name) { @@ -559,7 +563,7 @@ public static AddressInfo of(RegionId regionId, String name) { } /** - * Returns an AddressInfo object for the provided region and address names. Such an object + * Returns an {@code AddressInfo} object for the provided region and address names. The object * corresponds to a region address. */ public static AddressInfo of(String region, String name) { diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java index ac881488f362..a2d41542d28a 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java @@ -862,7 +862,7 @@ public static DiskTypeListOption filter(DiskTypeFilter filter) { } /** - * Returns an option to specify the maximum number of disk types to be returned. + * Returns an option to specify the maximum number of disk types returned per page. */ public static DiskTypeListOption pageSize(long pageSize) { return new DiskTypeListOption(ComputeRpc.Option.MAX_RESULTS, pageSize); @@ -907,7 +907,7 @@ public static DiskTypeAggregatedListOption filter(DiskTypeFilter filter) { } /** - * Returns an option to specify the maximum number of disk types to be returned. + * Returns an option to specify the maximum number of disk types returned per page. */ public static DiskTypeAggregatedListOption pageSize(long pageSize) { return new DiskTypeAggregatedListOption(ComputeRpc.Option.MAX_RESULTS, pageSize); @@ -955,7 +955,7 @@ private MachineTypeListOption(ComputeRpc.Option option, Object value) { } /** - * Returns an option to specify a filter on the machine types being listed. + * Returns an option to specify a filter to the machine types being listed. */ public static MachineTypeListOption filter(MachineTypeFilter filter) { return new MachineTypeListOption(ComputeRpc.Option.FILTER, filter.toPb()); @@ -1000,7 +1000,7 @@ private MachineTypeAggregatedListOption(ComputeRpc.Option option, Object value) } /** - * Returns an option to specify a filter on the machine types being listed. + * Returns an option to specify a filter to the machine types being listed. */ public static MachineTypeAggregatedListOption filter(MachineTypeFilter filter) { return new MachineTypeAggregatedListOption(ComputeRpc.Option.FILTER, filter.toPb()); @@ -1055,7 +1055,7 @@ private RegionListOption(ComputeRpc.Option option, Object value) { } /** - * Returns an option to specify a filter on the regions being listed. + * Returns an option to specify a filter to the regions being listed. */ public static RegionListOption filter(RegionFilter filter) { return new RegionListOption(ComputeRpc.Option.FILTER, filter.toPb()); @@ -1122,7 +1122,7 @@ private ZoneListOption(ComputeRpc.Option option, Object value) { } /** - * Returns an option to specify a filter on the zones being listed. + * Returns an option to specify a filter to the zones being listed. */ public static ZoneListOption filter(ZoneFilter filter) { return new ZoneListOption(ComputeRpc.Option.FILTER, filter.toPb()); @@ -1211,7 +1211,7 @@ private OperationListOption(ComputeRpc.Option option, Object value) { } /** - * Returns an option to specify a filter on the operations being listed. + * Returns an option to specify a filter to the operations being listed. */ public static OperationListOption filter(OperationFilter filter) { return new OperationListOption(ComputeRpc.Option.FILTER, filter.toPb()); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java index 2f08c2702264..7d1f2384063f 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java @@ -270,7 +270,7 @@ public Y y() { /** * Returns the requested region address or {@code null} if not found. * - * @throws ComputeException upon failure + * @throws ComputeException upon failure or if region is not found */ Address getRegionAddress(String region, String address, Map options); @@ -278,19 +278,19 @@ public Y y() { * Creates a new region address. * * @return a region operation for region address' creation - * @throws ComputeException upon failure + * @throws ComputeException upon failure or if region is not found */ Operation createRegionAddress(String region, Address address, Map options); /** * Lists the regions addresses for the provided region. * - * @throws ComputeException upon failure + * @throws ComputeException upon failure or if region is not found */ Tuple> listRegionAddresses(String region, Map options); /** - * Lists all addressest. + * Lists all addresses. * * @throws ComputeException upon failure */ @@ -301,7 +301,7 @@ public Y y() { * * @return a region operation if request was issued correctly, {@code null} if the address was not * found - * @throws ComputeException upon failure + * @throws ComputeException upon failure or if region is not found */ Operation deleteRegionAddress(String region, String address, Map options); } From 2d691aacdd3379389db290eb142f6f73a59ef8cd Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 21 Mar 2016 09:20:53 +0100 Subject: [PATCH 292/375] Refactor identity classes - Remove Zone/RegionResourceId - Make OperationId and AddressId abstract classes - Refactor javadoc - Add abstract setProjectId to AddressId and OperationId - Split testToAndFromUrl tests - Add better javadoc to identity classes --- .../com/google/gcloud/compute/AddressId.java | 64 ++++++++++----- .../com/google/gcloud/compute/DiskTypeId.java | 31 +++++-- .../gcloud/compute/ForwardingRuleId.java | 56 +++++++++---- .../gcloud/compute/GlobalAddressId.java | 48 ++++------- .../compute/GlobalForwardingRuleId.java | 47 ++++------- .../gcloud/compute/GlobalOperationId.java | 32 ++------ .../com/google/gcloud/compute/InstanceId.java | 65 +++++++++------ .../google/gcloud/compute/MachineTypeId.java | 31 +++++-- .../google/gcloud/compute/OperationId.java | 55 ++++++++++--- .../gcloud/compute/RegionAddressId.java | 51 +++++++----- .../compute/RegionForwardingRuleId.java | 72 +++++++++-------- .../gcloud/compute/RegionOperationId.java | 35 +++++--- .../gcloud/compute/RegionResourceId.java | 80 ------------------- .../gcloud/compute/ZoneOperationId.java | 35 +++++--- .../google/gcloud/compute/ZoneResourceId.java | 80 ------------------- .../google/gcloud/compute/AddressIdTest.java | 9 ++- .../gcloud/compute/ForwardingRuleIdTest.java | 25 ++++-- 17 files changed, 391 insertions(+), 425 deletions(-) delete mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionResourceId.java delete mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneResourceId.java diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressId.java index 01f163b867cd..c418ec2ae1ba 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressId.java @@ -16,10 +16,20 @@ package com.google.gcloud.compute; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; + +import java.util.Objects; + /** - * Interface for Google Compute Engine address identities. + * Base class for Google Compute Engine address identities. */ -public interface AddressId { +public abstract class AddressId extends ResourceId { + + private static final long serialVersionUID = 147328216049936438L; + + private final String address; /** * Possible types for a Google Compute Engine address identity. @@ -29,35 +39,53 @@ enum Type { * Global static external IP addresses can be assigned to global forwarding rules. */ GLOBAL, + /** * Region static external IP addresses can be assigned to instances and region forwarding rules. */ REGION } - /** - * Returns the type of this address identity. - */ - Type type(); + AddressId(String project, String address) { + super(project); + this.address = checkNotNull(address); + } /** - * Returns the name of the project. + * Returns the type of this address identity. */ - String project(); + public abstract Type type(); /** - * Returns the name of the address resource. The name must be 1-63 characters long, and comply - * with RFC1035. Specifically, the name must be 1-63 characters long and match the regular - * expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a - * lowercase letter, and all following characters must be a dash, lowercase letter, or digit, - * except the last character, which cannot be a dash. + * Returns the name of the address resource. The name must be 1-63 characters long and comply with + * RFC1035. Specifically, the name must match the regular expression + * {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a lowercase letter, + * and all following characters must be a dash, lowercase letter, or digit, except the last + * character, which cannot be a dash. * * @see RFC1035 */ - String address(); + public String address() { + return address; + } - /** - * Returns a fully qualified URL to the entity. - */ - String selfLink(); + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper().add("address", address); + } + + @Override + final int baseHashCode() { + return Objects.hash(super.baseHashCode(), address); + } + + @Override + final boolean baseEquals(ResourceId resourceId) { + return resourceId instanceof AddressId + && super.baseEquals(resourceId) + && Objects.equals(address, ((AddressId) resourceId).address); + } + + @Override + abstract AddressId setProjectId(String projectId); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java index cdf1fd42eedc..93fb1eff6aac 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java @@ -28,7 +28,7 @@ /** * Identity for a Google Compute Engine disk type. */ -public final class DiskTypeId extends ZoneResourceId { +public final class DiskTypeId extends ResourceId { static final Function FROM_URL_FUNCTION = new Function() { @Override @@ -43,14 +43,16 @@ public String apply(DiskTypeId diskTypeId) { } }; - private static final String REGEX = ZoneResourceId.REGEX + "diskTypes/([^/]+)"; + private static final String REGEX = ResourceId.REGEX + "zones/([^/]+)/diskTypes/([^/]+)"; private static final Pattern PATTERN = Pattern.compile(REGEX); private static final long serialVersionUID = 7337881474103686219L; + private final String zone; private final String diskType; private DiskTypeId(String project, String zone, String diskType) { - super(project, zone); + super(project); + this.zone = checkNotNull(zone); this.diskType = checkNotNull(diskType); } @@ -61,25 +63,40 @@ public String diskType() { return diskType; } + /** + * Returns the name of the zone this disk type belongs to. + */ + public String zone() { + return zone; + } + + /** + * Returns the identity of the zone this disk type belongs to. + */ + public ZoneId zoneId() { + return ZoneId.of(project(), zone); + } + @Override public String selfLink() { - return super.selfLink() + "/diskTypes/" + diskType; + return super.selfLink() + "/zones/" + zone + "/diskTypes/" + diskType; } @Override MoreObjects.ToStringHelper toStringHelper() { - return super.toStringHelper().add("diskType", diskType); + return super.toStringHelper().add("zone", zone).add("diskType", diskType); } @Override public int hashCode() { - return Objects.hash(super.baseHashCode(), diskType); + return Objects.hash(super.baseHashCode(), zone, diskType); } @Override public boolean equals(Object obj) { return obj instanceof DiskTypeId && baseEquals((DiskTypeId) obj) + && Objects.equals(zone, ((DiskTypeId) obj).zone) && Objects.equals(diskType, ((DiskTypeId) obj).diskType); } @@ -88,7 +105,7 @@ DiskTypeId setProjectId(String projectId) { if (project() != null) { return this; } - return DiskTypeId.of(projectId, zone(), diskType); + return DiskTypeId.of(projectId, zone, diskType); } /** diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ForwardingRuleId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ForwardingRuleId.java index ab0920de1b61..029f8c50f0a0 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ForwardingRuleId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ForwardingRuleId.java @@ -16,10 +16,25 @@ package com.google.gcloud.compute; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; + +import java.util.Objects; + /** * Interface for Google Compute Engine forwarding rule identities. */ -public interface ForwardingRuleId { +public abstract class ForwardingRuleId extends ResourceId { + + private static final long serialVersionUID = -4352410760458355391L; + + private final String rule; + + ForwardingRuleId(String project, String rule) { + super(project); + this.rule = checkNotNull(rule); + } /** * Possible types for a Google Compute Engine forwarding rule identity. @@ -30,6 +45,7 @@ enum Type { * load balancing. */ GLOBAL, + /** * Region forwarding rules are used to forward traffic to the correct pool of target virtual * machines. @@ -40,26 +56,38 @@ enum Type { /** * Returns the type of this forwarding rule identity. */ - Type type(); - - /** - * Returns the name of the project. - */ - String project(); + public abstract Type type(); /** - * Returns the name of the forwarding rule. The name must be 1-63 characters long, and comply with - * RFC1035. Specifically, the name must be 1-63 characters long and match the regular expression + * Returns the name of the forwarding rule. The forwarding rule name must be 1-63 characters long + * and comply with RFC1035. Specifically, the name must match the regular expression * {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a lowercase letter, * and all following characters must be a dash, lowercase letter, or digit, except the last * character, which cannot be a dash. * * @see RFC1035 */ - String rule(); + public String rule() { + return rule; + } - /** - * Returns a fully qualified URL to the entity. - */ - String selfLink(); + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper().add("rule", rule); + } + + @Override + final int baseHashCode() { + return Objects.hash(super.baseHashCode(), rule); + } + + @Override + final boolean baseEquals(ResourceId resourceId) { + return resourceId instanceof ForwardingRuleId + && super.baseEquals(resourceId) + && Objects.equals(rule, ((ForwardingRuleId) resourceId).rule); + } + + @Override + abstract ForwardingRuleId setProjectId(String projectId); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalAddressId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalAddressId.java index e7db4c56a5c3..dcda73ac7370 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalAddressId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalAddressId.java @@ -16,28 +16,20 @@ package com.google.gcloud.compute; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.base.MoreObjects.ToStringHelper; - -import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Identity for a Google Compute Engine global address. */ -public final class GlobalAddressId extends ResourceId implements AddressId { +public final class GlobalAddressId extends AddressId { private static final String REGEX = ResourceId.REGEX + "global/addresses/([^/]+)"; private static final Pattern PATTERN = Pattern.compile(REGEX); private static final long serialVersionUID = -2950815290049218593L; - private final String address; - private GlobalAddressId(String project, String address) { - super(project); - this.address = checkNotNull(address); + super(project, address); } @Override @@ -45,31 +37,19 @@ public Type type() { return Type.GLOBAL; } - @Override - public String address() { - return address; - } - @Override public String selfLink() { - return super.selfLink() + "/global/addresses/" + address; - } - - @Override - public ToStringHelper toStringHelper() { - return super.toStringHelper().add("address", address); + return super.selfLink() + "/global/addresses/" + address(); } @Override public int hashCode() { - return Objects.hash(baseHashCode(), address); + return baseHashCode(); } @Override public boolean equals(Object obj) { - return obj instanceof GlobalAddressId - && baseEquals((GlobalAddressId) obj) - && Objects.equals(address, ((GlobalAddressId) obj).address); + return obj instanceof GlobalAddressId && baseEquals((GlobalAddressId) obj); } @Override @@ -77,15 +57,15 @@ GlobalAddressId setProjectId(String projectId) { if (project() != null) { return this; } - return GlobalAddressId.of(projectId, address); + return GlobalAddressId.of(projectId, address()); } /** * Returns an address identity given the address name. The address name must be 1-63 characters - * long, and comply with RFC1035. Specifically, the name must be 1-63 characters long and match - * the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must - * be a lowercase letter, and all following characters must be a dash, lowercase letter, or digit, - * except the last character, which cannot be a dash. + * long and comply with RFC1035. Specifically, the name must match the regular expression + * {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a lowercase letter, + * and all following characters must be a dash, lowercase letter, or digit, except the last + * character, which cannot be a dash. * * @see RFC1035 */ @@ -95,10 +75,10 @@ public static GlobalAddressId of(String address) { /** * Returns an address identity given project and address names. The address name must be 1-63 - * characters long, and comply with RFC1035. Specifically, the name must be 1-63 characters long - * and match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first - * character must be a lowercase letter, and all following characters must be a dash, lowercase - * letter, or digit, except the last character, which cannot be a dash. + * characters long and comply with RFC1035. Specifically, the name must match the regular + * expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a + * lowercase letter, and all following characters must be a dash, lowercase letter, or digit, + * except the last character, which cannot be a dash. * * @see RFC1035 */ diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalForwardingRuleId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalForwardingRuleId.java index bd902ad3d6e0..1b37e9a1adef 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalForwardingRuleId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalForwardingRuleId.java @@ -16,19 +16,15 @@ package com.google.gcloud.compute; -import static com.google.common.base.Preconditions.checkNotNull; - import com.google.common.base.Function; -import com.google.common.base.MoreObjects; -import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Identity for a Google Compute Engine global forwarding rule. */ -public final class GlobalForwardingRuleId extends ResourceId implements ForwardingRuleId { +public final class GlobalForwardingRuleId extends ForwardingRuleId { static final Function FROM_URL_FUNCTION = new Function() { @@ -49,11 +45,8 @@ public String apply(GlobalForwardingRuleId forwardingRuleId) { private static final Pattern PATTERN = Pattern.compile(REGEX); private static final long serialVersionUID = -2648031793037534254L; - private final String rule; - private GlobalForwardingRuleId(String project, String rule) { - super(project); - this.rule = checkNotNull(rule); + super(project, rule); } @Override @@ -61,31 +54,19 @@ public Type type() { return Type.GLOBAL; } - @Override - public String rule() { - return rule; - } - @Override public String selfLink() { - return super.selfLink() + "/global/forwardingRules/" + rule; - } - - @Override - MoreObjects.ToStringHelper toStringHelper() { - return super.toStringHelper().add("rule", rule); + return super.selfLink() + "/global/forwardingRules/" + rule(); } @Override public int hashCode() { - return Objects.hash(baseHashCode(), rule); + return baseHashCode(); } @Override public boolean equals(Object obj) { - return obj instanceof GlobalForwardingRuleId - && baseEquals((GlobalForwardingRuleId) obj) - && Objects.equals(rule, ((GlobalForwardingRuleId) obj).rule); + return obj instanceof GlobalForwardingRuleId && baseEquals((GlobalForwardingRuleId) obj); } @Override @@ -93,15 +74,15 @@ GlobalForwardingRuleId setProjectId(String projectId) { if (project() != null) { return this; } - return GlobalForwardingRuleId.of(projectId, rule); + return GlobalForwardingRuleId.of(projectId, rule()); } /** * Returns a forwarding rule identity given the rule name. The forwarding rule name must be 1-63 - * characters long, and comply with RFC1035. Specifically, the name must be 1-63 characters long - * and match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first - * character must be a lowercase letter, and all following characters must be a dash, lowercase - * letter, or digit, except the last character, which cannot be a dash. + * characters long and comply with RFC1035. Specifically, the name must match the regular + * expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a + * lowercase letter, and all following characters must be a dash, lowercase letter, or digit, + * except the last character, which cannot be a dash. * * @see RFC1035 */ @@ -111,10 +92,10 @@ public static GlobalForwardingRuleId of(String rule) { /** * Returns a forwarding rule identity given the project rule names. The forwarding rule name must - * be 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 - * characters long and match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means - * the first character must be a lowercase letter, and all following characters must be a dash, - * lowercase letter, or digit, except the last character, which cannot be a dash. + * be 1-63 characters long and comply with RFC1035. Specifically, the name must match the regular + * expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a + * lowercase letter, and all following characters must be a dash, lowercase letter, or digit, + * except the last character, which cannot be a dash. * * @see RFC1035 */ diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalOperationId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalOperationId.java index c12e24c903cc..343b0cacc94c 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalOperationId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalOperationId.java @@ -16,28 +16,20 @@ package com.google.gcloud.compute; -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.base.MoreObjects; - -import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * Identity for a Google Compute Engine global operation. */ -public class GlobalOperationId extends ResourceId implements OperationId { +public final class GlobalOperationId extends OperationId { private static final String REGEX = ResourceId.REGEX + "global/operations/([^/]+)"; private static final Pattern PATTERN = Pattern.compile(REGEX); private static final long serialVersionUID = 3945756772641577962L; - private final String operation; - private GlobalOperationId(String project, String operation) { - super(project); - this.operation = checkNotNull(operation); + super(project, operation); } @Override @@ -45,31 +37,19 @@ public Type type() { return Type.GLOBAL; } - @Override - public String operation() { - return operation; - } - @Override public String selfLink() { - return super.selfLink() + "/global/operations/" + operation; - } - - @Override - MoreObjects.ToStringHelper toStringHelper() { - return super.toStringHelper().add("operation", operation); + return super.selfLink() + "/global/operations/" + operation(); } @Override public int hashCode() { - return Objects.hash(baseHashCode(), operation); + return baseHashCode(); } @Override public boolean equals(Object obj) { - return obj instanceof GlobalOperationId - && baseEquals((GlobalOperationId) obj) - && Objects.equals(operation, ((GlobalOperationId) obj).operation); + return obj instanceof GlobalOperationId && baseEquals((GlobalOperationId) obj); } @Override @@ -77,7 +57,7 @@ GlobalOperationId setProjectId(String projectId) { if (project() != null) { return this; } - return GlobalOperationId.of(projectId, operation); + return GlobalOperationId.of(projectId, operation()); } /** diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceId.java index fc6d91ccb0b4..5fcf19b3491c 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceId.java @@ -28,7 +28,7 @@ /** * Identity for a Google Compute Engine virtual machine instance. */ -public final class InstanceId extends ZoneResourceId { +public final class InstanceId extends ResourceId { static final Function FROM_URL_FUNCTION = new Function() { @Override @@ -43,23 +43,25 @@ public String apply(InstanceId instanceId) { } }; - private static final String REGEX = ZoneResourceId.REGEX + "instances/([^/]+)"; + private static final String REGEX = ResourceId.REGEX + "zones/([^/]+)/instances/([^/]+)"; private static final Pattern PATTERN = Pattern.compile(REGEX); private static final long serialVersionUID = -2787043125223159922L; + private final String zone; private final String instance; private InstanceId(String project, String zone, String instance) { - super(project, zone); + super(project); + this.zone = checkNotNull(zone); this.instance = checkNotNull(instance); } /** - * Returns the name of the instance. The instance name must be 1-63 characters long, and comply - * with RFC1035. Specifically, the name must be 1-63 characters long and match the regular - * expression [a-z]([-a-z0-9]*[a-z0-9])? which means the first character must be a lowercase - * letter, and all following characters must be a dash, lowercase letter, or digit, except the - * last character, which cannot be a dash. + * Returns the name of the instance. The name must be 1-63 characters long and comply with + * RFC1035. Specifically, the name must match the regular expression + * {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a lowercase letter, + * and all following characters must be a dash, lowercase letter, or digit, except the last + * character, which cannot be a dash. * * @see RFC1035 */ @@ -67,25 +69,40 @@ public String instance() { return instance; } + /** + * Returns the name of the zone this instance belongs to. + */ + public String zone() { + return zone; + } + + /** + * Returns the identity of the zone this instance belongs to. + */ + public ZoneId zoneId() { + return ZoneId.of(project(), zone); + } + @Override public String selfLink() { - return super.selfLink() + "/instances/" + instance; + return super.selfLink() + "/zones/" + zone + "/instances/" + instance; } @Override MoreObjects.ToStringHelper toStringHelper() { - return MoreObjects.toStringHelper(this).add("instance", instance); + return MoreObjects.toStringHelper(this).add("zone", zone).add("instance", instance); } @Override public int hashCode() { - return Objects.hash(super.baseHashCode(), instance); + return Objects.hash(super.baseHashCode(), zone, instance); } @Override public boolean equals(Object obj) { return obj instanceof InstanceId && baseEquals((InstanceId) obj) + && Objects.equals(zone, ((InstanceId) obj).zone) && Objects.equals(instance, ((InstanceId) obj).instance); } @@ -94,15 +111,15 @@ InstanceId setProjectId(String projectId) { if (project() != null) { return this; } - return InstanceId.of(projectId, zone(), instance); + return InstanceId.of(projectId, zone, instance); } /** * Returns an instance identity given the zone identity and the instance name. The instance name - * must be 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 - * characters long and match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means - * the first character must be a lowercase letter, and all following characters must be a dash, - * lowercase letter, or digit, except the last character, which cannot be a dash. + * must be 1-63 characters long and comply with RFC1035. Specifically, the name must match the + * regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a + * lowercase letter, and all following characters must be a dash, lowercase letter, or digit, + * except the last character, which cannot be a dash. * * @see RFC1035 */ @@ -112,10 +129,10 @@ public static InstanceId of(ZoneId zoneId, String instance) { /** * Returns an instance identity given the zone and instance names. The instance name must be 1-63 - * characters long, and comply with RFC1035. Specifically, the name must be 1-63 characters long - * and match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first - * character must be a lowercase letter, and all following characters must be a dash, lowercase - * letter, or digit, except the last character, which cannot be a dash. + * characters long and comply with RFC1035. Specifically, the name must match the regular + * expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a + * lowercase letter, and all following characters must be a dash, lowercase letter, or digit, + * except the last character, which cannot be a dash. * * @see RFC1035 */ @@ -125,10 +142,10 @@ public static InstanceId of(String zone, String instance) { /** * Returns an instance identity given project, zone and instance names. The instance name must be - * 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 characters - * long and match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first - * character must be a lowercase letter, and all following characters must be a dash, lowercase - * letter, or digit, except the last character, which cannot be a dash. + * 1-63 characters long and comply with RFC1035. Specifically, the name must match the regular + * expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a + * lowercase letter, and all following characters must be a dash, lowercase letter, or digit, + * except the last character, which cannot be a dash. * * @see RFC1035 */ diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java index 1252719e05d7..92daf2b05f60 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java @@ -28,7 +28,7 @@ /** * Identity for a Google Compute Engine machine type. */ -public final class MachineTypeId extends ZoneResourceId { +public final class MachineTypeId extends ResourceId { static final Function FROM_URL_FUNCTION = new Function() { @@ -45,14 +45,16 @@ public String apply(MachineTypeId machineTypeId) { } }; - private static final String REGEX = ZoneResourceId.REGEX + "machineTypes/([^/]+)"; + private static final String REGEX = ResourceId.REGEX + "zones/([^/]+)/machineTypes/([^/]+)"; private static final Pattern PATTERN = Pattern.compile(REGEX); private static final long serialVersionUID = -5819598544478859608L; + private final String zone; private final String machineType; private MachineTypeId(String project, String zone, String machineType) { - super(project, zone); + super(project); + this.zone = checkNotNull(zone); this.machineType = checkNotNull(machineType); } @@ -63,25 +65,40 @@ public String machineType() { return machineType; } + /** + * Returns the name of the zone this machine type belongs to. + */ + public String zone() { + return zone; + } + + /** + * Returns the identity of the zone this machine type belongs to. + */ + public ZoneId zoneId() { + return ZoneId.of(project(), zone); + } + @Override public String selfLink() { - return super.selfLink() + "/machineTypes/" + machineType; + return super.selfLink() + "/zones/" + zone + "/machineTypes/" + machineType; } @Override MoreObjects.ToStringHelper toStringHelper() { - return super.toStringHelper().add("machineType", machineType); + return super.toStringHelper().add("zone", zone).add("machineType", machineType); } @Override public int hashCode() { - return Objects.hash(baseHashCode(), machineType); + return Objects.hash(baseHashCode(), zone, machineType); } @Override public boolean equals(Object obj) { return obj instanceof MachineTypeId && baseEquals((MachineTypeId) obj) + && Objects.equals(zone, ((MachineTypeId) obj).zone) && Objects.equals(machineType, ((MachineTypeId) obj).machineType); } @@ -90,7 +107,7 @@ MachineTypeId setProjectId(String projectId) { if (project() != null) { return this; } - return MachineTypeId.of(projectId, zone(), machineType); + return MachineTypeId.of(projectId, zone, machineType); } /** diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/OperationId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/OperationId.java index 7f9100aa61a2..5ddf2dae43a2 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/OperationId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/OperationId.java @@ -16,10 +16,25 @@ package com.google.gcloud.compute; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; + +import java.util.Objects; + /** - * Interface for Google Compute Engine operation identities. + * Base class for Google Compute Engine operation identities. */ -public interface OperationId { +public abstract class OperationId extends ResourceId { + + private static final long serialVersionUID = -5502909279744388604L; + + private final String operation; + + OperationId(String project, String operation) { + super(project); + this.operation = checkNotNull(operation); + } /** * Possible types for a Google Compute Engine operation identity. @@ -30,11 +45,13 @@ enum Type { * addresses or snapshots. */ GLOBAL, + /** * Region operations are those operations that deal with resources that live in a region, such * as subnetworks. */ REGION, + /** * Zone operations are those operations that deal with resources that live in a zone, such as * disks and instances. @@ -45,20 +62,32 @@ enum Type { /** * Returns the type of this operation identity. */ - Type type(); - - /** - * Returns the name of the project. - */ - String project(); + public abstract Type type(); /** * Returns the name of the operation resource. */ - String operation(); + public String operation() { + return operation; + } - /** - * Returns a fully qualified URL to the operation. - */ - String selfLink(); + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper().add("operation", operation); + } + + @Override + final int baseHashCode() { + return Objects.hash(super.baseHashCode(), operation); + } + + @Override + final boolean baseEquals(ResourceId resourceId) { + return resourceId instanceof OperationId + && super.baseEquals(resourceId) + && Objects.equals(operation, ((OperationId) resourceId).operation); + } + + @Override + abstract OperationId setProjectId(String projectId); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionAddressId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionAddressId.java index d3927affed29..546d7eca6b79 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionAddressId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionAddressId.java @@ -27,17 +27,17 @@ /** * Identity for a Google Compute Engine region address. */ -public final class RegionAddressId extends RegionResourceId implements AddressId { +public final class RegionAddressId extends AddressId { - private static final String REGEX = RegionResourceId.REGEX + "addresses/([^/]+)"; + private static final String REGEX = ResourceId.REGEX + "regions/([^/]+)/addresses/([^/]+)"; private static final Pattern PATTERN = Pattern.compile(REGEX); private static final long serialVersionUID = 8170980880371085238L; - private final String address; + private final String region; private RegionAddressId(String project, String region, String address) { - super(project, region); - this.address = checkNotNull(address); + super(project, address); + this.region = checkNotNull(region); } @Override @@ -45,31 +45,40 @@ public Type type() { return Type.REGION; } - @Override - public String address() { - return address; + /** + * Returns the name of the region this address belongs to. + */ + public String region() { + return region; + } + + /** + * Returns the identity of the region this address belongs to. + */ + public RegionId regionId() { + return RegionId.of(project(), region); } @Override public String selfLink() { - return super.selfLink() + "/addresses/" + address; + return super.selfLink() + "/regions/" + region + "/addresses/" + address(); } @Override MoreObjects.ToStringHelper toStringHelper() { - return super.toStringHelper().add("address", address); + return super.toStringHelper().add("region", region); } @Override public int hashCode() { - return Objects.hash(baseHashCode(), address); + return Objects.hash(baseHashCode(), region); } @Override public boolean equals(Object obj) { return obj instanceof RegionAddressId && baseEquals((RegionAddressId) obj) - && Objects.equals(address, ((RegionAddressId) obj).address); + && Objects.equals(region, ((RegionAddressId) obj).region); } @Override @@ -77,7 +86,7 @@ RegionAddressId setProjectId(String projectId) { if (project() != null) { return this; } - return RegionAddressId.of(projectId, region(), address); + return RegionAddressId.of(projectId, region, address()); } /** @@ -95,10 +104,10 @@ public static RegionAddressId of(RegionId regionId, String address) { /** * Returns a region address identity given the region and address names. The address name must be - * 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 characters - * long and match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first - * character must be a lowercase letter, and all following characters must be a dash, lowercase - * letter, or digit, except the last character, which cannot be a dash. + * 1-63 characters long and comply with RFC1035. Specifically, the name must match the regular + * expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a + * lowercase letter, and all following characters must be a dash, lowercase letter, or digit, + * except the last character, which cannot be a dash. * * @see RFC1035 */ @@ -108,10 +117,10 @@ public static RegionAddressId of(String region, String address) { /** * Returns a region address identity given project, region and address names. The address name - * must be 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 - * characters long and match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means - * the first character must be a lowercase letter, and all following characters must be a dash, - * lowercase letter, or digit, except the last character, which cannot be a dash. + * must be 1-63 characters long and comply with RFC1035. Specifically, the name must match the + * regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a + * lowercase letter, and all following characters must be a dash, lowercase letter, or digit, + * except the last character, which cannot be a dash. * * @see RFC1035 */ diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionForwardingRuleId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionForwardingRuleId.java index bbdf0720273e..a982d88f5f42 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionForwardingRuleId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionForwardingRuleId.java @@ -28,7 +28,7 @@ /** * Identity for a Google Compute Engine region's forwarding rule. */ -public final class RegionForwardingRuleId extends RegionResourceId implements ForwardingRuleId { +public final class RegionForwardingRuleId extends ForwardingRuleId { static final Function FROM_URL_FUNCTION = new Function() { @@ -45,15 +45,15 @@ public String apply(RegionForwardingRuleId forwardingRuleId) { } }; - private static final String REGEX = RegionResourceId.REGEX + "forwardingRules/([^/]+)"; + private static final String REGEX = ResourceId.REGEX + "regions/([^/]+)/forwardingRules/([^/]+)"; private static final Pattern PATTERN = Pattern.compile(REGEX); private static final long serialVersionUID = 7885327931402904667L; - private final String rule; + private final String region; private RegionForwardingRuleId(String project, String region, String rule) { - super(project, region); - this.rule = checkNotNull(rule); + super(project, rule); + this.region = checkNotNull(region); } @Override @@ -61,31 +61,40 @@ public Type type() { return Type.REGION; } - @Override - public String rule() { - return rule; + /** + * Returns the name of the region this forwarding rule belongs to. + */ + public String region() { + return region; + } + + /** + * Returns the identity of the region this forwarding rule belongs to. + */ + public RegionId regionId() { + return RegionId.of(project(), region); } @Override public String selfLink() { - return super.selfLink() + "/forwardingRules/" + rule; + return super.selfLink() + "/regions/" + region + "/forwardingRules/" + rule(); } @Override MoreObjects.ToStringHelper toStringHelper() { - return MoreObjects.toStringHelper(this).add("rule", rule); + return MoreObjects.toStringHelper(this).add("region", region); } @Override public int hashCode() { - return Objects.hash(baseHashCode(), rule); + return Objects.hash(baseHashCode(), region); } @Override public boolean equals(Object obj) { return obj instanceof RegionForwardingRuleId && baseEquals((RegionForwardingRuleId) obj) - && Objects.equals(rule, ((RegionForwardingRuleId) obj).rule); + && Objects.equals(region, ((RegionForwardingRuleId) obj).region); } @Override @@ -93,47 +102,46 @@ RegionForwardingRuleId setProjectId(String projectId) { if (project() != null) { return this; } - return RegionForwardingRuleId.of(projectId, region(), rule); + return RegionForwardingRuleId.of(projectId, region, rule()); } /** * Returns a region forwarding rule identity given the region identity and the rule name. The - * forwarding rule name must be 1-63 characters long, and comply with RFC1035. Specifically, the - * name must be 1-63 characters long and match the regular expression - * {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a lowercase letter, - * and all following characters must be a dash, lowercase letter, or digit, except the last - * character, which cannot be a dash. + * forwarding rule name must be 1-63 characters long and comply with RFC1035. Specifically, the + * name must match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first + * character must be a lowercase letter, and all following characters must be a dash, lowercase + * letter, or digit, except the last character, which cannot be a dash. * * @see RFC1035 */ - public static RegionForwardingRuleId of(RegionId regionId, String operation) { - return new RegionForwardingRuleId(regionId.project(), regionId.region(), operation); + public static RegionForwardingRuleId of(RegionId regionId, String rule) { + return new RegionForwardingRuleId(regionId.project(), regionId.region(), rule); } /** * Returns a region forwarding rule identity given the region and rule names. The forwarding rule - * name must be 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 - * characters long and match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means - * the first character must be a lowercase letter, and all following characters must be a dash, - * lowercase letter, or digit, except the last character, which cannot be a dash. + * name must be 1-63 characters long and comply with RFC1035. Specifically, the name must match + * the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must + * be a lowercase letter, and all following characters must be a dash, lowercase letter, or digit, + * except the last character, which cannot be a dash. * * @see RFC1035 */ - public static RegionForwardingRuleId of(String region, String operation) { - return new RegionForwardingRuleId(null, region, operation); + public static RegionForwardingRuleId of(String region, String rule) { + return new RegionForwardingRuleId(null, region, rule); } /** * Returns a region forwarding rule identity given project, region and rule names. The forwarding - * rule name must be 1-63 characters long, and comply with RFC1035. Specifically, the name must be - * 1-63 characters long and match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which - * means the first character must be a lowercase letter, and all following characters must be a - * dash, lowercase letter, or digit, except the last character, which cannot be a dash. + * rule name must be 1-63 characters long and comply with RFC1035. Specifically, the name must + * match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character + * must be a lowercase letter, and all following characters must be a dash, lowercase letter, or + * digit, except the last character, which cannot be a dash. * * @see RFC1035 */ - public static RegionForwardingRuleId of(String project, String region, String operation) { - return new RegionForwardingRuleId(project, region, operation); + public static RegionForwardingRuleId of(String project, String region, String rule) { + return new RegionForwardingRuleId(project, region, rule); } /** diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionOperationId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionOperationId.java index 96a772b5b9ea..7608cfaa913f 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionOperationId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionOperationId.java @@ -27,17 +27,17 @@ /** * Identity for a Google Compute Engine region's operation. */ -public final class RegionOperationId extends RegionResourceId implements OperationId { +public final class RegionOperationId extends OperationId { - private static final String REGEX = RegionResourceId.REGEX + "operations/([^/]+)"; + private static final String REGEX = ResourceId.REGEX + "regions/([^/]+)/operations/([^/]+)"; private static final Pattern PATTERN = Pattern.compile(REGEX); private static final long serialVersionUID = 5816161906501886782L; - private final String operation; + private final String region; private RegionOperationId(String project, String region, String operation) { - super(project, region); - this.operation = checkNotNull(operation); + super(project, operation); + this.region = checkNotNull(region); } @Override @@ -45,31 +45,40 @@ public Type type() { return Type.REGION; } - @Override - public String operation() { - return operation; + /** + * Returns the name of the region this operation belongs to. + */ + public String region() { + return region; + } + + /** + * Returns the identity of the region this operation belongs to. + */ + public RegionId regionId() { + return RegionId.of(project(), region); } @Override public String selfLink() { - return super.selfLink() + "/operations/" + operation; + return super.selfLink() + "/regions/" + region + "/operations/" + operation(); } @Override MoreObjects.ToStringHelper toStringHelper() { - return MoreObjects.toStringHelper(this).add("operation", operation); + return MoreObjects.toStringHelper(this).add("region", region); } @Override public int hashCode() { - return Objects.hash(baseHashCode(), operation); + return Objects.hash(baseHashCode(), region); } @Override public boolean equals(Object obj) { return obj instanceof RegionOperationId && baseEquals((RegionOperationId) obj) - && Objects.equals(operation, ((RegionOperationId) obj).operation); + && Objects.equals(region, ((RegionOperationId) obj).region); } @Override @@ -77,7 +86,7 @@ RegionOperationId setProjectId(String projectId) { if (project() != null) { return this; } - return RegionOperationId.of(projectId, region(), operation); + return RegionOperationId.of(projectId, region, operation()); } /** diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionResourceId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionResourceId.java deleted file mode 100644 index eeb288b07be1..000000000000 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionResourceId.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2016 Google Inc. All Rights Reserved. - * - * 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.gcloud.compute; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.base.MoreObjects.ToStringHelper; - -import java.util.Objects; - -/** - * A base class for the identity of Google Compute Engine resources that live in a region. - */ -public abstract class RegionResourceId extends ResourceId { - - static final String REGEX = ResourceId.REGEX + "regions/([^/]+)/"; - private static final long serialVersionUID = 5569092266957249294L; - - private final String region; - - RegionResourceId(String project, String region) { - super(project); - this.region = checkNotNull(region); - } - - RegionResourceId(RegionId regionId) { - super(regionId.project()); - this.region = checkNotNull(regionId.region()); - } - - /** - * Returns the name of the region this resource belongs to. - */ - public final String region() { - return region; - } - - /** - * Returns the identity of the region this resource belongs to. - */ - public final RegionId regionId() { - return RegionId.of(project(), region); - } - - @Override - public String selfLink() { - return super.selfLink() + "/regions/" + region; - } - - @Override - ToStringHelper toStringHelper() { - return super.toStringHelper().add("region", region); - } - - @Override - final int baseHashCode() { - return Objects.hash(super.baseHashCode(), region); - } - - @Override - final boolean baseEquals(ResourceId resourceId) { - return resourceId instanceof RegionResourceId - && super.baseEquals(resourceId) - && Objects.equals(region, ((RegionResourceId) resourceId).region); - } -} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneOperationId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneOperationId.java index 837ca6888c83..99161b0f4eda 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneOperationId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneOperationId.java @@ -27,17 +27,17 @@ /** * Identity for a Google Compute Engine zone operation. */ -public final class ZoneOperationId extends ZoneResourceId implements OperationId { +public final class ZoneOperationId extends OperationId { - private static final String REGEX = ZoneResourceId.REGEX + "operations/([^/]+)"; + private static final String REGEX = ResourceId.REGEX + "zones/([^/]+)/operations/([^/]+)"; private static final Pattern PATTERN = Pattern.compile(REGEX); private static final long serialVersionUID = 4910670262094017392L; - private final String operation; + private final String zone; private ZoneOperationId(String project, String zone, String operation) { - super(project, zone); - this.operation = checkNotNull(operation); + super(project, operation); + this.zone = checkNotNull(zone); } @Override @@ -45,31 +45,40 @@ public Type type() { return Type.ZONE; } - @Override - public String operation() { - return operation; + /** + * Returns the name of the zone this operation belongs to. + */ + public String zone() { + return zone; + } + + /** + * Returns the identity of the zone this address belongs to. + */ + public ZoneId zoneId() { + return ZoneId.of(project(), zone); } @Override public String selfLink() { - return super.selfLink() + "/operations/" + operation; + return super.selfLink() + "/zones/" + zone + "/operations/" + operation(); } @Override MoreObjects.ToStringHelper toStringHelper() { - return MoreObjects.toStringHelper(this).add("operation", operation); + return MoreObjects.toStringHelper(this).add("zone", zone); } @Override public int hashCode() { - return Objects.hash(baseHashCode(), operation); + return Objects.hash(baseHashCode(), zone); } @Override public boolean equals(Object obj) { return obj instanceof ZoneOperationId && baseEquals((ZoneOperationId) obj) - && Objects.equals(operation, ((ZoneOperationId) obj).operation); + && Objects.equals(zone, ((ZoneOperationId) obj).zone); } @Override @@ -77,7 +86,7 @@ ZoneOperationId setProjectId(String projectId) { if (project() != null) { return this; } - return ZoneOperationId.of(projectId, zone(), operation); + return ZoneOperationId.of(projectId, zone, operation()); } /** diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneResourceId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneResourceId.java deleted file mode 100644 index 60117684c056..000000000000 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneResourceId.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2016 Google Inc. All Rights Reserved. - * - * 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.gcloud.compute; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.common.base.MoreObjects.ToStringHelper; - -import java.util.Objects; - -/** - * A base class for the identity of Google Compute Engine resources that live in a zone. - */ -public abstract class ZoneResourceId extends ResourceId { - - static final String REGEX = ResourceId.REGEX + "zones/([^/]+)/"; - private static final long serialVersionUID = -6249546895344926888L; - - private final String zone; - - ZoneResourceId(String project, String zone) { - super(project); - this.zone = checkNotNull(zone); - } - - ZoneResourceId(ZoneId zoneId) { - super(zoneId.project()); - this.zone = checkNotNull(zoneId.zone()); - } - - /** - * Returns the name of the zone this resource belongs to. - */ - public final String zone() { - return zone; - } - - /** - * Returns the identity of the zone this resource belongs to. - */ - public final ZoneId zoneId() { - return ZoneId.of(project(), zone); - } - - @Override - public String selfLink() { - return super.selfLink() + "/zones/" + zone; - } - - @Override - ToStringHelper toStringHelper() { - return super.toStringHelper().add("zone", zone); - } - - @Override - final int baseHashCode() { - return Objects.hash(super.baseHashCode(), zone); - } - - @Override - final boolean baseEquals(ResourceId resourceId) { - return resourceId instanceof ZoneResourceId - && super.baseEquals(resourceId) - && Objects.equals(zone, ((ZoneResourceId) resourceId).zone); - } -} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressIdTest.java index 2d3e1a63c613..804744af5615 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressIdTest.java @@ -65,16 +65,20 @@ public void testOf() { } @Test - public void testToAndFromUrl() { + public void testToAndFromUrlGlobal() { GlobalAddressId addressId = GlobalAddressId.of(PROJECT, NAME); compareAddressId(addressId, GlobalAddressId.fromUrl(addressId.selfLink())); thrown.expect(IllegalArgumentException.class); thrown.expectMessage("notMatchingUrl is not a valid global address URL"); GlobalAddressId.fromUrl("notMatchingUrl"); + } + + @Test + public void testToAndFromUrlRegion() { RegionAddressId regionAddressId = RegionAddressId.of(PROJECT, REGION, NAME); compareRegionAddressId(regionAddressId, RegionAddressId.fromUrl(regionAddressId.selfLink())); thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("notMatchingUrl is not a valid global address URL"); + thrown.expectMessage("notMatchingUrl is not a valid region address URL"); RegionAddressId.fromUrl("notMatchingUrl"); } @@ -84,6 +88,7 @@ public void testSetProjectId() { assertSame(addressId, addressId.setProjectId(PROJECT)); compareAddressId(addressId, GlobalAddressId.of(NAME).setProjectId(PROJECT)); RegionAddressId regionAddressId = RegionAddressId.of(PROJECT, REGION, NAME); + assertSame(regionAddressId, regionAddressId.setProjectId(PROJECT)); compareRegionAddressId(regionAddressId, RegionAddressId.of(REGION, NAME).setProjectId(PROJECT)); } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ForwardingRuleIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ForwardingRuleIdTest.java index e15059623fa7..9a6ab4b8668e 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ForwardingRuleIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ForwardingRuleIdTest.java @@ -71,7 +71,7 @@ public void testOf() { } @Test - public void testToAndFromUrl() { + public void testToAndFromUrlGlobal() { GlobalForwardingRuleId forwardingRuleId = GlobalForwardingRuleId.of(PROJECT, NAME); compareGlobalForwardingRuleId(forwardingRuleId, GlobalForwardingRuleId.fromUrl(forwardingRuleId.selfLink())); @@ -79,6 +79,20 @@ public void testToAndFromUrl() { RegionForwardingRuleId.of(PROJECT, REGION, NAME); compareRegionForwardingRuleId(regionForwardingRuleId, RegionForwardingRuleId.fromUrl(regionForwardingRuleId.selfLink())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid global forwarding rule URL"); + GlobalForwardingRuleId.fromUrl("notMatchingUrl"); + } + + @Test + public void testToAndFromUrlRegion() { + RegionForwardingRuleId regionForwardingRuleId = + RegionForwardingRuleId.of(PROJECT, REGION, NAME); + compareRegionForwardingRuleId(regionForwardingRuleId, + RegionForwardingRuleId.fromUrl(regionForwardingRuleId.selfLink())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid region forwarding rule URL"); + RegionForwardingRuleId.fromUrl("notMatchingUrl"); } @Test @@ -87,22 +101,17 @@ public void testSetProjectId() { assertSame(forwardingRuleId, forwardingRuleId.setProjectId(PROJECT)); compareGlobalForwardingRuleId(forwardingRuleId, GlobalForwardingRuleId.of(NAME).setProjectId(PROJECT)); - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("notMatchingUrl is not a valid global forwarding rule URL"); - GlobalForwardingRuleId.fromUrl("notMatchingUrl"); RegionForwardingRuleId regionForwardingRuleId = RegionForwardingRuleId.of(PROJECT, REGION, NAME); assertSame(regionForwardingRuleId, regionForwardingRuleId.setProjectId(PROJECT)); compareRegionForwardingRuleId(regionForwardingRuleId, RegionForwardingRuleId.of(REGION, NAME).setProjectId(PROJECT)); - thrown.expect(IllegalArgumentException.class); - thrown.expectMessage("notMatchingUrl is not a valid region forwarding rule URL"); - RegionForwardingRuleId.fromUrl("notMatchingUrl"); } @Test public void testMatchesUrl() { - assertTrue(GlobalForwardingRuleId.matchesUrl(GlobalForwardingRuleId.of(PROJECT, NAME).selfLink())); + assertTrue(GlobalForwardingRuleId.matchesUrl( + GlobalForwardingRuleId.of(PROJECT, NAME).selfLink())); assertFalse(GlobalForwardingRuleId.matchesUrl("notMatchingUrl")); assertTrue(RegionForwardingRuleId.matchesUrl( RegionForwardingRuleId.of(PROJECT, REGION, NAME).selfLink())); From 6e1a3f920c375b3ab5d0c4e2fb1d5e6b78874674 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 21 Mar 2016 12:36:44 +0100 Subject: [PATCH 293/375] Refactor Address and AddressInfo classes - Better class javadoc - Refactor setProjectId to avoid unnecessary casts - Make addressId setter public in Builder and subclasses - Add test to AddressTest for addressId setter --- .../com/google/gcloud/compute/Address.java | 23 ++++--- .../google/gcloud/compute/AddressInfo.java | 60 +++++++++---------- .../google/gcloud/compute/AddressTest.java | 14 ++++- 3 files changed, 51 insertions(+), 46 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java index 44a526b09241..b30293fb6d48 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java @@ -24,13 +24,12 @@ /** * A Google Compute Engine address. With Compute Engine you can create static external IP addresses - * that are assigned to your project and persists until you explicitly release them. A region - * address can be assigned to a Compute Engine instance or to a regional forwarding rule. Compute - * Engine also allows to create global addresses that are used for global forwarding rules. Both - * global addresses and global forwarding rules can only be used for HTTP load balancing. - * {@code Address} adds a layer of service-related functionality over {@link AddressInfo}. Objects - * of this class are immutable. To get an {@code Address} object with the most recent information - * use {@link #reload}. + * that are assigned to your project and persist until you explicitly release them. A region address + * can be assigned to a Compute Engine instance or to a regional forwarding rule. Compute Engine + * also allows you to create global addresses that are used for global forwarding rules. Both global + * addresses and global forwarding rules can only be used for HTTP load balancing. {@code Address} + * adds a layer of service-related functionality over {@link AddressInfo}. Objects of this class are + * immutable. To get an {@code Address} object with the most recent information use {@link #reload}. * * @see * Static external IP addresses @@ -87,7 +86,7 @@ Builder id(String id) { } @Override - Builder addressId(AddressId addressId) { + public Builder addressId(AddressId addressId) { infoBuilder.addressId(addressId); return this; } @@ -122,19 +121,19 @@ public Address build() { * @return {@code true} if this address exists, {@code false} otherwise * @throws ComputeException upon failure */ - public boolean exists() throws ComputeException { + public boolean exists() { return reload(Compute.AddressOption.fields()) != null; } /** - * Fetches current address' latest information. Returns {@code null} if the address does not + * Fetches the current address' latest information. Returns {@code null} if the address does not * exist. * * @param options address options * @return an {@code Address} object with latest information or {@code null} if not found * @throws ComputeException upon failure */ - public Address reload(Compute.AddressOption... options) throws ComputeException { + public Address reload(Compute.AddressOption... options) { return compute.get(addressId(), options); } @@ -145,7 +144,7 @@ public Address reload(Compute.AddressOption... options) throws ComputeException * the address was not found * @throws ComputeException upon failure */ - public Operation delete(Compute.OperationOption... options) throws ComputeException { + public Operation delete(Compute.OperationOption... options) { return compute.delete(addressId(), options); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressInfo.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressInfo.java index 18554ea7f241..0d5880201b61 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressInfo.java @@ -34,11 +34,11 @@ /** * A Google Compute Engine address. With Compute Engine you can create static external IP addresses - * that are assigned to your project and persists until you explicitly release them. A region - * address can be assigned to a Compute Engine instance or to a regional forwarding rule. To create - * a region address use a {@link RegionAddressId} identity. Compute Engine also allows to create - * global addresses that are used for global forwarding rules. Both global addresses and global - * forwarding rules can only be used for HTTP load balancing. To create a global address use a + * that are assigned to your project and persist until you explicitly release them. A region address + * can be assigned to a Compute Engine instance or to a regional forwarding rule. To create a region + * address, use a {@link RegionAddressId} identity. Compute Engine also allows you to create global + * addresses that are used for global forwarding rules. Both global addresses and global forwarding + * rules can only be used for HTTP load balancing. To create a global address, use a * {@link GlobalAddressId} identity. * * @see @@ -94,8 +94,8 @@ public enum Status { * class represent different possible usages of a Compute Engine address. {@link InstanceUsage} * contains information for region addresses assigned to a Google Compute Engine instance. * {@link RegionForwardingUsage} contains information for region addresses assigned to one or more - * region forwarding rule. {@link GlobalForwardingUsage} contains information for global addresses - * assigned to one or more global forwarding rule. + * region forwarding rules. {@link GlobalForwardingUsage} contains information for global + * addresses assigned to one or more global forwarding rules. */ public abstract static class Usage implements Serializable { @@ -106,7 +106,7 @@ public abstract static class Usage implements Serializable { /** * Returns the identities of resources currently using this address. */ - public abstract List users(); + public abstract List users(); final boolean baseEquals(Usage usage) { return Objects.equals(toPb(), usage.toPb()); @@ -128,8 +128,10 @@ static T fromPb(Address addressPb) { return (T) InstanceUsage.fromPb(addressPb); } else if (RegionForwardingRuleId.matchesUrl(url)) { return (T) RegionForwardingUsage.fromPb(addressPb); - } else { + } else if (GlobalForwardingRuleId.matchesUrl(url)) { return (T) GlobalForwardingUsage.fromPb(addressPb); + } else { + throw new IllegalArgumentException("Unexpected resource URL for address user"); } } } @@ -156,8 +158,8 @@ public InstanceId instance() { } @Override - public List users() { - return ImmutableList.of(instance); + public List users() { + return ImmutableList.of(instance); } @Override @@ -203,9 +205,8 @@ public List forwardingRules() { } @Override - @SuppressWarnings("unchecked") - public List users() { - return (List) (List) forwardingRules; + public List users() { + return forwardingRules; } @Override @@ -252,9 +253,8 @@ public List forwardingRules() { } @Override - @SuppressWarnings("unchecked") - public List users() { - return (List) (List) forwardingRules; + public List users() { + return forwardingRules; } @Override @@ -298,7 +298,7 @@ public abstract static class Builder { abstract Builder id(String id); - abstract Builder addressId(AddressId addressId); + public abstract Builder addressId(AddressId addressId); abstract Builder status(Status status); @@ -379,7 +379,7 @@ BuilderImpl id(String id) { } @Override - BuilderImpl addressId(AddressId addressId) { + public BuilderImpl addressId(AddressId addressId) { this.addressId = checkNotNull(addressId); return this; } @@ -457,11 +457,11 @@ public Status status() { } /** - * Returns the usage information of the address. Returns a {@link InstanceUsage} object for region - * addresses that are assigned to VM instances. Returns a {@link RegionForwardingUsage} object for - * region addresses assigned to region forwarding rules. Returns a {@link GlobalForwardingUsage} - * object for global addresses assigned to global forwarding rules. Returns {@code null} if the - * address is not in use. + * Returns the usage information of the address. Returns an {@link InstanceUsage} object for + * region addresses that are assigned to VM instances. Returns a {@link RegionForwardingUsage} + * object for region addresses assigned to region forwarding rules. Returns a + * {@link GlobalForwardingUsage} object for global addresses assigned to global forwarding rules. + * Returns {@code null} if the address is not in use. */ @SuppressWarnings("unchecked") public T usage() { @@ -501,14 +501,10 @@ public boolean equals(Object obj) { } AddressInfo setProjectId(String projectId) { - Builder builder = toBuilder(); - AddressId addressIdWithProject; - if (addressId instanceof RegionAddressId) { - addressIdWithProject = this.addressId().setProjectId(projectId); - } else { - addressIdWithProject = this.addressId().setProjectId(projectId); - } - return builder.addressId(addressIdWithProject).build(); + if (addressId().project() != null) { + return this; + } + return toBuilder().addressId(addressId.setProjectId(projectId)).build(); } Address toPb() { diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressTest.java index d6082343b2d3..230f603271f9 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressTest.java @@ -32,7 +32,6 @@ import org.junit.After; import org.junit.Test; -import java.math.BigInteger; import java.util.List; public class AddressTest { @@ -114,7 +113,7 @@ public void tearDown() throws Exception { @Test public void testBuilder() { - initializeExpectedAddress(5); + initializeExpectedAddress(6); assertEquals(ADDRESS, instanceAddress.address()); assertEquals(CREATION_TIMESTAMP, instanceAddress.creationTimestamp()); assertEquals(DESCRIPTION, instanceAddress.description()); @@ -157,6 +156,17 @@ public void testBuilder() { assertNull(address.id()); assertNull(address.status()); assertNull(address.usage()); + address = new Address.Builder(serviceMockReturnsOptions, REGION_ADDRESS_ID) + .addressId(GLOBAL_ADDRESS_ID) + .build(); + assertEquals(GLOBAL_ADDRESS_ID, address.addressId()); + assertSame(serviceMockReturnsOptions, address.compute()); + assertNull(address.address()); + assertNull(address.creationTimestamp()); + assertNull(address.description()); + assertNull(address.id()); + assertNull(address.status()); + assertNull(address.usage()); } @Test From e56cb4b7be99939d2e25f695dbdd924e0bc462d4 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 21 Mar 2016 12:38:58 +0100 Subject: [PATCH 294/375] Remove unused imports --- .../src/main/java/com/google/gcloud/spi/ComputeRpc.java | 6 ------ .../test/java/com/google/gcloud/compute/DiskTypeTest.java | 2 -- .../src/test/java/com/google/gcloud/compute/RegionTest.java | 1 - .../src/test/java/com/google/gcloud/compute/ZoneTest.java | 1 - 4 files changed, 10 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java index 7d1f2384063f..66152f5464a4 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java @@ -17,17 +17,11 @@ package com.google.gcloud.spi; import com.google.api.services.compute.model.Address; -import com.google.api.services.compute.model.DeprecationStatus; -import com.google.api.services.compute.model.Disk; import com.google.api.services.compute.model.DiskType; -import com.google.api.services.compute.model.Image; import com.google.api.services.compute.model.License; import com.google.api.services.compute.model.MachineType; -import com.google.api.services.compute.model.Network; import com.google.api.services.compute.model.Operation; import com.google.api.services.compute.model.Region; -import com.google.api.services.compute.model.Snapshot; -import com.google.api.services.compute.model.Subnetwork; import com.google.api.services.compute.model.Zone; import com.google.gcloud.compute.ComputeException; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java index 7cacf256523a..9e97b8d1becd 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java @@ -20,8 +20,6 @@ import org.junit.Test; -import java.math.BigInteger; - public class DiskTypeTest { private static final String ID = "42"; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java index 072823933110..fb0250366a5e 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java @@ -22,7 +22,6 @@ import org.junit.Test; -import java.math.BigInteger; import java.util.List; public class RegionTest { diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java index bdc96d3d9069..d686054b8cf6 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java @@ -23,7 +23,6 @@ import org.junit.Test; -import java.math.BigInteger; import java.util.List; public class ZoneTest { From 6f9ff3478f7eb7b85ae3da36d70ca28f656b9ab9 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 21 Mar 2016 12:42:46 +0100 Subject: [PATCH 295/375] Refactor Compute service class - Rename startPageToken option to pageToken - Add static factory methods from functional objects fromPb functions - Add tests for get methods that return null --- .../com/google/gcloud/compute/Compute.java | 42 +++--- .../google/gcloud/compute/ComputeImpl.java | 60 ++++---- .../gcloud/compute/ComputeImplTest.java | 134 ++++++++++++++++-- 3 files changed, 165 insertions(+), 71 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java index a2d41542d28a..815b5ebe49e6 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java @@ -799,11 +799,11 @@ class AddressFilter extends ListFilter { } /** - * Returns an equality filter for the given field and string value. For string fields, + * Returns an equals filter for the given field and string value. For string fields, * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must * match the entire field. * - * @see RE2 + * @see RE2 */ public static AddressFilter equals(AddressField field, String value) { return new AddressFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value)); @@ -855,7 +855,7 @@ private DiskTypeListOption(ComputeRpc.Option option, Object value) { } /** - * Returns an option to specify a filter to the disk types being listed. + * Returns an option to specify a filter on the disk types being listed. */ public static DiskTypeListOption filter(DiskTypeFilter filter) { return new DiskTypeListOption(ComputeRpc.Option.FILTER, filter.toPb()); @@ -871,7 +871,7 @@ public static DiskTypeListOption pageSize(long pageSize) { /** * Returns an option to specify the page token from which to start listing disk types. */ - public static DiskTypeListOption startPageToken(String pageToken) { + public static DiskTypeListOption pageToken(String pageToken) { return new DiskTypeListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); } @@ -900,7 +900,7 @@ private DiskTypeAggregatedListOption(ComputeRpc.Option option, Object value) { } /** - * Returns an option to specify a filter to the disk types being listed. + * Returns an option to specify a filter on the disk types being listed. */ public static DiskTypeAggregatedListOption filter(DiskTypeFilter filter) { return new DiskTypeAggregatedListOption(ComputeRpc.Option.FILTER, filter.toPb()); @@ -916,7 +916,7 @@ public static DiskTypeAggregatedListOption pageSize(long pageSize) { /** * Returns an option to specify the page token from which to start listing disk types. */ - public static DiskTypeAggregatedListOption startPageToken(String pageToken) { + public static DiskTypeAggregatedListOption pageToken(String pageToken) { return new DiskTypeAggregatedListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); } } @@ -955,7 +955,7 @@ private MachineTypeListOption(ComputeRpc.Option option, Object value) { } /** - * Returns an option to specify a filter to the machine types being listed. + * Returns an option to specify a filter on the machine types being listed. */ public static MachineTypeListOption filter(MachineTypeFilter filter) { return new MachineTypeListOption(ComputeRpc.Option.FILTER, filter.toPb()); @@ -971,7 +971,7 @@ public static MachineTypeListOption pageSize(long pageSize) { /** * Returns an option to specify the page token from which to start listing machine types. */ - public static MachineTypeListOption startPageToken(String pageToken) { + public static MachineTypeListOption pageToken(String pageToken) { return new MachineTypeListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); } @@ -1000,7 +1000,7 @@ private MachineTypeAggregatedListOption(ComputeRpc.Option option, Object value) } /** - * Returns an option to specify a filter to the machine types being listed. + * Returns an option to specify a filter on the machine types being listed. */ public static MachineTypeAggregatedListOption filter(MachineTypeFilter filter) { return new MachineTypeAggregatedListOption(ComputeRpc.Option.FILTER, filter.toPb()); @@ -1016,7 +1016,7 @@ public static MachineTypeAggregatedListOption pageSize(long pageSize) { /** * Returns an option to specify the page token from which to start listing machine types. */ - public static MachineTypeAggregatedListOption startPageToken(String pageToken) { + public static MachineTypeAggregatedListOption pageToken(String pageToken) { return new MachineTypeAggregatedListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); } } @@ -1055,7 +1055,7 @@ private RegionListOption(ComputeRpc.Option option, Object value) { } /** - * Returns an option to specify a filter to the regions being listed. + * Returns an option to specify a filter on the regions being listed. */ public static RegionListOption filter(RegionFilter filter) { return new RegionListOption(ComputeRpc.Option.FILTER, filter.toPb()); @@ -1071,7 +1071,7 @@ public static RegionListOption pageSize(long pageSize) { /** * Returns an option to specify the page token from which to start listing regions. */ - public static RegionListOption startPageToken(String pageToken) { + public static RegionListOption pageToken(String pageToken) { return new RegionListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); } @@ -1122,7 +1122,7 @@ private ZoneListOption(ComputeRpc.Option option, Object value) { } /** - * Returns an option to specify a filter to the zones being listed. + * Returns an option to specify a filter on the zones being listed. */ public static ZoneListOption filter(ZoneFilter filter) { return new ZoneListOption(ComputeRpc.Option.FILTER, filter.toPb()); @@ -1138,7 +1138,7 @@ public static ZoneListOption pageSize(long pageSize) { /** * Returns an option to specify the page token from which to start listing zones. */ - public static ZoneListOption startPageToken(String pageToken) { + public static ZoneListOption pageToken(String pageToken) { return new ZoneListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); } @@ -1211,7 +1211,7 @@ private OperationListOption(ComputeRpc.Option option, Object value) { } /** - * Returns an option to specify a filter to the operations being listed. + * Returns an option to specify a filter on the operations being listed. */ public static OperationListOption filter(OperationFilter filter) { return new OperationListOption(ComputeRpc.Option.FILTER, filter.toPb()); @@ -1227,7 +1227,7 @@ public static OperationListOption pageSize(long pageSize) { /** * Returns an option to specify the page token from which to start listing operations. */ - public static OperationListOption startPageToken(String pageToken) { + public static OperationListOption pageToken(String pageToken) { return new OperationListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); } @@ -1278,7 +1278,7 @@ private AddressListOption(ComputeRpc.Option option, Object value) { } /** - * Returns an option to specify a filter to the addresses being listed. + * Returns an option to specify a filter on the addresses being listed. */ public static AddressListOption filter(AddressFilter filter) { return new AddressListOption(ComputeRpc.Option.FILTER, filter.toPb()); @@ -1294,7 +1294,7 @@ public static AddressListOption pageSize(long pageSize) { /** * Returns an option to specify the page token from which to start listing addresses. */ - public static AddressListOption startPageToken(String pageToken) { + public static AddressListOption pageToken(String pageToken) { return new AddressListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); } @@ -1323,7 +1323,7 @@ private AddressAggregatedListOption(ComputeRpc.Option option, Object value) { } /** - * Returns an option to specify a filter to the addresses being listed. + * Returns an option to specify a filter on the addresses being listed. */ public static AddressAggregatedListOption filter(AddressFilter filter) { return new AddressAggregatedListOption(ComputeRpc.Option.FILTER, filter.toPb()); @@ -1339,7 +1339,7 @@ public static AddressAggregatedListOption pageSize(long pageSize) { /** * Returns an option to specify the page token from which to start listing addresses. */ - public static AddressAggregatedListOption startPageToken(String pageToken) { + public static AddressAggregatedListOption pageToken(String pageToken) { return new AddressAggregatedListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); } } @@ -1520,7 +1520,7 @@ public static AddressAggregatedListOption startPageToken(String pageToken) { /** * Deletes the requested address. * - * @return an operation if request was issued correctly, {@code null} if the address was not + * @return an operation if the request was issued correctly, {@code null} if the address was not * found * @throws ComputeException upon failure */ diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java index 001d0dd370de..838816a035e0 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java @@ -614,6 +614,16 @@ public com.google.api.services.compute.model.Operation call() { } } + private static Function + operationFromPb(final ComputeOptions serviceOptions) { + return new Function() { + @Override + public Operation apply(com.google.api.services.compute.model.Operation operation) { + return Operation.fromPb(serviceOptions.service(), operation); + } + }; + } + @Override public Page listGlobalOperations(OperationListOption... options) { return listGlobalOperations(options(), optionMap(options)); @@ -634,13 +644,7 @@ Iterable> call() { String cursor = result.x(); Iterable operations = Iterables.transform( result.y() == null ? ImmutableList.of() - : result.y(), - new Function() { - @Override - public Operation apply(com.google.api.services.compute.model.Operation operation) { - return Operation.fromPb(serviceOptions.service(), operation); - } - }); + : result.y(), operationFromPb(serviceOptions)); return new PageImpl<>(new GlobalOperationPageFetcher(serviceOptions, cursor, optionsMap), cursor, operations); } catch (RetryHelper.RetryHelperException e) { @@ -668,13 +672,7 @@ Iterable> call() { String cursor = result.x(); Iterable operations = Iterables.transform( result.y() == null ? ImmutableList.of() - : result.y(), - new Function() { - @Override - public Operation apply(com.google.api.services.compute.model.Operation operation) { - return Operation.fromPb(serviceOptions.service(), operation); - } - }); + : result.y(), operationFromPb(serviceOptions)); return new PageImpl<>(new RegionOperationPageFetcher(region, serviceOptions, cursor, optionsMap), cursor, operations); } catch (RetryHelper.RetryHelperException e) { @@ -702,13 +700,7 @@ Iterable> call() { String cursor = result.x(); Iterable operations = Iterables.transform( result.y() == null ? ImmutableList.of() - : result.y(), - new Function() { - @Override - public Operation apply(com.google.api.services.compute.model.Operation operation) { - return Operation.fromPb(serviceOptions.service(), operation); - } - }); + : result.y(), operationFromPb(serviceOptions)); return new PageImpl<>(new ZoneOperationPageFetcher(zone, serviceOptions, cursor, optionsMap), cursor, operations); } catch (RetryHelper.RetryHelperException e) { @@ -796,6 +788,16 @@ public com.google.api.services.compute.model.Operation call() { } } + private static Function addressFromPb( + final ComputeOptions serviceOptions) { + return new Function() { + @Override + public Address apply(com.google.api.services.compute.model.Address address) { + return Address.fromPb(serviceOptions.service(), address); + } + }; + } + @Override public Page
    listGlobalAddresses(AddressListOption... options) { return listGlobalAddresses(options(), optionMap(options)); @@ -816,13 +818,7 @@ Iterable> call() { String cursor = result.x(); Iterable
    operations = Iterables.transform( result.y() == null ? ImmutableList.of() - : result.y(), - new Function() { - @Override - public Address apply(com.google.api.services.compute.model.Address address) { - return Address.fromPb(serviceOptions.service(), address); - } - }); + : result.y(), addressFromPb(serviceOptions)); return new PageImpl<>(new GlobalAddressPageFetcher(serviceOptions, cursor, optionsMap), cursor, operations); } catch (RetryHelper.RetryHelperException e) { @@ -850,13 +846,7 @@ Iterable> call() { String cursor = result.x(); Iterable
    operations = Iterables.transform( result.y() == null ? ImmutableList.of() - : result.y(), - new Function() { - @Override - public Address apply(com.google.api.services.compute.model.Address address) { - return Address.fromPb(serviceOptions.service(), address); - } - }); + : result.y(), addressFromPb(serviceOptions)); return new PageImpl<>(new RegionAddressPageFetcher(region, serviceOptions, cursor, optionsMap), cursor, operations); } catch (RetryHelper.RetryHelperException e) { diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java index 3026bfcc8d40..14d4d5eba910 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java @@ -192,7 +192,7 @@ public class ComputeImplTest { private static final DiskTypeFilter DISK_TYPE_FILTER = DiskTypeFilter.equals(Compute.DiskTypeField.DESCRIPTION, "someDescription"); private static final DiskTypeListOption DISK_TYPE_LIST_PAGE_TOKEN = - DiskTypeListOption.startPageToken("cursor"); + DiskTypeListOption.pageToken("cursor"); private static final DiskTypeListOption DISK_TYPE_LIST_PAGE_SIZE = DiskTypeListOption.pageSize(42L); private static final DiskTypeListOption DISK_TYPE_LIST_FILTER = @@ -204,7 +204,7 @@ public class ComputeImplTest { // DiskType aggregated list options private static final DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_PAGE_TOKEN = - DiskTypeAggregatedListOption.startPageToken("cursor"); + DiskTypeAggregatedListOption.pageToken("cursor"); private static final DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_PAGE_SIZE = DiskTypeAggregatedListOption.pageSize(42L); private static final DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_FILTER = @@ -219,7 +219,7 @@ public class ComputeImplTest { private static final MachineTypeFilter MACHINE_TYPE_FILTER = MachineTypeFilter.notEquals(Compute.MachineTypeField.MAXIMUM_PERSISTENT_DISKS, 42L); private static final MachineTypeListOption MACHINE_TYPE_LIST_PAGE_TOKEN = - MachineTypeListOption.startPageToken("cursor"); + MachineTypeListOption.pageToken("cursor"); private static final MachineTypeListOption MACHINE_TYPE_LIST_PAGE_SIZE = MachineTypeListOption.pageSize(42L); private static final MachineTypeListOption MACHINE_TYPE_LIST_FILTER = @@ -231,7 +231,7 @@ public class ComputeImplTest { // MachineType aggregated list options private static final MachineTypeAggregatedListOption MACHINE_TYPE_AGGREGATED_LIST_PAGE_TOKEN = - MachineTypeAggregatedListOption.startPageToken("cursor"); + MachineTypeAggregatedListOption.pageToken("cursor"); private static final MachineTypeAggregatedListOption MACHINE_TYPE_AGGREGATED_LIST_PAGE_SIZE = MachineTypeAggregatedListOption.pageSize(42L); private static final MachineTypeAggregatedListOption MACHINE_TYPE_AGGREGATED_LIST_FILTER = @@ -245,7 +245,7 @@ public class ComputeImplTest { private static final RegionFilter REGION_FILTER = RegionFilter.equals(Compute.RegionField.ID, "someId"); private static final RegionListOption REGION_LIST_PAGE_TOKEN = - RegionListOption.startPageToken("cursor"); + RegionListOption.pageToken("cursor"); private static final RegionListOption REGION_LIST_PAGE_SIZE = RegionListOption.pageSize(42L); private static final RegionListOption REGION_LIST_FILTER = @@ -263,7 +263,7 @@ public class ComputeImplTest { private static final ZoneFilter ZONE_FILTER = ZoneFilter.notEquals(Compute.ZoneField.NAME, "someName"); private static final ZoneListOption ZONE_LIST_PAGE_TOKEN = - ZoneListOption.startPageToken("cursor"); + ZoneListOption.pageToken("cursor"); private static final ZoneListOption ZONE_LIST_PAGE_SIZE = ZoneListOption.pageSize(42L); private static final ZoneListOption ZONE_LIST_FILTER = ZoneListOption.filter(ZONE_FILTER); private static final Map ZONE_LIST_OPTIONS = ImmutableMap.of( @@ -283,7 +283,7 @@ public class ComputeImplTest { private static final OperationFilter OPERATION_FILTER = OperationFilter.notEquals(Compute.OperationField.PROGRESS, 0); private static final OperationListOption OPERATION_LIST_PAGE_TOKEN = - OperationListOption.startPageToken("cursor"); + OperationListOption.pageToken("cursor"); private static final OperationListOption OPERATION_LIST_PAGE_SIZE = OperationListOption.pageSize(42L); private static final OperationListOption OPERATION_LIST_FILTER = @@ -301,7 +301,7 @@ public class ComputeImplTest { private static final Compute.AddressFilter ADDRESS_FILTER = Compute.AddressFilter.notEquals(Compute.AddressField.REGION, "someRegion"); private static final Compute.AddressListOption ADDRESS_LIST_PAGE_TOKEN = - Compute.AddressListOption.startPageToken("cursor"); + Compute.AddressListOption.pageToken("cursor"); private static final Compute.AddressListOption ADDRESS_LIST_PAGE_SIZE = Compute.AddressListOption.pageSize(42L); private static final Compute.AddressListOption ADDRESS_LIST_FILTER = @@ -313,7 +313,7 @@ public class ComputeImplTest { // Address aggregated list options private static final Compute.AddressAggregatedListOption ADDRESS_AGGREGATED_LIST_PAGE_TOKEN = - Compute.AddressAggregatedListOption.startPageToken("cursor"); + Compute.AddressAggregatedListOption.pageToken("cursor"); private static final Compute.AddressAggregatedListOption ADDRESS_AGGREGATED_LIST_PAGE_SIZE = Compute.AddressAggregatedListOption.pageSize(42L); private static final Compute.AddressAggregatedListOption ADDRESS_AGGREGATED_LIST_FILTER = @@ -432,6 +432,16 @@ public void testGetDiskType() { assertEquals(DISK_TYPE, diskType); } + @Test + public void testGetDiskType_Null() { + EasyMock.expect( + computeRpcMock.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.diskType(), EMPTY_RPC_OPTIONS)) + .andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.diskType())); + } + @Test public void testGetDiskTypeFromDiskTypeId() { EasyMock.expect( @@ -610,6 +620,17 @@ public void testGetMachineType() { assertEquals(MACHINE_TYPE, machineType); } + @Test + public void testGetMachineType_Null() { + EasyMock.expect( + computeRpcMock.getMachineType( + MACHINE_TYPE_ID.zone(), MACHINE_TYPE_ID.machineType(), EMPTY_RPC_OPTIONS)) + .andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.getMachineType(MACHINE_TYPE_ID.zone(), MACHINE_TYPE_ID.machineType())); + } + @Test public void testGetMachineTypeFromMachineTypeId() { EasyMock.expect(computeRpcMock.getMachineType( @@ -799,6 +820,15 @@ public void testGetRegion() { assertEquals(REGION, region); } + @Test + public void testGetRegion_Null() { + EasyMock.expect(computeRpcMock.getRegion(REGION_ID.region(), EMPTY_RPC_OPTIONS)) + .andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.getRegion(REGION_ID.region())); + } + @Test public void testGetRegionWithSelectedFields() { Capture> capturedOptions = Capture.newInstance(); @@ -891,6 +921,14 @@ public void testGetZone() { assertEquals(ZONE, zone); } + @Test + public void testGetZone_Null() { + EasyMock.expect(computeRpcMock.getZone(ZONE_ID.zone(), EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.getZone(ZONE_ID.zone())); + } + @Test public void testGetZoneWithSelectedFields() { Capture> capturedOptions = Capture.newInstance(); @@ -982,6 +1020,15 @@ public void testGetLicenseFromString() { assertEquals(LICENSE, license); } + @Test + public void testGetLicenseFromString_Null() { + EasyMock.expect(computeRpcMock.getLicense(PROJECT, LICENSE_ID.license(), EMPTY_RPC_OPTIONS)) + .andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.getLicense(LICENSE_ID.license())); + } + @Test public void testGetLicenseFromStringWithOptions() { Capture> capturedOptions = Capture.newInstance(); @@ -1029,6 +1076,17 @@ public void testGetLicenseFromId() { assertEquals(LICENSE, license); } + @Test + public void testGetLicenseFromId_Null() { + LicenseId licenseId = LicenseId.of("project2", "license2"); + EasyMock.expect( + computeRpcMock.getLicense(licenseId.project(), licenseId.license(), EMPTY_RPC_OPTIONS)) + .andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.getLicense(licenseId)); + } + @Test public void testGetGlobalOperation() { EasyMock.expect( @@ -1036,8 +1094,17 @@ public void testGetGlobalOperation() { .andReturn(globalOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Operation operation = compute.get(GLOBAL_OPERATION_ID); - assertEquals(globalOperation, operation); + assertEquals(globalOperation, compute.get(GLOBAL_OPERATION_ID)); + } + + @Test + public void testGetGlobalOperation_Null() { + EasyMock.expect( + computeRpcMock.getGlobalOperation(GLOBAL_OPERATION_ID.operation(), EMPTY_RPC_OPTIONS)) + .andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.get(GLOBAL_OPERATION_ID)); } @Test @@ -1177,6 +1244,17 @@ public void testGetRegionOperation() { assertEquals(regionOperation, operation); } + @Test + public void testGetRegionOperation_Null() { + EasyMock.expect(computeRpcMock.getRegionOperation(REGION_OPERATION_ID.region(), + REGION_OPERATION_ID.operation(), EMPTY_RPC_OPTIONS)) + .andReturn(regionOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.get(REGION_OPERATION_ID); + assertEquals(regionOperation, operation); + } + @Test public void testGetRegionOperationWithSelectedFields() { Capture> capturedOptions = Capture.newInstance(); @@ -1314,14 +1392,22 @@ public void testDeleteRegionOperation_False() { @Test public void testGetZoneOperation() { EasyMock.expect(computeRpcMock.getZoneOperation(ZONE_OPERATION_ID.zone(), - ZONE_OPERATION_ID.operation(), EMPTY_RPC_OPTIONS)) - .andReturn(zoneOperation.toPb()); + ZONE_OPERATION_ID.operation(), EMPTY_RPC_OPTIONS)).andReturn(zoneOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); Operation operation = compute.get(ZONE_OPERATION_ID); assertEquals(zoneOperation, operation); } + @Test + public void testGetZoneOperation_Null() { + EasyMock.expect(computeRpcMock.getZoneOperation(ZONE_OPERATION_ID.zone(), + ZONE_OPERATION_ID.operation(), EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.get(ZONE_OPERATION_ID)); + } + @Test public void testGetZoneOperationWithSelectedFields() { Capture> capturedOptions = Capture.newInstance(); @@ -1458,8 +1544,7 @@ public void testDeleteZoneOperation_False() { @Test public void testGetGlobalAddress() { - EasyMock.expect( - computeRpcMock.getGlobalAddress(GLOBAL_ADDRESS_ID.address(), EMPTY_RPC_OPTIONS)) + EasyMock.expect(computeRpcMock.getGlobalAddress(GLOBAL_ADDRESS_ID.address(), EMPTY_RPC_OPTIONS)) .andReturn(GLOBAL_ADDRESS.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); @@ -1467,6 +1552,15 @@ public void testGetGlobalAddress() { assertEquals(new Address(compute, new AddressInfo.BuilderImpl(GLOBAL_ADDRESS)), address); } + @Test + public void testGetGlobalAddress_Null() { + EasyMock.expect(computeRpcMock.getGlobalAddress(GLOBAL_ADDRESS_ID.address(), EMPTY_RPC_OPTIONS)) + .andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.get(GLOBAL_ADDRESS_ID)); + } + @Test public void testGetGlobalAddressWithSelectedFields() { Capture> capturedOptions = Capture.newInstance(); @@ -1494,6 +1588,16 @@ public void testGetRegionAddress() { assertEquals(new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS)), address); } + @Test + public void testGetRegionAddress_Null() { + EasyMock.expect(computeRpcMock.getRegionAddress(REGION_ADDRESS_ID.region(), + REGION_ADDRESS_ID.address(), EMPTY_RPC_OPTIONS)).andReturn(REGION_ADDRESS.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Address address = compute.get(REGION_ADDRESS_ID); + assertEquals(new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS)), address); + } + @Test public void testGetRegionAddressWithSelectedFields() { Capture> capturedOptions = Capture.newInstance(); From 514e3fe873d50ddb5adf1e79f30b70db64fceaee Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 21 Mar 2016 12:47:21 +0100 Subject: [PATCH 296/375] Better javadoc for RemoteComputeHelper.baseResourceName --- .../google/gcloud/compute/testing/RemoteComputeHelper.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/RemoteComputeHelper.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/RemoteComputeHelper.java index 768650111b45..3613c75a4b7c 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/RemoteComputeHelper.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/RemoteComputeHelper.java @@ -54,7 +54,9 @@ public ComputeOptions options() { /** * Returns a base name for testing resources generated using a random UUID. This base name can be - * prepended to resource names to prevent name clashes. + * prepended to resource names to prevent name clashes. This method always returns a 30 characters + * long prefix. Since Compute Engine resource names can be at most 63 characters long your suffix + * should be no longer than 33 characters. */ public static String baseResourceName() { return "test-" + UUID.randomUUID().toString().replace("-", "").substring(0, 24) + "-"; @@ -69,8 +71,7 @@ public static String baseResourceName() { * @return A {@code RemoteComputeHelper} object for the provided options * @throws ComputeHelperException if {@code keyStream} is not a valid JSON key stream */ - public static RemoteComputeHelper create(String projectId, InputStream keyStream) - throws ComputeHelperException { + public static RemoteComputeHelper create(String projectId, InputStream keyStream) { try { ComputeOptions computeOptions = ComputeOptions.builder() .authCredentials(AuthCredentials.createForJson(keyStream)) From 9cf9309daa5406a23882b88fc5a32b9f51d37e83 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 21 Mar 2016 19:08:10 +0100 Subject: [PATCH 297/375] Make AddressInfo.builder return Builder instead of BuilderImpl --- .../src/main/java/com/google/gcloud/compute/AddressInfo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressInfo.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressInfo.java index 0d5880201b61..249f8462d401 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressInfo.java @@ -531,7 +531,7 @@ Address toPb() { /** * Returns a builder for the {@code AddressInfo} object given it's identity. */ - public static BuilderImpl builder(AddressId addressId) { + public static Builder builder(AddressId addressId) { return new BuilderImpl().addressId(addressId); } From 1d5f1716fd633b5d971c1e468dc336f79e21805b Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 22 Mar 2016 11:57:27 +0100 Subject: [PATCH 298/375] Use TO_PB_FUNCTION when possible in ComputeImplTest --- .../com/google/gcloud/compute/Operation.java | 2 - .../gcloud/compute/ComputeImplTest.java | 145 ++++-------------- 2 files changed, 26 insertions(+), 121 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java index 7b8a888cf40c..ce519edc970d 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java @@ -17,8 +17,6 @@ package com.google.gcloud.compute; import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.gcloud.compute.OperationId.Type.REGION; -import static com.google.gcloud.compute.OperationId.Type.ZONE; import com.google.common.base.Function; import com.google.common.base.MoreObjects; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java index 14d4d5eba910..808d4ce7d255 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java @@ -319,6 +319,15 @@ public class ComputeImplTest { private static final Compute.AddressAggregatedListOption ADDRESS_AGGREGATED_LIST_FILTER = Compute.AddressAggregatedListOption.filter(ADDRESS_FILTER); + private static final Function + OPERATION_TO_PB_FUNCTION = new Function() { + @Override + public com.google.api.services.compute.model.Operation apply(Operation operation) { + return operation.toPb(); + } + }; + private ComputeOptions options; private ComputeRpcFactory rpcFactoryMock; private ComputeRpc computeRpcMock; @@ -1130,13 +1139,7 @@ public void testListGlobalOperations() { compute = options.service(); ImmutableList operationList = ImmutableList.of(globalOperation, globalOperation); Tuple> result = - Tuple.of(cursor, Iterables.transform(operationList, - new Function() { - @Override - public com.google.api.services.compute.model.Operation apply(Operation operation) { - return operation.toPb(); - } - })); + Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listGlobalOperations(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listGlobalOperations(); @@ -1152,21 +1155,9 @@ public void testListGlobalOperationsNextPage() { ImmutableList operationList = ImmutableList.of(globalOperation, globalOperation); ImmutableList nextOperationList = ImmutableList.of(globalOperation); Tuple> result = - Tuple.of(cursor, Iterables.transform(operationList, - new Function() { - @Override - public com.google.api.services.compute.model.Operation apply(Operation operation) { - return operation.toPb(); - } - })); + Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextOperationList, - new Function() { - @Override - public com.google.api.services.compute.model.Operation apply(Operation operation) { - return operation.toPb(); - } - })); + Tuple.of(nextCursor, Iterables.transform(nextOperationList, OPERATION_TO_PB_FUNCTION)); Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listGlobalOperations(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.expect(computeRpcMock.listGlobalOperations(nextOptions)).andReturn(nextResult); @@ -1200,13 +1191,7 @@ public void testListGlobalOperationsWithOptions() { compute = options.service(); ImmutableList operationList = ImmutableList.of(globalOperation, globalOperation); Tuple> result = - Tuple.of(cursor, Iterables.transform(operationList, - new Function() { - @Override - public com.google.api.services.compute.model.Operation apply(Operation operation) { - return operation.toPb(); - } - })); + Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listGlobalOperations(OPERATION_LIST_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listGlobalOperations(OPERATION_LIST_PAGE_SIZE, @@ -1278,13 +1263,7 @@ public void testListRegionOperations() { compute = options.service(); ImmutableList operationList = ImmutableList.of(regionOperation, regionOperation); Tuple> result = - Tuple.of(cursor, Iterables.transform(operationList, - new Function() { - @Override - public com.google.api.services.compute.model.Operation apply(Operation operation) { - return operation.toPb(); - } - })); + Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); EasyMock.expect( computeRpcMock.listRegionOperations(REGION_OPERATION_ID.region(), EMPTY_RPC_OPTIONS)) .andReturn(result); @@ -1302,21 +1281,9 @@ public void testListRegionOperationsNextPage() { ImmutableList operationList = ImmutableList.of(regionOperation, regionOperation); ImmutableList nextOperationList = ImmutableList.of(regionOperation); Tuple> result = - Tuple.of(cursor, Iterables.transform(operationList, - new Function() { - @Override - public com.google.api.services.compute.model.Operation apply(Operation operation) { - return operation.toPb(); - } - })); + Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextOperationList, - new Function() { - @Override - public com.google.api.services.compute.model.Operation apply(Operation operation) { - return operation.toPb(); - } - })); + Tuple.of(nextCursor, Iterables.transform(nextOperationList, OPERATION_TO_PB_FUNCTION)); Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listRegionOperations(REGION_OPERATION_ID.region(), EMPTY_RPC_OPTIONS)).andReturn(result); @@ -1354,13 +1321,7 @@ public void testListRegionOperationsWithOptions() { compute = options.service(); ImmutableList operationList = ImmutableList.of(regionOperation, regionOperation); Tuple> result = - Tuple.of(cursor, Iterables.transform(operationList, - new Function() { - @Override - public com.google.api.services.compute.model.Operation apply(Operation operation) { - return operation.toPb(); - } - })); + Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); EasyMock.expect( computeRpcMock.listRegionOperations(REGION_OPERATION_ID.region(), OPERATION_LIST_OPTIONS)) .andReturn(result); @@ -1431,13 +1392,7 @@ public void testListZoneOperations() { compute = options.service(); ImmutableList operationList = ImmutableList.of(zoneOperation, zoneOperation); Tuple> result = - Tuple.of(cursor, Iterables.transform(operationList, - new Function() { - @Override - public com.google.api.services.compute.model.Operation apply(Operation operation) { - return operation.toPb(); - } - })); + Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); EasyMock.expect( computeRpcMock.listZoneOperations(ZONE_OPERATION_ID.zone(), EMPTY_RPC_OPTIONS)) .andReturn(result); @@ -1455,21 +1410,9 @@ public void testListZoneOperationsNextPage() { ImmutableList operationList = ImmutableList.of(zoneOperation, zoneOperation); ImmutableList nextOperationList = ImmutableList.of(zoneOperation); Tuple> result = - Tuple.of(cursor, Iterables.transform(operationList, - new Function() { - @Override - public com.google.api.services.compute.model.Operation apply(Operation operation) { - return operation.toPb(); - } - })); + Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextOperationList, - new Function() { - @Override - public com.google.api.services.compute.model.Operation apply(Operation operation) { - return operation.toPb(); - } - })); + Tuple.of(nextCursor, Iterables.transform(nextOperationList, OPERATION_TO_PB_FUNCTION)); Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listZoneOperations(ZONE_OPERATION_ID.zone(), EMPTY_RPC_OPTIONS)) .andReturn(result); @@ -1507,13 +1450,7 @@ public void testListZoneOperationsWithOptions() { compute = options.service(); ImmutableList operationList = ImmutableList.of(zoneOperation, zoneOperation); Tuple> result = - Tuple.of(cursor, Iterables.transform(operationList, - new Function() { - @Override - public com.google.api.services.compute.model.Operation apply(Operation operation) { - return operation.toPb(); - } - })); + Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); EasyMock.expect( computeRpcMock.listZoneOperations(ZONE_OPERATION_ID.zone(), OPERATION_LIST_OPTIONS)) .andReturn(result); @@ -1713,21 +1650,9 @@ public void testListGlobalAddressesNextPage() { ImmutableList
    nextAddressList = ImmutableList.of( new Address(compute, new AddressInfo.BuilderImpl(GLOBAL_ADDRESS))); Tuple> result = - Tuple.of(cursor, Iterables.transform(addressList, - new Function() { - @Override - public com.google.api.services.compute.model.Address apply(Address address) { - return address.toPb(); - } - })); + Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextAddressList, - new Function() { - @Override - public com.google.api.services.compute.model.Address apply(Address address) { - return address.toPb(); - } - })); + Tuple.of(nextCursor, Iterables.transform(nextAddressList, AddressInfo.TO_PB_FUNCTION)); Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listGlobalAddresses(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.expect(computeRpcMock.listGlobalAddresses(nextOptions)).andReturn(nextResult); @@ -1778,13 +1703,7 @@ public void testListRegionAddresses() { new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS)), new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS))); Tuple> result = - Tuple.of(cursor, Iterables.transform(addressList, - new Function() { - @Override - public com.google.api.services.compute.model.Address apply(Address address) { - return address.toPb(); - } - })); + Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); EasyMock.expect( computeRpcMock.listRegionAddresses(REGION_ADDRESS_ID.region(), EMPTY_RPC_OPTIONS)) .andReturn(result); @@ -1805,21 +1724,9 @@ public void testListRegionAddressesNextPage() { ImmutableList
    nextAddressList = ImmutableList.of( new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS))); Tuple> result = - Tuple.of(cursor, Iterables.transform(addressList, - new Function() { - @Override - public com.google.api.services.compute.model.Address apply(Address address) { - return address.toPb(); - } - })); + Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextAddressList, - new Function() { - @Override - public com.google.api.services.compute.model.Address apply(Address address) { - return address.toPb(); - } - })); + Tuple.of(nextCursor, Iterables.transform(nextAddressList, AddressInfo.TO_PB_FUNCTION)); Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); EasyMock.expect( computeRpcMock.listRegionAddresses(REGION_ADDRESS_ID.region(), EMPTY_RPC_OPTIONS)) From 44fedd64a2bfd05d4ce7742b798eff58875e241a Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 22 Mar 2016 12:24:23 +0100 Subject: [PATCH 299/375] Remove repeated casts in identities'equals method --- .../java/com/google/gcloud/compute/DiskTypeId.java | 14 ++++++++++---- .../google/gcloud/compute/ForwardingRuleId.java | 2 +- .../java/com/google/gcloud/compute/InstanceId.java | 14 ++++++++++---- .../java/com/google/gcloud/compute/LicenseId.java | 11 ++++++++--- .../com/google/gcloud/compute/MachineTypeId.java | 14 ++++++++++---- .../com/google/gcloud/compute/RegionAddressId.java | 11 ++++++++--- .../gcloud/compute/RegionForwardingRuleId.java | 11 ++++++++--- .../java/com/google/gcloud/compute/RegionId.java | 11 ++++++++--- .../google/gcloud/compute/RegionOperationId.java | 11 ++++++++--- .../java/com/google/gcloud/compute/ZoneId.java | 11 ++++++++--- 10 files changed, 79 insertions(+), 31 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java index 93fb1eff6aac..039565ec827f 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java @@ -94,10 +94,16 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof DiskTypeId - && baseEquals((DiskTypeId) obj) - && Objects.equals(zone, ((DiskTypeId) obj).zone) - && Objects.equals(diskType, ((DiskTypeId) obj).diskType); + if (obj == this) { + return true; + } + if (!(obj instanceof DiskTypeId)) { + return false; + } + DiskTypeId other = (DiskTypeId) obj; + return baseEquals(other) + && Objects.equals(zone, other.zone) + && Objects.equals(diskType, other.diskType); } @Override diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ForwardingRuleId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ForwardingRuleId.java index 029f8c50f0a0..546dcf596246 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ForwardingRuleId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ForwardingRuleId.java @@ -23,7 +23,7 @@ import java.util.Objects; /** - * Interface for Google Compute Engine forwarding rule identities. + * Base class for Google Compute Engine forwarding rule identities. */ public abstract class ForwardingRuleId extends ResourceId { diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceId.java index 5fcf19b3491c..408d95e641b4 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceId.java @@ -100,10 +100,16 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof InstanceId - && baseEquals((InstanceId) obj) - && Objects.equals(zone, ((InstanceId) obj).zone) - && Objects.equals(instance, ((InstanceId) obj).instance); + if (obj == this) { + return true; + } + if (!(obj instanceof InstanceId)) { + return false; + } + InstanceId other = (InstanceId) obj; + return baseEquals(other) + && Objects.equals(zone, other.zone) + && Objects.equals(instance, other.instance); } @Override diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java index 36d3037bc41b..0166e03ed325 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java @@ -78,9 +78,14 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof LicenseId - && baseEquals((LicenseId) obj) - && Objects.equals(license, ((LicenseId) obj).license); + if (obj == this) { + return true; + } + if (!(obj instanceof LicenseId)) { + return false; + } + LicenseId other = (LicenseId) obj; + return baseEquals(other) && Objects.equals(license, other.license); } @Override diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java index 92daf2b05f60..a431d29d1e85 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java @@ -96,10 +96,16 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof MachineTypeId - && baseEquals((MachineTypeId) obj) - && Objects.equals(zone, ((MachineTypeId) obj).zone) - && Objects.equals(machineType, ((MachineTypeId) obj).machineType); + if (obj == this) { + return true; + } + if (!(obj instanceof MachineTypeId)) { + return false; + } + MachineTypeId other = (MachineTypeId) obj; + return baseEquals(other) + && Objects.equals(zone, other.zone) + && Objects.equals(machineType, other.machineType); } @Override diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionAddressId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionAddressId.java index 546d7eca6b79..6ea0538b0edf 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionAddressId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionAddressId.java @@ -76,9 +76,14 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof RegionAddressId - && baseEquals((RegionAddressId) obj) - && Objects.equals(region, ((RegionAddressId) obj).region); + if (obj == this) { + return true; + } + if (!(obj instanceof RegionAddressId)) { + return false; + } + RegionAddressId other = (RegionAddressId) obj; + return baseEquals(other) && Objects.equals(region, other.region); } @Override diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionForwardingRuleId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionForwardingRuleId.java index a982d88f5f42..b6e7e120f94a 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionForwardingRuleId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionForwardingRuleId.java @@ -92,9 +92,14 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof RegionForwardingRuleId - && baseEquals((RegionForwardingRuleId) obj) - && Objects.equals(region, ((RegionForwardingRuleId) obj).region); + if (obj == this) { + return true; + } + if (!(obj instanceof RegionForwardingRuleId)) { + return false; + } + RegionForwardingRuleId other = (RegionForwardingRuleId) obj; + return baseEquals(other) && Objects.equals(region, other.region); } @Override diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java index 403edd47ce48..7e0f03e1e3ac 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java @@ -83,9 +83,14 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof RegionId - && baseEquals((RegionId) obj) - && Objects.equals(region, ((RegionId) obj).region); + if (obj == this) { + return true; + } + if (!(obj instanceof RegionId)) { + return false; + } + RegionId other = (RegionId) obj; + return baseEquals(other) && Objects.equals(region, other.region); } @Override diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionOperationId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionOperationId.java index 7608cfaa913f..b244c60fadf0 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionOperationId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionOperationId.java @@ -76,9 +76,14 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof RegionOperationId - && baseEquals((RegionOperationId) obj) - && Objects.equals(region, ((RegionOperationId) obj).region); + if (obj == this) { + return true; + } + if (!(obj instanceof RegionOperationId)) { + return false; + } + RegionOperationId other = (RegionOperationId) obj; + return baseEquals(other) && Objects.equals(region, other.region); } @Override diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java index 74ac5be58201..56386ace5455 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java @@ -78,9 +78,14 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof ZoneId - && baseEquals((ZoneId) obj) - && Objects.equals(zone, ((ZoneId) obj).zone); + if (obj == this) { + return true; + } + if (!(obj instanceof ZoneId)) { + return false; + } + ZoneId other = (ZoneId) obj; + return baseEquals(other) && Objects.equals(zone, other.zone); } @Override From f36d92c98a43174746235166f0649939c9a3ad2c Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 22 Mar 2016 13:35:03 +0100 Subject: [PATCH 300/375] Replace 'an unique' with 'the unique' everywhere --- .../src/main/java/com/google/gcloud/compute/DiskType.java | 2 +- .../src/main/java/com/google/gcloud/compute/MachineType.java | 2 +- .../src/main/java/com/google/gcloud/compute/Region.java | 2 +- .../src/main/java/com/google/gcloud/compute/Zone.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java index 0991a9d5d666..f6c8342a0f1c 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java @@ -137,7 +137,7 @@ public DiskTypeId diskTypeId() { } /** - * Returns an unique identifier for the disk type; defined by the service. + * Returns the unique identifier for the disk type; defined by the service. */ public String id() { return id; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java index d9c446dddf72..2d7bfa7d26c8 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java @@ -160,7 +160,7 @@ public MachineTypeId machineTypeId() { } /** - * Returns an unique identifier for the machine type; defined by the service. + * Returns the unique identifier for the machine type; defined by the service. */ public String id() { return id; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java index 470acf4e9061..fb7890187a14 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java @@ -241,7 +241,7 @@ public RegionId regionId() { } /** - * Returns an unique identifier for the region; defined by the service. + * Returns the unique identifier for the region; defined by the service. */ public String id() { return id; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java index 903f994118de..7c766bef27c9 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java @@ -270,7 +270,7 @@ public String description() { } /** - * Returns an unique identifier for the zone; defined by the service. + * Returns the unique identifier for the zone; defined by the service. */ public String id() { return id; From 4c8f8882a783a47400cf8a365e19ba42a525a5c7 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 22 Mar 2016 16:29:47 +0100 Subject: [PATCH 301/375] Add SnapshotInfo, related classes and tests --- .../com/google/gcloud/compute/DiskId.java | 162 ++++++ .../com/google/gcloud/compute/SnapshotId.java | 132 +++++ .../google/gcloud/compute/SnapshotInfo.java | 484 ++++++++++++++++++ .../com/google/gcloud/compute/DiskIdTest.java | 87 ++++ .../google/gcloud/compute/SnapshotIdTest.java | 79 +++ .../gcloud/compute/SnapshotInfoTest.java | 135 +++++ 6 files changed, 1079 insertions(+) create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskId.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotId.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotInfo.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskIdTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotIdTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotInfoTest.java diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskId.java new file mode 100644 index 000000000000..b2a0f3e45db7 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskId.java @@ -0,0 +1,162 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; + +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Identity for a Google Compute Engine disk. + */ +public final class DiskId extends ResourceId { + + private static final String REGEX = ResourceId.REGEX + "zones/([^/]+)/disks/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); + private static final long serialVersionUID = -8761290740495870787L; + + private final String zone; + private final String disk; + + private DiskId(String project, String zone, String disk) { + super(project); + this.zone = checkNotNull(zone); + this.disk = checkNotNull(disk); + } + + /** + * Returns the name of the zone this disk belongs to. + */ + public String zone() { + return zone; + } + + /** + * Returns the identity of the zone this disk belongs to. + */ + public ZoneId zoneId() { + return ZoneId.of(project(), zone); + } + + /** + * Returns the name of the disk. The name must be 1-63 characters long and comply with RFC1035. + * Specifically, the name must match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} + * which means the first character must be a lowercase letter, and all following characters must + * be a dash, lowercase letter, or digit, except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public String disk() { + return disk; + } + + @Override + public String selfLink() { + return super.selfLink() + "/zones/" + zone + "/disks/" + disk; + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper().add("zone", zone).add("disk", disk); + } + + @Override + public int hashCode() { + return Objects.hash(super.baseHashCode(), zone, disk); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof DiskId)) { + return false; + } + DiskId other = (DiskId) obj; + return baseEquals(other) + && Objects.equals(zone, other.zone) + && Objects.equals(disk, other.disk); + } + + @Override + DiskId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return DiskId.of(projectId, zone, disk); + } + + /** + * Returns a disk identity given the zone identity and the disk name. The address name must be + * 1-63 characters long and comply with RFC1035. Specifically, the name must match the regular + * expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a + * lowercase letter, and all following characters must be a dash, lowercase letter, or digit, + * except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public static DiskId of(ZoneId zoneId, String disk) { + return new DiskId(zoneId.project(), zoneId.zone(), disk); + } + + /** + * Returns a disk identity given the zone and disk names. The address name must be 1-63 characters + * long and comply with RFC1035. Specifically, the name must match the regular expression + * {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a lowercase letter, + * and all following characters must be a dash, lowercase letter, or digit, except the last + * character, which cannot be a dash. + * + * @see RFC1035 + */ + public static DiskId of(String zone, String disk) { + return new DiskId(null, zone, disk); + } + + /** + * Returns a disk identity given project, zone and disks names. The address name must be 1-63 + * characters long and comply with RFC1035. Specifically, the name must match the regular + * expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a + * lowercase letter, and all following characters must be a dash, lowercase letter, or digit, + * except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public static DiskId of(String project, String zone, String disk) { + return new DiskId(project, zone, disk); + } + + /** + * Returns {@code true} if the provided string matches the expected format of a disk URL. Returns + * {@code false} otherwise. + */ + static boolean matchesUrl(String url) { + return PATTERN.matcher(url).matches(); + } + + static DiskId fromUrl(String url) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { + throw new IllegalArgumentException(url + " is not a valid disk URL"); + } + return DiskId.of(matcher.group(1), matcher.group(2), matcher.group(3)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotId.java new file mode 100644 index 000000000000..5df2d9f0f9a8 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotId.java @@ -0,0 +1,132 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; + +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Identity for a Google Compute Engine snapshot. + */ +public final class SnapshotId extends ResourceId { + + private static final String REGEX = ResourceId.REGEX + "global/snapshots/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); + private static final long serialVersionUID = -1699492866663041082L; + + private final String snapshot; + + private SnapshotId(String project, String snapshot) { + super(project); + this.snapshot = checkNotNull(snapshot); + } + + /** + * Returns the name of the snapshot. The name must be 1-63 characters long and comply with + * RFC1035. Specifically, the name must match the regular expression + * {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a lowercase letter, + * and all following characters must be a dash, lowercase letter, or digit, except the last + * character, which cannot be a dash. + * + * @see RFC1035 + */ + public String snapshot() { + return snapshot; + } + + @Override + public String selfLink() { + return super.selfLink() + "/global/snapshots/" + snapshot; + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper().add("snapshot", snapshot); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), snapshot); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof SnapshotId)) { + return false; + } + SnapshotId other = (SnapshotId) obj; + return baseEquals(other) && Objects.equals(snapshot, other.snapshot); + } + + @Override + SnapshotId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return SnapshotId.of(projectId, snapshot); + } + + /** + * Returns a snapshot identity given the snapshot name. The snapshot name must be 1-63 characters + * long and comply with RFC1035. Specifically, the name must match the regular expression + * {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a lowercase letter, + * and all following characters must be a dash, lowercase letter, or digit, except the last + * character, which cannot be a dash. + * + * @see RFC1035 + */ + public static SnapshotId of(String snapshot) { + return new SnapshotId(null, snapshot); + } + + /** + * Returns a snapshot identity given project and snapshot names. The snapshot name must be 1-63 + * characters long and comply with RFC1035. Specifically, the name must match the regular + * expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a + * lowercase letter, and all following characters must be a dash, lowercase letter, or digit, + * except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public static SnapshotId of(String project, String snapshot) { + return new SnapshotId(project, snapshot); + } + + /** + * Returns {@code true} if the provided string matches the expected format of a snapshot URL. + * Returns {@code false} otherwise. + */ + static boolean matchesUrl(String url) { + return url.matches(REGEX); + } + + static SnapshotId fromUrl(String url) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { + throw new IllegalArgumentException(url + " is not a valid snapshot URL"); + } + return SnapshotId.of(matcher.group(1), matcher.group(2)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotInfo.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotInfo.java new file mode 100644 index 000000000000..283ca665d173 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotInfo.java @@ -0,0 +1,484 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.api.services.compute.model.Snapshot; +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; + +import java.io.Serializable; +import java.math.BigInteger; +import java.util.List; +import java.util.Objects; + +/** + * A Google Compute Engine snapshot. Compute Engine allows you to take snapshots of your persistent + * disk and create new persistent disks from that snapshot. This can be useful for backing up data, + * recreating a persistent disk that might have been lost, or copying a persistent disk. Snapshots + * can be applied across persistent disk types. + * + * @see Use + * persistent disk snapshots + */ +public class SnapshotInfo implements Serializable { + + static final Function FROM_PB_FUNCTION = + new Function() { + @Override + public SnapshotInfo apply(Snapshot pb) { + return SnapshotInfo.fromPb(pb); + } + }; + static final Function TO_PB_FUNCTION = + new Function() { + @Override + public Snapshot apply(SnapshotInfo snapshot) { + return snapshot.toPb(); + } + }; + + private static final long serialVersionUID = 1065513502131159769L; + private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); + + private final String id; + private final SnapshotId snapshotId; + private final Long creationTimestamp; + private final String description; + private final Status status; + private final Long diskSizeGb; + private final List licenses; + private final DiskId sourceDisk; + private final String sourceDiskId; + private final Long storageBytes; + private final StorageBytesStatus storageBytesStatus; + + /** + * The status of a Google Compute Engine snapshot. A snapshot can be used to create other + * resources, such as disks, only after the snapshot has been successfully created and the status + * is set to {@code READY}. + */ + public enum Status { + /** + * The snapshot is being created. + */ + CREATING, + + /** + * The snapshot is being deleted. + */ + DELETING, + + /** + * Snapshot's creation failed. + */ + FAILED, + + /** + * Snapshot has been successfully created. + */ + READY, + + /** + * Snapshot is being uploaded. + */ + UPLOADING + } + + /** + * An indicator whether {@link SnapshotInfo#storageBytes()} is in a stable state or it is being + * adjusted as a result of shared storage reallocation. + */ + public enum StorageBytesStatus { + /** + * Indicates that the size of the snapshot is being updated. + */ + UPDATING, + + /** + * Indicates that the size of the snapshot is up-to-date. + */ + UP_TO_DATE + } + + /** + * A builder for {@code SnapshotInfo} objects. + */ + public abstract static class Builder { + + abstract Builder id(String id); + + abstract Builder creationTimestamp(Long creationTimestamp); + + /** + * Sets the snapshot identity. + */ + public abstract Builder snapshotId(SnapshotId snapshotId); + + /** + * Sets an optional textual description of the snapshot. + */ + public abstract Builder description(String description); + + abstract Builder status(Status status); + + abstract Builder diskSizeGb(Long diskSizeGb); + + abstract Builder licenses(List licenses); + + /** + * Sets the identity of the source disk used to create the snapshot. + */ + public abstract Builder sourceDisk(DiskId sourceDisk); + + abstract Builder sourceDiskId(String sourceDiskId); + + abstract Builder storageBytes(Long storageBytes); + + abstract Builder storageBytesStatus(StorageBytesStatus storageBytesStatus); + + /** + * Creates a {@code SnapshotInfo} object. + */ + public abstract SnapshotInfo build(); + } + + static final class BuilderImpl extends Builder { + + private String id; + private Long creationTimestamp; + private SnapshotId snapshotId; + private String description; + private Status status; + private Long diskSizeGb; + private List licenses; + private DiskId sourceDisk; + private String sourceDiskId; + private Long storageBytes; + private StorageBytesStatus storageBytesStatus; + + BuilderImpl() {} + + BuilderImpl(SnapshotInfo snapshotInfo) { + this.id = snapshotInfo.id; + this.creationTimestamp = snapshotInfo.creationTimestamp; + this.snapshotId = snapshotInfo.snapshotId; + this.description = snapshotInfo.description; + this.status = snapshotInfo.status; + this.diskSizeGb = snapshotInfo.diskSizeGb; + this.licenses = snapshotInfo.licenses; + this.sourceDisk = snapshotInfo.sourceDisk; + this.sourceDiskId = snapshotInfo.sourceDiskId; + this.storageBytes = snapshotInfo.storageBytes; + this.storageBytesStatus = snapshotInfo.storageBytesStatus; + } + + BuilderImpl(Snapshot snapshotPb) { + if (snapshotPb.getId() != null) { + this.id = snapshotPb.getId().toString(); + } + if (snapshotPb.getCreationTimestamp() != null) { + this.creationTimestamp = TIMESTAMP_FORMATTER.parseMillis(snapshotPb.getCreationTimestamp()); + } + this.snapshotId = SnapshotId.fromUrl(snapshotPb.getSelfLink()); + this.description = snapshotPb.getDescription(); + if (snapshotPb.getStatus() != null) { + this.status = Status.valueOf(snapshotPb.getStatus()); + } + this.diskSizeGb = snapshotPb.getDiskSizeGb(); + if (snapshotPb.getLicenses() != null) { + this.licenses = Lists.transform(snapshotPb.getLicenses(), LicenseId.FROM_URL_FUNCTION); + } + if (snapshotPb.getSourceDisk() != null) { + this.sourceDisk = DiskId.fromUrl(snapshotPb.getSourceDisk()); + } + this.sourceDiskId = snapshotPb.getSourceDiskId(); + this.storageBytes = snapshotPb.getStorageBytes(); + if (snapshotPb.getStorageBytesStatus() != null) { + this.storageBytesStatus = StorageBytesStatus.valueOf(snapshotPb.getStorageBytesStatus()); + } + } + + @Override + BuilderImpl id(String id) { + this.id = id; + return this; + } + + @Override + BuilderImpl creationTimestamp(Long creationTimestamp) { + this.creationTimestamp = creationTimestamp; + return this; + } + + @Override + public BuilderImpl snapshotId(SnapshotId snapshotId) { + this.snapshotId = checkNotNull(snapshotId); + return this; + } + + @Override + public BuilderImpl description(String description) { + this.description = description; + return this; + } + + @Override + BuilderImpl status(Status status) { + this.status = status; + return this; + } + + @Override + BuilderImpl diskSizeGb(Long diskSizeGb) { + this.diskSizeGb = diskSizeGb; + return this; + } + + @Override + BuilderImpl licenses(List licenses) { + this.licenses = licenses != null ? ImmutableList.copyOf(licenses) : null; + return this; + } + + @Override + public BuilderImpl sourceDisk(DiskId sourceDisk) { + this.sourceDisk = checkNotNull(sourceDisk); + return this; + } + + @Override + BuilderImpl sourceDiskId(String sourceDiskId) { + this.sourceDiskId = sourceDiskId; + return this; + } + + @Override + BuilderImpl storageBytes(Long storageBytes) { + this.storageBytes = storageBytes; + return this; + } + + @Override + BuilderImpl storageBytesStatus(StorageBytesStatus storageBytesStatus) { + this.storageBytesStatus = storageBytesStatus; + return this; + } + + @Override + public SnapshotInfo build() { + return new SnapshotInfo(this); + } + } + + SnapshotInfo(BuilderImpl builder) { + this.id = builder.id; + this.creationTimestamp = builder.creationTimestamp; + this.snapshotId = checkNotNull(builder.snapshotId); + this.description = builder.description; + this.status = builder.status; + this.diskSizeGb = builder.diskSizeGb; + this.licenses = builder.licenses; + this.sourceDisk = builder.sourceDisk; + this.sourceDiskId = builder.sourceDiskId; + this.storageBytes = builder.storageBytes; + this.storageBytesStatus = builder.storageBytesStatus; + } + + /** + * Returns the unique identifier for the snapshot; defined by the service. + */ + public String id() { + return id; + } + + /** + * Returns the creation timestamp in milliseconds since epoch. + */ + public Long creationTimestamp() { + return creationTimestamp; + } + + /** + * Returns the snapshot identity. + */ + public SnapshotId snapshotId() { + return snapshotId; + } + + /** + * Returns a textual description of the snapshot. + */ + public String description() { + return description; + } + + /** + * Returns all applicable publicly visible licenses. + */ + public List licenses() { + return licenses; + } + + /** + * Returns the status of the snapshot. A snapshot can be used to create other resources, such as + * disks, only after the snapshot has been successfully created and the status is set to + * {@code READY}. + */ + public Status status() { + return status; + } + + /** + * Returns the size of the snapshot (in GB). + */ + public Long diskSizeGb() { + return diskSizeGb; + } + + /** + * Returns the identity of the source disk used to create this snapshot. + */ + public DiskId sourceDisk() { + return sourceDisk; + } + + /** + * Returns the id value of the disk used to create this snapshot. This value may be used to + * determine whether the snapshot was taken from the current or a previous instance of a given + * disk name. + */ + public String sourceDiskId() { + return sourceDiskId; + } + + /** + * Returns the size of the the storage used by the snapshot. As snapshots share storage, this + * number is expected to change with snapshot creation/deletion. + */ + public Long storageBytes() { + return storageBytes; + } + + /** + * Indicates whether {@link SnapshotInfo#storageBytes()} is in a stable state or it is being + * adjusted as a result of shared storage reallocation. {@link StorageBytesStatus#UPDATING} + * indicates that the size of the snapshot is being updated. {@link StorageBytesStatus#UP_TO_DATE} + * indicates that the size of the snapshot is up-to-date. + */ + public StorageBytesStatus storageBytesStatus() { + return storageBytesStatus; + } + + /** + * Returns a builder for the current snapshot. + */ + public Builder toBuilder() { + return new BuilderImpl(this); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id) + .add("creationTimestamp", creationTimestamp) + .add("snapshotId", snapshotId) + .add("description", description) + .add("status", status) + .add("diskSizeGb", diskSizeGb) + .add("licenses", licenses) + .add("sourceDisk", sourceDisk) + .add("sourceDiskId", sourceDiskId) + .add("storageBytes", storageBytes) + .add("storageBytesStatus", storageBytesStatus) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(id, creationTimestamp, snapshotId, description, status, diskSizeGb, + licenses, sourceDisk, sourceDiskId, storageBytes, storageBytesStatus); + } + + @Override + public boolean equals(Object obj) { + return obj != null + && obj.getClass().equals(SnapshotInfo.class) + && Objects.equals(toPb(), ((SnapshotInfo) obj).toPb()); + } + + SnapshotInfo setProjectId(String projectId) { + return toBuilder() + .snapshotId(snapshotId.setProjectId(projectId)) + .sourceDisk(sourceDisk.setProjectId(projectId)) + .build(); + } + + Snapshot toPb() { + Snapshot snapshotPb = new Snapshot(); + if (id != null) { + snapshotPb.setId(new BigInteger(id)); + } + if (creationTimestamp != null) { + snapshotPb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); + } + snapshotPb.setName(snapshotId.snapshot()); + snapshotPb.setDescription(description); + snapshotPb.setSelfLink(snapshotId.selfLink()); + if (status != null) { + snapshotPb.setStatus(status.name()); + } + snapshotPb.setDiskSizeGb(diskSizeGb); + if (licenses != null) { + snapshotPb.setLicenses(Lists.transform(licenses, LicenseId.TO_URL_FUNCTION)); + } + if (sourceDisk != null) { + snapshotPb.setSourceDisk(sourceDisk.selfLink()); + } + snapshotPb.setSourceDiskId(sourceDiskId); + snapshotPb.setStorageBytes(storageBytes); + if (storageBytesStatus != null) { + snapshotPb.setStorageBytesStatus(storageBytesStatus.name()); + } + return snapshotPb; + } + + /** + * Returns a builder for a {@code SnapshotInfo} object given the snapshot identity and a source + * disk identity. + */ + public static Builder builder(SnapshotId snapshotId, DiskId source) { + return new BuilderImpl().snapshotId(snapshotId).sourceDisk(source); + } + + /** + * Returns a {@code SnapshotInfo} object given the snapshot identity and a source disk identity. + */ + public static SnapshotInfo of(SnapshotId snapshotId, DiskId source) { + return builder(snapshotId, source).build(); + } + + static SnapshotInfo fromPb(Snapshot snapshotPb) { + return new BuilderImpl(snapshotPb).build(); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskIdTest.java new file mode 100644 index 000000000000..216f3237f8a5 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskIdTest.java @@ -0,0 +1,87 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class DiskIdTest { + + private static final String PROJECT = "project"; + private static final String ZONE = "zone"; + private static final String NAME = "disk"; + private static final String URL = + "https://www.googleapis.com/compute/v1/projects/project/zones/zone/disks/disk"; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testOf() { + DiskId diskId = DiskId.of(PROJECT, ZONE, NAME); + assertEquals(PROJECT, diskId.project()); + assertEquals(ZONE, diskId.zone()); + assertEquals(NAME, diskId.disk()); + assertEquals(URL, diskId.selfLink()); + diskId = DiskId.of(ZONE, NAME); + assertNull(diskId.project()); + assertEquals(ZONE, diskId.zone()); + assertEquals(NAME, diskId.disk()); + diskId = DiskId.of(ZoneId.of(ZONE), NAME); + assertNull(diskId.project()); + assertEquals(ZONE, diskId.zone()); + assertEquals(NAME, diskId.disk()); + } + + @Test + public void testToAndFromUrl() { + DiskId diskId = DiskId.of(PROJECT, ZONE, NAME); + compareDiskId(diskId, DiskId.fromUrl(diskId.selfLink())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid disk URL"); + DiskId.fromUrl("notMatchingUrl"); + } + + @Test + public void testSetProjectId() { + DiskId diskId = DiskId.of(PROJECT, ZONE, NAME); + assertSame(diskId, diskId.setProjectId(PROJECT)); + compareDiskId(diskId, DiskId.of(ZONE, NAME).setProjectId(PROJECT)); + } + + @Test + public void testMatchesUrl() { + assertTrue(DiskId.matchesUrl(DiskId.of(PROJECT, ZONE, NAME).selfLink())); + assertFalse(DiskId.matchesUrl("notMatchingUrl")); + } + + private void compareDiskId(DiskId expected, DiskId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.zone(), expected.zone()); + assertEquals(expected.disk(), expected.disk()); + assertEquals(expected.selfLink(), expected.selfLink()); + assertEquals(expected.hashCode(), expected.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotIdTest.java new file mode 100644 index 000000000000..cbda6fd3ebd0 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotIdTest.java @@ -0,0 +1,79 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class SnapshotIdTest { + + private static final String PROJECT = "project"; + private static final String NAME = "snapshot"; + private static final String URL = + "https://www.googleapis.com/compute/v1/projects/project/global/snapshots/snapshot"; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testOf() { + SnapshotId snapshotId = SnapshotId.of(PROJECT, NAME); + assertEquals(PROJECT, snapshotId.project()); + assertEquals(NAME, snapshotId.snapshot()); + assertEquals(URL, snapshotId.selfLink()); + snapshotId = SnapshotId.of(NAME); + assertNull(snapshotId.project()); + assertEquals(NAME, snapshotId.snapshot()); + } + + @Test + public void testToAndFromUrl() { + SnapshotId snapshotId = SnapshotId.of(PROJECT, NAME); + compareSnapshotId(snapshotId, SnapshotId.fromUrl(snapshotId.selfLink())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid snapshot URL"); + SnapshotId.fromUrl("notMatchingUrl"); + } + + @Test + public void testSetProjectId() { + SnapshotId snapshotId = SnapshotId.of(PROJECT, NAME); + assertSame(snapshotId, snapshotId.setProjectId(PROJECT)); + compareSnapshotId(snapshotId, SnapshotId.of(NAME).setProjectId(PROJECT)); + } + + @Test + public void testMatchesUrl() { + assertTrue(GlobalOperationId.matchesUrl(GlobalOperationId.of(PROJECT, NAME).selfLink())); + assertFalse(GlobalOperationId.matchesUrl("notMatchingUrl")); + } + + private void compareSnapshotId(SnapshotId expected, SnapshotId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.snapshot(), expected.snapshot()); + assertEquals(expected.selfLink(), expected.selfLink()); + assertEquals(expected.hashCode(), expected.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotInfoTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotInfoTest.java new file mode 100644 index 000000000000..15789b414574 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotInfoTest.java @@ -0,0 +1,135 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import com.google.common.collect.ImmutableList; +import com.google.gcloud.compute.SnapshotInfo.Status; +import com.google.gcloud.compute.SnapshotInfo.StorageBytesStatus; + +import org.junit.Test; + +import java.util.List; + +public class SnapshotInfoTest { + + private static final String ID = "42"; + private static final DiskId SOURCE_DISK = DiskId.of("project", "zone", "disk"); + private static final Long CREATION_TIMESTAMP = 1453293540000L; + private static final String DESCRIPTION = "description"; + private static final List LICENSES = ImmutableList.of( + LicenseId.of("project", "license1"), LicenseId.of("project", "license2")); + private static final SnapshotId SNAPSHOT_ID = SnapshotId.of("project", "snapshot"); + private static final Status STATUS = Status.CREATING; + private static final Long DISK_SIZE_GB = 42L; + private static final String SOURCE_DISK_ID = "diskId"; + private static final Long STORAGE_BYTES = 24L; + private static final StorageBytesStatus STORAGE_BYTES_STATUS = StorageBytesStatus.UP_TO_DATE; + private static final SnapshotInfo SNAPSHOT_INFO = SnapshotInfo.builder(SNAPSHOT_ID, SOURCE_DISK) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .status(STATUS) + .diskSizeGb(DISK_SIZE_GB) + .licenses(LICENSES) + .sourceDiskId(SOURCE_DISK_ID) + .storageBytes(STORAGE_BYTES) + .storageBytesStatus(STORAGE_BYTES_STATUS) + .build(); + + @Test + public void testToBuilder() { + compareSnapshotInfo(SNAPSHOT_INFO, SNAPSHOT_INFO.toBuilder().build()); + SnapshotInfo snapshotInfo = SNAPSHOT_INFO.toBuilder().description("newDescription").build(); + assertEquals("newDescription", snapshotInfo.description()); + snapshotInfo = snapshotInfo.toBuilder().description("description").build(); + compareSnapshotInfo(SNAPSHOT_INFO, snapshotInfo); + } + + @Test + public void testToBuilderIncomplete() { + SnapshotInfo snapshotInfo = SnapshotInfo.of(SNAPSHOT_ID, SOURCE_DISK); + assertEquals(snapshotInfo, snapshotInfo.toBuilder().build()); + } + + @Test + public void testBuilder() { + assertEquals(ID, SNAPSHOT_INFO.id()); + assertEquals(SNAPSHOT_ID, SNAPSHOT_INFO.snapshotId()); + assertEquals(CREATION_TIMESTAMP, SNAPSHOT_INFO.creationTimestamp()); + assertEquals(DESCRIPTION, SNAPSHOT_INFO.description()); + assertEquals(STATUS, SNAPSHOT_INFO.status()); + assertEquals(DISK_SIZE_GB, SNAPSHOT_INFO.diskSizeGb()); + assertEquals(LICENSES, SNAPSHOT_INFO.licenses()); + assertEquals(SOURCE_DISK, SNAPSHOT_INFO.sourceDisk()); + assertEquals(SOURCE_DISK_ID, SNAPSHOT_INFO.sourceDiskId()); + assertEquals(STORAGE_BYTES, SNAPSHOT_INFO.storageBytes()); + assertEquals(STORAGE_BYTES_STATUS, SNAPSHOT_INFO.storageBytesStatus()); + } + + @Test + public void testOf() { + SnapshotInfo snapshotInfo = SnapshotInfo.of(SNAPSHOT_ID, SOURCE_DISK); + assertNull(snapshotInfo.id()); + assertEquals(SNAPSHOT_ID, snapshotInfo.snapshotId()); + assertNull(snapshotInfo.creationTimestamp()); + assertNull(snapshotInfo.description()); + assertNull(snapshotInfo.status()); + assertNull(snapshotInfo.diskSizeGb()); + assertNull(snapshotInfo.licenses()); + assertEquals(SOURCE_DISK, snapshotInfo.sourceDisk()); + assertNull(snapshotInfo.sourceDiskId()); + assertNull(snapshotInfo.storageBytes()); + assertNull(snapshotInfo.storageBytesStatus()); + } + + @Test + public void testToAndFromPb() { + compareSnapshotInfo(SNAPSHOT_INFO, SnapshotInfo.fromPb(SNAPSHOT_INFO.toPb())); + SnapshotInfo snapshotInfo = SnapshotInfo.of(SNAPSHOT_ID, SOURCE_DISK); + compareSnapshotInfo(snapshotInfo, SnapshotInfo.fromPb(snapshotInfo.toPb())); + snapshotInfo = new SnapshotInfo.BuilderImpl().snapshotId(SNAPSHOT_ID).build(); + compareSnapshotInfo(snapshotInfo, SnapshotInfo.fromPb(snapshotInfo.toPb())); + } + + @Test + public void testSetProjectId() { + SnapshotInfo snapshotInfo = SNAPSHOT_INFO.toBuilder() + .snapshotId(SnapshotId.of("snapshot")) + .sourceDisk(DiskId.of("zone", "disk")) + .build(); + compareSnapshotInfo(SNAPSHOT_INFO, snapshotInfo.setProjectId("project")); + } + + public void compareSnapshotInfo(SnapshotInfo expected, SnapshotInfo value) { + assertEquals(expected, value); + assertEquals(expected.id(), value.id()); + assertEquals(expected.snapshotId(), value.snapshotId()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.status(), value.status()); + assertEquals(expected.diskSizeGb(), value.diskSizeGb()); + assertEquals(expected.licenses(), value.licenses()); + assertEquals(expected.sourceDisk(), value.sourceDisk()); + assertEquals(expected.sourceDiskId(), value.sourceDiskId()); + assertEquals(expected.storageBytes(), value.storageBytes()); + assertEquals(expected.storageBytesStatus(), value.storageBytesStatus()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} From 65fdd481cc5ce3040d4ac92eaf2e9fe8fdcec705 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 23 Mar 2016 17:10:21 +0100 Subject: [PATCH 302/375] Add SnapshotInfo and related classes to SerializationTest, minor fixes --- .../java/com/google/gcloud/compute/DiskId.java | 8 ++++---- .../com/google/gcloud/compute/SnapshotInfo.java | 7 +++---- .../google/gcloud/compute/SerializationTest.java | 14 +++++++++----- .../com/google/gcloud/compute/SnapshotIdTest.java | 4 ++-- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskId.java index b2a0f3e45db7..7338e04ef5d8 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskId.java @@ -106,8 +106,8 @@ DiskId setProjectId(String projectId) { } /** - * Returns a disk identity given the zone identity and the disk name. The address name must be - * 1-63 characters long and comply with RFC1035. Specifically, the name must match the regular + * Returns a disk identity given the zone identity and the disk name. The disk name must be 1-63 + * characters long and comply with RFC1035. Specifically, the name must match the regular * expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a * lowercase letter, and all following characters must be a dash, lowercase letter, or digit, * except the last character, which cannot be a dash. @@ -119,7 +119,7 @@ public static DiskId of(ZoneId zoneId, String disk) { } /** - * Returns a disk identity given the zone and disk names. The address name must be 1-63 characters + * Returns a disk identity given the zone and disk names. The disk name must be 1-63 characters * long and comply with RFC1035. Specifically, the name must match the regular expression * {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a lowercase letter, * and all following characters must be a dash, lowercase letter, or digit, except the last @@ -132,7 +132,7 @@ public static DiskId of(String zone, String disk) { } /** - * Returns a disk identity given project, zone and disks names. The address name must be 1-63 + * Returns a disk identity given project, zone and disks names. The disk name must be 1-63 * characters long and comply with RFC1035. Specifically, the name must match the regular * expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a * lowercase letter, and all following characters must be a dash, lowercase letter, or digit, diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotInfo.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotInfo.java index 283ca665d173..fe567988d82c 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotInfo.java @@ -74,9 +74,8 @@ public Snapshot apply(SnapshotInfo snapshot) { private final StorageBytesStatus storageBytesStatus; /** - * The status of a Google Compute Engine snapshot. A snapshot can be used to create other - * resources, such as disks, only after the snapshot has been successfully created and the status - * is set to {@code READY}. + * The status of a Google Compute Engine snapshot. A snapshot can be used to create a disk only + * after the snapshot has been successfully created and the status is set to {@code READY}. */ public enum Status { /** @@ -106,7 +105,7 @@ public enum Status { } /** - * An indicator whether {@link SnapshotInfo#storageBytes()} is in a stable state or it is being + * An indicator of whether {@link SnapshotInfo#storageBytes()} is in a stable state or it is being * adjusted as a result of shared storage reallocation. */ public enum StorageBytesStatus { diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java index 81afee4acf50..8b5956cef100 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java @@ -147,6 +147,9 @@ public class SerializationTest { .usage(INSTANCE_USAGE) .build(); private static final Address ADDRESS = new Address.Builder(COMPUTE, REGION_ADDRESS_ID).build(); + private static final DiskId DISK_ID = DiskId.of("project", "zone", "disk"); + private static final SnapshotId SNAPSHOT_ID = SnapshotId.of("project", "snapshot"); + private static final SnapshotInfo SNAPSHOT_INFO = SnapshotInfo.of(SNAPSHOT_ID, DISK_ID); private static final Compute.DiskTypeOption DISK_TYPE_OPTION = Compute.DiskTypeOption.fields(); private static final Compute.DiskTypeFilter DISK_TYPE_FILTER = @@ -212,11 +215,12 @@ public void testModelAndRequests() throws Exception { REGION_OPERATION_ID, ZONE_OPERATION_ID, GLOBAL_OPERATION, REGION_OPERATION, ZONE_OPERATION, INSTANCE_ID, REGION_FORWARDING_RULE_ID, GLOBAL_FORWARDING_RULE_ID, GLOBAL_ADDRESS_ID, REGION_ADDRESS_ID, INSTANCE_USAGE, GLOBAL_FORWARDING_USAGE, REGION_FORWARDING_USAGE, - ADDRESS_INFO, ADDRESS, DISK_TYPE_OPTION, DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, - DISK_TYPE_AGGREGATED_LIST_OPTION, MACHINE_TYPE_OPTION, MACHINE_TYPE_FILTER, - MACHINE_TYPE_LIST_OPTION, MACHINE_TYPE_AGGREGATED_LIST_OPTION, REGION_OPTION, REGION_FILTER, - REGION_LIST_OPTION, ZONE_OPTION, ZONE_FILTER, ZONE_LIST_OPTION, LICENSE_OPTION, - OPERATION_OPTION, OPERATION_FILTER, OPERATION_LIST_OPTION, ADDRESS_OPTION, ADDRESS_FILTER, + ADDRESS_INFO, ADDRESS, DISK_ID, SNAPSHOT_ID, SNAPSHOT_INFO, DISK_TYPE_OPTION, + DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, DISK_TYPE_AGGREGATED_LIST_OPTION, + MACHINE_TYPE_OPTION, MACHINE_TYPE_FILTER, MACHINE_TYPE_LIST_OPTION, + MACHINE_TYPE_AGGREGATED_LIST_OPTION, REGION_OPTION, REGION_FILTER, REGION_LIST_OPTION, + ZONE_OPTION, ZONE_FILTER, ZONE_LIST_OPTION, LICENSE_OPTION, OPERATION_OPTION, + OPERATION_FILTER, OPERATION_LIST_OPTION, ADDRESS_OPTION, ADDRESS_FILTER, ADDRESS_LIST_OPTION, ADDRESS_AGGREGATED_LIST_OPTION}; for (Serializable obj : objects) { Object copy = serializeAndDeserialize(obj); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotIdTest.java index cbda6fd3ebd0..13dadee790b9 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotIdTest.java @@ -65,8 +65,8 @@ public void testSetProjectId() { @Test public void testMatchesUrl() { - assertTrue(GlobalOperationId.matchesUrl(GlobalOperationId.of(PROJECT, NAME).selfLink())); - assertFalse(GlobalOperationId.matchesUrl("notMatchingUrl")); + assertTrue(SnapshotId.matchesUrl(SnapshotId.of(PROJECT, NAME).selfLink())); + assertFalse(SnapshotId.matchesUrl("notMatchingUrl")); } private void compareSnapshotId(SnapshotId expected, SnapshotId value) { From 36ddd14a4af45dafa5741ee368c69eef411e3f4e Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 23 Mar 2016 18:16:30 +0100 Subject: [PATCH 303/375] Add functional methods for snapshots and Snapshot class --- .../com/google/gcloud/compute/Compute.java | 164 ++++++++++++ .../google/gcloud/compute/ComputeImpl.java | 116 ++++++++- .../com/google/gcloud/compute/Snapshot.java | 208 ++++++++++++++++ .../com/google/gcloud/spi/ComputeRpc.java | 44 +++- .../google/gcloud/spi/DefaultComputeRpc.java | 57 +++++ .../gcloud/compute/ComputeImplTest.java | 163 ++++++++++++ .../gcloud/compute/SerializationTest.java | 12 +- .../google/gcloud/compute/SnapshotTest.java | 235 ++++++++++++++++++ 8 files changed, 991 insertions(+), 8 deletions(-) create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/Snapshot.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotTest.java diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java index 815b5ebe49e6..98318280ccdf 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java @@ -821,6 +821,54 @@ public static AddressFilter notEquals(AddressField field, String value) { } } + /** + * Class for filtering snapshot lists. + */ + class SnapshotFilter extends ListFilter { + + private static final long serialVersionUID = 8757711630092406747L; + + SnapshotFilter(SnapshotField field, ComparisonOperator operator, Object value) { + super(field.selector(), operator, value); + } + + /** + * Returns an equality filter for the given field and string value. For string fields, + * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must + * match the entire field. + * + * @see RE2 + */ + public static SnapshotFilter equals(SnapshotField field, String value) { + return new SnapshotFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value)); + } + + /** + * Returns a not-equals filter for the given field and string value. For string fields, + * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must + * match the entire field. + * + * @see RE2 + */ + public static SnapshotFilter notEquals(SnapshotField field, String value) { + return new SnapshotFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value)); + } + + /** + * Returns an equality filter for the given field and long value. + */ + public static SnapshotFilter equals(SnapshotField field, long value) { + return new SnapshotFilter(checkNotNull(field), ComparisonOperator.EQ, value); + } + + /** + * Returns a not-equals filter for the given field and long value. + */ + public static SnapshotFilter notEquals(SnapshotField field, long value) { + return new SnapshotFilter(checkNotNull(field), ComparisonOperator.NE, value); + } + } + /** * Class for specifying disk type get options. */ @@ -1344,6 +1392,73 @@ public static AddressAggregatedListOption pageToken(String pageToken) { } } + /** + * Class for specifying snapshot get options. + */ + class SnapshotOption extends Option { + + private static final long serialVersionUID = -3505179459035500945L; + + private SnapshotOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify the snapshot's fields to be returned by the RPC call. If this + * option is not provided, all snapshot's fields are returned. {@code SnapshotOption.fields} can + * be used to specify only the fields of interest. {@link Snapshot#snapshotId()} is always + * returned, even if not specified. + */ + public static SnapshotOption fields(SnapshotField... fields) { + return new SnapshotOption(ComputeRpc.Option.FIELDS, SnapshotField.selector(fields)); + } + } + + /** + * Class for specifying snapshot list options. + */ + class SnapshotListOption extends Option { + + private static final long serialVersionUID = 8278588147660831257L; + + private SnapshotListOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify a filter on the snapshots being listed. + */ + public static SnapshotListOption filter(SnapshotFilter filter) { + return new SnapshotListOption(ComputeRpc.Option.FILTER, filter.toPb()); + } + + /** + * Returns an option to specify the maximum number of snapshots returned per page. + */ + public static SnapshotListOption pageSize(long pageSize) { + return new SnapshotListOption(ComputeRpc.Option.MAX_RESULTS, pageSize); + } + + /** + * Returns an option to specify the page token from which to start listing snapshots. + */ + public static SnapshotListOption pageToken(String pageToken) { + return new SnapshotListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); + } + + /** + * Returns an option to specify the snapshot's fields to be returned by the RPC call. If this + * option is not provided, all snapshot's fields are returned. {@code SnapshotListOption.fields} + * can be used to specify only the fields of interest. {@link Snapshot#snapshotId()} is always + * returned, even if not specified. + */ + public static SnapshotListOption fields(SnapshotField... fields) { + StringBuilder builder = new StringBuilder(); + builder.append("items(").append(SnapshotField.selector(fields)).append("),nextPageToken"); + return new SnapshotListOption(ComputeRpc.Option.FIELDS, builder.toString()); + } + } + /** * Returns the requested disk type or {@code null} if not found. * @@ -1525,4 +1640,53 @@ public static AddressAggregatedListOption pageToken(String pageToken) { * @throws ComputeException upon failure */ Operation delete(AddressId addressId, OperationOption... options); + + /** + * Creates a new snapshot. + * + * @return a zone operation if the create request was issued correctly, {@code null} if + * {@code snapshot.sourceDisk} was not found + * @throws ComputeException upon failure + */ + Operation create(SnapshotInfo snapshot, OperationOption... options); + + /** + * Returns the requested snapshot or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + Snapshot getSnapshot(String snapshot, SnapshotOption... options); + + /** + * Lists all snapshots. + * + * @throws ComputeException upon failure + */ + Page listSnapshots(SnapshotListOption... options); + + /** + * Deletes the requested snapshot. Keep in mind that deleting a single snapshot might not + * necessarily delete all the data for that snapshot. If any data for the snapshot that is marked + * for deletion is needed for subsequent snapshots, the data will be moved to the next snapshot. + * + * @return a global operation if the request was issued correctly, {@code null} if the snapshot + * was not found + * @throws ComputeException upon failure + * @see + * Deleting a snapshot + */ + Operation deleteSnapshot(SnapshotId snapshot, OperationOption... options); + + /** + * Deletes the requested snapshot. Keep in mind that deleting a single snapshot might not + * necessarily delete all the data for that snapshot. If any data on the snapshot that is marked + * for deletion is needed for subsequent snapshots, the data will be moved to the next snapshot. + * + * @return a global operation if the request was issued correctly, {@code null} if the snapshot + * was not found + * @throws ComputeException upon failure + * @see + * Deleting a snapshot + */ + Operation deleteSnapshot(String snapshot, OperationOption... options); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java index 838816a035e0..1b7cdecb4e38 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java @@ -273,6 +273,25 @@ public Page
    nextPage() { } } + private static class SnapshotPageFetcher implements NextPageFetcher { + + private static final long serialVersionUID = 6205774609802216986L; + private final Map requestOptions; + private final ComputeOptions serviceOptions; + + SnapshotPageFetcher(ComputeOptions serviceOptions, String cursor, + Map optionMap) { + this.requestOptions = + PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + } + + @Override + public Page nextPage() { + return listSnapshots(serviceOptions, requestOptions); + } + } + private final ComputeRpc computeRpc; ComputeImpl(ComputeOptions options) { @@ -881,8 +900,8 @@ public Address apply(com.google.api.services.compute.model.Address address) { return Address.fromPb(serviceOptions.service(), address); } }); - return new PageImpl<>(new AggregatedAddressPageFetcher(serviceOptions, cursor, - optionsMap), cursor, operations); + return new PageImpl<>(new AggregatedAddressPageFetcher(serviceOptions, cursor, optionsMap), + cursor, operations); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); } @@ -914,6 +933,99 @@ public com.google.api.services.compute.model.Operation call() { } } + @Override + public Operation create(SnapshotInfo snapshot, final OperationOption... options) { + final SnapshotInfo completeSnapshot = snapshot.setProjectId(options().projectId()); + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.createSnapshot(completeSnapshot.sourceDisk().zone(), + completeSnapshot.sourceDisk().disk(), completeSnapshot.snapshotId().snapshot(), + completeSnapshot.description(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Snapshot getSnapshot(final String snapshot, SnapshotOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Snapshot answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Snapshot call() { + return computeRpc.getSnapshot(snapshot, optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Snapshot.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Page listSnapshots(SnapshotListOption... options) { + return listSnapshots(options(), optionMap(options)); + } + + private static Page listSnapshots(final ComputeOptions serviceOptions, + final Map optionsMap) { + try { + ComputeRpc.Tuple> result = + runWithRetries(new Callable>>() { + @Override + public ComputeRpc.Tuple> call() { + return serviceOptions.rpc().listSnapshots(optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.x(); + Iterable snapshots = Iterables.transform( + result.y() == null ? ImmutableList.of() + : result.y(), + new Function() { + @Override + public Snapshot apply(com.google.api.services.compute.model.Snapshot snapshot) { + return Snapshot.fromPb(serviceOptions.service(), snapshot); + } + }); + return new PageImpl<>(new SnapshotPageFetcher(serviceOptions, cursor, optionsMap), cursor, + snapshots); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation deleteSnapshot(final SnapshotId snapshot, OperationOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.deleteSnapshot(snapshot.snapshot(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation deleteSnapshot(final String snapshot, OperationOption... options) { + return deleteSnapshot(SnapshotId.of(snapshot)); + } + private Map optionMap(Option... options) { Map optionMap = Maps.newEnumMap(ComputeRpc.Option.class); for (Option option : options) { diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Snapshot.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Snapshot.java new file mode 100644 index 000000000000..9ca4c95c9956 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Snapshot.java @@ -0,0 +1,208 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.util.List; +import java.util.Objects; + +/** + * A Google Compute Engine snapshot. Compute Engine allows you to take snapshots of your persistent + * disk and create new persistent disks from that snapshot. This can be useful for backing up data, + * recreating a persistent disk that might have been lost, or copying a persistent disk. Snapshots + * can be applied across persistent disk types. {@code Snapshot} adds a layer of service-related + * functionality over {@link SnapshotInfo}. Obejcts of this class are immutable, to get a + * {@code Snapshot} object with the most recent information use {@link #reload}. + * + * @see Use + * persistent disk snapshots + */ +public class Snapshot extends SnapshotInfo { + + private static final long serialVersionUID = -973924811396336695L; + + private final ComputeOptions options; + private transient Compute compute; + + /** + * A builder for {@code Snapshot} objects. + */ + public static class Builder extends SnapshotInfo.Builder { + + private final Compute compute; + private final SnapshotInfo.BuilderImpl infoBuilder; + + Builder(Compute compute, SnapshotId snapshotId, DiskId sourceDisk) { + this.compute = compute; + this.infoBuilder = new SnapshotInfo.BuilderImpl(); + this.infoBuilder.snapshotId(snapshotId); + this.infoBuilder.sourceDisk(sourceDisk); + } + + Builder(Snapshot snapshot) { + this.compute = snapshot.compute; + this.infoBuilder = new SnapshotInfo.BuilderImpl(snapshot); + } + + @Override + Builder id(String id) { + infoBuilder.id(id); + return this; + } + + @Override + Builder creationTimestamp(Long creationTimestamp) { + infoBuilder.creationTimestamp(creationTimestamp); + return this; + } + + @Override + public Builder snapshotId(SnapshotId snapshotId) { + infoBuilder.snapshotId(snapshotId); + return this; + } + + @Override + public Builder description(String description) { + infoBuilder.description(description); + return this; + } + + @Override + Builder status(Status status) { + infoBuilder.status(status); + return this; + } + + @Override + Builder diskSizeGb(Long diskSizeGb) { + infoBuilder.diskSizeGb(diskSizeGb); + return this; + } + + @Override + Builder licenses(List licenses) { + infoBuilder.licenses(licenses); + return this; + } + + @Override + public Builder sourceDisk(DiskId sourceDisk) { + infoBuilder.sourceDisk(sourceDisk); + return this; + } + + @Override + Builder sourceDiskId(String sourceDiskId) { + infoBuilder.sourceDiskId(sourceDiskId); + return this; + } + + @Override + Builder storageBytes(Long storageBytes) { + infoBuilder.storageBytes(storageBytes); + return this; + } + + @Override + Builder storageBytesStatus(StorageBytesStatus storageBytesStatus) { + infoBuilder.storageBytesStatus(storageBytesStatus); + return this; + } + + @Override + public Snapshot build() { + return new Snapshot(compute, infoBuilder); + } + } + + Snapshot(Compute compute, SnapshotInfo.BuilderImpl infoBuilder) { + super(infoBuilder); + this.compute = checkNotNull(compute); + this.options = compute.options(); + } + + /** + * Checks if this snapshot exists. + * + * @return {@code true} if this snapshot exists, {@code false} otherwise + * @throws ComputeException upon failure + */ + public boolean exists() { + return reload(Compute.SnapshotOption.fields()) != null; + } + + /** + * Fetches current snapshot's latest information. Returns {@code null} if the snapshot does not + * exist. + * + * @param options snapshot options + * @return a {@code Snapshot} object with latest information or {@code null} if not found + * @throws ComputeException upon failure + */ + public Snapshot reload(Compute.SnapshotOption... options) { + return compute.getSnapshot(snapshotId().snapshot(), options); + } + + /** + * Deletes this snapshot. + * + * @return a global operation if delete request was successfully sent, {@code null} if the + * snapshot was not found + * @throws ComputeException upon failure + */ + public Operation delete(Compute.OperationOption... options) { + return compute.deleteSnapshot(snapshotId(), options); + } + + /** + * Returns the snapshot's {@code Compute} object used to issue requests. + */ + public Compute compute() { + return compute; + } + + @Override + public Builder toBuilder() { + return new Builder(this); + } + + @Override + public final boolean equals(Object obj) { + return obj instanceof Snapshot + && Objects.equals(toPb(), ((Snapshot) obj).toPb()) + && Objects.equals(options, ((Snapshot) obj).options); + } + + @Override + public final int hashCode() { + return Objects.hash(super.hashCode(), options); + } + + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { + in.defaultReadObject(); + this.compute = options.service(); + } + + static Snapshot fromPb(Compute compute, + com.google.api.services.compute.model.Snapshot snapshotPb) { + return new Snapshot(compute, new SnapshotInfo.BuilderImpl(snapshotPb)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java index 66152f5464a4..ff0831ece6e9 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java @@ -22,6 +22,7 @@ import com.google.api.services.compute.model.MachineType; import com.google.api.services.compute.model.Operation; import com.google.api.services.compute.model.Region; +import com.google.api.services.compute.model.Snapshot; import com.google.api.services.compute.model.Zone; import com.google.gcloud.compute.ComputeException; @@ -255,8 +256,8 @@ public Y y() { /** * Deletes the requested global address. * - * @return a global operation if request was issued correctly, {@code null} if the address was not - * found + * @return a global operation if the request was issued correctly, {@code null} if the address was + * not found * @throws ComputeException upon failure */ Operation deleteGlobalAddress(String address, Map options); @@ -293,9 +294,44 @@ public Y y() { /** * Deletes the requested region address. * - * @return a region operation if request was issued correctly, {@code null} if the address was not - * found + * @return a region operation if the request was issued correctly, {@code null} if the address was + * not found * @throws ComputeException upon failure or if region is not found */ Operation deleteRegionAddress(String region, String address, Map options); + + /** + * Creates a snapshot for the specified disk. + * + * @return a zone operation if the create request was issued correctly, {@code null} if the disk + * was not found + * @throws ComputeException upon failure + */ + Operation createSnapshot(String zone, String disk, String snapshot, String description, + Map options); + + /** + * Returns the requested snapshot or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + Snapshot getSnapshot(String snapshot, Map options); + + /** + * Lists all snapshots. + * + * @throws ComputeException upon failure + */ + Tuple> listSnapshots(Map options); + + /** + * Deletes the requested snapshot. Keep in mind that deleting a single snapshot might not + * necessarily delete all the data for that snapshot. If any data for the snapshot that is marked + * for deletion is needed for subsequent snapshots, the data will be moved to the next snapshot. + * + * @return a global operation if the request was issued correctly, {@code null} if the snapshot + * was not found + * @throws ComputeException upon failure + */ + Operation deleteSnapshot(String snapshot, Map options); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java index 78100f1c3c1f..d41a879f5d91 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java @@ -43,6 +43,8 @@ import com.google.api.services.compute.model.OperationList; import com.google.api.services.compute.model.Region; import com.google.api.services.compute.model.RegionList; +import com.google.api.services.compute.model.Snapshot; +import com.google.api.services.compute.model.SnapshotList; import com.google.api.services.compute.model.Zone; import com.google.api.services.compute.model.ZoneList; import com.google.common.collect.ImmutableList; @@ -507,6 +509,61 @@ public Operation deleteRegionAddress(String region, String address, Map options) { + Snapshot snapshotObject = new Snapshot().setName(snapshot).setDescription(description); + try { + return compute.disks() + .createSnapshot(this.options.projectId(), zone, disk, snapshotObject) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Snapshot getSnapshot(String snapshot, Map options) { + try { + return compute.snapshots() + .get(this.options.projectId(), snapshot) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Tuple> listSnapshots(Map options) { + try { + SnapshotList snapshotList = compute.snapshots() + .list(this.options.projectId()) + .setFilter(FILTER.getString(options)) + .setMaxResults(MAX_RESULTS.getLong(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + .setFields(FIELDS.getString(options)) + .execute(); + Iterable snapshots = snapshotList.getItems(); + return Tuple.of(snapshotList.getNextPageToken(), snapshots); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Operation deleteSnapshot(String snapshot, Map options) { + try { + return compute.snapshots() + .delete(this.options.projectId(), snapshot) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + /** * This method returns {@code null} if the error code of {@code exception} was 404, re-throws the * exception otherwise. diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java index 808d4ce7d255..31325da8de61 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java @@ -180,6 +180,9 @@ public class ComputeImplTest { GlobalAddressId.of("project", "address"); private static final AddressInfo REGION_ADDRESS = AddressInfo.builder(REGION_ADDRESS_ID).build(); private static final AddressInfo GLOBAL_ADDRESS = AddressInfo.builder(GLOBAL_ADDRESS_ID).build(); + private static final DiskId DISK_ID = DiskId.of("project", "zone", "disk"); + private static final SnapshotId SNAPSHOT_ID = SnapshotId.of("project", "snapshot"); + private static final SnapshotInfo SNAPSHOT = SnapshotInfo.of(SNAPSHOT_ID, DISK_ID); // Empty ComputeRpc options private static final Map EMPTY_RPC_OPTIONS = ImmutableMap.of(); @@ -319,6 +322,24 @@ public class ComputeImplTest { private static final Compute.AddressAggregatedListOption ADDRESS_AGGREGATED_LIST_FILTER = Compute.AddressAggregatedListOption.filter(ADDRESS_FILTER); + // Snapshot options + private static final Compute.SnapshotOption SNAPSHOT_OPTION_FIELDS = + Compute.SnapshotOption.fields(Compute.SnapshotField.ID, Compute.SnapshotField.DESCRIPTION); + + // Snapshot list options + private static final Compute.SnapshotFilter SNAPSHOT_FILTER = + Compute.SnapshotFilter.equals(Compute.SnapshotField.DISK_SIZE_GB, 500L); + private static final Compute.SnapshotListOption SNAPSHOT_LIST_PAGE_TOKEN = + Compute.SnapshotListOption.pageToken("cursor"); + private static final Compute.SnapshotListOption SNAPSHOT_LIST_MAX_RESULTS = + Compute.SnapshotListOption.pageSize(42L); + private static final Compute.SnapshotListOption SNAPSHOT_LIST_FILTER = + Compute.SnapshotListOption.filter(SNAPSHOT_FILTER); + private static final Map SNAPSHOT_LIST_OPTIONS = ImmutableMap.of( + PAGE_TOKEN, "cursor", + MAX_RESULTS, 42L, + FILTER, "diskSizeGb eq 500"); + private static final Function OPERATION_TO_PB_FUNCTION = new Function() { @@ -1906,6 +1927,148 @@ public void testCreateRegionAddressWithOptions() { assertEquals(regionOperation, operation); } + @Test + public void testCreateSnapshot() { + EasyMock.expect(computeRpcMock.createSnapshot(DISK_ID.zone(), DISK_ID.disk(), + SNAPSHOT_ID.snapshot(), null, EMPTY_RPC_OPTIONS)).andReturn(globalOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.create(SNAPSHOT); + assertEquals(globalOperation, operation); + } + + @Test + public void testCreateSnapshotWithOptions() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.createSnapshot(eq(DISK_ID.zone()), eq(DISK_ID.disk()), + eq(SNAPSHOT_ID.snapshot()), EasyMock.isNull(), capture(capturedOptions))) + .andReturn(globalOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.create(SNAPSHOT, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(globalOperation, operation); + } + + @Test + public void testGetSnapshot() { + EasyMock.expect(computeRpcMock.getSnapshot(SNAPSHOT_ID.snapshot(), EMPTY_RPC_OPTIONS)) + .andReturn(SNAPSHOT.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Snapshot snapshot = compute.getSnapshot(SNAPSHOT_ID.snapshot()); + assertEquals(new Snapshot(compute, new SnapshotInfo.BuilderImpl(SNAPSHOT)), snapshot); + } + + @Test + public void testGetSnapshot_Null() { + EasyMock.expect(computeRpcMock.getSnapshot(SNAPSHOT_ID.snapshot(), EMPTY_RPC_OPTIONS)) + .andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.getSnapshot(SNAPSHOT_ID.snapshot())); + } + + @Test + public void testGetSnapshotWithSelectedFields() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.getSnapshot(eq(SNAPSHOT_ID.snapshot()), + capture(capturedOptions))).andReturn(SNAPSHOT.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Snapshot snapshot = compute.getSnapshot(SNAPSHOT_ID.snapshot(), SNAPSHOT_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(SNAPSHOT_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(new Snapshot(compute, new SnapshotInfo.BuilderImpl(SNAPSHOT)), snapshot); + } + + @Test + public void testDeleteSnapshot_Operation() { + EasyMock.expect(computeRpcMock.deleteSnapshot(SNAPSHOT_ID.snapshot(), EMPTY_RPC_OPTIONS)) + .andReturn(globalOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(globalOperation, compute.deleteSnapshot(SNAPSHOT_ID)); + } + + @Test + public void testDeleteSnapshotWithSelectedFields_Operation() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.deleteSnapshot(eq(SNAPSHOT_ID.snapshot()), + capture(capturedOptions))).andReturn(globalOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.deleteSnapshot(SNAPSHOT_ID, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(globalOperation, operation); + } + + @Test + public void testDeleteSnapshot_Null() { + EasyMock.expect(computeRpcMock.deleteSnapshot(SNAPSHOT_ID.snapshot(), EMPTY_RPC_OPTIONS)) + .andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.deleteSnapshot(SNAPSHOT_ID)); + } + + @Test + public void testListSnapshots() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList snapshotList = ImmutableList.of( + new Snapshot(compute, new SnapshotInfo.BuilderImpl(SNAPSHOT)), + new Snapshot(compute, new SnapshotInfo.BuilderImpl(SNAPSHOT))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(snapshotList, SnapshotInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listSnapshots(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listSnapshots(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(snapshotList.toArray(), Iterables.toArray(page.values(), Snapshot.class)); + } + + @Test + public void testListEmptySnapshots() { + compute = options.service(); + ImmutableList snapshots = ImmutableList.of(); + Tuple> result = + Tuple.>of(null, snapshots); + EasyMock.expect(computeRpcMock.listSnapshots(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listSnapshots(); + assertNull(page.nextPageCursor()); + assertArrayEquals(snapshots.toArray(), Iterables.toArray(page.values(), Snapshot.class)); + } + + @Test + public void testListSnapshotsWithOptions() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList snapshotList = ImmutableList.of( + new Snapshot(compute, new SnapshotInfo.BuilderImpl(SNAPSHOT)), + new Snapshot(compute, new SnapshotInfo.BuilderImpl(SNAPSHOT))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(snapshotList, SnapshotInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listSnapshots(SNAPSHOT_LIST_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listSnapshots(SNAPSHOT_LIST_MAX_RESULTS, SNAPSHOT_LIST_PAGE_TOKEN, + SNAPSHOT_LIST_FILTER); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(snapshotList.toArray(), Iterables.toArray(page.values(), Snapshot.class)); + } + @Test public void testRetryableException() { EasyMock.expect( diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java index 8b5956cef100..ab15ca5dc6a9 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java @@ -150,6 +150,8 @@ public class SerializationTest { private static final DiskId DISK_ID = DiskId.of("project", "zone", "disk"); private static final SnapshotId SNAPSHOT_ID = SnapshotId.of("project", "snapshot"); private static final SnapshotInfo SNAPSHOT_INFO = SnapshotInfo.of(SNAPSHOT_ID, DISK_ID); + private static final Snapshot SNAPSHOT = + new Snapshot.Builder(COMPUTE, SNAPSHOT_ID, DISK_ID).build(); private static final Compute.DiskTypeOption DISK_TYPE_OPTION = Compute.DiskTypeOption.fields(); private static final Compute.DiskTypeFilter DISK_TYPE_FILTER = @@ -189,6 +191,11 @@ public class SerializationTest { Compute.AddressListOption.filter(ADDRESS_FILTER); private static final Compute.AddressAggregatedListOption ADDRESS_AGGREGATED_LIST_OPTION = Compute.AddressAggregatedListOption.filter(ADDRESS_FILTER); + private static final Compute.SnapshotOption SNAPSHOT_OPTION = Compute.SnapshotOption.fields(); + private static final Compute.SnapshotFilter SNAPSHOT_FILTER = + Compute.SnapshotFilter.equals(Compute.SnapshotField.SELF_LINK, "selfLink"); + private static final Compute.SnapshotListOption SNAPSHOT_LIST_OPTION = + Compute.SnapshotListOption.filter(SNAPSHOT_FILTER); @Test public void testServiceOptions() throws Exception { @@ -215,13 +222,14 @@ public void testModelAndRequests() throws Exception { REGION_OPERATION_ID, ZONE_OPERATION_ID, GLOBAL_OPERATION, REGION_OPERATION, ZONE_OPERATION, INSTANCE_ID, REGION_FORWARDING_RULE_ID, GLOBAL_FORWARDING_RULE_ID, GLOBAL_ADDRESS_ID, REGION_ADDRESS_ID, INSTANCE_USAGE, GLOBAL_FORWARDING_USAGE, REGION_FORWARDING_USAGE, - ADDRESS_INFO, ADDRESS, DISK_ID, SNAPSHOT_ID, SNAPSHOT_INFO, DISK_TYPE_OPTION, + ADDRESS_INFO, ADDRESS, DISK_ID, SNAPSHOT_ID, SNAPSHOT_INFO, SNAPSHOT, DISK_TYPE_OPTION, DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, DISK_TYPE_AGGREGATED_LIST_OPTION, MACHINE_TYPE_OPTION, MACHINE_TYPE_FILTER, MACHINE_TYPE_LIST_OPTION, MACHINE_TYPE_AGGREGATED_LIST_OPTION, REGION_OPTION, REGION_FILTER, REGION_LIST_OPTION, ZONE_OPTION, ZONE_FILTER, ZONE_LIST_OPTION, LICENSE_OPTION, OPERATION_OPTION, OPERATION_FILTER, OPERATION_LIST_OPTION, ADDRESS_OPTION, ADDRESS_FILTER, - ADDRESS_LIST_OPTION, ADDRESS_AGGREGATED_LIST_OPTION}; + ADDRESS_LIST_OPTION, ADDRESS_AGGREGATED_LIST_OPTION, SNAPSHOT_OPTION, SNAPSHOT_FILTER, + SNAPSHOT_LIST_OPTION}; for (Serializable obj : objects) { Object copy = serializeAndDeserialize(obj); assertEquals(obj, obj); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotTest.java new file mode 100644 index 000000000000..2297199d16c8 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotTest.java @@ -0,0 +1,235 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.createStrictMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import com.google.common.collect.ImmutableList; + +import org.junit.Test; + +import java.util.List; + +public class SnapshotTest { + + private static final String ID = "42"; + private static final DiskId SOURCE_DISK = DiskId.of("project", "zone", "disk"); + private static final Long CREATION_TIMESTAMP = 1453293540000L; + private static final String DESCRIPTION = "description"; + private static final List LICENSES = ImmutableList.of( + LicenseId.of("project", "license1"), LicenseId.of("project", "license2")); + private static final SnapshotId SNAPSHOT_ID = SnapshotId.of("project", "snapshot"); + private static final SnapshotInfo.Status STATUS = SnapshotInfo.Status.CREATING; + private static final Long DISK_SIZE_GB = 42L; + private static final String SOURCE_DISK_ID = "diskId"; + private static final Long STORAGE_BYTES = 24L; + private static final SnapshotInfo.StorageBytesStatus STORAGE_BYTES_STATUS = + SnapshotInfo.StorageBytesStatus.UP_TO_DATE; + + private Compute serviceMockReturnsOptions = createStrictMock(Compute.class); + private ComputeOptions mockOptions = createMock(ComputeOptions.class); + private Compute compute; + private Snapshot snapshot; + private Snapshot expectedSnapshot; + + private void initializeExpectedSnapshot(int optionsCalls) { + expect(serviceMockReturnsOptions.options()).andReturn(mockOptions).times(optionsCalls); + replay(serviceMockReturnsOptions); + expectedSnapshot = new Snapshot.Builder(serviceMockReturnsOptions, SNAPSHOT_ID, SOURCE_DISK) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .status(STATUS) + .diskSizeGb(DISK_SIZE_GB) + .licenses(LICENSES) + .sourceDiskId(SOURCE_DISK_ID) + .storageBytes(STORAGE_BYTES) + .storageBytesStatus(STORAGE_BYTES_STATUS) + .build(); + compute = createStrictMock(Compute.class); + } + + private void initializeSnapshot() { + snapshot = new Snapshot.Builder(compute, SNAPSHOT_ID, SOURCE_DISK) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .status(STATUS) + .diskSizeGb(DISK_SIZE_GB) + .licenses(LICENSES) + .sourceDiskId(SOURCE_DISK_ID) + .storageBytes(STORAGE_BYTES) + .storageBytesStatus(STORAGE_BYTES_STATUS) + .build(); + } + + @Test + public void testToBuilder() { + initializeExpectedSnapshot(8); + compareSnapshot(expectedSnapshot, expectedSnapshot.toBuilder().build()); + Snapshot newSnapshot = expectedSnapshot.toBuilder().description("newDescription").build(); + assertEquals("newDescription", newSnapshot.description()); + newSnapshot = newSnapshot.toBuilder().description("description").build(); + compareSnapshot(expectedSnapshot, newSnapshot); + } + + @Test + public void testToBuilderIncomplete() { + initializeExpectedSnapshot(5); + SnapshotInfo snapshotInfo = SnapshotInfo.of(SNAPSHOT_ID, SOURCE_DISK); + Snapshot snapshot = + new Snapshot(serviceMockReturnsOptions, new SnapshotInfo.BuilderImpl(snapshotInfo)); + compareSnapshot(snapshot, snapshot.toBuilder().build()); + } + + @Test + public void testBuilder() { + initializeExpectedSnapshot(1); + assertEquals(ID, expectedSnapshot.id()); + assertEquals(SNAPSHOT_ID, expectedSnapshot.snapshotId()); + assertEquals(CREATION_TIMESTAMP, expectedSnapshot.creationTimestamp()); + assertEquals(DESCRIPTION, expectedSnapshot.description()); + assertEquals(STATUS, expectedSnapshot.status()); + assertEquals(DISK_SIZE_GB, expectedSnapshot.diskSizeGb()); + assertEquals(LICENSES, expectedSnapshot.licenses()); + assertEquals(SOURCE_DISK, expectedSnapshot.sourceDisk()); + assertEquals(SOURCE_DISK_ID, expectedSnapshot.sourceDiskId()); + assertEquals(STORAGE_BYTES, expectedSnapshot.storageBytes()); + assertEquals(STORAGE_BYTES_STATUS, expectedSnapshot.storageBytesStatus()); + assertSame(serviceMockReturnsOptions, expectedSnapshot.compute()); + } + + @Test + public void testToAndFromPb() { + initializeExpectedSnapshot(8); + compareSnapshot(expectedSnapshot, + Snapshot.fromPb(serviceMockReturnsOptions, expectedSnapshot.toPb())); + Snapshot snapshot = + new Snapshot.Builder(serviceMockReturnsOptions, SNAPSHOT_ID, SOURCE_DISK).build(); + compareSnapshot(snapshot, Snapshot.fromPb(serviceMockReturnsOptions, snapshot.toPb())); + } + + @Test + public void testDeleteOperation() { + initializeExpectedSnapshot(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(GlobalOperationId.of("project", "op")) + .build(); + expect(compute.deleteSnapshot(SNAPSHOT_ID)).andReturn(operation); + replay(compute); + initializeSnapshot(); + assertSame(operation, snapshot.delete()); + } + + @Test + public void testDeleteNull() { + initializeExpectedSnapshot(1); + expect(compute.options()).andReturn(mockOptions); + expect(compute.deleteSnapshot(SNAPSHOT_ID)).andReturn(null); + replay(compute); + initializeSnapshot(); + assertNull(snapshot.delete()); + } + + @Test + public void testExists_True() throws Exception { + initializeExpectedSnapshot(1); + Compute.SnapshotOption[] expectedOptions = {Compute.SnapshotOption.fields()}; + expect(compute.options()).andReturn(mockOptions); + expect(compute.getSnapshot(SNAPSHOT_ID.snapshot(), expectedOptions)) + .andReturn(expectedSnapshot); + replay(compute); + initializeSnapshot(); + assertTrue(snapshot.exists()); + verify(compute); + } + + @Test + public void testExists_False() throws Exception { + initializeExpectedSnapshot(1); + Compute.SnapshotOption[] expectedOptions = {Compute.SnapshotOption.fields()}; + expect(compute.options()).andReturn(mockOptions); + expect(compute.getSnapshot(SNAPSHOT_ID.snapshot(), expectedOptions)).andReturn(null); + replay(compute); + initializeSnapshot(); + assertFalse(snapshot.exists()); + verify(compute); + } + + @Test + public void testReload() throws Exception { + initializeExpectedSnapshot(3); + expect(compute.options()).andReturn(mockOptions); + expect(compute.getSnapshot(SNAPSHOT_ID.snapshot())).andReturn(expectedSnapshot); + replay(compute); + initializeSnapshot(); + Snapshot updatedSnapshot = snapshot.reload(); + compareSnapshot(expectedSnapshot, updatedSnapshot); + verify(compute); + } + + @Test + public void testReloadNull() throws Exception { + initializeExpectedSnapshot(1); + expect(compute.options()).andReturn(mockOptions); + expect(compute.getSnapshot(SNAPSHOT_ID.snapshot())).andReturn(null); + replay(compute); + initializeSnapshot(); + assertNull(snapshot.reload()); + verify(compute); + } + + @Test + public void testReloadWithOptions() throws Exception { + initializeExpectedSnapshot(3); + expect(compute.options()).andReturn(mockOptions); + expect(compute.getSnapshot(SNAPSHOT_ID.snapshot(), Compute.SnapshotOption.fields())) + .andReturn(expectedSnapshot); + replay(compute); + initializeSnapshot(); + Snapshot updatedSnapshot = snapshot.reload(Compute.SnapshotOption.fields()); + compareSnapshot(expectedSnapshot, updatedSnapshot); + verify(compute); + } + + public void compareSnapshot(Snapshot expected, Snapshot value) { + assertEquals(expected, value); + assertEquals(expected.compute().options(), value.compute().options()); + assertEquals(expected.id(), value.id()); + assertEquals(expected.snapshotId(), value.snapshotId()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.status(), value.status()); + assertEquals(expected.diskSizeGb(), value.diskSizeGb()); + assertEquals(expected.licenses(), value.licenses()); + assertEquals(expected.sourceDisk(), value.sourceDisk()); + assertEquals(expected.sourceDiskId(), value.sourceDiskId()); + assertEquals(expected.storageBytes(), value.storageBytes()); + assertEquals(expected.storageBytesStatus(), value.storageBytesStatus()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} From f66ea60be34714f6279aaa4eadd3162679daee1a Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 24 Mar 2016 21:36:02 +0100 Subject: [PATCH 304/375] Fix minor issues with functional snapshot methods and tests --- .../com/google/gcloud/compute/Compute.java | 38 +++++++---- .../google/gcloud/compute/ComputeImpl.java | 17 ++--- .../com/google/gcloud/compute/Snapshot.java | 11 +-- .../gcloud/compute/ComputeImplTest.java | 68 ++++++++++--------- .../google/gcloud/compute/SnapshotTest.java | 20 +++++- 5 files changed, 96 insertions(+), 58 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java index 98318280ccdf..9b527a041bde 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java @@ -582,7 +582,7 @@ class DiskTypeFilter extends ListFilter { private static final long serialVersionUID = 4847837203592234453L; - DiskTypeFilter(DiskTypeField field, ComparisonOperator operator, Object value) { + private DiskTypeFilter(DiskTypeField field, ComparisonOperator operator, Object value) { super(field.selector(), operator, value); } @@ -630,7 +630,7 @@ class MachineTypeFilter extends ListFilter { private static final long serialVersionUID = 7346062041571853235L; - MachineTypeFilter(MachineTypeField field, ComparisonOperator operator, Object value) { + private MachineTypeFilter(MachineTypeField field, ComparisonOperator operator, Object value) { super(field.selector(), operator, value); } @@ -678,7 +678,7 @@ class RegionFilter extends ListFilter { private static final long serialVersionUID = 4464892812442567172L; - RegionFilter(RegionField field, ComparisonOperator operator, Object value) { + private RegionFilter(RegionField field, ComparisonOperator operator, Object value) { super(field.selector(), operator, value); } @@ -712,7 +712,7 @@ class ZoneFilter extends ListFilter { private static final long serialVersionUID = -3927428278548808737L; - ZoneFilter(ZoneField field, ComparisonOperator operator, Object value) { + private ZoneFilter(ZoneField field, ComparisonOperator operator, Object value) { super(field.selector(), operator, value); } @@ -746,7 +746,7 @@ class OperationFilter extends ListFilter { private static final long serialVersionUID = -3202249202748346427L; - OperationFilter(OperationField field, ComparisonOperator operator, Object value) { + private OperationFilter(OperationField field, ComparisonOperator operator, Object value) { super(field.selector(), operator, value); } @@ -794,7 +794,7 @@ class AddressFilter extends ListFilter { private static final long serialVersionUID = -227481644259653765L; - AddressFilter(AddressField field, ComparisonOperator operator, Object value) { + private AddressFilter(AddressField field, ComparisonOperator operator, Object value) { super(field.selector(), operator, value); } @@ -828,12 +828,12 @@ class SnapshotFilter extends ListFilter { private static final long serialVersionUID = 8757711630092406747L; - SnapshotFilter(SnapshotField field, ComparisonOperator operator, Object value) { + private SnapshotFilter(SnapshotField field, ComparisonOperator operator, Object value) { super(field.selector(), operator, value); } /** - * Returns an equality filter for the given field and string value. For string fields, + * Returns an equals filter for the given field and string value. For string fields, * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must * match the entire field. * @@ -855,7 +855,7 @@ public static SnapshotFilter notEquals(SnapshotField field, String value) { } /** - * Returns an equality filter for the given field and long value. + * Returns an equals filter for the given field and long value. */ public static SnapshotFilter equals(SnapshotField field, long value) { return new SnapshotFilter(checkNotNull(field), ComparisonOperator.EQ, value); @@ -911,6 +911,7 @@ public static DiskTypeListOption filter(DiskTypeFilter filter) { /** * Returns an option to specify the maximum number of disk types returned per page. + * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used. */ public static DiskTypeListOption pageSize(long pageSize) { return new DiskTypeListOption(ComputeRpc.Option.MAX_RESULTS, pageSize); @@ -956,6 +957,7 @@ public static DiskTypeAggregatedListOption filter(DiskTypeFilter filter) { /** * Returns an option to specify the maximum number of disk types returned per page. + * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used. */ public static DiskTypeAggregatedListOption pageSize(long pageSize) { return new DiskTypeAggregatedListOption(ComputeRpc.Option.MAX_RESULTS, pageSize); @@ -1011,6 +1013,7 @@ public static MachineTypeListOption filter(MachineTypeFilter filter) { /** * Returns an option to specify the maximum number of machine types returned per page. + * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used. */ public static MachineTypeListOption pageSize(long pageSize) { return new MachineTypeListOption(ComputeRpc.Option.MAX_RESULTS, pageSize); @@ -1056,6 +1059,7 @@ public static MachineTypeAggregatedListOption filter(MachineTypeFilter filter) { /** * Returns an option to specify the maximum number of machine types returned per page. + * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used. */ public static MachineTypeAggregatedListOption pageSize(long pageSize) { return new MachineTypeAggregatedListOption(ComputeRpc.Option.MAX_RESULTS, pageSize); @@ -1111,6 +1115,7 @@ public static RegionListOption filter(RegionFilter filter) { /** * Returns an option to specify the maximum number of regions returned per page. + * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used. */ public static RegionListOption pageSize(long pageSize) { return new RegionListOption(ComputeRpc.Option.MAX_RESULTS, pageSize); @@ -1178,6 +1183,7 @@ public static ZoneListOption filter(ZoneFilter filter) { /** * Returns an option to specify the maximum number of zones returned per page. + * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used. */ public static ZoneListOption pageSize(long pageSize) { return new ZoneListOption(ComputeRpc.Option.MAX_RESULTS, pageSize); @@ -1267,6 +1273,7 @@ public static OperationListOption filter(OperationFilter filter) { /** * Returns an option to specify the maximum number of operations returned per page. + * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used. */ public static OperationListOption pageSize(long pageSize) { return new OperationListOption(ComputeRpc.Option.MAX_RESULTS, pageSize); @@ -1334,6 +1341,7 @@ public static AddressListOption filter(AddressFilter filter) { /** * Returns an option to specify the maximum number of addresses returned per page. + * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used. */ public static AddressListOption pageSize(long pageSize) { return new AddressListOption(ComputeRpc.Option.MAX_RESULTS, pageSize); @@ -1379,6 +1387,7 @@ public static AddressAggregatedListOption filter(AddressFilter filter) { /** * Returns an option to specify the maximum number of addresses returned per page. + * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used. */ public static AddressAggregatedListOption pageSize(long pageSize) { return new AddressAggregatedListOption(ComputeRpc.Option.MAX_RESULTS, pageSize); @@ -1405,8 +1414,8 @@ private SnapshotOption(ComputeRpc.Option option, Object value) { /** * Returns an option to specify the snapshot's fields to be returned by the RPC call. If this - * option is not provided, all snapshot's fields are returned. {@code SnapshotOption.fields} can - * be used to specify only the fields of interest. {@link Snapshot#snapshotId()} is always + * option is not provided, all the snapshot's fields are returned. {@code SnapshotOption.fields} + * can be used to specify only the fields of interest. {@link Snapshot#snapshotId()} is always * returned, even if not specified. */ public static SnapshotOption fields(SnapshotField... fields) { @@ -1434,6 +1443,7 @@ public static SnapshotListOption filter(SnapshotFilter filter) { /** * Returns an option to specify the maximum number of snapshots returned per page. + * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used. */ public static SnapshotListOption pageSize(long pageSize) { return new SnapshotListOption(ComputeRpc.Option.MAX_RESULTS, pageSize); @@ -1448,9 +1458,9 @@ public static SnapshotListOption pageToken(String pageToken) { /** * Returns an option to specify the snapshot's fields to be returned by the RPC call. If this - * option is not provided, all snapshot's fields are returned. {@code SnapshotListOption.fields} - * can be used to specify only the fields of interest. {@link Snapshot#snapshotId()} is always - * returned, even if not specified. + * option is not provided, all the snapshot's fields are returned. + * {@code SnapshotListOption.fields} can be used to specify only the fields of interest. + * {@link Snapshot#snapshotId()} is always returned, even if not specified. */ public static SnapshotListOption fields(SnapshotField... fields) { StringBuilder builder = new StringBuilder(); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java index 1b7cdecb4e38..468a66eb0526 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java @@ -934,7 +934,7 @@ public com.google.api.services.compute.model.Operation call() { } @Override - public Operation create(SnapshotInfo snapshot, final OperationOption... options) { + public Operation create(SnapshotInfo snapshot, OperationOption... options) { final SnapshotInfo completeSnapshot = snapshot.setProjectId(options().projectId()); final Map optionsMap = optionMap(options); try { @@ -1005,14 +1005,20 @@ public Snapshot apply(com.google.api.services.compute.model.Snapshot snapshot) { } @Override - public Operation deleteSnapshot(final SnapshotId snapshot, OperationOption... options) { + public Operation deleteSnapshot(SnapshotId snapshot, OperationOption... options) { + return deleteSnapshot(snapshot.snapshot(), options); + + } + + @Override + public Operation deleteSnapshot(final String snapshot, OperationOption... options) { final Map optionsMap = optionMap(options); try { com.google.api.services.compute.model.Operation answer = runWithRetries(new Callable() { @Override public com.google.api.services.compute.model.Operation call() { - return computeRpc.deleteSnapshot(snapshot.snapshot(), optionsMap); + return computeRpc.deleteSnapshot(snapshot, optionsMap); } }, options().retryParams(), EXCEPTION_HANDLER); return answer == null ? null : Operation.fromPb(this, answer); @@ -1021,11 +1027,6 @@ public com.google.api.services.compute.model.Operation call() { } } - @Override - public Operation deleteSnapshot(final String snapshot, OperationOption... options) { - return deleteSnapshot(SnapshotId.of(snapshot)); - } - private Map optionMap(Option... options) { Map optionMap = Maps.newEnumMap(ComputeRpc.Option.class); for (Option option : options) { diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Snapshot.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Snapshot.java index 9ca4c95c9956..239a257ba307 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Snapshot.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Snapshot.java @@ -18,6 +18,9 @@ import static com.google.common.base.Preconditions.checkNotNull; +import com.google.gcloud.compute.Compute.OperationOption; +import com.google.gcloud.compute.Compute.SnapshotOption; + import java.io.IOException; import java.io.ObjectInputStream; import java.util.List; @@ -28,7 +31,7 @@ * disk and create new persistent disks from that snapshot. This can be useful for backing up data, * recreating a persistent disk that might have been lost, or copying a persistent disk. Snapshots * can be applied across persistent disk types. {@code Snapshot} adds a layer of service-related - * functionality over {@link SnapshotInfo}. Obejcts of this class are immutable, to get a + * functionality over {@link SnapshotInfo}. Objects of this class are immutable; to get a * {@code Snapshot} object with the most recent information use {@link #reload}. * * @see Use @@ -146,7 +149,7 @@ public Snapshot build() { * @throws ComputeException upon failure */ public boolean exists() { - return reload(Compute.SnapshotOption.fields()) != null; + return reload(SnapshotOption.fields()) != null; } /** @@ -157,7 +160,7 @@ public boolean exists() { * @return a {@code Snapshot} object with latest information or {@code null} if not found * @throws ComputeException upon failure */ - public Snapshot reload(Compute.SnapshotOption... options) { + public Snapshot reload(SnapshotOption... options) { return compute.getSnapshot(snapshotId().snapshot(), options); } @@ -168,7 +171,7 @@ public Snapshot reload(Compute.SnapshotOption... options) { * snapshot was not found * @throws ComputeException upon failure */ - public Operation delete(Compute.OperationOption... options) { + public Operation delete(OperationOption... options) { return compute.deleteSnapshot(snapshotId(), options); } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java index 31325da8de61..9cff65dc7dad 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java @@ -34,6 +34,10 @@ import com.google.common.collect.Iterables; import com.google.gcloud.Page; import com.google.gcloud.RetryParams; +import com.google.gcloud.compute.Compute.AddressAggregatedListOption; +import com.google.gcloud.compute.Compute.AddressFilter; +import com.google.gcloud.compute.Compute.AddressListOption; +import com.google.gcloud.compute.Compute.AddressOption; import com.google.gcloud.compute.Compute.DiskTypeAggregatedListOption; import com.google.gcloud.compute.Compute.DiskTypeFilter; import com.google.gcloud.compute.Compute.DiskTypeListOption; @@ -49,6 +53,9 @@ import com.google.gcloud.compute.Compute.RegionFilter; import com.google.gcloud.compute.Compute.RegionListOption; import com.google.gcloud.compute.Compute.RegionOption; +import com.google.gcloud.compute.Compute.SnapshotFilter; +import com.google.gcloud.compute.Compute.SnapshotListOption; +import com.google.gcloud.compute.Compute.SnapshotOption; import com.google.gcloud.compute.Compute.ZoneFilter; import com.google.gcloud.compute.Compute.ZoneListOption; import com.google.gcloud.compute.Compute.ZoneOption; @@ -297,44 +304,43 @@ public class ComputeImplTest { FILTER, "progress ne 0"); // Address options - private static final Compute.AddressOption ADDRESS_OPTION_FIELDS = - Compute.AddressOption.fields(Compute.AddressField.ID, Compute.AddressField.DESCRIPTION); + private static final AddressOption ADDRESS_OPTION_FIELDS = + AddressOption.fields(Compute.AddressField.ID, Compute.AddressField.DESCRIPTION); // Address list options - private static final Compute.AddressFilter ADDRESS_FILTER = - Compute.AddressFilter.notEquals(Compute.AddressField.REGION, "someRegion"); - private static final Compute.AddressListOption ADDRESS_LIST_PAGE_TOKEN = - Compute.AddressListOption.pageToken("cursor"); - private static final Compute.AddressListOption ADDRESS_LIST_PAGE_SIZE = - Compute.AddressListOption.pageSize(42L); - private static final Compute.AddressListOption ADDRESS_LIST_FILTER = - Compute.AddressListOption.filter(ADDRESS_FILTER); + private static final AddressFilter ADDRESS_FILTER = + AddressFilter.notEquals(Compute.AddressField.REGION, "someRegion"); + private static final AddressListOption ADDRESS_LIST_PAGE_TOKEN = + AddressListOption.pageToken("cursor"); + private static final AddressListOption ADDRESS_LIST_PAGE_SIZE = AddressListOption.pageSize(42L); + private static final AddressListOption ADDRESS_LIST_FILTER = + AddressListOption.filter(ADDRESS_FILTER); private static final Map ADDRESS_LIST_OPTIONS = ImmutableMap.of( PAGE_TOKEN, "cursor", MAX_RESULTS, 42L, FILTER, "region ne someRegion"); // Address aggregated list options - private static final Compute.AddressAggregatedListOption ADDRESS_AGGREGATED_LIST_PAGE_TOKEN = - Compute.AddressAggregatedListOption.pageToken("cursor"); - private static final Compute.AddressAggregatedListOption ADDRESS_AGGREGATED_LIST_PAGE_SIZE = - Compute.AddressAggregatedListOption.pageSize(42L); - private static final Compute.AddressAggregatedListOption ADDRESS_AGGREGATED_LIST_FILTER = - Compute.AddressAggregatedListOption.filter(ADDRESS_FILTER); + private static final AddressAggregatedListOption ADDRESS_AGGREGATED_LIST_PAGE_TOKEN = + AddressAggregatedListOption.pageToken("cursor"); + private static final AddressAggregatedListOption ADDRESS_AGGREGATED_LIST_PAGE_SIZE = + AddressAggregatedListOption.pageSize(42L); + private static final AddressAggregatedListOption ADDRESS_AGGREGATED_LIST_FILTER = + AddressAggregatedListOption.filter(ADDRESS_FILTER); // Snapshot options - private static final Compute.SnapshotOption SNAPSHOT_OPTION_FIELDS = - Compute.SnapshotOption.fields(Compute.SnapshotField.ID, Compute.SnapshotField.DESCRIPTION); + private static final SnapshotOption SNAPSHOT_OPTION_FIELDS = + SnapshotOption.fields(Compute.SnapshotField.ID, Compute.SnapshotField.DESCRIPTION); // Snapshot list options - private static final Compute.SnapshotFilter SNAPSHOT_FILTER = - Compute.SnapshotFilter.equals(Compute.SnapshotField.DISK_SIZE_GB, 500L); - private static final Compute.SnapshotListOption SNAPSHOT_LIST_PAGE_TOKEN = - Compute.SnapshotListOption.pageToken("cursor"); - private static final Compute.SnapshotListOption SNAPSHOT_LIST_MAX_RESULTS = - Compute.SnapshotListOption.pageSize(42L); - private static final Compute.SnapshotListOption SNAPSHOT_LIST_FILTER = - Compute.SnapshotListOption.filter(SNAPSHOT_FILTER); + private static final SnapshotFilter SNAPSHOT_FILTER = + SnapshotFilter.equals(Compute.SnapshotField.DISK_SIZE_GB, 500L); + private static final SnapshotListOption SNAPSHOT_LIST_PAGE_TOKEN = + SnapshotListOption.pageToken("cursor"); + private static final SnapshotListOption SNAPSHOT_LIST_MAX_RESULTS = + SnapshotListOption.pageSize(42L); + private static final SnapshotListOption SNAPSHOT_LIST_FILTER = + SnapshotListOption.filter(SNAPSHOT_FILTER); private static final Map SNAPSHOT_LIST_OPTIONS = ImmutableMap.of( PAGE_TOKEN, "cursor", MAX_RESULTS, 42L, @@ -1930,11 +1936,11 @@ public void testCreateRegionAddressWithOptions() { @Test public void testCreateSnapshot() { EasyMock.expect(computeRpcMock.createSnapshot(DISK_ID.zone(), DISK_ID.disk(), - SNAPSHOT_ID.snapshot(), null, EMPTY_RPC_OPTIONS)).andReturn(globalOperation.toPb()); + SNAPSHOT_ID.snapshot(), null, EMPTY_RPC_OPTIONS)).andReturn(zoneOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); Operation operation = compute.create(SNAPSHOT); - assertEquals(globalOperation, operation); + assertEquals(zoneOperation, operation); } @Test @@ -1942,7 +1948,7 @@ public void testCreateSnapshotWithOptions() { Capture> capturedOptions = Capture.newInstance(); EasyMock.expect(computeRpcMock.createSnapshot(eq(DISK_ID.zone()), eq(DISK_ID.disk()), eq(SNAPSHOT_ID.snapshot()), EasyMock.isNull(), capture(capturedOptions))) - .andReturn(globalOperation.toPb()); + .andReturn(zoneOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); Operation operation = compute.create(SNAPSHOT, OPERATION_OPTION_FIELDS); @@ -1951,7 +1957,7 @@ public void testCreateSnapshotWithOptions() { assertTrue(selector.contains("id")); assertTrue(selector.contains("description")); assertEquals(23, selector.length()); - assertEquals(globalOperation, operation); + assertEquals(zoneOperation, operation); } @Test @@ -1995,7 +2001,7 @@ public void testDeleteSnapshot_Operation() { .andReturn(globalOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - assertEquals(globalOperation, compute.deleteSnapshot(SNAPSHOT_ID)); + assertEquals(globalOperation, compute.deleteSnapshot(SNAPSHOT_ID.snapshot())); } @Test diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotTest.java index 2297199d16c8..d827c19213c1 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotTest.java @@ -107,7 +107,7 @@ public void testToBuilderIncomplete() { @Test public void testBuilder() { - initializeExpectedSnapshot(1); + initializeExpectedSnapshot(2); assertEquals(ID, expectedSnapshot.id()); assertEquals(SNAPSHOT_ID, expectedSnapshot.snapshotId()); assertEquals(CREATION_TIMESTAMP, expectedSnapshot.creationTimestamp()); @@ -120,6 +120,24 @@ public void testBuilder() { assertEquals(STORAGE_BYTES, expectedSnapshot.storageBytes()); assertEquals(STORAGE_BYTES_STATUS, expectedSnapshot.storageBytesStatus()); assertSame(serviceMockReturnsOptions, expectedSnapshot.compute()); + SnapshotId otherSnapshotId = SnapshotId.of("otherSnapshot"); + DiskId otherSourceDisk = DiskId.of("zone", "otherDisk"); + Snapshot snapshot = new Snapshot.Builder(serviceMockReturnsOptions, SNAPSHOT_ID, SOURCE_DISK) + .snapshotId(otherSnapshotId) + .sourceDisk(otherSourceDisk) + .build(); + assertNull(snapshot.id()); + assertEquals(otherSnapshotId, snapshot.snapshotId()); + assertNull(snapshot.creationTimestamp()); + assertNull(snapshot.description()); + assertNull(snapshot.status()); + assertNull(snapshot.diskSizeGb()); + assertNull(snapshot.licenses()); + assertEquals(otherSourceDisk, snapshot.sourceDisk()); + assertNull(snapshot.sourceDiskId()); + assertNull(snapshot.storageBytes()); + assertNull(snapshot.storageBytesStatus()); + assertSame(serviceMockReturnsOptions, snapshot.compute()); } @Test From de2a6b4c2191223e176765af43bab313f2ce3596 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 25 Mar 2016 19:27:29 +0100 Subject: [PATCH 305/375] Add missing final, fix codacy issues --- .../src/main/java/com/google/gcloud/compute/Address.java | 4 ++-- .../src/main/java/com/google/gcloud/compute/Compute.java | 2 +- .../src/main/java/com/google/gcloud/compute/ComputeImpl.java | 1 - .../src/main/java/com/google/gcloud/compute/Operation.java | 4 ++-- .../src/main/java/com/google/gcloud/compute/Snapshot.java | 4 ++-- .../src/test/java/com/google/gcloud/compute/AddressTest.java | 4 ++-- .../test/java/com/google/gcloud/compute/OperationTest.java | 4 ++-- .../src/test/java/com/google/gcloud/compute/SnapshotTest.java | 4 ++-- 8 files changed, 13 insertions(+), 14 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java index b30293fb6d48..e1e70def80d5 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java @@ -172,8 +172,8 @@ public final int hashCode() { return Objects.hash(super.hashCode(), options); } - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - in.defaultReadObject(); + private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { + input.defaultReadObject(); this.compute = options.service(); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java index 9b527a041bde..a0052744e3f7 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java @@ -1668,7 +1668,7 @@ public static SnapshotListOption fields(SnapshotField... fields) { Snapshot getSnapshot(String snapshot, SnapshotOption... options); /** - * Lists all snapshots. + * Lists snapshots. * * @throws ComputeException upon failure */ diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java index 468a66eb0526..a348e1e0e253 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java @@ -1007,7 +1007,6 @@ public Snapshot apply(com.google.api.services.compute.model.Snapshot snapshot) { @Override public Operation deleteSnapshot(SnapshotId snapshot, OperationOption... options) { return deleteSnapshot(snapshot.snapshot(), options); - } @Override diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java index ce519edc970d..78afc170f671 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java @@ -792,8 +792,8 @@ com.google.api.services.compute.model.Operation toPb() { return operationPb; } - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - in.defaultReadObject(); + private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { + input.defaultReadObject(); this.compute = options.service(); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Snapshot.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Snapshot.java index 239a257ba307..e93a419d5b4a 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Snapshot.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Snapshot.java @@ -199,8 +199,8 @@ public final int hashCode() { return Objects.hash(super.hashCode(), options); } - private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { - in.defaultReadObject(); + private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { + input.defaultReadObject(); this.compute = options.service(); } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressTest.java index 230f603271f9..a9404a90f755 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressTest.java @@ -57,8 +57,8 @@ public class AddressTest { private static final AddressInfo.RegionForwardingUsage REGION_FORWARDING_USAGE = new AddressInfo.RegionForwardingUsage(REGION_FORWARDING_RULES); - private Compute serviceMockReturnsOptions = createStrictMock(Compute.class); - private ComputeOptions mockOptions = createMock(ComputeOptions.class); + private final Compute serviceMockReturnsOptions = createStrictMock(Compute.class); + private final ComputeOptions mockOptions = createMock(ComputeOptions.class); private Compute compute; private Address globalForwardingAddress; private Address instanceAddress; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java index 9f08491a1632..62899071ce32 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java @@ -76,8 +76,8 @@ public class OperationTest { private static final RegionOperationId REGION_OPERATION_ID = RegionOperationId.of("project", "region", "op"); - private Compute serviceMockReturnsOptions = createStrictMock(Compute.class); - private ComputeOptions mockOptions = createMock(ComputeOptions.class); + private final Compute serviceMockReturnsOptions = createStrictMock(Compute.class); + private final ComputeOptions mockOptions = createMock(ComputeOptions.class); private Compute compute; private Operation globalOperation; private Operation regionOperation; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotTest.java index d827c19213c1..ac02669d7d5c 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotTest.java @@ -49,8 +49,8 @@ public class SnapshotTest { private static final SnapshotInfo.StorageBytesStatus STORAGE_BYTES_STATUS = SnapshotInfo.StorageBytesStatus.UP_TO_DATE; - private Compute serviceMockReturnsOptions = createStrictMock(Compute.class); - private ComputeOptions mockOptions = createMock(ComputeOptions.class); + private final Compute serviceMockReturnsOptions = createStrictMock(Compute.class); + private final ComputeOptions mockOptions = createMock(ComputeOptions.class); private Compute compute; private Snapshot snapshot; private Snapshot expectedSnapshot; From 2d8d0ece1b867966e7bc6b711597f950ba047eda Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Sat, 26 Mar 2016 00:52:25 +0100 Subject: [PATCH 306/375] Better javadoc for aggregated list methods --- .../src/main/java/com/google/gcloud/compute/Compute.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java index a0052744e3f7..6d033688d8c2 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java @@ -1491,7 +1491,7 @@ public static SnapshotListOption fields(SnapshotField... fields) { Page listDiskTypes(String zone, DiskTypeListOption... options); /** - * Lists all disk types. + * Lists the disk types in all zones. * * @throws ComputeException upon failure */ @@ -1519,7 +1519,7 @@ public static SnapshotListOption fields(SnapshotField... fields) { Page listMachineTypes(String zone, MachineTypeListOption... options); /** - * Lists all machine types. + * Lists the machine types in all zones. * * @throws ComputeException upon failure */ @@ -1636,7 +1636,7 @@ public static SnapshotListOption fields(SnapshotField... fields) { Page
    listRegionAddresses(String region, AddressListOption... options); /** - * Lists all addresses. + * Lists both global and region addresses. * * @throws ComputeException upon failure */ From 5d2c682b7c5f60d6b1e59c61efb7767f3633943d Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 31 Mar 2016 08:48:05 +0200 Subject: [PATCH 307/375] Add ImageInfo and related non-functional classes - Add public builder and factory methods to DeprecationStatus - Add setters/getters for DeprecationStatus timestamps as String - Add ImageId, configuration classes and ImageInfo class --- .../gcloud/compute/DeprecationStatus.java | 271 ++++++++++-- .../compute/DiskImageConfiguration.java | 161 +++++++ .../gcloud/compute/ImageConfiguration.java | 190 ++++++++ .../com/google/gcloud/compute/ImageId.java | 145 ++++++ .../com/google/gcloud/compute/ImageInfo.java | 416 ++++++++++++++++++ .../compute/StorageImageConfiguration.java | 201 +++++++++ .../gcloud/compute/DeprecationStatusTest.java | 121 ++++- .../compute/DiskImageConfigurationTest.java | 112 +++++ .../google/gcloud/compute/DiskTypeTest.java | 6 +- .../google/gcloud/compute/ImageIdTest.java | 79 ++++ .../google/gcloud/compute/ImageInfoTest.java | 175 ++++++++ .../gcloud/compute/MachineTypeTest.java | 6 +- .../com/google/gcloud/compute/RegionTest.java | 7 +- .../gcloud/compute/SerializationTest.java | 15 +- .../StorageImageConfigurationTest.java | 108 +++++ .../com/google/gcloud/compute/ZoneTest.java | 7 +- 16 files changed, 1944 insertions(+), 76 deletions(-) create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskImageConfiguration.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageConfiguration.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageId.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageInfo.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/StorageImageConfiguration.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskImageConfigurationTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageIdTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageInfoTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/StorageImageConfigurationTest.java diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java index c80071dde10a..896aeebe096f 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java @@ -16,6 +16,8 @@ package com.google.gcloud.compute; +import static com.google.common.base.Preconditions.checkNotNull; + import com.google.common.base.Function; import com.google.common.base.MoreObjects; @@ -28,16 +30,17 @@ /** * The deprecation status associated to a Google Compute Engine resource. * - * @param The Google Compute Engine resource to which the deprecation status refers to. + * @param The Google Compute Engine resource identity to which the deprecation status refers */ public final class DeprecationStatus implements Serializable { private static final long serialVersionUID = -2695077634793679794L; private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); + private static final DateTimeFormatter TIMESTAMP_PARSER = ISODateTimeFormat.dateTimeParser(); - private final Long deleted; - private final Long deprecated; - private final Long obsolete; + private final String deleted; + private final String deprecated; + private final String obsolete; private final T replacement; private final Status status; @@ -64,38 +67,203 @@ public enum Status { DELETED } - DeprecationStatus(Long deleted, Long deprecated, Long obsolete, T replacement, Status status) { - this.deleted = deleted; - this.deprecated = deprecated; - this.obsolete = obsolete; - this.replacement = replacement; - this.status = status; + /** + * A builder for {@code DeprecationStatus} objects. + * + * @param The Google Compute Engine resource identity to which the deprecation status refers + */ + public static final class Builder { + + private String deleted; + private String deprecated; + private String obsolete; + private T replacement; + private Status status; + + Builder() {} + + Builder(DeprecationStatus deprecationStatus) { + this.deleted = deprecationStatus.deleted; + this.deprecated = deprecationStatus.deprecated; + this.obsolete = deprecationStatus.obsolete; + this.replacement = deprecationStatus.replacement; + this.status = deprecationStatus.status; + } + + /** + * Sets the timestamp on or after which the deprecation state of this resource will be changed + * to {@link Status#DELETED}. Timestamp should be in RFC3339 format. + * + * @see RFC3339 + */ + // todo(mziccard): remove this method if #732 is closed + public Builder deleted(String deleted) { + this.deleted = deleted; + return this; + } + + /** + * Sets the timestamp on or after which the deprecation state of this resource will be changed + * to {@link Status#DEPRECATED}. Timestamp should be in RFC3339 format. + * + * @see RFC3339 + */ + // todo(mziccard): remove this method if #732 is closed + public Builder deprecated(String deprecated) { + this.deprecated = deprecated; + return this; + } + + /** + * Sets the timestamp on or after which the deprecation state of this resource will be changed + * to {@link Status#OBSOLETE}. Timestamp should be in RFC3339 format. + * + * @see RFC3339 + */ + // todo(mziccard): remove this method if #732 is closed + public Builder obsolete(String obsolete) { + this.obsolete = obsolete; + return this; + } + + /** + * Sets the timestamp on or after which the deprecation state of this resource will be changed + * to {@link Status#DELETED}. In milliseconds since epoch. + */ + public Builder deleted(long deleted) { + this.deleted = TIMESTAMP_FORMATTER.print(deleted); + return this; + } + + /** + * Sets the timestamp on or after which the deprecation state of this resource will be changed + * to {@link Status#DEPRECATED}. In milliseconds since epoch. + */ + public Builder deprecated(long deprecated) { + this.deprecated = TIMESTAMP_FORMATTER.print(deprecated); + return this; + } + + /** + * Sets the timestamp on or after which the deprecation state of this resource will be changed + * to {@link Status#OBSOLETE}. In milliseconds since epoch. + */ + public Builder obsolete(long obsolete) { + this.obsolete = TIMESTAMP_FORMATTER.print(obsolete); + return this; + } + + /** + * Sets the identity of the suggested replacement for a deprecated resource. The suggested + * replacement resource must be the same kind of resource as the deprecated resource. + */ + public Builder replacement(T replacement) { + this.replacement = replacement; + return this; + } + + /** + * Sets the status of the deprecated resource. + */ + public Builder status(Status status) { + this.status = checkNotNull(status); + return this; + } + + /** + * Creates a {@code DeprecationStatus} object. + */ + public DeprecationStatus build() { + return new DeprecationStatus(this); + } + } + + DeprecationStatus(Builder builder) { + this.deleted = builder.deleted; + this.deprecated = builder.deprecated; + this.obsolete = builder.obsolete; + this.replacement = builder.replacement; + this.status = checkNotNull(builder.status); } /** * Returns the timestamp on or after which the deprecation state of this resource will be changed - * to {@link Status#DELETED}. In milliseconds since epoch. + * to {@link Status#DELETED}. Returns {@code null} if not set. This value should be in RFC3339 + * format. + * + * @see RFC3339 */ - public Long deleted() { + // todo(mziccard): remove this method if #732 is closed + public String deleted() { return deleted; } /** * Returns the timestamp on or after which the deprecation state of this resource will be changed - * to {@link Status#DEPRECATED}. In milliseconds since epoch. + * to {@link Status#DEPRECATED}. Returns {@code null} if not set. This value should be in RFC3339 + * format. + * + * @see RFC3339 */ - public Long deprecated() { + // todo(mziccard): remove this method if #732 is closed + public String deprecated() { return deprecated; } /** * Returns the timestamp on or after which the deprecation state of this resource will be changed - * to {@link Status#OBSOLETE}. In milliseconds since epoch. + * to {@link Status#OBSOLETE}. Returns {@code null} if not set. This value should be in RFC3339 + * format. + * + * @see RFC3339 */ - public Long obsolete() { + // todo(mziccard): remove this method if #732 is closed + public String obsolete() { return obsolete; } + /** + * Returns the timestamp (in milliseconds since epoch) on or after which the deprecation state of + * this resource will be changed to {@link Status#DELETED}. Returns {@code null} if not set. + * + * @throws IllegalStateException if {@link #deleted()} is not a valid date, time or datetime + */ + public Long deletedMillis() { + try { + return deleted != null ? TIMESTAMP_PARSER.parseMillis(deleted) : null; + } catch (IllegalArgumentException ex) { + throw new IllegalStateException(ex.getMessage(), ex); + } + } + + /** + * Returns the timestamp (in milliseconds since epoch) on or after which the deprecation state of + * this resource will be changed to {@link Status#DEPRECATED}. Returns {@code null} if not set. + * + * @throws IllegalStateException if {@link #deprecated()} is not a valid date, time or datetime + */ + public Long deprecatedMillis() { + try { + return deprecated != null ? TIMESTAMP_PARSER.parseMillis(deprecated) : null; + } catch (IllegalArgumentException ex) { + throw new IllegalStateException(ex.getMessage(), ex); + } + } + + /** + * Returns the timestamp (in milliseconds since epoch) on or after which the deprecation state of + * this resource will be changed to {@link Status#OBSOLETE}. Returns {@code null} if not set. + * + * @throws IllegalStateException if {@link #obsolete()} is not a valid date, time or datetime + */ + public Long obsoleteMillis() { + try { + return obsolete != null ? TIMESTAMP_PARSER.parseMillis(obsolete) : null; + } catch (IllegalArgumentException ex) { + throw new IllegalStateException(ex.getMessage(), ex); + } + } + /** * Returns the identity of the suggested replacement for a deprecated resource. The suggested * replacement resource must be the same kind of resource as the deprecated resource. @@ -111,6 +279,13 @@ public Status status() { return status; } + /** + * Returns a builder for the {@code DeprecationStatus} object. + */ + public Builder toBuilder() { + return new Builder<>(this); + } + @Override public String toString() { return MoreObjects.toStringHelper(this) @@ -136,37 +311,49 @@ public boolean equals(Object obj) { com.google.api.services.compute.model.DeprecationStatus toPb() { com.google.api.services.compute.model.DeprecationStatus deprecationStatusPb = new com.google.api.services.compute.model.DeprecationStatus(); - if (deleted != null) { - deprecationStatusPb.setDeleted(TIMESTAMP_FORMATTER.print(deleted)); - } - if (deprecated != null) { - deprecationStatusPb.setDeprecated(TIMESTAMP_FORMATTER.print(deprecated)); - } - if (obsolete != null) { - deprecationStatusPb.setObsolete(TIMESTAMP_FORMATTER.print(obsolete)); - } - if (replacement != null) { - deprecationStatusPb.setReplacement(replacement.selfLink()); - } - if (status() != null) { - deprecationStatusPb.setState(status.name()); - } + deprecationStatusPb.setDeleted(deleted); + deprecationStatusPb.setDeprecated(deprecated); + deprecationStatusPb.setObsolete(obsolete); + deprecationStatusPb.setReplacement(replacement.selfLink()); + deprecationStatusPb.setState(status.name()); return deprecationStatusPb; } + /** + * Returns the builder for a {@code DeprecationStatus} object given the status. + */ + public static Builder builder(Status status) { + return new Builder().status(status); + } + + /** + * Returns the builder for a {@code DeprecationStatus} object given the status and replacement's + * identity. + */ + public static Builder builder(Status status, T replacement) { + return new Builder().status(status).replacement(replacement); + } + + /** + * Returns a {@code DeprecationStatus} object given the status and replacement's identity. + */ + public static DeprecationStatus of(Status status, T replacement) { + return builder(status, replacement).build(); + } + static DeprecationStatus fromPb( com.google.api.services.compute.model.DeprecationStatus deprecationStatusPb, Function fromUrl) { - return new DeprecationStatus<>( - deprecationStatusPb.getDeleted() != null - ? TIMESTAMP_FORMATTER.parseMillis(deprecationStatusPb.getDeleted()) : null, - deprecationStatusPb.getDeprecated() != null - ? TIMESTAMP_FORMATTER.parseMillis(deprecationStatusPb.getDeprecated()) : null, - deprecationStatusPb.getObsolete() != null - ? TIMESTAMP_FORMATTER.parseMillis(deprecationStatusPb.getObsolete()) : null, - deprecationStatusPb.getReplacement() != null - ? fromUrl.apply(deprecationStatusPb.getReplacement()) : null, - deprecationStatusPb.getState() != null - ? Status.valueOf(deprecationStatusPb.getState()) : null); + Builder builder = new Builder<>(); + builder.deleted(deprecationStatusPb.getDeleted()); + builder.deprecated(deprecationStatusPb.getDeprecated()); + builder.obsolete(deprecationStatusPb.getObsolete()); + if (deprecationStatusPb.getReplacement() != null) { + builder.replacement(fromUrl.apply(deprecationStatusPb.getReplacement())); + } + if (deprecationStatusPb.getState() != null) { + builder.status(Status.valueOf(deprecationStatusPb.getState())); + } + return builder.build(); } } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskImageConfiguration.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskImageConfiguration.java new file mode 100644 index 000000000000..b8b0857b3963 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskImageConfiguration.java @@ -0,0 +1,161 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.api.services.compute.model.Image; +import com.google.common.base.MoreObjects; + +import java.util.Objects; + +/** + * A Google Compute Engine disk image configuration. This class can be used to create images from an + * existing Google Compute Engine disk. + */ +public class DiskImageConfiguration extends ImageConfiguration { + + private static final long serialVersionUID = 2716403667042981170L; + + private final DiskId sourceDisk; + private final String sourceDiskId; + + /** + * A builder for {@code DiskImageConfiguration} objects. + */ + public static final class Builder + extends ImageConfiguration.Builder { + + private DiskId sourceDisk; + private String sourceDiskId; + + private Builder() { + super(Type.DISK); + } + + private Builder(DiskImageConfiguration imageConfiguration) { + super(Type.DISK, imageConfiguration); + this.sourceDisk = imageConfiguration.sourceDisk; + this.sourceDiskId = imageConfiguration.sourceDiskId; + } + + private Builder(Image imagePb) { + super(Type.DISK, imagePb); + this.sourceDisk = DiskId.fromUrl(imagePb.getSourceDisk()); + this.sourceDiskId = imagePb.getSourceDiskId(); + } + + /** + * Sets the identity of the source disk used to create the image. + */ + public Builder sourceDisk(DiskId sourceDisk) { + this.sourceDisk = checkNotNull(sourceDisk); + return this; + } + + Builder sourceDiskId(String sourceDiskId) { + this.sourceDiskId = sourceDiskId; + return this; + } + + /** + * Creates a {@code DiskImageConfiguration} object. + */ + @Override + public DiskImageConfiguration build() { + return new DiskImageConfiguration(this); + } + } + + private DiskImageConfiguration(Builder builder) { + super(builder); + this.sourceDisk = checkNotNull(builder.sourceDisk); + this.sourceDiskId = builder.sourceDiskId; + } + + /** + * Returns the identity of the source disk used to create this image. + */ + public DiskId sourceDisk() { + return sourceDisk; + } + + /** + * Returns the id of the disk used to create this image. This value may be used to determine + * whether the image was taken from the current or a previous instance of a given disk name. + */ + public String sourceDiskId() { + return sourceDiskId; + } + + @Override + public Builder toBuilder() { + return new Builder(this); + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper() + .add("sourceDisk", sourceDisk) + .add("sourceDiskId", sourceDiskId); + } + + @Override + public final int hashCode() { + return Objects.hash(baseHashCode(), sourceDisk, sourceDiskId); + } + + @Override + public final boolean equals(Object obj) { + return obj instanceof DiskImageConfiguration && baseEquals((DiskImageConfiguration) obj); + } + + @Override + DiskImageConfiguration setProjectId(String projectId) { + if (sourceDisk.project() != null) { + return this; + } + return toBuilder().sourceDisk(sourceDisk.setProjectId(projectId)).build(); + } + + @Override + Image toPb() { + Image imagePb = super.toPb(); + imagePb.setSourceDisk(sourceDisk.selfLink()); + imagePb.setSourceDiskId(sourceDiskId); + return imagePb; + } + + /** + * Creates a builder for a {@code DiskImageConfiguration} given the source disk identity. + */ + public static Builder builder(DiskId sourceDisk) { + return new Builder().sourceDisk(sourceDisk); + } + + /** + * Creates a {@code DiskImageConfiguration} object given the source disk identity. + */ + public static DiskImageConfiguration of(DiskId sourceId) { + return builder(sourceId).build(); + } + + @SuppressWarnings("unchecked") + static DiskImageConfiguration fromPb(Image imagePb) { + return new Builder(imagePb).build(); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageConfiguration.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageConfiguration.java new file mode 100644 index 000000000000..aa6379b12f4f --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageConfiguration.java @@ -0,0 +1,190 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import com.google.api.services.compute.model.Image; +import com.google.common.base.MoreObjects; + +import java.io.Serializable; +import java.util.Objects; + +/** + * Base class for Google Compute Engine image configuration. Use {@link DiskImageConfiguration} to + * create an image from an existing Google Compute Engine disk. Use + * {@link StorageImageConfiguration} to create an image from a file stored in Google Cloud Storage. + */ +public abstract class ImageConfiguration implements Serializable { + + private static final long serialVersionUID = -9154332316597745316L; + + private final Type type; + private final SourceType sourceType; + private final Long archiveSizeBytes; + + /** + * Type of a Google Compute Engine image. + */ + public enum Type { + /** + * A Google Compute Engine image created from a Google Compute Engine disk. + */ + DISK, + + /** + * A Google Compute Engine image created from a file saved in Google Cloud Storage. + */ + STORAGE + } + + /** + * Image source type. The only admissible value is {@code RAW}. + */ + public enum SourceType { + RAW + } + + /** + * Base builder for image configurations. + * + * @param the image configuration class + * @param the image configuration builder + */ + public abstract static class Builder> { + + private Type type; + private SourceType sourceType; + private Long archiveSizeBytes; + + Builder(Type type) { + this.type = type; + } + + Builder(Type type, ImageConfiguration imageConfiguration) { + this.type = type; + this.sourceType = imageConfiguration.sourceType; + this.archiveSizeBytes = imageConfiguration.archiveSizeBytes; + } + + Builder(Type type, Image imagePb) { + this.type = type; + if (imagePb.getSourceType() != null) { + this.sourceType = SourceType.valueOf(imagePb.getSourceType()); + } + this.archiveSizeBytes = imagePb.getArchiveSizeBytes(); + } + + @SuppressWarnings("unchecked") + B self() { + return (B) this; + } + + B type(Type type) { + this.type = type; + return self(); + } + + B sourceType(SourceType sourceType) { + this.sourceType = sourceType; + return self(); + } + + B archiveSizeBytes(Long archiveSizeBytes) { + this.archiveSizeBytes = archiveSizeBytes; + return self(); + } + + /** + * Creates a configuration object. + */ + public abstract T build(); + } + + ImageConfiguration(Builder builder) { + this.type = builder.type; + this.sourceType = builder.sourceType; + this.archiveSizeBytes = builder.archiveSizeBytes; + } + + /** + * Returns the image's type. This method returns {@link Type#DISK} if this image was created from + * an existing disk. This method returns {@link Type#STORAGE} if this image was created from a + * file in Google Cloud Storage. + */ + public Type type() { + return type; + } + + /** + * Returns the source type of the disk. The default and only value is {@link SourceType#RAW}. + */ + public SourceType sourceType() { + return sourceType; + } + + /** + * Returns the size of the image archive stored in Google Cloud Storage (in bytes). + */ + public Long archiveSizeBytes() { + return archiveSizeBytes; + } + + /** + * Returns a builder for the object. + */ + public abstract Builder toBuilder(); + + MoreObjects.ToStringHelper toStringHelper() { + return MoreObjects.toStringHelper(this) + .add("type", type) + .add("sourceType", sourceType) + .add("archiveSizeBytes", archiveSizeBytes); + } + + @Override + public String toString() { + return toStringHelper().toString(); + } + + final int baseHashCode() { + return Objects.hash(type, sourceType, archiveSizeBytes); + } + + final boolean baseEquals(ImageConfiguration imageConfiguration) { + return imageConfiguration != null + && getClass().equals(imageConfiguration.getClass()) + && Objects.equals(toPb(), imageConfiguration.toPb()); + } + + abstract ImageConfiguration setProjectId(String projectId); + + Image toPb() { + Image imagePb = new Image(); + if (sourceType != null) { + imagePb.setSourceType(sourceType.name()); + } + imagePb.setArchiveSizeBytes(archiveSizeBytes); + return imagePb; + } + + @SuppressWarnings("unchecked") + static T fromPb(Image imagePb) { + if (imagePb.getSourceDisk() != null) { + return (T) DiskImageConfiguration.fromPb(imagePb); + } + return (T) StorageImageConfiguration.fromPb(imagePb); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageId.java new file mode 100644 index 000000000000..eacea6402cba --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageId.java @@ -0,0 +1,145 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; + +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Identity for a Google Compute Engine image. + */ +public final class ImageId extends ResourceId { + + static final Function FROM_URL_FUNCTION = new Function() { + @Override + public ImageId apply(String pb) { + return ImageId.fromUrl(pb); + } + }; + static final Function TO_URL_FUNCTION = new Function() { + @Override + public String apply(ImageId imageId) { + return imageId.selfLink(); + } + }; + + private static final String REGEX = ResourceId.REGEX + "global/images/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); + private static final long serialVersionUID = 6434553917859414341L; + + private final String image; + + private ImageId(String project, String image) { + super(project); + this.image = checkNotNull(image); + } + + /** + * Returns the name of the image. The name must be 1-63 characters long and comply with RFC1035. + * Specifically, the name must match the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} + * which means the first character must be a lowercase letter, and all following characters must + * be a dash, lowercase letter, or digit, except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public String image() { + return image; + } + + @Override + public String selfLink() { + return super.selfLink() + "/global/images/" + image; + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper().add("image", image); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), image); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof ImageId)) { + return false; + } + ImageId other = (ImageId) obj; + return baseEquals(other) && Objects.equals(image, other.image); + } + + @Override + ImageId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return ImageId.of(projectId, image); + } + + /** + * Returns an image identity given the image name. The image name must be 1-63 characters long and + * comply with RFC1035. Specifically, the name must match the regular expression + * {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a lowercase letter, + * and all following characters must be a dash, lowercase letter, or digit, except the last + * character, which cannot be a dash. + * + * @see RFC1035 + */ + public static ImageId of(String image) { + return new ImageId(null, image); + } + + /** + * Returns an image identity given project and image names. The image name must be 1-63 characters + * long and comply with RFC1035. Specifically, the name must match the regular expression + * {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a lowercase letter, + * and all following characters must be a dash, lowercase letter, or digit, except the last + * character, which cannot be a dash. + * + * @see RFC1035 + */ + public static ImageId of(String project, String image) { + return new ImageId(project, image); + } + + /** + * Returns {@code true} if the provided string matches the expected format of an image URL. + * Returns {@code false} otherwise. + */ + static boolean matchesUrl(String url) { + return PATTERN.matcher(url).matches(); + } + + static ImageId fromUrl(String url) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { + throw new IllegalArgumentException(url + " is not a valid image URL"); + } + return ImageId.of(matcher.group(1), matcher.group(2)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageInfo.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageInfo.java new file mode 100644 index 000000000000..c243154cec4e --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageInfo.java @@ -0,0 +1,416 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.api.services.compute.model.Image; +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; + +import java.io.Serializable; +import java.math.BigInteger; +import java.util.List; +import java.util.Objects; + +/** + * A Google Compute Engine Image. An image contains a boot loader, an operating system and a root + * file system that is necessary for starting an instance. Compute Engine offers publicly-available + * images of certain operating systems that you can use, or you can create a custom image. A custom + * image is an image created from one of your virtual machine instances that contains your specific + * instance configurations. Use {@link DiskImageConfiguration} to create an image from an existing + * disk. Use {@link StorageImageConfiguration} to create an image from a file stored in Google + * Cloud Storage. + * + * @see Images + */ +public class ImageInfo implements Serializable { + + static final Function FROM_PB_FUNCTION = + new Function() { + @Override + public ImageInfo apply(Image pb) { + return ImageInfo.fromPb(pb); + } + }; + static final Function TO_PB_FUNCTION = + new Function() { + @Override + public Image apply(ImageInfo image) { + return image.toPb(); + } + }; + + private static final long serialVersionUID = -1061916352807358977L; + private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); + + private final String id; + private final ImageId imageId; + private final Long creationTimestamp; + private final String description; + private final ImageConfiguration configuration; + private final Status status; + private final Long diskSizeGb; + private final List licenses; + private final DeprecationStatus deprecationStatus; + + /** + * The status of a Google Compute Engine Image. An image can be used to create other disks only + * after it has been successfully created and its status is set to {@code READY}. + */ + public enum Status { + /** + * Image creation failed. The image can not be used. + */ + FAILED, + + /** + * Image creation is pending. The image is not ready to be used yet. + */ + PENDING, + + /** + * Image has been created and is ready for use. + */ + READY + } + + /** + * A builder for {@code ImageInfo} objects. + */ + public abstract static class Builder { + + abstract Builder id(String id); + + abstract Builder creationTimestamp(Long creationTimestamp); + + /** + * Sets the image identity. + */ + public abstract Builder imageId(ImageId imageId); + + /** + * Sets an optional textual description of the image. + */ + public abstract Builder description(String description); + + /** + * Sets the image configuration. Use {@link DiskImageConfiguration} to create an image from an + * existing disk. Use {@link StorageImageConfiguration} to create an image from a file stored in + * Google Cloud Storage. + */ + public abstract Builder configuration(ImageConfiguration configuration); + + abstract Builder status(Status status); + + abstract Builder diskSizeGb(Long diskSizeGb); + + abstract Builder licenses(List licenses); + + abstract Builder deprecationStatus(DeprecationStatus deprecationStatus); + + /** + * Creates a {@code ImageInfo} object. + */ + public abstract ImageInfo build(); + } + + static final class BuilderImpl extends Builder { + + private String id; + private Long creationTimestamp; + private ImageId imageId; + private String description; + private ImageConfiguration configuration; + private Status status; + private Long diskSizeGb; + private List licenses; + private DeprecationStatus deprecationStatus; + + BuilderImpl() {} + + BuilderImpl(ImageInfo imageInfo) { + this.id = imageInfo.id; + this.creationTimestamp = imageInfo.creationTimestamp; + this.imageId = imageInfo.imageId; + this.description = imageInfo.description; + this.configuration = imageInfo.configuration; + this.status = imageInfo.status; + this.diskSizeGb = imageInfo.diskSizeGb; + this.licenses = imageInfo.licenses; + this.deprecationStatus = imageInfo.deprecationStatus; + } + + BuilderImpl(Image imagePb) { + if (imagePb.getId() != null) { + this.id = imagePb.getId().toString(); + } + if (imagePb.getCreationTimestamp() != null) { + this.creationTimestamp = TIMESTAMP_FORMATTER.parseMillis(imagePb.getCreationTimestamp()); + } + this.imageId = ImageId.fromUrl(imagePb.getSelfLink()); + this.description = imagePb.getDescription(); + this.configuration = ImageConfiguration.fromPb(imagePb); + if (imagePb.getStatus() != null) { + this.status = Status.valueOf(imagePb.getStatus()); + } + this.diskSizeGb = imagePb.getDiskSizeGb(); + if (imagePb.getLicenses() != null) { + this.licenses = Lists.transform(imagePb.getLicenses(), LicenseId.FROM_URL_FUNCTION); + } + if (imagePb.getDeprecated() != null) { + this.deprecationStatus = + DeprecationStatus.fromPb(imagePb.getDeprecated(), ImageId.FROM_URL_FUNCTION); + } + } + + @Override + BuilderImpl id(String id) { + this.id = id; + return this; + } + + @Override + BuilderImpl creationTimestamp(Long creationTimestamp) { + this.creationTimestamp = creationTimestamp; + return this; + } + + @Override + public BuilderImpl imageId(ImageId imageId) { + this.imageId = checkNotNull(imageId); + return this; + } + + @Override + public BuilderImpl description(String description) { + this.description = description; + return this; + } + + @Override + public BuilderImpl configuration(ImageConfiguration configuration) { + this.configuration = checkNotNull(configuration); + return this; + } + + @Override + BuilderImpl status(Status status) { + this.status = status; + return this; + } + + @Override + BuilderImpl diskSizeGb(Long diskSizeGb) { + this.diskSizeGb = diskSizeGb; + return this; + } + + @Override + BuilderImpl licenses(List licenses) { + this.licenses = licenses != null ? ImmutableList.copyOf(licenses) : null; + return this; + } + + @Override + BuilderImpl deprecationStatus(DeprecationStatus deprecationStatus) { + this.deprecationStatus = deprecationStatus; + return this; + } + + @Override + public ImageInfo build() { + return new ImageInfo(this); + } + } + + ImageInfo(BuilderImpl builder) { + this.id = builder.id; + this.creationTimestamp = builder.creationTimestamp; + this.imageId = checkNotNull(builder.imageId); + this.description = builder.description; + this.configuration = checkNotNull(builder.configuration); + this.status = builder.status; + this.diskSizeGb = builder.diskSizeGb; + this.licenses = builder.licenses; + this.deprecationStatus = builder.deprecationStatus; + } + + /** + * Returns the unique identifier for the image; defined by the service. + */ + public String id() { + return id; + } + + /** + * Returns the creation timestamp in milliseconds since epoch. + */ + public Long creationTimestamp() { + return creationTimestamp; + } + + /** + * Returns the image identity. + */ + public ImageId imageId() { + return imageId; + } + + /** + * Returns a textual description of the image. + */ + public String description() { + return description; + } + + /** + * Returns the image configuration. This method returns an instance of + * {@link DiskImageConfiguration} if the the image was created from a Google Compute Engine disk. + * This method returns an instance of {@link StorageImageConfiguration} if the image was created + * from a file stored in Google Cloud Storage. + */ + @SuppressWarnings("unchecked") + public T configuration() { + return (T) configuration; + } + + /** + * Returns all applicable publicly visible licenses. + */ + public List licenses() { + return licenses; + } + + /** + * Returns the status of the image. An image can be used to create other disks only after it has + * been successfully created and its status is set to {@link Status#READY}. + */ + public Status status() { + return status; + } + + /** + * Returns the size of the image when restored onto a persistent disk (in GB). + */ + public Long diskSizeGb() { + return diskSizeGb; + } + + /** + * Returns the deprecation status of the image. If {@link DeprecationStatus#status()} is either + * {@link DeprecationStatus.Status#DELETED} or {@link DeprecationStatus.Status#OBSOLETE} the + * image must not be used. Returns {@code null} if the image is not deprecated. + */ + public DeprecationStatus deprecationStatus() { + return deprecationStatus; + } + + /** + * Returns a builder for the current image. + */ + public Builder toBuilder() { + return new BuilderImpl(this); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id) + .add("creationTimestamp", creationTimestamp) + .add("imageId", imageId) + .add("description", description) + .add("configuration", configuration) + .add("status", status) + .add("diskSizeGb", diskSizeGb) + .add("licenses", licenses) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(id, creationTimestamp, imageId, description, configuration, status, + diskSizeGb, licenses); + } + + @Override + public boolean equals(Object obj) { + return obj != null + && obj.getClass().equals(ImageInfo.class) + && Objects.equals(toPb(), ((ImageInfo) obj).toPb()); + } + + ImageInfo setProjectId(String projectId) { + return toBuilder() + .imageId(imageId.setProjectId(projectId)) + .configuration(configuration.setProjectId(projectId)) + .build(); + } + + Image toPb() { + Image imagePb = configuration.toPb(); + if (id != null) { + imagePb.setId(new BigInteger(id)); + } + if (creationTimestamp != null) { + imagePb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); + } + imagePb.setName(imageId.image()); + imagePb.setDescription(description); + imagePb.setSelfLink(imageId.selfLink()); + if (status != null) { + imagePb.setStatus(status.name()); + } + imagePb.setDiskSizeGb(diskSizeGb); + if (licenses != null) { + imagePb.setLicenses(Lists.transform(licenses, LicenseId.TO_URL_FUNCTION)); + } + if (deprecationStatus != null) { + imagePb.setDeprecated(deprecationStatus.toPb()); + } + return imagePb; + } + + /** + * Returns a builder for an {@code ImageInfo} object given the image identity and an image + * configuration. Use {@link DiskImageConfiguration} to create an image from an existing disk. Use + * {@link StorageImageConfiguration} to create an image from a file stored in Google Cloud + * Storage. + */ + public static Builder builder(ImageId imageId, ImageConfiguration configuration) { + return new BuilderImpl().imageId(imageId).configuration(configuration); + } + + /** + * Returns an {@code ImageInfo} object given the image identity and an image configuration. Use + * {@link DiskImageConfiguration} to create an image from an existing disk. Use + * {@link StorageImageConfiguration} to create an image from a file stored in Google Cloud + * Storage. + */ + public static ImageInfo of(ImageId imageId, ImageConfiguration configuration) { + return builder(imageId, configuration).build(); + } + + static ImageInfo fromPb(Image imagePb) { + return new BuilderImpl(imagePb).build(); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/StorageImageConfiguration.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/StorageImageConfiguration.java new file mode 100644 index 000000000000..a09be89aefe6 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/StorageImageConfiguration.java @@ -0,0 +1,201 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.api.services.compute.model.Image; +import com.google.common.base.MoreObjects; + +import java.util.Objects; + +/** + * A Google Compute Engine image configuration used to create images from a Google Cloud Storage + * URL where the disk image is stored. + */ +public class StorageImageConfiguration extends ImageConfiguration { + + private static final long serialVersionUID = 8160447986545005880L; + + private final ContainerType containerType; + private final String sha1; + private final String source; + + /** + * The format used to encode and transmit the block device. The only supported value is + * {@code TAR}. This is just a container and transmission format, not a runtime format. + */ + public enum ContainerType { + TAR + } + + /** + * A builder for {@code StorageImageConfiguration} objects. + */ + public static final class Builder + extends ImageConfiguration.Builder { + + private ContainerType containerType; + private String sha1; + private String source; + + private Builder() { + super(Type.STORAGE); + } + + private Builder(StorageImageConfiguration imageConfiguration) { + super(Type.STORAGE, imageConfiguration); + this.containerType = imageConfiguration.containerType; + this.sha1 = imageConfiguration.sha1; + this.source = imageConfiguration.source; + } + + private Builder(Image imagePb) { + super(Type.STORAGE, imagePb); + if (imagePb.getRawDisk().getContainerType() != null) { + this.containerType = ContainerType.valueOf(imagePb.getRawDisk().getContainerType()); + } + this.sha1 = imagePb.getRawDisk().getSha1Checksum(); + this.source = imagePb.getRawDisk().getSource(); + } + + /** + * Sets the format used to encode and transmit the block device. The only supported value is + * {@code TAR}. This is just a container and transmission format, not a runtime format. + */ + public Builder containerType(ContainerType containerType) { + this.containerType = containerType; + return this; + } + + /** + * Sets the SHA1 checksum of the disk image before unpackaging. + */ + public Builder sha1(String sha1) { + this.sha1 = sha1; + return this; + } + + /** + * Sets the full Google Cloud Storage URL where the disk image is stored (e.g. + * {@code gs://bucket/file}). + */ + public Builder source(String source) { + this.source = checkNotNull(source); + return this; + } + + /** + * Creates a {@code StorageImageConfiguration} object. + */ + @Override + public StorageImageConfiguration build() { + return new StorageImageConfiguration(this); + } + } + + private StorageImageConfiguration(Builder builder) { + super(builder); + this.source = checkNotNull(builder.source); + this.containerType = builder.containerType; + this.sha1 = builder.sha1; + } + + /** + * Returns the format used to encode and transmit the block device. This is just a container and + * transmission format, not a runtime format. + */ + public ContainerType containerType() { + return containerType; + } + + /** + * Returns the SHA1 checksum of the disk image before unpackaging. + */ + public String sha1() { + return sha1; + } + + /** + * Returns the full Google Cloud Storage URL where the disk image is stored (e.g. + * {@code gs://bucket/file}). + */ + public String source() { + return source; + } + + @Override + public Builder toBuilder() { + return new Builder(this); + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper() + .add("source", source) + .add("containerType", containerType) + .add("sha1", sha1); + } + + @Override + public final int hashCode() { + return Objects.hash(baseHashCode(), source, containerType, sha1); + } + + @Override + public final boolean equals(Object obj) { + return obj instanceof StorageImageConfiguration && baseEquals((StorageImageConfiguration) obj); + } + + @Override + StorageImageConfiguration setProjectId(String projectId) { + return this; + } + + @Override + Image toPb() { + Image.RawDisk rawDiskPb = new Image.RawDisk(); + rawDiskPb.setSource(source); + rawDiskPb.setSha1Checksum(sha1); + if (containerType != null) { + rawDiskPb.setContainerType(containerType.name()); + } + Image imagePb = super.toPb(); + return imagePb.setRawDisk(rawDiskPb); + } + + /** + * Creates a {@code StorageImageConfiguration} builder given the full Google Cloud Storage URL + * where the disk image is stored. + */ + public static Builder builder(String source) { + return new Builder().source(source); + } + + /** + * Creates a {@code StorageImageConfiguration} object given the full Google Cloud Storage URL + * where the disk image is stored. + */ + public static StorageImageConfiguration of(String source) { + return builder(source).build(); + } + + @SuppressWarnings("unchecked") + static StorageImageConfiguration fromPb(Image imagePb) { + return new Builder(imagePb).build(); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java index e8d29669da7b..389d470bd300 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java @@ -17,39 +17,137 @@ package com.google.gcloud.compute; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; import com.google.gcloud.compute.DeprecationStatus.Status; +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; import org.junit.Test; public class DeprecationStatusTest { - private static final Long DELETED = 1453293540000L; - private static final Long DEPRECATED = 1453293420000L; - private static final Long OBSOLETE = 1453293480000L; + private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); + private static final Long DELETED_MILLIS = 1453293540000L; + private static final Long DEPRECATED_MILLIS = 1453293420000L; + private static final Long OBSOLETE_MILLIS = 1453293480000L; + private static final String DELETED = TIMESTAMP_FORMATTER.print(DELETED_MILLIS); + private static final String DEPRECATED = TIMESTAMP_FORMATTER.print(DEPRECATED_MILLIS); + private static final String OBSOLETE = TIMESTAMP_FORMATTER.print(OBSOLETE_MILLIS); private static final DiskTypeId DISK_TYPE_ID = DiskTypeId.of("project", "zone", "diskType"); private static final MachineTypeId MACHINE_TYPE_ID = MachineTypeId.of("project", "zone", "machineType"); private static final Status STATUS = Status.DELETED; private static final DeprecationStatus DISK_TYPE_STATUS = - new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, DISK_TYPE_ID, STATUS); + DeprecationStatus.builder(STATUS) + .replacement(DISK_TYPE_ID) + .deprecated(DEPRECATED) + .obsolete(OBSOLETE) + .deleted(DELETED) + .build(); + private static final DeprecationStatus DISK_TYPE_STATUS_MILLIS = + DeprecationStatus.builder(STATUS) + .replacement(DISK_TYPE_ID) + .deprecated(DEPRECATED_MILLIS) + .obsolete(OBSOLETE_MILLIS) + .deleted(DELETED_MILLIS) + .build(); private static final DeprecationStatus MACHINE_TYPE_STATUS = - new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, MACHINE_TYPE_ID, STATUS); + DeprecationStatus.builder(STATUS, MACHINE_TYPE_ID) + .deprecated(DEPRECATED) + .obsolete(OBSOLETE) + .deleted(DELETED) + .build(); @Test - public void testConstructor() { + public void testBuilder() { + compareDeprecationStatus(DISK_TYPE_STATUS, DISK_TYPE_STATUS_MILLIS); assertEquals(DELETED, DISK_TYPE_STATUS.deleted()); assertEquals(DEPRECATED, DISK_TYPE_STATUS.deprecated()); assertEquals(OBSOLETE, DISK_TYPE_STATUS.obsolete()); assertEquals(DISK_TYPE_ID, DISK_TYPE_STATUS.replacement()); + assertEquals(DEPRECATED_MILLIS, DISK_TYPE_STATUS.deprecatedMillis()); + assertEquals(DELETED_MILLIS, DISK_TYPE_STATUS.deletedMillis()); + assertEquals(OBSOLETE_MILLIS, DISK_TYPE_STATUS.obsoleteMillis()); + assertEquals(STATUS, DISK_TYPE_STATUS.status()); + assertEquals(DELETED, DISK_TYPE_STATUS_MILLIS.deleted()); + assertEquals(DEPRECATED, DISK_TYPE_STATUS_MILLIS.deprecated()); + assertEquals(OBSOLETE, DISK_TYPE_STATUS_MILLIS.obsolete()); + assertEquals(DISK_TYPE_ID, DISK_TYPE_STATUS_MILLIS.replacement()); + assertEquals(DEPRECATED_MILLIS, DISK_TYPE_STATUS_MILLIS.deprecatedMillis()); + assertEquals(DELETED_MILLIS, DISK_TYPE_STATUS_MILLIS.deletedMillis()); + assertEquals(OBSOLETE_MILLIS, DISK_TYPE_STATUS_MILLIS.obsoleteMillis()); assertEquals(STATUS, DISK_TYPE_STATUS.status()); assertEquals(DELETED, MACHINE_TYPE_STATUS.deleted()); assertEquals(DEPRECATED, MACHINE_TYPE_STATUS.deprecated()); assertEquals(OBSOLETE, MACHINE_TYPE_STATUS.obsolete()); + assertEquals(DEPRECATED_MILLIS, MACHINE_TYPE_STATUS.deprecatedMillis()); + assertEquals(DELETED_MILLIS, MACHINE_TYPE_STATUS.deletedMillis()); + assertEquals(OBSOLETE_MILLIS, MACHINE_TYPE_STATUS.obsoleteMillis()); assertEquals(MACHINE_TYPE_ID, MACHINE_TYPE_STATUS.replacement()); assertEquals(STATUS, MACHINE_TYPE_STATUS.status()); } + @Test + public void testGettersIllegalArgument() { + DeprecationStatus deprecationStatus = + DeprecationStatus.builder(STATUS, MACHINE_TYPE_ID) + .deprecated("deprecated") + .obsolete("obsolete") + .deleted("delete") + .build(); + assertEquals("deprecated", deprecationStatus.deprecated()); + try { + deprecationStatus.deprecatedMillis(); + fail("Expected IllegalArgumentException"); + } catch (IllegalStateException ex) { + // never reached + } + assertEquals("obsolete", deprecationStatus.obsolete()); + try { + deprecationStatus.obsoleteMillis(); + fail("Expected IllegalArgumentException"); + } catch (IllegalStateException ex) { + // never reached + } + assertEquals("delete", deprecationStatus.deleted()); + try { + deprecationStatus.deletedMillis(); + fail("Expected IllegalArgumentException"); + } catch (IllegalStateException ex) { + // never reached + } + } + + @Test + public void testToBuilder() { + compareDeprecationStatus(DISK_TYPE_STATUS, DISK_TYPE_STATUS.toBuilder().build()); + compareDeprecationStatus(MACHINE_TYPE_STATUS, MACHINE_TYPE_STATUS.toBuilder().build()); + DeprecationStatus deprecationStatus = DISK_TYPE_STATUS.toBuilder() + .deleted(DEPRECATED) + .build(); + assertEquals(DEPRECATED, deprecationStatus.deleted()); + deprecationStatus = deprecationStatus.toBuilder().deleted(DELETED).build(); + compareDeprecationStatus(DISK_TYPE_STATUS, deprecationStatus); + } + + @Test + public void testToBuilderIncomplete() { + DeprecationStatus diskStatus = DeprecationStatus.of(STATUS, DISK_TYPE_ID); + assertEquals(diskStatus, diskStatus.toBuilder().build()); + } + + @Test + public void testOf() { + DeprecationStatus diskStatus = DeprecationStatus.of(STATUS, DISK_TYPE_ID); + assertNull(diskStatus.deleted()); + assertNull(diskStatus.deprecated()); + assertNull(diskStatus.obsolete()); + assertEquals(DISK_TYPE_ID, diskStatus.replacement()); + assertEquals(STATUS, diskStatus.status()); + } + @Test public void testToAndFromPb() { DeprecationStatus diskStatus = @@ -58,12 +156,16 @@ public void testToAndFromPb() { DeprecationStatus machineStatus = DeprecationStatus.fromPb(MACHINE_TYPE_STATUS.toPb(), MachineTypeId.FROM_URL_FUNCTION); compareDeprecationStatus(MACHINE_TYPE_STATUS, machineStatus); - diskStatus = new DeprecationStatus<>(null, DEPRECATED, null, DISK_TYPE_ID, STATUS); + diskStatus = DeprecationStatus.builder(STATUS, DISK_TYPE_ID).deprecated(DEPRECATED).build(); assertEquals(diskStatus, DeprecationStatus.fromPb(diskStatus.toPb(), DiskTypeId.FROM_URL_FUNCTION)); - machineStatus = new DeprecationStatus<>(null, DEPRECATED, null, MACHINE_TYPE_ID, STATUS); + machineStatus = + DeprecationStatus.builder(STATUS, MACHINE_TYPE_ID).deprecated(DEPRECATED).build(); assertEquals(machineStatus, DeprecationStatus.fromPb(machineStatus.toPb(), MachineTypeId.FROM_URL_FUNCTION)); + diskStatus = DeprecationStatus.of(STATUS, DISK_TYPE_ID); + assertEquals(diskStatus, + DeprecationStatus.fromPb(diskStatus.toPb(), DiskTypeId.FROM_URL_FUNCTION)); } private void compareDeprecationStatus(DeprecationStatus expected, DeprecationStatus value) { @@ -71,6 +173,9 @@ private void compareDeprecationStatus(DeprecationStatus expected, DeprecationSta assertEquals(expected.deleted(), value.deleted()); assertEquals(expected.deprecated(), value.deprecated()); assertEquals(expected.obsolete(), value.obsolete()); + assertEquals(expected.deletedMillis(), value.deletedMillis()); + assertEquals(expected.deprecatedMillis(), value.deprecatedMillis()); + assertEquals(expected.obsoleteMillis(), value.obsoleteMillis()); assertEquals(expected.replacement(), value.replacement()); assertEquals(expected.status(), value.status()); assertEquals(expected.hashCode(), value.hashCode()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskImageConfigurationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskImageConfigurationTest.java new file mode 100644 index 000000000000..df1e8bf62a4c --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskImageConfigurationTest.java @@ -0,0 +1,112 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import com.google.gcloud.compute.ImageConfiguration.SourceType; +import com.google.gcloud.compute.ImageConfiguration.Type; + +import org.junit.Test; + +public class DiskImageConfigurationTest { + + private static final DiskId SOURCE_DISK = DiskId.of("project", "zone", "disk"); + private static final String SOURCE_DISK_ID = "diskId"; + private static final Long ARCHIVE_SIZE_BYTES = 42L; + private static final SourceType SOURCE_TYPE = SourceType.RAW; + private static final DiskImageConfiguration CONFIGURATION = + DiskImageConfiguration.builder(SOURCE_DISK) + .sourceDiskId(SOURCE_DISK_ID) + .sourceType(SOURCE_TYPE) + .archiveSizeBytes(ARCHIVE_SIZE_BYTES) + .build(); + + @Test + public void testToBuilder() { + compareDiskImageConfiguration(CONFIGURATION, CONFIGURATION.toBuilder().build()); + DiskId newDisk = DiskId.of("newProject", "newZone", "newDisk"); + String newDiskId = "newDiskId"; + DiskImageConfiguration configuration = CONFIGURATION.toBuilder() + .sourceDisk(newDisk) + .sourceDiskId(newDiskId) + .build(); + assertEquals(newDisk, configuration.sourceDisk()); + assertEquals(newDiskId, configuration.sourceDiskId()); + configuration = configuration.toBuilder() + .sourceDiskId(SOURCE_DISK_ID) + .sourceDisk(SOURCE_DISK) + .build(); + compareDiskImageConfiguration(CONFIGURATION, configuration); + } + + @Test + public void testToBuilderIncomplete() { + DiskImageConfiguration configuration = DiskImageConfiguration.of(SOURCE_DISK); + compareDiskImageConfiguration(configuration, configuration.toBuilder().build()); + } + + @Test + public void testBuilder() { + assertEquals(SOURCE_TYPE, CONFIGURATION.sourceType()); + assertEquals(SOURCE_DISK, CONFIGURATION.sourceDisk()); + assertEquals(SOURCE_DISK_ID, CONFIGURATION.sourceDiskId()); + assertEquals(ARCHIVE_SIZE_BYTES, CONFIGURATION.archiveSizeBytes()); + assertEquals(Type.DISK, CONFIGURATION.type()); + } + + @Test + public void testToAndFromPb() { + assertTrue(ImageConfiguration.fromPb(CONFIGURATION.toPb()) instanceof DiskImageConfiguration); + compareDiskImageConfiguration(CONFIGURATION, + ImageConfiguration.fromPb(CONFIGURATION.toPb())); + DiskImageConfiguration configuration = DiskImageConfiguration.of(SOURCE_DISK); + compareDiskImageConfiguration(configuration, + DiskImageConfiguration.fromPb(configuration.toPb())); + } + + @Test + public void testOf() { + DiskImageConfiguration configuration = DiskImageConfiguration.of(SOURCE_DISK); + assertEquals(Type.DISK, configuration.type()); + assertNull(configuration.sourceDiskId()); + assertNull(configuration.sourceType()); + assertNull(configuration.archiveSizeBytes()); + assertEquals(SOURCE_DISK, configuration.sourceDisk()); + } + + @Test + public void testSetProjectId() { + DiskImageConfiguration configuration = CONFIGURATION.toBuilder() + .sourceDisk(DiskId.of("zone", "disk")) + .build(); + compareDiskImageConfiguration(CONFIGURATION, configuration.setProjectId("project")); + } + + private void compareDiskImageConfiguration(DiskImageConfiguration expected, + DiskImageConfiguration value) { + assertEquals(expected, value); + assertEquals(expected.type(), value.type()); + assertEquals(expected.archiveSizeBytes(), value.archiveSizeBytes()); + assertEquals(expected.sourceDisk(), value.sourceDisk()); + assertEquals(expected.sourceDiskId(), value.sourceDiskId()); + assertEquals(expected.sourceType(), value.sourceType()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java index 9e97b8d1becd..4cbb8351270c 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java @@ -28,12 +28,8 @@ public class DiskTypeTest { private static final String VALID_DISK_SIZE = "10GB-10TB"; private static final Long DEFAULT_DISK_SIZE_GB = 10L; private static final DiskTypeId DISK_TYPE_ID = DiskTypeId.of("project", "zone", "diskType"); - private static final Long DELETED = 1453293540000L; - private static final Long DEPRECATED = 1453293420000L; - private static final Long OBSOLETE = 1453293480000L; - private static final DeprecationStatus.Status STATUS = DeprecationStatus.Status.DELETED; private static final DeprecationStatus DEPRECATION_STATUS = - new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, DISK_TYPE_ID, STATUS); + DeprecationStatus.of(DeprecationStatus.Status.DELETED, DISK_TYPE_ID); private static final DiskType DISK_TYPE = DiskType.builder() .id(ID) .diskTypeId(DISK_TYPE_ID) diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageIdTest.java new file mode 100644 index 000000000000..0a11b7fe60f6 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageIdTest.java @@ -0,0 +1,79 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class ImageIdTest { + + private static final String PROJECT = "project"; + private static final String NAME = "image"; + private static final String URL = + "https://www.googleapis.com/compute/v1/projects/project/global/images/image"; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testOf() { + ImageId imageId = ImageId.of(PROJECT, NAME); + assertEquals(PROJECT, imageId.project()); + assertEquals(NAME, imageId.image()); + assertEquals(URL, imageId.selfLink()); + imageId = ImageId.of(NAME); + assertNull(imageId.project()); + assertEquals(NAME, imageId.image()); + } + + @Test + public void testToAndFromUrl() { + ImageId imageId = ImageId.of(PROJECT, NAME); + compareImageId(imageId, ImageId.fromUrl(imageId.selfLink())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid image URL"); + ImageId.fromUrl("notMatchingUrl"); + } + + @Test + public void testSetProjectId() { + ImageId imageId = ImageId.of(PROJECT, NAME); + assertSame(imageId, imageId.setProjectId(PROJECT)); + compareImageId(imageId, ImageId.of(NAME).setProjectId(PROJECT)); + } + + @Test + public void testMatchesUrl() { + assertTrue(ImageId.matchesUrl(ImageId.of(PROJECT, NAME).selfLink())); + assertFalse(ImageId.matchesUrl("notMatchingUrl")); + } + + private void compareImageId(ImageId expected, ImageId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.image(), expected.image()); + assertEquals(expected.selfLink(), expected.selfLink()); + assertEquals(expected.hashCode(), expected.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageInfoTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageInfoTest.java new file mode 100644 index 000000000000..db6e092b5587 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageInfoTest.java @@ -0,0 +1,175 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import com.google.common.collect.ImmutableList; +import com.google.gcloud.compute.ImageConfiguration.SourceType; + +import org.junit.Test; + +import java.util.List; + +public class ImageInfoTest { + + private static final ImageId IMAGE_ID = ImageId.of("project", "image"); + private static final String ID = "42"; + private static final Long CREATION_TIMESTAMP = 1453293540000L; + private static final String DESCRIPTION = "description"; + private static final ImageInfo.Status STATUS = ImageInfo.Status.READY; + private static final List LICENSES = ImmutableList.of( + LicenseId.of("project", "license1"), LicenseId.of("project", "license2")); + private static final Long DISK_SIZE_GB = 42L; + private static final String STORAGE_SOURCE = "source"; + private static final Long ARCHIVE_SIZE_BYTES = 24L; + private static final String SHA1_CHECKSUM = "checksum"; + private static final DiskId SOURCE_DISK = DiskId.of("project", "zone", "disk"); + private static final String SOURCE_DISK_ID = "diskId"; + private static final SourceType SOURCE_TYPE = SourceType.RAW; + private static final StorageImageConfiguration STORAGE_CONFIGURATION = + StorageImageConfiguration.builder(STORAGE_SOURCE) + .archiveSizeBytes(ARCHIVE_SIZE_BYTES) + .containerType(StorageImageConfiguration.ContainerType.TAR) + .sha1(SHA1_CHECKSUM) + .sourceType(SOURCE_TYPE) + .build(); + private static final DiskImageConfiguration DISK_CONFIGURATION = + DiskImageConfiguration.builder(SOURCE_DISK) + .archiveSizeBytes(ARCHIVE_SIZE_BYTES) + .sourceDiskId(SOURCE_DISK_ID) + .sourceType(SOURCE_TYPE) + .build(); + private static final DeprecationStatus DEPRECATION_STATUS = + DeprecationStatus.of(DeprecationStatus.Status.DELETED, IMAGE_ID); + private static final ImageInfo STORAGE_IMAGE = ImageInfo.builder(IMAGE_ID, STORAGE_CONFIGURATION) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .status(STATUS) + .diskSizeGb(DISK_SIZE_GB) + .licenses(LICENSES) + .deprecationStatus(DEPRECATION_STATUS) + .build(); + private static final ImageInfo DISK_IMAGE = ImageInfo.builder(IMAGE_ID, DISK_CONFIGURATION) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .status(STATUS) + .diskSizeGb(DISK_SIZE_GB) + .licenses(LICENSES) + .deprecationStatus(DEPRECATION_STATUS) + .build(); + + @Test + public void testToBuilder() { + compareImageInfo(STORAGE_IMAGE, STORAGE_IMAGE.toBuilder().build()); + compareImageInfo(DISK_IMAGE, DISK_IMAGE.toBuilder().build()); + ImageInfo imageInfo = STORAGE_IMAGE.toBuilder().description("newDescription").build(); + assertEquals("newDescription", imageInfo.description()); + imageInfo = imageInfo.toBuilder().description("description").build(); + compareImageInfo(STORAGE_IMAGE, imageInfo); + } + + @Test + public void testToBuilderIncomplete() { + ImageInfo imageInfo = ImageInfo.of(IMAGE_ID, STORAGE_CONFIGURATION); + assertEquals(imageInfo, imageInfo.toBuilder().build()); + imageInfo = ImageInfo.of(IMAGE_ID, DISK_CONFIGURATION); + assertEquals(imageInfo, imageInfo.toBuilder().build()); + } + + @Test + public void testBuilder() { + assertEquals(ID, STORAGE_IMAGE.id()); + assertEquals(IMAGE_ID, STORAGE_IMAGE.imageId()); + assertEquals(CREATION_TIMESTAMP, STORAGE_IMAGE.creationTimestamp()); + assertEquals(DESCRIPTION, STORAGE_IMAGE.description()); + assertEquals(STORAGE_CONFIGURATION, STORAGE_IMAGE.configuration()); + assertEquals(STATUS, STORAGE_IMAGE.status()); + assertEquals(DISK_SIZE_GB, STORAGE_IMAGE.diskSizeGb()); + assertEquals(LICENSES, STORAGE_IMAGE.licenses()); + assertEquals(DEPRECATION_STATUS, STORAGE_IMAGE.deprecationStatus()); + assertEquals(ID, DISK_IMAGE.id()); + assertEquals(IMAGE_ID, DISK_IMAGE.imageId()); + assertEquals(CREATION_TIMESTAMP, DISK_IMAGE.creationTimestamp()); + assertEquals(DESCRIPTION, DISK_IMAGE.description()); + assertEquals(DISK_CONFIGURATION, DISK_IMAGE.configuration()); + assertEquals(STATUS, DISK_IMAGE.status()); + assertEquals(DISK_SIZE_GB, DISK_IMAGE.diskSizeGb()); + assertEquals(LICENSES, DISK_IMAGE.licenses()); + assertEquals(DEPRECATION_STATUS, DISK_IMAGE.deprecationStatus()); + } + + @Test + public void testOf() { + ImageInfo imageInfo = ImageInfo.of(IMAGE_ID, STORAGE_CONFIGURATION); + assertEquals(IMAGE_ID, imageInfo.imageId()); + assertEquals(STORAGE_CONFIGURATION, imageInfo.configuration()); + assertNull(imageInfo.id()); + assertNull(imageInfo.creationTimestamp()); + assertNull(imageInfo.description()); + assertNull(imageInfo.status()); + assertNull(imageInfo.diskSizeGb()); + assertNull(imageInfo.licenses()); + assertNull(imageInfo.deprecationStatus()); + imageInfo = ImageInfo.of(IMAGE_ID, DISK_CONFIGURATION); + assertEquals(IMAGE_ID, imageInfo.imageId()); + assertEquals(DISK_CONFIGURATION, imageInfo.configuration()); + assertNull(imageInfo.id()); + assertNull(imageInfo.creationTimestamp()); + assertNull(imageInfo.description()); + assertNull(imageInfo.status()); + assertNull(imageInfo.diskSizeGb()); + assertNull(imageInfo.licenses()); + assertNull(imageInfo.deprecationStatus()); + } + + @Test + public void testToAndFromPb() { + compareImageInfo(STORAGE_IMAGE, ImageInfo.fromPb(STORAGE_IMAGE.toPb())); + compareImageInfo(DISK_IMAGE, ImageInfo.fromPb(DISK_IMAGE.toPb())); + ImageInfo imageInfo = ImageInfo.of(IMAGE_ID, StorageImageConfiguration.of(STORAGE_SOURCE)); + compareImageInfo(imageInfo, ImageInfo.fromPb(imageInfo.toPb())); + imageInfo = ImageInfo.of(IMAGE_ID, DiskImageConfiguration.of(SOURCE_DISK)); + compareImageInfo(imageInfo, ImageInfo.fromPb(imageInfo.toPb())); + } + + @Test + public void testSetProjectId() { + ImageInfo imageInfo = DISK_IMAGE.toBuilder() + .imageId(ImageId.of("image")) + .configuration(DISK_CONFIGURATION.toBuilder().sourceDisk(DiskId.of("zone", "disk")).build()) + .build(); + compareImageInfo(DISK_IMAGE, imageInfo.setProjectId("project")); + } + + public void compareImageInfo(ImageInfo expected, ImageInfo value) { + assertEquals(expected, value); + assertEquals(expected.id(), value.id()); + assertEquals(expected.imageId(), value.imageId()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.configuration(), value.configuration()); + assertEquals(expected.status(), value.status()); + assertEquals(expected.diskSizeGb(), value.diskSizeGb()); + assertEquals(expected.licenses(), value.licenses()); + assertEquals(expected.deprecationStatus(), value.deprecationStatus()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java index 969b370ddce8..6b0f78dff00a 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java @@ -35,12 +35,8 @@ public class MachineTypeTest { private static final List SCRATCH_DISKS = ImmutableList.of(3); private static final Integer MAXIMUM_PERSISTENT_DISKS = 4; private static final Long MAXIMUM_PERSISTENT_DISKS_SIZE_GB = 5L; - private static final Long DELETED = 1453293540000L; - private static final Long DEPRECATED = 1453293420000L; - private static final Long OBSOLETE = 1453293480000L; - private static final DeprecationStatus.Status STATUS = DeprecationStatus.Status.DELETED; private static final DeprecationStatus DEPRECATION_STATUS = - new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, MACHINE_TYPE_ID, STATUS); + DeprecationStatus.of(DeprecationStatus.Status.DELETED, MACHINE_TYPE_ID); private static final MachineType MACHINE_TYPE = MachineType.builder() .id(ID) .machineTypeId(MACHINE_TYPE_ID) diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java index fb0250366a5e..07701b1d2248 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java @@ -39,11 +39,8 @@ public class RegionTest { private static final Region.Quota QUOTA2 = new Region.Quota("METRIC2", 4, 3); private static final List QUOTAS = ImmutableList.of(QUOTA1, QUOTA2); - private static final Long DELETED = 1453293540000L; - private static final Long DEPRECATED = 1453293420000L; - private static final Long OBSOLETE = 1453293480000L; - private static final DeprecationStatus DEPRECATION_STATUS = new DeprecationStatus<>( - DELETED, DEPRECATED, OBSOLETE, REGION_ID, DeprecationStatus.Status.DELETED); + private static final DeprecationStatus DEPRECATION_STATUS = + DeprecationStatus.of(DeprecationStatus.Status.DELETED, REGION_ID); private static final Region REGION = Region.builder() .regionId(REGION_ID) .id(ID) diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java index ab15ca5dc6a9..b533ae9c6ae7 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java @@ -105,12 +105,8 @@ public class SerializationTest { .maintenanceWindows(WINDOWS) .region(REGION_ID) .build(); - private static final Long DELETED = 1453293540000L; - private static final Long DEPRECATED = 1453293420000L; - private static final Long OBSOLETE = 1453293480000L; private static final DeprecationStatus DEPRECATION_STATUS = - new DeprecationStatus<>(DELETED, DEPRECATED, OBSOLETE, MACHINE_TYPE_ID, - DeprecationStatus.Status.DELETED); + DeprecationStatus.of(DeprecationStatus.Status.DELETED, MACHINE_TYPE_ID); private static final LicenseId LICENSE_ID = LicenseId.of("project", "license"); private static final Boolean CHARGES_USE_FEE = true; private static final License LICENSE = new License(LICENSE_ID, CHARGES_USE_FEE); @@ -152,6 +148,12 @@ public class SerializationTest { private static final SnapshotInfo SNAPSHOT_INFO = SnapshotInfo.of(SNAPSHOT_ID, DISK_ID); private static final Snapshot SNAPSHOT = new Snapshot.Builder(COMPUTE, SNAPSHOT_ID, DISK_ID).build(); + private static final ImageId IMAGE_ID = ImageId.of("project", "image"); + private static final DiskImageConfiguration DISK_IMAGE_CONFIGURATION = + DiskImageConfiguration.of(DISK_ID); + private static final StorageImageConfiguration RAW_IMAGE_CONFIGURATION = + StorageImageConfiguration.of("gs:/bucket/file"); + private static final ImageInfo IMAGE_INFO = ImageInfo.of(IMAGE_ID, DISK_IMAGE_CONFIGURATION); private static final Compute.DiskTypeOption DISK_TYPE_OPTION = Compute.DiskTypeOption.fields(); private static final Compute.DiskTypeFilter DISK_TYPE_FILTER = @@ -222,7 +224,8 @@ public void testModelAndRequests() throws Exception { REGION_OPERATION_ID, ZONE_OPERATION_ID, GLOBAL_OPERATION, REGION_OPERATION, ZONE_OPERATION, INSTANCE_ID, REGION_FORWARDING_RULE_ID, GLOBAL_FORWARDING_RULE_ID, GLOBAL_ADDRESS_ID, REGION_ADDRESS_ID, INSTANCE_USAGE, GLOBAL_FORWARDING_USAGE, REGION_FORWARDING_USAGE, - ADDRESS_INFO, ADDRESS, DISK_ID, SNAPSHOT_ID, SNAPSHOT_INFO, SNAPSHOT, DISK_TYPE_OPTION, + ADDRESS_INFO, ADDRESS, DISK_ID, SNAPSHOT_ID, SNAPSHOT_INFO, SNAPSHOT, IMAGE_ID, + DISK_IMAGE_CONFIGURATION, RAW_IMAGE_CONFIGURATION, IMAGE_INFO, DISK_TYPE_OPTION, DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, DISK_TYPE_AGGREGATED_LIST_OPTION, MACHINE_TYPE_OPTION, MACHINE_TYPE_FILTER, MACHINE_TYPE_LIST_OPTION, MACHINE_TYPE_AGGREGATED_LIST_OPTION, REGION_OPTION, REGION_FILTER, REGION_LIST_OPTION, diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/StorageImageConfigurationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/StorageImageConfigurationTest.java new file mode 100644 index 000000000000..dc05686a478f --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/StorageImageConfigurationTest.java @@ -0,0 +1,108 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import com.google.gcloud.compute.ImageConfiguration.SourceType; +import com.google.gcloud.compute.StorageImageConfiguration.ContainerType; +import com.google.gcloud.compute.ImageConfiguration.Type; + +import org.junit.Test; + +public class StorageImageConfigurationTest { + + private static final String SOURCE = "source"; + private static final SourceType SOURCE_TYPE = SourceType.RAW; + private static final ContainerType CONTAINER_TYPE = ContainerType.TAR; + private static final Long ARCHIVE_SIZE_BYTES = 42L; + private static final String SHA1 = "sha1"; + private static final StorageImageConfiguration CONFIGURATION = + StorageImageConfiguration.builder(SOURCE) + .sourceType(SOURCE_TYPE) + .containerType(CONTAINER_TYPE) + .archiveSizeBytes(ARCHIVE_SIZE_BYTES) + .sha1(SHA1) + .build(); + + @Test + public void testToBuilder() { + compareRawImageConfiguration(CONFIGURATION, CONFIGURATION.toBuilder().build()); + String newSource = "newSource"; + StorageImageConfiguration configuration = CONFIGURATION.toBuilder().source(newSource).build(); + assertEquals(newSource, configuration.source()); + configuration = configuration.toBuilder().source(SOURCE).build(); + compareRawImageConfiguration(CONFIGURATION, configuration); + } + + @Test + public void testToBuilderIncomplete() { + StorageImageConfiguration configuration = StorageImageConfiguration.of(SOURCE); + compareRawImageConfiguration(configuration, configuration.toBuilder().build()); + } + + @Test + public void testBuilder() { + assertEquals(SOURCE_TYPE, CONFIGURATION.sourceType()); + assertEquals(SOURCE, CONFIGURATION.source()); + assertEquals(CONTAINER_TYPE, CONFIGURATION.containerType()); + assertEquals(ARCHIVE_SIZE_BYTES, CONFIGURATION.archiveSizeBytes()); + assertEquals(SHA1, CONFIGURATION.sha1()); + assertEquals(Type.STORAGE, CONFIGURATION.type()); + } + + @Test + public void testToAndFromPb() { + assertTrue(ImageConfiguration.fromPb(CONFIGURATION.toPb()) instanceof StorageImageConfiguration); + compareRawImageConfiguration(CONFIGURATION, + ImageConfiguration.fromPb(CONFIGURATION.toPb())); + StorageImageConfiguration configuration = StorageImageConfiguration.of(SOURCE); + compareRawImageConfiguration(configuration, + StorageImageConfiguration.fromPb(configuration.toPb())); + } + + @Test + public void testOf() { + StorageImageConfiguration configuration = StorageImageConfiguration.of(SOURCE); + assertEquals(Type.STORAGE, configuration.type()); + assertNull(configuration.sourceType()); + assertEquals(SOURCE, configuration.source()); + assertNull(configuration.containerType()); + assertNull(configuration.archiveSizeBytes()); + assertNull(configuration.sha1()); + } + + @Test + public void testSetProjectId() { + assertSame(CONFIGURATION, CONFIGURATION.setProjectId("project")); + } + + private void compareRawImageConfiguration(StorageImageConfiguration expected, + StorageImageConfiguration value) { + assertEquals(expected, value); + assertEquals(expected.type(), value.type()); + assertEquals(expected.source(), value.source()); + assertEquals(expected.sourceType(), value.sourceType()); + assertEquals(expected.containerType(), value.containerType()); + assertEquals(expected.archiveSizeBytes(), value.archiveSizeBytes()); + assertEquals(expected.sha1(), value.sha1()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java index d686054b8cf6..1224c607a567 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java @@ -40,11 +40,8 @@ public class ZoneTest { private static final MaintenanceWindow WINDOW2 = new MaintenanceWindow("NAME2", "DESCRIPTION2", BEGIN_TIME, END_TIME); private static final List WINDOWS = ImmutableList.of(WINDOW1, WINDOW2); - private static final Long DELETED = 1453293540000L; - private static final Long DEPRECATED = 1453293420000L; - private static final Long OBSOLETE = 1453293480000L; - private static final DeprecationStatus DEPRECATION_STATUS = new DeprecationStatus<>( - DELETED, DEPRECATED, OBSOLETE, ZONE_ID, DeprecationStatus.Status.DELETED); + private static final DeprecationStatus DEPRECATION_STATUS = + DeprecationStatus.of(DeprecationStatus.Status.DELETED, ZONE_ID); private static final Zone ZONE = Zone.builder() .zoneId(ZONE_ID) .id(ID) From cd08330f26b6bd879e80b71f97615b9ba8963880 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Sat, 2 Apr 2016 05:23:34 +0200 Subject: [PATCH 308/375] Add functional methods for images and Image class Add functional methods for images and Image class --- .../com/google/gcloud/compute/Compute.java | 169 ++++++++++ .../google/gcloud/compute/ComputeImpl.java | 135 ++++++++ .../java/com/google/gcloud/compute/Image.java | 209 ++++++++++++ .../com/google/gcloud/spi/ComputeRpc.java | 49 ++- .../google/gcloud/spi/DefaultComputeRpc.java | 69 ++++ .../gcloud/compute/ComputeImplTest.java | 305 ++++++++++++++++- .../com/google/gcloud/compute/ImageTest.java | 306 ++++++++++++++++++ .../gcloud/compute/SerializationTest.java | 13 +- 8 files changed, 1247 insertions(+), 8 deletions(-) create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/Image.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageTest.java diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java index 6d033688d8c2..300d38908a8b 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java @@ -869,6 +869,54 @@ public static SnapshotFilter notEquals(SnapshotField field, long value) { } } + /** + * Class for filtering image lists. + */ + class ImageFilter extends ListFilter { + + private static final long serialVersionUID = -3601427417234098397L; + + private ImageFilter(ImageField field, ComparisonOperator operator, Object value) { + super(field.selector(), operator, value); + } + + /** + * Returns an equals filter for the given field and string value. For string fields, + * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must + * match the entire field. + * + * @see RE2 + */ + public static ImageFilter equals(ImageField field, String value) { + return new ImageFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value)); + } + + /** + * Returns a not-equals filter for the given field and string value. For string fields, + * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must + * match the entire field. + * + * @see RE2 + */ + public static ImageFilter notEquals(ImageField field, String value) { + return new ImageFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value)); + } + + /** + * Returns an equals filter for the given field and long value. + */ + public static ImageFilter equals(ImageField field, long value) { + return new ImageFilter(checkNotNull(field), ComparisonOperator.EQ, value); + } + + /** + * Returns a not-equals filter for the given field and long value. + */ + public static ImageFilter notEquals(ImageField field, long value) { + return new ImageFilter(checkNotNull(field), ComparisonOperator.NE, value); + } + } + /** * Class for specifying disk type get options. */ @@ -1469,6 +1517,74 @@ public static SnapshotListOption fields(SnapshotField... fields) { } } + /** + * Class for specifying image get options. + */ + class ImageOption extends Option { + + private static final long serialVersionUID = -7622190783089299272L; + + private ImageOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify the image's fields to be returned by the RPC call. If this + * option is not provided, all image's fields are returned. {@code ImageOption.fields} can be + * used to specify only the fields of interest. {@link Image#imageId()} and + * {@link Image#configuration()} are always returned, even if not specified. + */ + public static ImageOption fields(ImageField... fields) { + return new ImageOption(ComputeRpc.Option.FIELDS, ImageField.selector(fields)); + } + } + + /** + * Class for specifying image list options. + */ + class ImageListOption extends Option { + + private static final long serialVersionUID = -4927977224287915654L; + + private ImageListOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify a filter on the images being listed. + */ + public static ImageListOption filter(ImageFilter filter) { + return new ImageListOption(ComputeRpc.Option.FILTER, filter.toPb()); + } + + /** + * Returns an option to specify the maximum number of images returned per page. {@code pageSize} + * must be between 0 and 500 (inclusive). If not specified 500 is used. + */ + public static ImageListOption pageSize(long pageSize) { + return new ImageListOption(ComputeRpc.Option.MAX_RESULTS, pageSize); + } + + /** + * Returns an option to specify the page token from which to start listing images. + */ + public static ImageListOption pageToken(String pageToken) { + return new ImageListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); + } + + /** + * Returns an option to specify the image's fields to be returned by the RPC call. If this + * option is not provided, all image's fields are returned. {@code ImageListOption.fields} can + * be used to specify only the fields of interest. {@link Image#imageId()} and + * {@link Image#configuration()} are always returned, even if not specified. + */ + public static ImageListOption fields(ImageField... fields) { + StringBuilder builder = new StringBuilder(); + builder.append("items(").append(ImageField.selector(fields)).append("),nextPageToken"); + return new ImageListOption(ComputeRpc.Option.FIELDS, builder.toString()); + } + } + /** * Returns the requested disk type or {@code null} if not found. * @@ -1699,4 +1815,57 @@ public static SnapshotListOption fields(SnapshotField... fields) { * Deleting a snapshot */ Operation deleteSnapshot(String snapshot, OperationOption... options); + + /** + * Creates a new image. + * + * @return a global operation for image's creation + * @throws ComputeException upon failure + */ + Operation create(ImageInfo image, OperationOption... options); + + /** + * Returns the requested image or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + Image get(ImageId imageId, ImageOption... options); + + /** + * Lists images in the provided project that are available to the current user. This method can be + * used to list publicly-available images by providing the respective image project. Examples of + * image projects are: {@code centos-cloud}, {@code coreos-cloud}, {@code debian-cloud}, + * {@code opensuse-cloud}, {@code rhel-cloud}, {@code suse-cloud}, {@code ubuntu-os-cloud} and + * {@code windows-cloud}. Attempting to delete or deprecate a publicly-available image will fail. + * + * @throws ComputeException upon failure + * @see Operating Systems + */ + Page listImages(String project, ImageListOption... options); + + /** + * Lists images in the current project. + * + * @throws ComputeException upon failure + */ + Page listImages(ImageListOption... options); + + /** + * Deletes the requested image. + * + * @return a global operation if the delete request was issued correctly, {@code null} if the + * image was not found + * @throws ComputeException upon failure or if {@code image} is a publicly-available image + */ + Operation delete(ImageId image, OperationOption... options); + + /** + * Deprecates the requested image. + * + * @return a global operation if the deprecation request was issued correctly, {@code null} if the + * image was not found + * @throws ComputeException upon failure or if {@code image} is a publicly-available image + */ + Operation deprecate(ImageId image, DeprecationStatus deprecationStatus, + OperationOption... options); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java index a348e1e0e253..1f875ad337f1 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java @@ -292,6 +292,27 @@ public Page nextPage() { } } + private static class ImagePageFetcher implements NextPageFetcher { + + private static final long serialVersionUID = 6403679803137922023L; + private final Map requestOptions; + private final ComputeOptions serviceOptions; + private final String project; + + ImagePageFetcher(String project, ComputeOptions serviceOptions, String cursor, + Map optionMap) { + this.requestOptions = + PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + this.project = project; + } + + @Override + public Page nextPage() { + return listImages(project, serviceOptions, requestOptions); + } + } + private final ComputeRpc computeRpc; ComputeImpl(ComputeOptions options) { @@ -1026,6 +1047,120 @@ public com.google.api.services.compute.model.Operation call() { } } + @Override + public Operation create(ImageInfo image, OperationOption... options) { + final ImageInfo completeImage = image.setProjectId(options().projectId()); + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.createImage(completeImage.toPb(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Image get(ImageId imageId, ImageOption... options) { + final ImageId completeImageId = imageId.setProjectId(options().projectId()); + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Image answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Image call() { + return computeRpc.getImage(completeImageId.project(), completeImageId.image(), + optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Image.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Page listImages(String project, ImageListOption... options) { + return listImages(project, options(), optionMap(options)); + } + + @Override + public Page listImages(ImageListOption... options) { + return listImages(options().projectId(), options(), optionMap(options)); + } + + private static Page listImages(final String project, final ComputeOptions serviceOptions, + final Map optionsMap) { + try { + ComputeRpc.Tuple> result = + runWithRetries(new Callable>>() { + @Override + public ComputeRpc.Tuple> call() { + return serviceOptions.rpc().listImages(project, optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.x(); + Iterable images = Iterables.transform( + result.y() == null ? ImmutableList.of() + : result.y(), + new Function() { + @Override + public Image apply(com.google.api.services.compute.model.Image image) { + return Image.fromPb(serviceOptions.service(), image); + } + }); + return new PageImpl<>(new ImagePageFetcher(project, serviceOptions, cursor, optionsMap), + cursor, images); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation delete(ImageId image, OperationOption... options) { + final ImageId completeId = image.setProjectId(options().projectId()); + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.deleteImage(completeId.project(), completeId.image(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation deprecate(ImageId image, + final DeprecationStatus deprecationStatus, OperationOption... options) { + final ImageId completeId = image.setProjectId(options().projectId()); + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.deprecateImage(completeId.project(), completeId.image(), + deprecationStatus.toPb(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + private Map optionMap(Option... options) { Map optionMap = Maps.newEnumMap(ComputeRpc.Option.class); for (Option option : options) { diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Image.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Image.java new file mode 100644 index 000000000000..7815929f3bf3 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Image.java @@ -0,0 +1,209 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.gcloud.compute.Compute.ImageOption; +import com.google.gcloud.compute.Compute.OperationOption; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.util.List; +import java.util.Objects; + +/** + * A Google Compute Engine Image. An image contains a boot loader, an operating system and a root + * file system that is necessary for starting an instance. Compute Engine offers publicly-available + * images of certain operating systems that you can use, or you can create a custom image. A custom + * image is an image created from one of your virtual machine instances that contains your specific + * instance configurations. To get an {@code Image} object with the most recent information use + * {@link #reload}. {@code Image} adds a layer of service-related functionality + * over {@link ImageInfo}. + * + * @see Images + */ +public class Image extends ImageInfo { + + private static final long serialVersionUID = 4623766590317494020L; + + private final ComputeOptions options; + private transient Compute compute; + + /** + * A builder for {@code Image} objects. + */ + public static class Builder extends ImageInfo.Builder { + + private final Compute compute; + private final ImageInfo.BuilderImpl infoBuilder; + + Builder(Compute compute, ImageId imageId, ImageConfiguration configuration) { + this.compute = compute; + this.infoBuilder = new ImageInfo.BuilderImpl(); + this.infoBuilder.imageId(imageId); + this.infoBuilder.configuration(configuration); + } + + Builder(Image image) { + this.compute = image.compute; + this.infoBuilder = new ImageInfo.BuilderImpl(image); + } + + @Override + Builder id(String id) { + infoBuilder.id(id); + return this; + } + + @Override + Builder creationTimestamp(Long creationTimestamp) { + infoBuilder.creationTimestamp(creationTimestamp); + return this; + } + + @Override + public Builder imageId(ImageId imageId) { + infoBuilder.imageId(imageId); + return this; + } + + @Override + public Builder description(String description) { + infoBuilder.description(description); + return this; + } + + @Override + public Builder configuration(ImageConfiguration configuration) { + infoBuilder.configuration(configuration); + return this; + } + + @Override + Builder status(Status status) { + infoBuilder.status(status); + return this; + } + + @Override + Builder diskSizeGb(Long diskSizeGb) { + infoBuilder.diskSizeGb(diskSizeGb); + return this; + } + + @Override + Builder licenses(List licenses) { + infoBuilder.licenses(licenses); + return this; + } + + @Override + Builder deprecationStatus(DeprecationStatus deprecationStatus) { + infoBuilder.deprecationStatus(deprecationStatus); + return this; + } + + @Override + public Image build() { + return new Image(compute, infoBuilder); + } + } + + Image(Compute compute, ImageInfo.BuilderImpl infoBuilder) { + super(infoBuilder); + this.compute = checkNotNull(compute); + this.options = compute.options(); + } + + /** + * Checks if this image exists. + * + * @return {@code true} if this image exists, {@code false} otherwise + * @throws ComputeException upon failure + */ + public boolean exists() { + return reload(ImageOption.fields()) != null; + } + + /** + * Fetches current image' latest information. Returns {@code null} if the image does not exist. + * + * @param options image options + * @return an {@code Image} object with latest information or {@code null} if not found + * @throws ComputeException upon failure + */ + public Image reload(ImageOption... options) { + return compute.get(imageId(), options); + } + + /** + * Deletes this image. + * + * @return a global operation if the delete request was successfully sent, {@code null} if the + * image was not found + * @throws ComputeException upon failure or if this image is a publicly-available image + */ + public Operation delete(OperationOption... options) { + return compute.delete(imageId(), options); + } + + /** + * Deprecates this image. + * + * @return a global operation if the deprecation request was successfully sent, {@code null} if + * the image was not found + * @throws ComputeException upon failure or if this image is a publicly-available image + */ + public Operation deprecate(DeprecationStatus deprecationStatus, + OperationOption... options) { + return compute.deprecate(imageId(), deprecationStatus, options); + } + + /** + * Returns the image's {@code Compute} object used to issue requests. + */ + public Compute compute() { + return compute; + } + + @Override + public Builder toBuilder() { + return new Builder(this); + } + + @Override + public final boolean equals(Object obj) { + return obj instanceof Image + && Objects.equals(toPb(), ((Image) obj).toPb()) + && Objects.equals(options, ((Image) obj).options); + } + + @Override + public final int hashCode() { + return Objects.hash(super.hashCode(), options); + } + + private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { + input.defaultReadObject(); + this.compute = options.service(); + } + + static Image fromPb(Compute compute, com.google.api.services.compute.model.Image imagePb) { + return new Image(compute, new ImageInfo.BuilderImpl(imagePb)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java index ff0831ece6e9..523686283db0 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java @@ -17,7 +17,9 @@ package com.google.gcloud.spi; import com.google.api.services.compute.model.Address; +import com.google.api.services.compute.model.DeprecationStatus; import com.google.api.services.compute.model.DiskType; +import com.google.api.services.compute.model.Image; import com.google.api.services.compute.model.License; import com.google.api.services.compute.model.MachineType; import com.google.api.services.compute.model.Operation; @@ -103,7 +105,7 @@ public Y y() { Tuple> listDiskTypes(String zone, Map options); /** - * Lists all disk types. + * Lists disk types. * * @throws ComputeException upon failure */ @@ -124,7 +126,7 @@ public Y y() { Tuple> listMachineTypes(String zone, Map options); /** - * Lists all machine types. + * Lists machine types. * * @throws ComputeException upon failure */ @@ -318,7 +320,7 @@ Operation createSnapshot(String zone, String disk, String snapshot, String descr Snapshot getSnapshot(String snapshot, Map options); /** - * Lists all snapshots. + * Lists snapshots. * * @throws ComputeException upon failure */ @@ -334,4 +336,45 @@ Operation createSnapshot(String zone, String disk, String snapshot, String descr * @throws ComputeException upon failure */ Operation deleteSnapshot(String snapshot, Map options); + + /** + * Creates a new image. + * + * @return a global operation for image's creation + * @throws ComputeException upon failure + */ + Operation createImage(Image image, Map options); + + /** + * Returns the requested image or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + Image getImage(String project, String image, Map options); + + /** + * Lists images in the provided project that are available to the current user. + * + * @throws ComputeException upon failure + */ + Tuple> listImages(String project, Map options); + + /** + * Deletes the requested image. + * + * @return a global operation if the delete request was issued correctly, {@code null} if the + * image was not found + * @throws ComputeException upon failure + */ + Operation deleteImage(String project, String image, Map options); + + /** + * Deprecates the requested image. + * + * @return a global operation if the deprecation request was issued correctly, {@code null} if the + * image was not found + * @throws ComputeException upon failure + */ + Operation deprecateImage(String project, String image, DeprecationStatus deprecationStatus, + Map options); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java index d41a879f5d91..7d0b77a7a73a 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java @@ -30,10 +30,13 @@ import com.google.api.services.compute.model.AddressAggregatedList; import com.google.api.services.compute.model.AddressList; import com.google.api.services.compute.model.AddressesScopedList; +import com.google.api.services.compute.model.DeprecationStatus; import com.google.api.services.compute.model.DiskType; import com.google.api.services.compute.model.DiskTypeAggregatedList; import com.google.api.services.compute.model.DiskTypeList; import com.google.api.services.compute.model.DiskTypesScopedList; +import com.google.api.services.compute.model.Image; +import com.google.api.services.compute.model.ImageList; import com.google.api.services.compute.model.License; import com.google.api.services.compute.model.MachineType; import com.google.api.services.compute.model.MachineTypeAggregatedList; @@ -564,6 +567,72 @@ public Operation deleteSnapshot(String snapshot, Map options) { } } + @Override + public Operation createImage(Image image, Map options) { + try { + return compute.images() + .insert(this.options.projectId(), image) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Image getImage(String project, String image, Map options) { + try { + return compute.images() + .get(project, image) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Tuple> listImages(String project, Map options) { + try { + ImageList imageList = compute.images() + .list(project) + .setFilter(FILTER.getString(options)) + .setMaxResults(MAX_RESULTS.getLong(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + .setFields(FIELDS.getString(options)) + .execute(); + Iterable images = imageList.getItems(); + return Tuple.of(imageList.getNextPageToken(), images); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Operation deleteImage(String project, String image, Map options) { + try { + return compute.images() + .delete(project, image) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Operation deprecateImage(String project, String image, DeprecationStatus deprecationStatus, + Map options) { + try { + return compute.images() + .deprecate(project, image, deprecationStatus) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + /** * This method returns {@code null} if the error code of {@code exception} was 404, re-throws the * exception otherwise. diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java index 9cff65dc7dad..ec981a95e0e7 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java @@ -42,6 +42,10 @@ import com.google.gcloud.compute.Compute.DiskTypeFilter; import com.google.gcloud.compute.Compute.DiskTypeListOption; import com.google.gcloud.compute.Compute.DiskTypeOption; +import com.google.gcloud.compute.Compute.ImageField; +import com.google.gcloud.compute.Compute.ImageFilter; +import com.google.gcloud.compute.Compute.ImageListOption; +import com.google.gcloud.compute.Compute.ImageOption; import com.google.gcloud.compute.Compute.LicenseOption; import com.google.gcloud.compute.Compute.MachineTypeAggregatedListOption; import com.google.gcloud.compute.Compute.MachineTypeFilter; @@ -190,6 +194,10 @@ public class ComputeImplTest { private static final DiskId DISK_ID = DiskId.of("project", "zone", "disk"); private static final SnapshotId SNAPSHOT_ID = SnapshotId.of("project", "snapshot"); private static final SnapshotInfo SNAPSHOT = SnapshotInfo.of(SNAPSHOT_ID, DISK_ID); + private static final ImageId IMAGE_ID = ImageId.of("project", "image"); + private static final ImageInfo IMAGE = ImageInfo.of(IMAGE_ID, DiskImageConfiguration.of(DISK_ID)); + private static final DeprecationStatus DEPRECATION_STATUS = + DeprecationStatus.builder(DeprecationStatus.Status.DEPRECATED, IMAGE_ID).build(); // Empty ComputeRpc options private static final Map EMPTY_RPC_OPTIONS = ImmutableMap.of(); @@ -337,7 +345,7 @@ public class ComputeImplTest { SnapshotFilter.equals(Compute.SnapshotField.DISK_SIZE_GB, 500L); private static final SnapshotListOption SNAPSHOT_LIST_PAGE_TOKEN = SnapshotListOption.pageToken("cursor"); - private static final SnapshotListOption SNAPSHOT_LIST_MAX_RESULTS = + private static final SnapshotListOption SNAPSHOT_LIST_PAGE_SIZE = SnapshotListOption.pageSize(42L); private static final SnapshotListOption SNAPSHOT_LIST_FILTER = SnapshotListOption.filter(SNAPSHOT_FILTER); @@ -346,6 +354,21 @@ public class ComputeImplTest { MAX_RESULTS, 42L, FILTER, "diskSizeGb eq 500"); + // Image options + private static final ImageOption IMAGE_OPTION_FIELDS = + ImageOption.fields(ImageField.ID, ImageField.DESCRIPTION); + + // Image list options + private static final ImageFilter IMAGE_FILTER = + ImageFilter.notEquals(ImageField.DISK_SIZE_GB, 500L); + private static final ImageListOption IMAGE_LIST_PAGE_TOKEN = ImageListOption.pageToken("cursor"); + private static final ImageListOption IMAGE_LIST_PAGE_SIZE = ImageListOption.pageSize(42L); + private static final ImageListOption IMAGE_LIST_FILTER = ImageListOption.filter(IMAGE_FILTER); + private static final Map IMAGE_LIST_OPTIONS = ImmutableMap.of( + PAGE_TOKEN, "cursor", + MAX_RESULTS, 42L, + FILTER, "diskSizeGb ne 500"); + private static final Function OPERATION_TO_PB_FUNCTION = new Function() { @@ -2045,6 +2068,32 @@ public void testListSnapshots() { assertArrayEquals(snapshotList.toArray(), Iterables.toArray(page.values(), Snapshot.class)); } + @Test + public void testListSnapshotsNextPage() { + String cursor = "cursor"; + String nextCursor = "nextCursor"; + compute = options.service(); + ImmutableList snapshotList = ImmutableList.of( + new Snapshot(compute, new SnapshotInfo.BuilderImpl(SNAPSHOT)), + new Snapshot(compute, new SnapshotInfo.BuilderImpl(SNAPSHOT))); + ImmutableList nextSnapshotList = ImmutableList.of( + new Snapshot(compute, new SnapshotInfo.BuilderImpl(SNAPSHOT))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(snapshotList, SnapshotInfo.TO_PB_FUNCTION)); + Tuple> nextResult = + Tuple.of(nextCursor, Iterables.transform(nextSnapshotList, SnapshotInfo.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + EasyMock.expect(computeRpcMock.listSnapshots(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.expect(computeRpcMock.listSnapshots(nextOptions)).andReturn(nextResult); + EasyMock.replay(computeRpcMock); + Page page = compute.listSnapshots(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(snapshotList.toArray(), Iterables.toArray(page.values(), Snapshot.class)); + page = page.nextPage(); + assertEquals(nextCursor, page.nextPageCursor()); + assertArrayEquals(nextSnapshotList.toArray(), Iterables.toArray(page.values(), Snapshot.class)); + } + @Test public void testListEmptySnapshots() { compute = options.service(); @@ -2069,12 +2118,264 @@ public void testListSnapshotsWithOptions() { Tuple.of(cursor, Iterables.transform(snapshotList, SnapshotInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listSnapshots(SNAPSHOT_LIST_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); - Page page = compute.listSnapshots(SNAPSHOT_LIST_MAX_RESULTS, SNAPSHOT_LIST_PAGE_TOKEN, + Page page = compute.listSnapshots(SNAPSHOT_LIST_PAGE_SIZE, SNAPSHOT_LIST_PAGE_TOKEN, SNAPSHOT_LIST_FILTER); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(snapshotList.toArray(), Iterables.toArray(page.values(), Snapshot.class)); } + @Test + public void testCreateImage() { + EasyMock.expect(computeRpcMock.createImage(IMAGE.toPb(), EMPTY_RPC_OPTIONS)) + .andReturn(globalOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.create(IMAGE); + assertEquals(globalOperation, operation); + } + + @Test + public void testCreateImageWithOptions() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.createImage(eq(IMAGE.toPb()), capture(capturedOptions))) + .andReturn(globalOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.create(IMAGE, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(globalOperation, operation); + } + + @Test + public void testGetImage() { + EasyMock.expect( + computeRpcMock.getImage(IMAGE_ID.project(), IMAGE_ID.image(), EMPTY_RPC_OPTIONS)) + .andReturn(IMAGE.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Image image = compute.get(IMAGE_ID); + assertEquals(new Image(compute, new ImageInfo.BuilderImpl(IMAGE)), image); + } + + @Test + public void testGetImage_Null() { + EasyMock.expect( + computeRpcMock.getImage(IMAGE_ID.project(), IMAGE_ID.image(), EMPTY_RPC_OPTIONS)) + .andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.get(IMAGE_ID)); + } + + @Test + public void testGetImageWithSelectedFields() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.getImage(eq(IMAGE_ID.project()), eq(IMAGE_ID.image()), + capture(capturedOptions))).andReturn(IMAGE.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Image image = compute.get(IMAGE_ID, IMAGE_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(IMAGE_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("sourceDisk")); + assertTrue(selector.contains("rawDisk")); + assertTrue(selector.contains("description")); + assertEquals(42, selector.length()); + assertEquals(new Image(compute, new ImageInfo.BuilderImpl(IMAGE)), image); + } + + @Test + public void testDeleteImage_Operation() { + EasyMock.expect(computeRpcMock.deleteImage(IMAGE_ID.project(), IMAGE_ID.image(), + EMPTY_RPC_OPTIONS)).andReturn(globalOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(globalOperation, compute.delete(IMAGE_ID)); + } + + @Test + public void testDeleteImageWithSelectedFields_Operation() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.deleteImage(eq(PROJECT), eq(IMAGE_ID.image()), + capture(capturedOptions))).andReturn(globalOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.delete(ImageId.of("image"), OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(globalOperation, operation); + } + + @Test + public void testDeleteImage_Null() { + EasyMock.expect(computeRpcMock.deleteImage(IMAGE_ID.project(), IMAGE_ID.image(), + EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.delete(IMAGE_ID)); + } + + @Test + public void testDeprecateImage_Operation() { + EasyMock.expect(computeRpcMock.deprecateImage(IMAGE_ID.project(), IMAGE_ID.image(), + DEPRECATION_STATUS.toPb(), EMPTY_RPC_OPTIONS)).andReturn(globalOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(globalOperation, compute.deprecate(IMAGE_ID, DEPRECATION_STATUS)); + } + + @Test + public void testDeprecateImageWithSelectedFields_Operation() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.deprecateImage(eq(PROJECT), eq(IMAGE_ID.image()), + eq(DEPRECATION_STATUS.toPb()), capture(capturedOptions))).andReturn(globalOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = + compute.deprecate(ImageId.of("image"), DEPRECATION_STATUS, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(globalOperation, operation); + } + + @Test + public void testDeprecateImage_Null() { + EasyMock.expect(computeRpcMock.deprecateImage(IMAGE_ID.project(), IMAGE_ID.image(), + DEPRECATION_STATUS.toPb(), EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.deprecate(IMAGE_ID, DEPRECATION_STATUS)); + } + + @Test + public void testListImages() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList imageList = ImmutableList.of( + new Image(compute, new ImageInfo.BuilderImpl(IMAGE)), + new Image(compute, new ImageInfo.BuilderImpl(IMAGE))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(imageList, ImageInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listImages(PROJECT, EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listImages(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(imageList.toArray(), Iterables.toArray(page.values(), Image.class)); + } + + @Test + public void testListImagesNextPage() { + String cursor = "cursor"; + String nextCursor = "nextCursor"; + compute = options.service(); + ImmutableList imageList = ImmutableList.of( + new Image(compute, new ImageInfo.BuilderImpl(IMAGE)), + new Image(compute, new ImageInfo.BuilderImpl(IMAGE))); + ImmutableList nextImageList = ImmutableList.of( + new Image(compute, new ImageInfo.BuilderImpl(IMAGE))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(imageList, ImageInfo.TO_PB_FUNCTION)); + Tuple> nextResult = + Tuple.of(nextCursor, Iterables.transform(nextImageList, ImageInfo.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + EasyMock.expect(computeRpcMock.listImages(PROJECT, EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.expect(computeRpcMock.listImages(PROJECT, nextOptions)).andReturn(nextResult); + EasyMock.replay(computeRpcMock); + Page page = compute.listImages(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(imageList.toArray(), Iterables.toArray(page.values(), Image.class)); + page = page.nextPage(); + assertEquals(nextCursor, page.nextPageCursor()); + assertArrayEquals(nextImageList.toArray(), Iterables.toArray(page.values(), Image.class)); + } + + @Test + public void testListImagesForProject() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList imageList = ImmutableList.of( + new Image(compute, new ImageInfo.BuilderImpl(IMAGE)), + new Image(compute, new ImageInfo.BuilderImpl(IMAGE))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(imageList, ImageInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listImages("otherProject", EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listImages("otherProject"); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(imageList.toArray(), Iterables.toArray(page.values(), Image.class)); + } + + @Test + public void testListEmptyImages() { + compute = options.service(); + ImmutableList images = ImmutableList.of(); + Tuple> result = + Tuple.>of(null, images); + EasyMock.expect(computeRpcMock.listImages(PROJECT, EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listImages(); + assertNull(page.nextPageCursor()); + assertArrayEquals(images.toArray(), Iterables.toArray(page.values(), Image.class)); + } + + @Test + public void testListEmptyImagesForProject() { + compute = options.service(); + ImmutableList images = ImmutableList.of(); + Tuple> result = + Tuple.>of(null, images); + EasyMock.expect(computeRpcMock.listImages("otherProject", EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listImages("otherProject"); + assertNull(page.nextPageCursor()); + assertArrayEquals(images.toArray(), Iterables.toArray(page.values(), Image.class)); + } + + @Test + public void testListImagesWithOptions() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList imageList = ImmutableList.of( + new Image(compute, new ImageInfo.BuilderImpl(IMAGE)), + new Image(compute, new ImageInfo.BuilderImpl(IMAGE))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(imageList, ImageInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listImages(PROJECT, IMAGE_LIST_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listImages(IMAGE_LIST_PAGE_SIZE, IMAGE_LIST_PAGE_TOKEN, + IMAGE_LIST_FILTER); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(imageList.toArray(), Iterables.toArray(page.values(), Image.class)); + } + + @Test + public void testListImagesForProjectWithOptions() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList imageList = ImmutableList.of( + new Image(compute, new ImageInfo.BuilderImpl(IMAGE)), + new Image(compute, new ImageInfo.BuilderImpl(IMAGE))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(imageList, ImageInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listImages("other", IMAGE_LIST_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listImages("other", IMAGE_LIST_PAGE_SIZE, IMAGE_LIST_PAGE_TOKEN, + IMAGE_LIST_FILTER); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(imageList.toArray(), Iterables.toArray(page.values(), Image.class)); + } + @Test public void testRetryableException() { EasyMock.expect( diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageTest.java new file mode 100644 index 000000000000..dcf7e2513e07 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageTest.java @@ -0,0 +1,306 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.createStrictMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import com.google.common.collect.ImmutableList; +import com.google.gcloud.compute.DeprecationStatus.Status; +import com.google.gcloud.compute.ImageConfiguration.SourceType; + +import org.junit.Test; + +import java.util.List; + +public class ImageTest { + + private static final ImageId IMAGE_ID = ImageId.of("project", "image"); + private static final String ID = "42"; + private static final Long CREATION_TIMESTAMP = 1453293540000L; + private static final String DESCRIPTION = "description"; + private static final ImageInfo.Status STATUS = ImageInfo.Status.READY; + private static final List LICENSES = ImmutableList.of( + LicenseId.of("project", "license1"), LicenseId.of("project", "license2")); + private static final Long DISK_SIZE_GB = 42L; + private static final String STORAGE_SOURCE = "source"; + private static final Long ARCHIVE_SIZE_BYTES = 24L; + private static final String SHA1_CHECKSUM = "checksum"; + private static final DiskId SOURCE_DISK = DiskId.of("project", "zone", "disk"); + private static final String SOURCE_DISK_ID = "diskId"; + private static final SourceType SOURCE_TYPE = SourceType.RAW; + private static final StorageImageConfiguration STORAGE_CONFIGURATION = + StorageImageConfiguration.builder(STORAGE_SOURCE) + .archiveSizeBytes(ARCHIVE_SIZE_BYTES) + .containerType(StorageImageConfiguration.ContainerType.TAR) + .sha1(SHA1_CHECKSUM) + .sourceType(SOURCE_TYPE) + .build(); + private static final DiskImageConfiguration DISK_CONFIGURATION = + DiskImageConfiguration.builder(SOURCE_DISK) + .archiveSizeBytes(ARCHIVE_SIZE_BYTES) + .sourceDiskId(SOURCE_DISK_ID) + .sourceType(SOURCE_TYPE) + .build(); + private static final DeprecationStatus DEPRECATION_STATUS = + DeprecationStatus.of(Status.DELETED, IMAGE_ID); + + private final Compute serviceMockReturnsOptions = createStrictMock(Compute.class); + private final ComputeOptions mockOptions = createMock(ComputeOptions.class); + private Compute compute; + private Image image; + private Image diskImage; + private Image storageImage; + + private void initializeExpectedImage(int optionsCalls) { + expect(serviceMockReturnsOptions.options()).andReturn(mockOptions).times(optionsCalls); + replay(serviceMockReturnsOptions); + diskImage = new Image.Builder(serviceMockReturnsOptions, IMAGE_ID, DISK_CONFIGURATION) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .status(STATUS) + .diskSizeGb(DISK_SIZE_GB) + .licenses(LICENSES) + .deprecationStatus(DEPRECATION_STATUS) + .build(); + storageImage = new Image.Builder(serviceMockReturnsOptions, IMAGE_ID, STORAGE_CONFIGURATION) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .status(STATUS) + .diskSizeGb(DISK_SIZE_GB) + .licenses(LICENSES) + .deprecationStatus(DEPRECATION_STATUS) + .build(); + compute = createStrictMock(Compute.class); + } + + private void initializeImage() { + image = new Image.Builder(compute, IMAGE_ID, DISK_CONFIGURATION) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .status(STATUS) + .diskSizeGb(DISK_SIZE_GB) + .licenses(LICENSES) + .deprecationStatus(DEPRECATION_STATUS) + .build(); + } + + @Test + public void testToBuilder() { + initializeExpectedImage(12); + compareImage(diskImage, diskImage.toBuilder().build()); + compareImage(storageImage, storageImage.toBuilder().build()); + Image newImage = diskImage.toBuilder().description("newDescription").build(); + assertEquals("newDescription", newImage.description()); + newImage = newImage.toBuilder().description("description").build(); + compareImage(diskImage, newImage); + } + + @Test + public void testToBuilderIncomplete() { + initializeExpectedImage(6); + ImageInfo imageInfo = ImageInfo.of(IMAGE_ID, DISK_CONFIGURATION); + Image image = + new Image(serviceMockReturnsOptions, new ImageInfo.BuilderImpl(imageInfo)); + compareImage(image, image.toBuilder().build()); + } + + @Test + public void testBuilder() { + initializeExpectedImage(3); + assertEquals(ID, diskImage.id()); + assertEquals(IMAGE_ID, diskImage.imageId()); + assertEquals(CREATION_TIMESTAMP, diskImage.creationTimestamp()); + assertEquals(DESCRIPTION, diskImage.description()); + assertEquals(DISK_CONFIGURATION, diskImage.configuration()); + assertEquals(STATUS, diskImage.status()); + assertEquals(DISK_SIZE_GB, diskImage.diskSizeGb()); + assertEquals(LICENSES, diskImage.licenses()); + assertEquals(DEPRECATION_STATUS, diskImage.deprecationStatus()); + assertSame(serviceMockReturnsOptions, diskImage.compute()); + assertEquals(ID, storageImage.id()); + assertEquals(IMAGE_ID, storageImage.imageId()); + assertEquals(CREATION_TIMESTAMP, storageImage.creationTimestamp()); + assertEquals(DESCRIPTION, storageImage.description()); + assertEquals(STORAGE_CONFIGURATION, storageImage.configuration()); + assertEquals(STATUS, storageImage.status()); + assertEquals(DISK_SIZE_GB, storageImage.diskSizeGb()); + assertEquals(LICENSES, storageImage.licenses()); + assertEquals(DEPRECATION_STATUS, storageImage.deprecationStatus()); + assertSame(serviceMockReturnsOptions, storageImage.compute()); + ImageId imageId = ImageId.of("otherImage"); + Image image = new Image.Builder(serviceMockReturnsOptions, IMAGE_ID, STORAGE_CONFIGURATION) + .imageId(imageId) + .configuration(DISK_CONFIGURATION) + .build(); + assertNull(image.id()); + assertEquals(imageId, image.imageId()); + assertNull(image.creationTimestamp()); + assertNull(image.description()); + assertEquals(DISK_CONFIGURATION, image.configuration()); + assertNull(image.status()); + assertNull(image.diskSizeGb()); + assertNull(image.licenses()); + assertNull(image.deprecationStatus()); + assertSame(serviceMockReturnsOptions, image.compute()); + } + + @Test + public void testToAndFromPb() { + initializeExpectedImage(12); + compareImage(diskImage, + Image.fromPb(serviceMockReturnsOptions, diskImage.toPb())); + compareImage(storageImage, + Image.fromPb(serviceMockReturnsOptions, storageImage.toPb())); + Image image = + new Image.Builder(serviceMockReturnsOptions, IMAGE_ID, DISK_CONFIGURATION).build(); + compareImage(image, Image.fromPb(serviceMockReturnsOptions, image.toPb())); + } + + @Test + public void testDeleteOperation() { + initializeExpectedImage(3); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(GlobalOperationId.of("project", "op")) + .build(); + expect(compute.delete(IMAGE_ID)).andReturn(operation); + replay(compute); + initializeImage(); + assertSame(operation, image.delete()); + } + + @Test + public void testDeleteNull() { + initializeExpectedImage(2); + expect(compute.options()).andReturn(mockOptions); + expect(compute.delete(IMAGE_ID)).andReturn(null); + replay(compute); + initializeImage(); + assertNull(image.delete()); + } + + @Test + public void testExists_True() throws Exception { + initializeExpectedImage(2); + Compute.ImageOption[] expectedOptions = {Compute.ImageOption.fields()}; + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(IMAGE_ID, expectedOptions)).andReturn(diskImage); + replay(compute); + initializeImage(); + assertTrue(image.exists()); + verify(compute); + } + + @Test + public void testExists_False() throws Exception { + initializeExpectedImage(2); + Compute.ImageOption[] expectedOptions = {Compute.ImageOption.fields()}; + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(IMAGE_ID, expectedOptions)).andReturn(null); + replay(compute); + initializeImage(); + assertFalse(image.exists()); + verify(compute); + } + + @Test + public void testReload() throws Exception { + initializeExpectedImage(5); + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(IMAGE_ID)).andReturn(storageImage); + replay(compute); + initializeImage(); + Image updateImage = image.reload(); + compareImage(storageImage, updateImage); + verify(compute); + } + + @Test + public void testReloadNull() throws Exception { + initializeExpectedImage(2); + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(IMAGE_ID)).andReturn(null); + replay(compute); + initializeImage(); + assertNull(image.reload()); + verify(compute); + } + + @Test + public void testReloadWithOptions() throws Exception { + initializeExpectedImage(5); + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(IMAGE_ID, Compute.ImageOption.fields())).andReturn(storageImage); + replay(compute); + initializeImage(); + Image updateImage = image.reload(Compute.ImageOption.fields()); + compareImage(storageImage, updateImage); + verify(compute); + } + + @Test + public void testDeprecateImage() { + initializeExpectedImage(3); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(GlobalOperationId.of("project", "op")) + .build(); + DeprecationStatus status = DeprecationStatus.of(Status.DEPRECATED, IMAGE_ID); + expect(compute.deprecate(IMAGE_ID, status)).andReturn(operation); + replay(compute); + initializeImage(); + assertSame(operation, image.deprecate(status)); + } + + @Test + public void testDeprecateNull() { + initializeExpectedImage(2); + expect(compute.options()).andReturn(mockOptions); + DeprecationStatus status = DeprecationStatus.of(Status.DEPRECATED, IMAGE_ID); + expect(compute.deprecate(IMAGE_ID, status)).andReturn(null); + replay(compute); + initializeImage(); + assertNull(image.deprecate(status)); + } + + public void compareImage(Image expected, Image value) { + assertEquals(expected, value); + assertEquals(expected.compute().options(), value.compute().options()); + assertEquals(expected.id(), value.id()); + assertEquals(expected.imageId(), value.imageId()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.configuration(), value.configuration()); + assertEquals(expected.status(), value.status()); + assertEquals(expected.diskSizeGb(), value.diskSizeGb()); + assertEquals(expected.licenses(), value.licenses()); + assertEquals(expected.deprecationStatus(), value.deprecationStatus()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java index b533ae9c6ae7..0251dca1fc39 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java @@ -151,9 +151,11 @@ public class SerializationTest { private static final ImageId IMAGE_ID = ImageId.of("project", "image"); private static final DiskImageConfiguration DISK_IMAGE_CONFIGURATION = DiskImageConfiguration.of(DISK_ID); - private static final StorageImageConfiguration RAW_IMAGE_CONFIGURATION = + private static final StorageImageConfiguration STORAGE_IMAGE_CONFIGURATION = StorageImageConfiguration.of("gs:/bucket/file"); private static final ImageInfo IMAGE_INFO = ImageInfo.of(IMAGE_ID, DISK_IMAGE_CONFIGURATION); + private static final Image IMAGE = + new Image.Builder(COMPUTE, IMAGE_ID, DISK_IMAGE_CONFIGURATION).build(); private static final Compute.DiskTypeOption DISK_TYPE_OPTION = Compute.DiskTypeOption.fields(); private static final Compute.DiskTypeFilter DISK_TYPE_FILTER = @@ -198,6 +200,11 @@ public class SerializationTest { Compute.SnapshotFilter.equals(Compute.SnapshotField.SELF_LINK, "selfLink"); private static final Compute.SnapshotListOption SNAPSHOT_LIST_OPTION = Compute.SnapshotListOption.filter(SNAPSHOT_FILTER); + private static final Compute.ImageOption IMAGE_OPTION = Compute.ImageOption.fields(); + private static final Compute.ImageFilter IMAGE_FILTER = + Compute.ImageFilter.equals(Compute.ImageField.SELF_LINK, "selfLink"); + private static final Compute.ImageListOption IMAGE_LIST_OPTION = + Compute.ImageListOption.filter(IMAGE_FILTER); @Test public void testServiceOptions() throws Exception { @@ -225,14 +232,14 @@ public void testModelAndRequests() throws Exception { INSTANCE_ID, REGION_FORWARDING_RULE_ID, GLOBAL_FORWARDING_RULE_ID, GLOBAL_ADDRESS_ID, REGION_ADDRESS_ID, INSTANCE_USAGE, GLOBAL_FORWARDING_USAGE, REGION_FORWARDING_USAGE, ADDRESS_INFO, ADDRESS, DISK_ID, SNAPSHOT_ID, SNAPSHOT_INFO, SNAPSHOT, IMAGE_ID, - DISK_IMAGE_CONFIGURATION, RAW_IMAGE_CONFIGURATION, IMAGE_INFO, DISK_TYPE_OPTION, + DISK_IMAGE_CONFIGURATION, STORAGE_IMAGE_CONFIGURATION, IMAGE_INFO, IMAGE, DISK_TYPE_OPTION, DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, DISK_TYPE_AGGREGATED_LIST_OPTION, MACHINE_TYPE_OPTION, MACHINE_TYPE_FILTER, MACHINE_TYPE_LIST_OPTION, MACHINE_TYPE_AGGREGATED_LIST_OPTION, REGION_OPTION, REGION_FILTER, REGION_LIST_OPTION, ZONE_OPTION, ZONE_FILTER, ZONE_LIST_OPTION, LICENSE_OPTION, OPERATION_OPTION, OPERATION_FILTER, OPERATION_LIST_OPTION, ADDRESS_OPTION, ADDRESS_FILTER, ADDRESS_LIST_OPTION, ADDRESS_AGGREGATED_LIST_OPTION, SNAPSHOT_OPTION, SNAPSHOT_FILTER, - SNAPSHOT_LIST_OPTION}; + SNAPSHOT_LIST_OPTION, IMAGE_OPTION, IMAGE_FILTER, IMAGE_LIST_OPTION}; for (Serializable obj : objects) { Object copy = serializeAndDeserialize(obj); assertEquals(obj, obj); From e7866b281cdce0a17565f89d879d98c1537dfd3a Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 7 Apr 2016 10:17:54 +0200 Subject: [PATCH 309/375] Add DiskInfo, disk configurations and test classes Add DiskInfo, disk configurations and test classes --- .../gcloud/compute/DiskConfiguration.java | 203 ++++++++ .../compute/DiskImageConfiguration.java | 2 +- .../com/google/gcloud/compute/DiskInfo.java | 442 ++++++++++++++++++ .../gcloud/compute/ImageConfiguration.java | 4 +- .../compute/ImageDiskConfiguration.java | 174 +++++++ .../compute/SnapshotDiskConfiguration.java | 181 +++++++ .../compute/StandardDiskConfiguration.java | 128 +++++ .../compute/StorageImageConfiguration.java | 2 +- .../google/gcloud/compute/DiskInfoTest.java | 268 +++++++++++ .../compute/ImageDiskConfigurationTest.java | 112 +++++ .../gcloud/compute/SerializationTest.java | 20 +- .../SnapshotDiskConfigurationTest.java | 112 +++++ .../StandardDiskConfigurationTest.java | 103 ++++ 13 files changed, 1741 insertions(+), 10 deletions(-) create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskConfiguration.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskInfo.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageDiskConfiguration.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotDiskConfiguration.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/StandardDiskConfiguration.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskInfoTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageDiskConfigurationTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotDiskConfigurationTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/StandardDiskConfigurationTest.java diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskConfiguration.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskConfiguration.java new file mode 100644 index 000000000000..0c48e3442515 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskConfiguration.java @@ -0,0 +1,203 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import com.google.api.services.compute.model.Disk; +import com.google.common.base.MoreObjects; +import com.google.common.base.MoreObjects.ToStringHelper; + +import java.io.Serializable; +import java.util.Objects; + +/** + * Base class for Google Compute Engine disk configurations. A disk can be used as primary storage + * for your virtual machine instances. Use {@link StandardDiskConfiguration} to create a standard + * disk given a disk type and size. Use {@link ImageDiskConfiguration} to create a disk from a + * Compute Engine disk image. Use {@link SnapshotDiskConfiguration} to create a disk from a Compute + * Engine disk snapshot. + * + * @see Block Storage + */ +public abstract class DiskConfiguration implements Serializable { + + private static final long serialVersionUID = -1783061701255428417L; + + private final Type type; + private final Long sizeGb; + private final DiskTypeId diskType; + + /** + * Type of a Google Compute Engine disk configuration. + */ + public enum Type { + /** + * A Google Compute Engine standard disk configuration. + */ + STANDARD, + + /** + * A Google Compute Engine disk configuration that creates a disk from an image. + */ + IMAGE, + + /** + * A Google Compute Engine disk configuration that creates a disk from a snapshot. + */ + SNAPSHOT + } + + /** + * Base builder for disk configurations. + * + * @param the disk configuration type + * @param the disk configuration builder + */ + public abstract static class Builder> { + + private Type type; + private Long sizeGb; + private DiskTypeId diskType; + + Builder(Type type) { + this.type = type; + } + + Builder(DiskConfiguration diskConfiguration) { + this.type = diskConfiguration.type; + this.sizeGb = diskConfiguration.sizeGb; + this.diskType = diskConfiguration.diskType; + } + + Builder(Type type, Disk diskPb) { + this.type = type; + this.sizeGb = diskPb.getSizeGb(); + if (diskPb.getType() != null) { + this.diskType = DiskTypeId.fromUrl(diskPb.getType()); + } + } + + @SuppressWarnings("unchecked") + protected B self() { + return (B) this; + } + + B type(Type type) { + this.type = type; + return self(); + } + + /** + * Sets the size of the persistent disk, in GB. + */ + public B sizeGb(Long sizeGb) { + this.sizeGb = sizeGb; + return self(); + } + + /** + * Sets the identity of the disk type. If not set {@code pd-standard} will be used. + */ + public B diskType(DiskTypeId diskType) { + this.diskType = diskType; + return self(); + } + + /** + * Creates an object. + */ + public abstract T build(); + } + + DiskConfiguration(Builder builder) { + this.type = builder.type; + this.sizeGb = builder.sizeGb; + this.diskType = builder.diskType; + } + + /** + * Returns the disk configuration's type. This method returns {@link Type#STANDARD} for a standard + * configuration that creates a disk given its type and size. This method returns + * {@link Type#SNAPSHOT} for a configuration that creates a disk from a Google Compute Engine + * snapshot. This method returns {@link Type#IMAGE} for a configuration that creates a disk + * from a Google Compute Engine image. + */ + public Type type() { + return type; + } + + /** + * Returns the size of the persistent disk, in GB. + */ + public Long sizeGb() { + return sizeGb; + } + + /** + * Returns the identity of the disk type. + */ + public DiskTypeId diskType() { + return diskType; + } + + /** + * Returns a builder for the object. + */ + public abstract Builder toBuilder(); + + ToStringHelper toStringHelper() { + return MoreObjects.toStringHelper(this) + .add("type", type) + .add("sizeGb", sizeGb) + .add("diskType", diskType); + } + + @Override + public String toString() { + return toStringHelper().toString(); + } + + final int baseHashCode() { + return Objects.hash(type, sizeGb, diskType); + } + + final boolean baseEquals(DiskConfiguration diskConfiguration) { + return diskConfiguration != null + && getClass().equals(diskConfiguration.getClass()) + && Objects.equals(toPb(), diskConfiguration.toPb()); + } + + abstract DiskConfiguration setProjectId(String projectId); + + Disk toPb() { + Disk diskPb = new Disk(); + diskPb.setSizeGb(sizeGb); + if (diskType != null) { + diskPb.setType(diskType.selfLink()); + } + return diskPb; + } + + @SuppressWarnings("unchecked") + static T fromPb(Disk diskPb) { + if (diskPb.getSourceImage() != null) { + return (T) ImageDiskConfiguration.fromPb(diskPb); + } else if (diskPb.getSourceSnapshot() != null) { + return (T) SnapshotDiskConfiguration.fromPb(diskPb); + } + return (T) StandardDiskConfiguration.fromPb(diskPb); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskImageConfiguration.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskImageConfiguration.java index b8b0857b3963..51b6cb912272 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskImageConfiguration.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskImageConfiguration.java @@ -48,7 +48,7 @@ private Builder() { } private Builder(DiskImageConfiguration imageConfiguration) { - super(Type.DISK, imageConfiguration); + super(imageConfiguration); this.sourceDisk = imageConfiguration.sourceDisk; this.sourceDiskId = imageConfiguration.sourceDiskId; } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskInfo.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskInfo.java new file mode 100644 index 000000000000..1f55b4256a30 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskInfo.java @@ -0,0 +1,442 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.api.services.compute.model.Disk; +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; + +import java.io.Serializable; +import java.math.BigInteger; +import java.util.List; +import java.util.Objects; + +/** + * A Google Compute Engine persistent disk. A disk can be used as primary storage for your virtual + * machine instances. + * + * @see Block Storage + */ +public class DiskInfo implements Serializable { + + static final Function FROM_PB_FUNCTION = + new Function() { + @Override + public DiskInfo apply(Disk pb) { + return DiskInfo.fromPb(pb); + } + }; + static final Function TO_PB_FUNCTION = + new Function() { + @Override + public Disk apply(DiskInfo diskType) { + return diskType.toPb(); + } + }; + + private static final long serialVersionUID = -7173418340679279619L; + private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); + + private final String id; + private final DiskId diskId; + private final DiskConfiguration configuration; + private final Long creationTimestamp; + private final CreationStatus creationStatus; + private final String description; + private final List licenses; + private final List attachedInstances; + private final Long lastAttachTimestamp; + private final Long lastDetachTimestamp; + + /** + * The status of disk creation. + */ + public enum CreationStatus { + /** + * The disk is being created. + */ + CREATING, + + /** + * Disk creation failed. + */ + FAILED, + + /** + * The disk has been created and is ready to use. + */ + READY, + + /** + * The disk is being restored. + */ + RESTORING + } + + /** + * Builder for {@code DiskInfo} objects. + */ + public abstract static class Builder { + + abstract Builder id(String id); + + /** + * Sets the disk configuration. + */ + public abstract Builder configuration(DiskConfiguration configuration); + + /** + * Sets the disk identity. + */ + public abstract Builder diskId(DiskId diskId); + + abstract Builder creationTimestamp(Long creationTimestamp); + + abstract Builder creationStatus(CreationStatus creationStatus); + + /** + * Sets an optional textual description of the resource. + */ + public abstract Builder description(String description); + + abstract Builder licenses(List licenses); + + abstract Builder attachedInstances(List attachedInstances); + + abstract Builder lastAttachTimestamp(Long lastAttachTimestamp); + + abstract Builder lastDetachTimestamp(Long lastDetachTimestamp); + + /** + * Creates a {@code DiskInfo} object. + */ + public abstract DiskInfo build(); + } + + static final class BuilderImpl extends Builder { + + private String id; + private DiskId diskId; + private DiskConfiguration configuration; + private Long creationTimestamp; + private CreationStatus creationStatus; + private String description; + private List licenses; + private List attachedInstances; + private Long lastAttachTimestamp; + private Long lastDetachTimestamp; + + BuilderImpl(DiskId diskId, DiskConfiguration configuration) { + this.diskId = checkNotNull(diskId); + this.configuration = checkNotNull(configuration); + } + + BuilderImpl(DiskInfo diskInfo) { + this.id = diskInfo.id; + this.configuration = diskInfo.configuration; + this.creationTimestamp = diskInfo.creationTimestamp; + this.creationStatus = diskInfo.creationStatus; + this.diskId = diskInfo.diskId; + this.description = diskInfo.description; + this.licenses = diskInfo.licenses; + this.attachedInstances = diskInfo.attachedInstances; + this.lastAttachTimestamp = diskInfo.lastAttachTimestamp; + this.lastDetachTimestamp = diskInfo.lastDetachTimestamp; + } + + BuilderImpl(Disk diskPb) { + if (diskPb.getId() != null) { + this.id = diskPb.getId().toString(); + } + this.configuration = DiskConfiguration.fromPb(diskPb); + if (diskPb.getCreationTimestamp() != null) { + this.creationTimestamp = TIMESTAMP_FORMATTER.parseMillis(diskPb.getCreationTimestamp()); + } + if (diskPb.getStatus() != null) { + this.creationStatus = CreationStatus.valueOf(diskPb.getStatus()); + } + this.diskId = DiskId.fromUrl(diskPb.getSelfLink()); + this.description = diskPb.getDescription(); + if (diskPb.getLicenses() != null) { + this.licenses = Lists.transform(diskPb.getLicenses(), LicenseId.FROM_URL_FUNCTION); + } + if (diskPb.getUsers() != null) { + this.attachedInstances = Lists.transform(diskPb.getUsers(), InstanceId.FROM_URL_FUNCTION); + } + if (diskPb.getLastAttachTimestamp() != null) { + this.lastAttachTimestamp = TIMESTAMP_FORMATTER.parseMillis(diskPb.getLastAttachTimestamp()); + } + if (diskPb.getLastDetachTimestamp() != null) { + this.lastDetachTimestamp = TIMESTAMP_FORMATTER.parseMillis(diskPb.getLastDetachTimestamp()); + } + } + + @Override + BuilderImpl id(String id) { + this.id = id; + return this; + } + + @Override + public BuilderImpl configuration(DiskConfiguration configuration) { + this.configuration = checkNotNull(configuration); + return this; + } + + @Override + public BuilderImpl diskId(DiskId diskId) { + this.diskId = checkNotNull(diskId); + return this; + } + + @Override + BuilderImpl creationTimestamp(Long creationTimestamp) { + this.creationTimestamp = creationTimestamp; + return this; + } + + @Override + BuilderImpl creationStatus(CreationStatus creationStatus) { + this.creationStatus = creationStatus; + return this; + } + + @Override + public BuilderImpl description(String description) { + this.description = description; + return this; + } + + @Override + BuilderImpl licenses(List licenses) { + this.licenses = licenses != null ? ImmutableList.copyOf(licenses) : null; + return this; + } + + @Override + BuilderImpl attachedInstances(List attachedInstances) { + this.attachedInstances = + attachedInstances != null ? ImmutableList.copyOf(attachedInstances) : null; + return this; + } + + @Override + BuilderImpl lastAttachTimestamp(Long lastAttachTimestamp) { + this.lastAttachTimestamp = lastAttachTimestamp; + return this; + } + + @Override + BuilderImpl lastDetachTimestamp(Long lastDetachTimestamp) { + this.lastDetachTimestamp = lastDetachTimestamp; + return this; + } + + @Override + public DiskInfo build() { + return new DiskInfo(this); + } + } + + DiskInfo(BuilderImpl builder) { + this.id = builder.id; + this.configuration = builder.configuration; + this.creationTimestamp = builder.creationTimestamp; + this.creationStatus = builder.creationStatus; + this.diskId = builder.diskId; + this.description = builder.description; + this.licenses = builder.licenses; + this.attachedInstances = builder.attachedInstances; + this.lastAttachTimestamp = builder.lastAttachTimestamp; + this.lastDetachTimestamp = builder.lastDetachTimestamp; + } + + /** + * Returns the creation timestamp in milliseconds since epoch. + */ + public Long creationTimestamp() { + return creationTimestamp; + } + + /** + * Returns the unique identifier for the disk; defined by the service. + */ + public String id() { + return id; + } + + /** + * Returns the disk configuration. + */ + @SuppressWarnings("unchecked") + public T configuration() { + return (T) configuration; + } + + /** + * Returns the disk identity. + */ + public DiskId diskId() { + return diskId; + } + + /** + * Returns the creation status of the disk. + */ + public CreationStatus creationStatus() { + return creationStatus; + } + + /** + * Returns a textual description of the disk. + */ + public String description() { + return description; + } + + /** + * Returns all applicable publicly visible licenses for the disk. + */ + public List licenses() { + return licenses; + } + + /** + * Returns all the identities of the instances this disk is attached to. + */ + public List attachedInstances() { + return attachedInstances; + } + + /** + * Returns the last attach timestamp in milliseconds since epoch. + */ + public Long lastAttachTimestamp() { + return lastAttachTimestamp; + } + + /** + * Returns the last detach timestamp in milliseconds since epoch. + */ + public Long lastDetachTimestamp() { + return lastDetachTimestamp; + } + + /** + * Returns a builder for the object. + */ + public Builder toBuilder() { + return new BuilderImpl(this); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id) + .add("diskId", diskId) + .add("configuration", configuration) + .add("creationTimestamp", creationTimestamp) + .add("creationStatus", creationStatus) + .add("description", description) + .add("licenses", licenses) + .add("attachedInstances", attachedInstances) + .add("lastAttachTimestamp", lastAttachTimestamp) + .add("lastDetachTimestamp", lastDetachTimestamp) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(diskId, configuration, creationTimestamp, creationStatus, description, + licenses, attachedInstances, lastAttachTimestamp, lastDetachTimestamp); + } + + @Override + public boolean equals(Object obj) { + return obj != null + && obj.getClass().equals(DiskInfo.class) + && Objects.equals(toPb(), ((DiskInfo) obj).toPb()); + } + + /** + * Returns a builder for a {@code DiskInfo} object given its identity and configuration. Use + * {@link StandardDiskConfiguration} to create a simple disk given its type and size. Use + * {@link SnapshotDiskConfiguration} to create a disk from a snapshot. Use + * {@link ImageDiskConfiguration} to create a disk from a disk image. + */ + public static Builder builder(DiskId diskId, DiskConfiguration configuration) { + return new BuilderImpl(diskId, configuration); + } + + /** + * Returns a {@code DiskInfo} object given its identity and configuration. Use + * {@link StandardDiskConfiguration} to create a simple disk given its type and size. Use + * {@link SnapshotDiskConfiguration} to create a disk from a snapshot. Use + * {@link ImageDiskConfiguration} to create a disk from a disk image. + */ + public static DiskInfo of(DiskId diskId, DiskConfiguration configuration) { + return builder(diskId, configuration).build(); + } + + DiskInfo setProjectId(String projectId) { + return toBuilder() + .diskId(diskId.setProjectId(projectId)) + .configuration(configuration.setProjectId(projectId)) + .build(); + } + + Disk toPb() { + Disk diskPb = configuration.toPb(); + if (id != null) { + diskPb.setId(new BigInteger(id)); + } + if (creationTimestamp != null) { + diskPb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); + } + diskPb.setZone(diskId.zoneId().selfLink()); + if (creationStatus != null) { + diskPb.setStatus(creationStatus.toString()); + } + diskPb.setName(diskId.disk()); + diskPb.setDescription(description); + diskPb.setSelfLink(diskId.selfLink()); + if (licenses != null) { + diskPb.setLicenses(Lists.transform(licenses, LicenseId.TO_URL_FUNCTION)); + } + if (attachedInstances != null) { + diskPb.setUsers(Lists.transform(attachedInstances, InstanceId.TO_URL_FUNCTION)); + } + if (lastAttachTimestamp != null) { + diskPb.setLastAttachTimestamp(TIMESTAMP_FORMATTER.print(lastAttachTimestamp)); + } + if (lastDetachTimestamp != null) { + diskPb.setLastDetachTimestamp(TIMESTAMP_FORMATTER.print(lastDetachTimestamp)); + } + return diskPb; + } + + static DiskInfo fromPb(Disk diskPb) { + return new BuilderImpl(diskPb).build(); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageConfiguration.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageConfiguration.java index aa6379b12f4f..c47f9d73157f 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageConfiguration.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageConfiguration.java @@ -73,8 +73,8 @@ public abstract static class BuilderBlock Storage + */ +public class ImageDiskConfiguration extends DiskConfiguration { + + private static final long serialVersionUID = 6469117882950722812L; + + private final ImageId sourceImage; + private final String sourceImageId; + + /** + * A builder for {@code ImageDiskConfiguration} objects. + */ + public static class Builder + extends DiskConfiguration.Builder { + + private ImageId sourceImage; + private String sourceImageId; + + private Builder(ImageId sourceImage) { + super(Type.IMAGE); + this.sourceImage = checkNotNull(sourceImage); + } + + private Builder(ImageDiskConfiguration configuration) { + super(configuration); + this.sourceImage = configuration.sourceImage; + this.sourceImageId = configuration.sourceImageId; + } + + private Builder(Disk diskPb) { + super(Type.IMAGE, diskPb); + this.sourceImage = ImageId.fromUrl(diskPb.getSourceImage()); + this.sourceImageId = diskPb.getSourceImageId(); + } + + /** + * Sets the size of the persistent disk, in GB. If not set the disk will have the size of the + * image. This value can be larger than the image's size. If the provided size is smaller than + * the image's size then disk creation will fail. + */ + @Override + public Builder sizeGb(Long sizeGb) { + super.sizeGb(sizeGb); + return this; + } + + /** + * Sets the identity of the source image used to create the disk. + */ + public Builder sourceImage(ImageId sourceImage) { + this.sourceImage = checkNotNull(sourceImage); + return this; + } + + Builder sourceImageId(String sourceImageId) { + this.sourceImageId = sourceImageId; + return this; + } + + /** + * Creates an {@code ImageDiskConfiguration} object. + */ + @Override + public ImageDiskConfiguration build() { + return new ImageDiskConfiguration(this); + } + } + + private ImageDiskConfiguration(Builder builder) { + super(builder); + this.sourceImage = builder.sourceImage; + this.sourceImageId = builder.sourceImageId; + } + + /** + * Returns the identity of the source image used to create the disk. + */ + public ImageId sourceImage() { + return sourceImage; + } + + /** + * Returns the ID value of the image used to create this disk. This value identifies the exact + * image that was used to create this persistent disk. For example, if you created the persistent + * disk from an image that was later deleted and recreated under the same name, the source image + * ID would identify the exact version of the image that was used. + */ + public String sourceImageId() { + return sourceImageId; + } + + @Override + public Builder toBuilder() { + return new Builder(this); + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper() + .add("sourceImage", sourceImage) + .add("sourceImageId", sourceImageId); + } + + @Override + public final int hashCode() { + return Objects.hash(baseHashCode(), sourceImage, sourceImageId); + } + + @Override + public final boolean equals(Object obj) { + return obj instanceof ImageDiskConfiguration && baseEquals((ImageDiskConfiguration) obj); + } + + @Override + ImageDiskConfiguration setProjectId(String projectId) { + Builder builder = toBuilder().sourceImage(sourceImage.setProjectId(projectId)); + if (diskType() != null) { + builder.diskType(diskType().setProjectId(projectId)); + } + return builder.build(); + } + + @Override + Disk toPb() { + return super.toPb().setSourceImage(sourceImage.selfLink()).setSourceImageId(sourceImageId); + } + + /** + * Returns a builder for an {@code ImageDiskConfiguration} object given the image identity. + */ + public static Builder builder(ImageId imageId) { + return new Builder(imageId); + } + + /** + * Returns an {@code ImageDiskConfiguration} object given the image identity. + */ + public static ImageDiskConfiguration of(ImageId imageId) { + return builder(imageId).build(); + } + + @SuppressWarnings("unchecked") + static ImageDiskConfiguration fromPb(Disk diskPb) { + return new Builder(diskPb).build(); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotDiskConfiguration.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotDiskConfiguration.java new file mode 100644 index 000000000000..1bdc319e30c5 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotDiskConfiguration.java @@ -0,0 +1,181 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.api.services.compute.model.Disk; +import com.google.common.base.MoreObjects; + +import java.util.Objects; + +/** + * A Google Compute Engine disk configuration to create a disk from a Google Compute Engine + * snapshot. + * + * @see Block Storage + */ +public class SnapshotDiskConfiguration extends DiskConfiguration { + + private static final long serialVersionUID = -1996055058706221049L; + + private final SnapshotId sourceSnapshot; + private final String sourceSnapshotId; + + /** + * A builder for {@code SnapshotDiskConfiguration} objects. + */ + public static class Builder + extends DiskConfiguration.Builder { + + private SnapshotId sourceSnapshot; + private String sourceSnapshotId; + + private Builder(SnapshotId sourceSnapshot) { + super(Type.SNAPSHOT); + this.sourceSnapshot = checkNotNull(sourceSnapshot); + } + + private Builder(SnapshotDiskConfiguration configuration) { + super(configuration); + this.sourceSnapshot = configuration.sourceSnapshot; + this.sourceSnapshotId = configuration.sourceSnapshotId; + } + + private Builder(Disk diskPb) { + super(Type.SNAPSHOT, diskPb); + this.sourceSnapshot = SnapshotId.fromUrl(diskPb.getSourceSnapshot()); + this.sourceSnapshotId = diskPb.getSourceSnapshotId(); + } + + /** + * Sets the size of the persistent disk, in GB. If not set the disk will have the size of the + * snapshot. This value can be larger than the snapshot's size. If the provided size is smaller + * than the snapshot's size then disk creation will fail. + * + * @see + * Restoring a snapshot to a larger size + */ + @Override + public Builder sizeGb(Long sizeGb) { + super.sizeGb(sizeGb); + return this; + } + + /** + * Sets the identity of the source snapshot used to create the disk. + */ + public Builder sourceSnapshot(SnapshotId sourceSnapshot) { + this.sourceSnapshot = checkNotNull(sourceSnapshot); + return this; + } + + Builder sourceSnapshotId(String sourceSnapshotId) { + this.sourceSnapshotId = sourceSnapshotId; + return this; + } + + /** + * Creates a {@code SnapshotDiskConfiguration} object. + */ + @Override + public SnapshotDiskConfiguration build() { + return new SnapshotDiskConfiguration(this); + } + } + + private SnapshotDiskConfiguration(Builder builder) { + super(builder); + this.sourceSnapshot = builder.sourceSnapshot; + this.sourceSnapshotId = builder.sourceSnapshotId; + } + + /** + * Returns the identity of the source snapshot used to create the disk. + */ + public SnapshotId sourceSnapshot() { + return sourceSnapshot; + } + + /** + * Returns the unique ID of the snapshot used to create this disk. This value identifies the exact + * snapshot that was used to create the persistent disk. For example, if you created the + * persistent disk from a snapshot that was later deleted and recreated under the same name, the + * source snapshot ID would identify the exact version of the snapshot that was used. + */ + public String sourceSnapshotId() { + return sourceSnapshotId; + } + + @Override + public Builder toBuilder() { + return new Builder(this); + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper() + .add("sourceSnapshot", sourceSnapshot) + .add("sourceSnapshotId", sourceSnapshotId); + } + + @Override + public final int hashCode() { + return Objects.hash(baseHashCode(), sourceSnapshot, sourceSnapshotId); + } + + @Override + public final boolean equals(Object obj) { + return obj instanceof SnapshotDiskConfiguration && baseEquals((SnapshotDiskConfiguration) obj); + } + + @Override + SnapshotDiskConfiguration setProjectId(String projectId) { + Builder builder = toBuilder().sourceSnapshot(sourceSnapshot.setProjectId(projectId)); + if (diskType() != null) { + builder.diskType(diskType().setProjectId(projectId)); + } + return builder.build(); + } + + @Override + Disk toPb() { + return super.toPb() + .setSourceSnapshot(sourceSnapshot.selfLink()) + .setSourceSnapshotId(sourceSnapshotId); + } + + /** + * Returns a builder for a {@code SnapshotDiskConfiguration} object given the snapshot identity. + */ + public static Builder builder(SnapshotId sourceSnapshot) { + return new Builder(sourceSnapshot); + } + + /** + * Returns a {@code SnapshotDiskConfiguration} object given the snapshot identity. + */ + public static SnapshotDiskConfiguration of(SnapshotId sourceSnapshot) { + return builder(sourceSnapshot).build(); + } + + @SuppressWarnings("unchecked") + static SnapshotDiskConfiguration fromPb(Disk diskPb) { + return new Builder(diskPb).build(); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/StandardDiskConfiguration.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/StandardDiskConfiguration.java new file mode 100644 index 000000000000..1d1e0e56bb6b --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/StandardDiskConfiguration.java @@ -0,0 +1,128 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import com.google.api.services.compute.model.Disk; + +import java.util.Objects; + +/** + * A Google Compute Engine standard persistent disk configuration. This class allows users to create + * a disk given its type and size. + * + * @see Block Storage + */ +public class StandardDiskConfiguration extends DiskConfiguration { + + private static final long serialVersionUID = -6974045909359567054L; + + /** + * A builder for {@code StandardDiskConfiguration} objects. + */ + public static class Builder + extends DiskConfiguration.Builder { + + private Builder() { + super(Type.STANDARD); + } + + private Builder(StandardDiskConfiguration configuration) { + super(configuration); + } + + private Builder(Disk diskPb) { + super(Type.STANDARD, diskPb); + } + + /** + * Sets the size of the persistent disk, in GB. If not set, 500GB is used. + */ + @Override + public Builder sizeGb(Long sizeGb) { + super.sizeGb(sizeGb); + return this; + } + + /** + * Creates a {@code StandardDiskConfiguration} object. + */ + @Override + public StandardDiskConfiguration build() { + return new StandardDiskConfiguration(this); + } + } + + private StandardDiskConfiguration(Builder builder) { + super(builder); + } + + @Override + public Builder toBuilder() { + return new Builder(this); + } + + @Override + public final int hashCode() { + return Objects.hash(baseHashCode()); + } + + @Override + public final boolean equals(Object obj) { + return obj instanceof StandardDiskConfiguration && baseEquals((StandardDiskConfiguration) obj); + } + + @Override + StandardDiskConfiguration setProjectId(String projectId) { + if (diskType() == null || diskType().project() != null) { + return this; + } + return toBuilder().diskType(diskType().setProjectId(projectId)).build(); + } + + /** + * Returns a builder for a {@code StandardDiskConfiguration} object. + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Returns a {@code StandardDiskConfiguration} object given the disk type. + */ + public static StandardDiskConfiguration of(DiskTypeId diskType) { + return builder().diskType(diskType).build(); + } + + /** + * Returns a {@code StandardDiskConfiguration} object given the disk size in GB. + */ + public static StandardDiskConfiguration of(long sizeGb) { + return builder().sizeGb(sizeGb).build(); + } + + /** + * Returns a {@code StandardDiskConfiguration} object given the disk type and size in GB. + */ + public static StandardDiskConfiguration of(DiskTypeId diskType, long sizeGb) { + return builder().diskType(diskType).sizeGb(sizeGb).build(); + } + + @SuppressWarnings("unchecked") + static StandardDiskConfiguration fromPb(Disk diskPb) { + return new Builder(diskPb).build(); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/StorageImageConfiguration.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/StorageImageConfiguration.java index a09be89aefe6..88d37e5180b8 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/StorageImageConfiguration.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/StorageImageConfiguration.java @@ -58,7 +58,7 @@ private Builder() { } private Builder(StorageImageConfiguration imageConfiguration) { - super(Type.STORAGE, imageConfiguration); + super(imageConfiguration); this.containerType = imageConfiguration.containerType; this.sha1 = imageConfiguration.sha1; this.source = imageConfiguration.source; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskInfoTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskInfoTest.java new file mode 100644 index 000000000000..1138d8008452 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskInfoTest.java @@ -0,0 +1,268 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import com.google.api.services.compute.model.Disk; +import com.google.common.collect.ImmutableList; +import com.google.gcloud.compute.DiskInfo.CreationStatus; + +import org.junit.Test; + +import java.util.List; + +public class DiskInfoTest { + + private static final String ID = "42"; + private static final DiskId DISK_ID = DiskId.of("project", "zone", "disk"); + private static final Long CREATION_TIMESTAMP = 1453293540000L; + private static final CreationStatus CREATION_STATUS = CreationStatus.READY; + private static final String DESCRIPTION = "description"; + private static final Long SIZE_GB = 500L; + private static final DiskTypeId TYPE = DiskTypeId.of("project", "zone", "disk"); + private static final List LICENSES = ImmutableList.of( + LicenseId.of("project", "license1"), LicenseId.of("project", "license2")); + private static final List ATTACHED_INSTANCES = ImmutableList.of( + InstanceId.of("project", "zone", "instance1"), + InstanceId.of("project", "zone", "instance2")); + private static final SnapshotId SNAPSHOT = SnapshotId.of("project", "snapshot"); + private static final ImageId IMAGE = ImageId.of("project", "image"); + private static final String SNAPSHOT_ID = "snapshotId"; + private static final String IMAGE_ID = "snapshotId"; + private static final Long LAST_ATTACH_TIMESTAMP = 1453293600000L; + private static final Long LAST_DETACH_TIMESTAMP = 1453293660000L; + private static final StandardDiskConfiguration DISK_CONFIGURATION = + StandardDiskConfiguration.builder() + .sizeGb(SIZE_GB) + .diskType(TYPE) + .build(); + private static final SnapshotDiskConfiguration SNAPSHOT_DISK_CONFIGURATION = + SnapshotDiskConfiguration.builder(SNAPSHOT) + .sizeGb(SIZE_GB) + .diskType(TYPE) + .sourceSnapshotId(SNAPSHOT_ID) + .build(); + private static final ImageDiskConfiguration IMAGE_DISK_CONFIGURATION = + ImageDiskConfiguration.builder(IMAGE) + .sizeGb(SIZE_GB) + .diskType(TYPE) + .sourceImageId(IMAGE_ID) + .build(); + private static final DiskInfo DISK_INFO = DiskInfo.builder(DISK_ID, DISK_CONFIGURATION) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .creationStatus(CREATION_STATUS) + .description(DESCRIPTION) + .licenses(LICENSES) + .attachedInstances(ATTACHED_INSTANCES) + .lastAttachTimestamp(LAST_ATTACH_TIMESTAMP) + .lastDetachTimestamp(LAST_DETACH_TIMESTAMP) + .build(); + private static final DiskInfo SNAPSHOT_DISK_INFO = + DiskInfo.builder(DISK_ID, SNAPSHOT_DISK_CONFIGURATION) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .creationStatus(CREATION_STATUS) + .description(DESCRIPTION) + .licenses(LICENSES) + .attachedInstances(ATTACHED_INSTANCES) + .lastAttachTimestamp(LAST_ATTACH_TIMESTAMP) + .lastDetachTimestamp(LAST_DETACH_TIMESTAMP) + .build(); + private static final DiskInfo IMAGE_DISK_INFO = + DiskInfo.builder(DISK_ID, IMAGE_DISK_CONFIGURATION) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .creationStatus(CREATION_STATUS) + .description(DESCRIPTION) + .licenses(LICENSES) + .attachedInstances(ATTACHED_INSTANCES) + .lastAttachTimestamp(LAST_ATTACH_TIMESTAMP) + .lastDetachTimestamp(LAST_DETACH_TIMESTAMP) + .build(); + + @Test + public void testToBuilder() { + compareDiskInfo(DISK_INFO, DISK_INFO.toBuilder().build()); + compareDiskInfo(IMAGE_DISK_INFO, IMAGE_DISK_INFO.toBuilder().build()); + compareDiskInfo(SNAPSHOT_DISK_INFO, SNAPSHOT_DISK_INFO.toBuilder().build()); + DiskInfo diskInfo = DISK_INFO.toBuilder().description("newDescription").build(); + assertEquals("newDescription", diskInfo.description()); + diskInfo = diskInfo.toBuilder().description("description").build(); + compareDiskInfo(DISK_INFO, diskInfo); + } + + @Test + public void testToBuilderIncomplete() { + DiskInfo diskInfo = DiskInfo.of(DISK_ID, DISK_CONFIGURATION); + assertEquals(diskInfo, diskInfo.toBuilder().build()); + diskInfo = DiskInfo.of(DISK_ID, SNAPSHOT_DISK_CONFIGURATION); + assertEquals(diskInfo, diskInfo.toBuilder().build()); + diskInfo = DiskInfo.of(DISK_ID, IMAGE_DISK_CONFIGURATION); + assertEquals(diskInfo, diskInfo.toBuilder().build()); + } + + @Test + public void testBuilder() { + assertEquals(ID, DISK_INFO.id()); + assertEquals(DISK_ID, DISK_INFO.diskId()); + assertEquals(DISK_CONFIGURATION, DISK_INFO.configuration()); + assertEquals(CREATION_TIMESTAMP, DISK_INFO.creationTimestamp()); + assertEquals(CREATION_STATUS, DISK_INFO.creationStatus()); + assertEquals(DESCRIPTION, DISK_INFO.description()); + assertEquals(LICENSES, DISK_INFO.licenses()); + assertEquals(ATTACHED_INSTANCES, DISK_INFO.attachedInstances()); + assertEquals(LAST_ATTACH_TIMESTAMP, DISK_INFO.lastAttachTimestamp()); + assertEquals(LAST_DETACH_TIMESTAMP, DISK_INFO.lastDetachTimestamp()); + assertEquals(ID, IMAGE_DISK_INFO.id()); + assertEquals(DISK_ID, IMAGE_DISK_INFO.diskId()); + assertEquals(IMAGE_DISK_CONFIGURATION, IMAGE_DISK_INFO.configuration()); + assertEquals(CREATION_TIMESTAMP, IMAGE_DISK_INFO.creationTimestamp()); + assertEquals(CREATION_STATUS, IMAGE_DISK_INFO.creationStatus()); + assertEquals(DESCRIPTION, IMAGE_DISK_INFO.description()); + assertEquals(LICENSES, IMAGE_DISK_INFO.licenses()); + assertEquals(ATTACHED_INSTANCES, IMAGE_DISK_INFO.attachedInstances()); + assertEquals(LAST_ATTACH_TIMESTAMP, IMAGE_DISK_INFO.lastAttachTimestamp()); + assertEquals(LAST_DETACH_TIMESTAMP, IMAGE_DISK_INFO.lastDetachTimestamp()); + assertEquals(ID, SNAPSHOT_DISK_INFO.id()); + assertEquals(DISK_ID, SNAPSHOT_DISK_INFO.diskId()); + assertEquals(SNAPSHOT_DISK_CONFIGURATION, SNAPSHOT_DISK_INFO.configuration()); + assertEquals(CREATION_TIMESTAMP, SNAPSHOT_DISK_INFO.creationTimestamp()); + assertEquals(CREATION_STATUS, SNAPSHOT_DISK_INFO.creationStatus()); + assertEquals(DESCRIPTION, SNAPSHOT_DISK_INFO.description()); + assertEquals(LICENSES, SNAPSHOT_DISK_INFO.licenses()); + assertEquals(ATTACHED_INSTANCES, SNAPSHOT_DISK_INFO.attachedInstances()); + assertEquals(LAST_ATTACH_TIMESTAMP, SNAPSHOT_DISK_INFO.lastAttachTimestamp()); + assertEquals(LAST_DETACH_TIMESTAMP, SNAPSHOT_DISK_INFO.lastDetachTimestamp()); + } + + @Test + public void testOf() { + DiskInfo diskInfo = DiskInfo.of(DISK_ID, DISK_CONFIGURATION); + assertNull(diskInfo.id()); + assertEquals(DISK_ID, diskInfo.diskId()); + assertEquals(DISK_CONFIGURATION, diskInfo.configuration()); + assertNull(diskInfo.creationTimestamp()); + assertNull(diskInfo.creationStatus()); + assertNull(diskInfo.description()); + assertNull(diskInfo.licenses()); + assertNull(diskInfo.attachedInstances()); + assertNull(diskInfo.lastAttachTimestamp()); + assertNull(diskInfo.lastDetachTimestamp()); + diskInfo = DiskInfo.of(DISK_ID, IMAGE_DISK_CONFIGURATION); + assertNull(diskInfo.id()); + assertEquals(DISK_ID, diskInfo.diskId()); + assertEquals(IMAGE_DISK_CONFIGURATION, diskInfo.configuration()); + assertNull(diskInfo.creationTimestamp()); + assertNull(diskInfo.creationStatus()); + assertNull(diskInfo.description()); + assertNull(diskInfo.licenses()); + assertNull(diskInfo.attachedInstances()); + assertNull(diskInfo.lastAttachTimestamp()); + assertNull(diskInfo.lastDetachTimestamp()); + diskInfo = DiskInfo.of(DISK_ID, SNAPSHOT_DISK_CONFIGURATION); + assertNull(diskInfo.id()); + assertEquals(DISK_ID, diskInfo.diskId()); + assertEquals(SNAPSHOT_DISK_CONFIGURATION, diskInfo.configuration()); + assertNull(diskInfo.creationTimestamp()); + assertNull(diskInfo.creationStatus()); + assertNull(diskInfo.description()); + assertNull(diskInfo.licenses()); + assertNull(diskInfo.attachedInstances()); + assertNull(diskInfo.lastAttachTimestamp()); + assertNull(diskInfo.lastDetachTimestamp()); + } + + @Test + public void testToAndFromPb() { + DiskInfo diskInfo = DiskInfo.fromPb(DISK_INFO.toPb()); + compareDiskInfo(DISK_INFO, diskInfo); + diskInfo = DiskInfo.fromPb(SNAPSHOT_DISK_INFO.toPb()); + compareDiskInfo(SNAPSHOT_DISK_INFO, diskInfo); + diskInfo = DiskInfo.fromPb(IMAGE_DISK_INFO.toPb()); + compareDiskInfo(IMAGE_DISK_INFO, diskInfo); + Disk disk = new Disk() + .setSelfLink(DISK_ID.selfLink()) + .setType(TYPE.selfLink()) + .setSizeGb(SIZE_GB); + diskInfo = DiskInfo.of(DISK_ID, DISK_CONFIGURATION); + compareDiskInfo(diskInfo, DiskInfo.fromPb(disk)); + disk = new Disk() + .setType(TYPE.selfLink()) + .setSizeGb(SIZE_GB) + .setSelfLink(DISK_ID.selfLink()) + .setSourceSnapshotId(SNAPSHOT_ID) + .setSourceSnapshot(SNAPSHOT.selfLink()); + diskInfo = DiskInfo.of(DISK_ID, SNAPSHOT_DISK_CONFIGURATION); + compareDiskInfo(diskInfo, DiskInfo.fromPb(disk)); + disk = new Disk() + .setType(TYPE.selfLink()) + .setSizeGb(SIZE_GB) + .setSelfLink(DISK_ID.selfLink()) + .setSourceImageId(IMAGE_ID) + .setSourceImage(IMAGE.selfLink()); + diskInfo = DiskInfo.of(DISK_ID, IMAGE_DISK_CONFIGURATION); + compareDiskInfo(diskInfo, DiskInfo.fromPb(disk)); + } + + @Test + public void testSetProjectId() { + StandardDiskConfiguration standardDiskConfiguration = DISK_CONFIGURATION.toBuilder() + .diskType(DiskTypeId.of(TYPE.zone(), TYPE.diskType())) + .build(); + DiskInfo diskInfo = DISK_INFO.toBuilder() + .diskId(DiskId.of(DISK_ID.zone(), DISK_ID.disk())) + .configuration(standardDiskConfiguration) + .build(); + compareDiskInfo(DISK_INFO, diskInfo.setProjectId("project")); + SnapshotDiskConfiguration snapshotDiskConfiguration = SNAPSHOT_DISK_CONFIGURATION.toBuilder() + .diskType(DiskTypeId.of(TYPE.zone(), TYPE.diskType())) + .sourceSnapshot(SnapshotId.of(SNAPSHOT.snapshot())) + .build(); + diskInfo = SNAPSHOT_DISK_INFO.toBuilder() + .diskId(DiskId.of(DISK_ID.zone(), DISK_ID.disk())) + .configuration(snapshotDiskConfiguration) + .build(); + compareDiskInfo(SNAPSHOT_DISK_INFO, diskInfo.setProjectId("project")); + ImageDiskConfiguration imageDiskConfiguration = IMAGE_DISK_CONFIGURATION.toBuilder() + .diskType(DiskTypeId.of(TYPE.zone(), TYPE.diskType())) + .sourceImage(ImageId.of(IMAGE.image())) + .build(); + diskInfo = IMAGE_DISK_INFO.toBuilder() + .diskId(DiskId.of(DISK_ID.zone(), DISK_ID.disk())) + .configuration(imageDiskConfiguration) + .build(); + compareDiskInfo(IMAGE_DISK_INFO, diskInfo.setProjectId("project")); + } + + public void compareDiskInfo(DiskInfo expected, DiskInfo value) { + assertEquals(expected, value); + assertEquals(expected.configuration(), value.configuration()); + assertEquals(expected.id(), value.id()); + assertEquals(expected.diskId(), value.diskId()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.creationStatus(), value.creationStatus()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.licenses(), value.licenses()); + assertEquals(expected.attachedInstances(), value.attachedInstances()); + assertEquals(expected.lastAttachTimestamp(), value.lastAttachTimestamp()); + assertEquals(expected.lastDetachTimestamp(), value.lastDetachTimestamp()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageDiskConfigurationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageDiskConfigurationTest.java new file mode 100644 index 000000000000..f388109db199 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageDiskConfigurationTest.java @@ -0,0 +1,112 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import com.google.gcloud.compute.DiskConfiguration.Type; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class ImageDiskConfigurationTest { + + private static final Long SIZE = 42L; + private static final DiskTypeId DISK_TYPE = DiskTypeId.of("project", "zone", "type"); + private static final ImageId IMAGE = ImageId.of("project", "image"); + private static final String IMAGE_ID = "imageId"; + private static final ImageDiskConfiguration DISK_CONFIGURATION = + ImageDiskConfiguration.builder(IMAGE) + .sizeGb(SIZE) + .diskType(DISK_TYPE) + .sourceImageId(IMAGE_ID) + .build(); + + @Test + public void testToBuilder() { + compareImageDiskConfiguration(DISK_CONFIGURATION, DISK_CONFIGURATION.toBuilder().build()); + ImageId newImageId = ImageId.of("newProject", "newImage"); + ImageDiskConfiguration diskConfiguration = DISK_CONFIGURATION.toBuilder() + .sizeGb(24L) + .sourceImage(newImageId) + .sourceImageId("newImageId") + .build(); + assertEquals(24L, diskConfiguration.sizeGb().longValue()); + assertEquals(newImageId, diskConfiguration.sourceImage()); + assertEquals("newImageId", diskConfiguration.sourceImageId()); + diskConfiguration = diskConfiguration.toBuilder() + .sizeGb(SIZE) + .sourceImage(IMAGE) + .sourceImageId(IMAGE_ID) + .build(); + compareImageDiskConfiguration(DISK_CONFIGURATION, diskConfiguration); + } + + @Test + public void testToBuilderIncomplete() { + ImageDiskConfiguration diskConfiguration = ImageDiskConfiguration.of(IMAGE); + compareImageDiskConfiguration(diskConfiguration, diskConfiguration.toBuilder().build()); + } + + @Test + public void testBuilder() { + assertEquals(DISK_TYPE, DISK_CONFIGURATION.diskType()); + assertEquals(SIZE, DISK_CONFIGURATION.sizeGb()); + assertEquals(IMAGE, DISK_CONFIGURATION.sourceImage()); + assertEquals(IMAGE_ID, DISK_CONFIGURATION.sourceImageId()); + assertEquals(Type.IMAGE, DISK_CONFIGURATION.type()); + } + + @Test + public void testToAndFromPb() { + assertTrue(DiskConfiguration.fromPb(DISK_CONFIGURATION.toPb()) + instanceof ImageDiskConfiguration); + compareImageDiskConfiguration(DISK_CONFIGURATION, + DiskConfiguration.fromPb(DISK_CONFIGURATION.toPb())); + } + + @Test + public void testOf() { + ImageDiskConfiguration configuration = ImageDiskConfiguration.of(IMAGE); + assertNull(configuration.diskType()); + assertNull(configuration.sizeGb()); + assertNull(configuration.sourceImageId()); + assertEquals(IMAGE, configuration.sourceImage()); + assertEquals(Type.IMAGE, configuration.type()); + } + + @Test + public void testSetProjectId() { + ImageDiskConfiguration diskConfiguration = DISK_CONFIGURATION.toBuilder() + .diskType(DiskTypeId.of(DISK_TYPE.zone(), DISK_TYPE.diskType())) + .sourceImage(ImageId.of(IMAGE.image())) + .build(); + compareImageDiskConfiguration(DISK_CONFIGURATION, diskConfiguration.setProjectId("project")); + } + + private void compareImageDiskConfiguration(ImageDiskConfiguration expected, + ImageDiskConfiguration value) { + assertEquals(expected, value); + assertEquals(expected.diskType(), value.diskType()); + assertEquals(expected.sizeGb(), value.sizeGb()); + assertEquals(expected.sourceImage(), value.sourceImage()); + assertEquals(expected.sourceImageId(), value.sourceImageId()); + assertEquals(expected.type(), value.type()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java index 0251dca1fc39..57736854091f 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java @@ -156,6 +156,13 @@ public class SerializationTest { private static final ImageInfo IMAGE_INFO = ImageInfo.of(IMAGE_ID, DISK_IMAGE_CONFIGURATION); private static final Image IMAGE = new Image.Builder(COMPUTE, IMAGE_ID, DISK_IMAGE_CONFIGURATION).build(); + private static final StandardDiskConfiguration STANDARD_DISK_CONFIGURATION = + StandardDiskConfiguration.of(DISK_TYPE_ID); + private static final ImageDiskConfiguration IMAGE_DISK_CONFIGURATION = + ImageDiskConfiguration.of(IMAGE_ID); + private static final SnapshotDiskConfiguration SNAPSHOT_DISK_CONFIGURATION = + SnapshotDiskConfiguration.of(SNAPSHOT_ID); + private static final DiskInfo DISK_INFO = DiskInfo.of(DISK_ID, STANDARD_DISK_CONFIGURATION); private static final Compute.DiskTypeOption DISK_TYPE_OPTION = Compute.DiskTypeOption.fields(); private static final Compute.DiskTypeFilter DISK_TYPE_FILTER = @@ -232,12 +239,13 @@ public void testModelAndRequests() throws Exception { INSTANCE_ID, REGION_FORWARDING_RULE_ID, GLOBAL_FORWARDING_RULE_ID, GLOBAL_ADDRESS_ID, REGION_ADDRESS_ID, INSTANCE_USAGE, GLOBAL_FORWARDING_USAGE, REGION_FORWARDING_USAGE, ADDRESS_INFO, ADDRESS, DISK_ID, SNAPSHOT_ID, SNAPSHOT_INFO, SNAPSHOT, IMAGE_ID, - DISK_IMAGE_CONFIGURATION, STORAGE_IMAGE_CONFIGURATION, IMAGE_INFO, IMAGE, DISK_TYPE_OPTION, - DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, DISK_TYPE_AGGREGATED_LIST_OPTION, - MACHINE_TYPE_OPTION, MACHINE_TYPE_FILTER, MACHINE_TYPE_LIST_OPTION, - MACHINE_TYPE_AGGREGATED_LIST_OPTION, REGION_OPTION, REGION_FILTER, REGION_LIST_OPTION, - ZONE_OPTION, ZONE_FILTER, ZONE_LIST_OPTION, LICENSE_OPTION, OPERATION_OPTION, - OPERATION_FILTER, OPERATION_LIST_OPTION, ADDRESS_OPTION, ADDRESS_FILTER, + DISK_IMAGE_CONFIGURATION, STORAGE_IMAGE_CONFIGURATION, IMAGE_INFO, + STANDARD_DISK_CONFIGURATION, IMAGE_DISK_CONFIGURATION, SNAPSHOT_DISK_CONFIGURATION, + DISK_INFO, IMAGE, DISK_TYPE_OPTION, DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, + DISK_TYPE_AGGREGATED_LIST_OPTION, MACHINE_TYPE_OPTION, MACHINE_TYPE_FILTER, + MACHINE_TYPE_LIST_OPTION, MACHINE_TYPE_AGGREGATED_LIST_OPTION, REGION_OPTION, REGION_FILTER, + REGION_LIST_OPTION, ZONE_OPTION, ZONE_FILTER, ZONE_LIST_OPTION, LICENSE_OPTION, + OPERATION_OPTION, OPERATION_FILTER, OPERATION_LIST_OPTION, ADDRESS_OPTION, ADDRESS_FILTER, ADDRESS_LIST_OPTION, ADDRESS_AGGREGATED_LIST_OPTION, SNAPSHOT_OPTION, SNAPSHOT_FILTER, SNAPSHOT_LIST_OPTION, IMAGE_OPTION, IMAGE_FILTER, IMAGE_LIST_OPTION}; for (Serializable obj : objects) { diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotDiskConfigurationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotDiskConfigurationTest.java new file mode 100644 index 000000000000..a6380dca667d --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotDiskConfigurationTest.java @@ -0,0 +1,112 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import com.google.gcloud.compute.DiskConfiguration.Type; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class SnapshotDiskConfigurationTest { + + private static final Long SIZE = 42L; + private static final DiskTypeId DISK_TYPE = DiskTypeId.of("project", "zone", "type"); + private static final SnapshotId SNAPSHOT = SnapshotId.of("project", "snapshot"); + private static final String SNAPSHOT_ID = "snapshotId"; + private static final SnapshotDiskConfiguration DISK_CONFIGURATION = + SnapshotDiskConfiguration.builder(SNAPSHOT) + .sizeGb(SIZE) + .diskType(DISK_TYPE) + .sourceSnapshotId(SNAPSHOT_ID) + .build(); + + @Test + public void testToBuilder() { + compareSnapshotDiskConfiguration(DISK_CONFIGURATION, DISK_CONFIGURATION.toBuilder().build()); + SnapshotId newSnapshot = SnapshotId.of("newProject", "newSnapshot"); + SnapshotDiskConfiguration diskConfiguration = DISK_CONFIGURATION.toBuilder() + .sizeGb(24L) + .sourceSnapshot(newSnapshot) + .sourceSnapshotId("newSnapshotId") + .build(); + assertEquals(24L, diskConfiguration.sizeGb().longValue()); + assertEquals(newSnapshot, diskConfiguration.sourceSnapshot()); + assertEquals("newSnapshotId", diskConfiguration.sourceSnapshotId()); + diskConfiguration = diskConfiguration.toBuilder() + .sizeGb(SIZE) + .sourceSnapshot(SNAPSHOT) + .sourceSnapshotId(SNAPSHOT_ID) + .build(); + compareSnapshotDiskConfiguration(DISK_CONFIGURATION, diskConfiguration); + } + + @Test + public void testToBuilderIncomplete() { + SnapshotDiskConfiguration diskConfiguration = SnapshotDiskConfiguration.of(SNAPSHOT); + compareSnapshotDiskConfiguration(diskConfiguration, diskConfiguration.toBuilder().build()); + } + + @Test + public void testBuilder() { + assertEquals(DISK_TYPE, DISK_CONFIGURATION.diskType()); + assertEquals(SIZE, DISK_CONFIGURATION.sizeGb()); + assertEquals(SNAPSHOT, DISK_CONFIGURATION.sourceSnapshot()); + assertEquals(SNAPSHOT_ID, DISK_CONFIGURATION.sourceSnapshotId()); + assertEquals(Type.SNAPSHOT, DISK_CONFIGURATION.type()); + } + + @Test + public void testToAndFromPb() { + assertTrue(DiskConfiguration.fromPb(DISK_CONFIGURATION.toPb()) + instanceof SnapshotDiskConfiguration); + compareSnapshotDiskConfiguration(DISK_CONFIGURATION, + DiskConfiguration.fromPb(DISK_CONFIGURATION.toPb())); + } + + @Test + public void testOf() { + SnapshotDiskConfiguration configuration = SnapshotDiskConfiguration.of(SNAPSHOT); + assertNull(configuration.diskType()); + assertNull(configuration.sizeGb()); + assertNull(configuration.sourceSnapshotId()); + assertEquals(SNAPSHOT, configuration.sourceSnapshot()); + assertEquals(Type.SNAPSHOT, configuration.type()); + } + + @Test + public void testSetProjectId() { + SnapshotDiskConfiguration configuration = DISK_CONFIGURATION.toBuilder() + .diskType(DiskTypeId.of(DISK_TYPE.zone(), DISK_TYPE.diskType())) + .sourceSnapshot(SnapshotId.of(SNAPSHOT.snapshot())) + .build(); + compareSnapshotDiskConfiguration(DISK_CONFIGURATION, configuration.setProjectId("project")); + } + + private void compareSnapshotDiskConfiguration(SnapshotDiskConfiguration expected, + SnapshotDiskConfiguration value) { + assertEquals(expected, value); + assertEquals(expected.diskType(), value.diskType()); + assertEquals(expected.sizeGb(), value.sizeGb()); + assertEquals(expected.sourceSnapshot(), value.sourceSnapshot()); + assertEquals(expected.sourceSnapshotId(), value.sourceSnapshotId()); + assertEquals(expected.type(), value.type()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/StandardDiskConfigurationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/StandardDiskConfigurationTest.java new file mode 100644 index 000000000000..702a362b6ddc --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/StandardDiskConfigurationTest.java @@ -0,0 +1,103 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import com.google.gcloud.compute.DiskConfiguration.Type; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class StandardDiskConfigurationTest { + + private static final Long SIZE = 42L; + private static final DiskTypeId DISK_TYPE = DiskTypeId.of("project", "zone", "type"); + private static final StandardDiskConfiguration DISK_CONFIGURATION = + StandardDiskConfiguration.builder() + .sizeGb(SIZE) + .diskType(DISK_TYPE) + .build(); + + @Test + public void testToBuilder() { + compareStandardDiskConfiguration(DISK_CONFIGURATION, DISK_CONFIGURATION.toBuilder().build()); + StandardDiskConfiguration diskConfiguration = DISK_CONFIGURATION.toBuilder() + .sizeGb(24L) + .build(); + assertEquals(24L, diskConfiguration.sizeGb().longValue()); + diskConfiguration = diskConfiguration.toBuilder() + .sizeGb(SIZE) + .build(); + compareStandardDiskConfiguration(DISK_CONFIGURATION, diskConfiguration); + } + + @Test + public void testToBuilderIncomplete() { + StandardDiskConfiguration diskConfiguration = StandardDiskConfiguration.of(DISK_TYPE); + compareStandardDiskConfiguration(diskConfiguration, diskConfiguration.toBuilder().build()); + } + + @Test + public void testBuilder() { + assertEquals(DISK_TYPE, DISK_CONFIGURATION.diskType()); + assertEquals(SIZE, DISK_CONFIGURATION.sizeGb()); + assertEquals(Type.STANDARD, DISK_CONFIGURATION.type()); + } + + @Test + public void testToAndFromPb() { + assertTrue(DiskConfiguration.fromPb(DISK_CONFIGURATION.toPb()) + instanceof StandardDiskConfiguration); + compareStandardDiskConfiguration(DISK_CONFIGURATION, + DiskConfiguration.fromPb(DISK_CONFIGURATION.toPb())); + } + + @Test + public void testOf() { + StandardDiskConfiguration configuration = StandardDiskConfiguration.of(DISK_TYPE); + assertEquals(DISK_TYPE, configuration.diskType()); + assertNull(configuration.sizeGb()); + assertEquals(Type.STANDARD, configuration.type()); + configuration = StandardDiskConfiguration.of(DISK_TYPE, SIZE); + assertEquals(DISK_TYPE, configuration.diskType()); + assertEquals(SIZE, configuration.sizeGb()); + assertEquals(Type.STANDARD, configuration.type()); + configuration = StandardDiskConfiguration.of(SIZE); + assertNull(configuration.diskType()); + assertEquals(SIZE, configuration.sizeGb()); + assertEquals(Type.STANDARD, configuration.type()); + } + + @Test + public void testSetProjectId() { + StandardDiskConfiguration configuration = DISK_CONFIGURATION.toBuilder() + .diskType(DiskTypeId.of(DISK_TYPE.zone(), DISK_TYPE.diskType())) + .build(); + compareStandardDiskConfiguration(DISK_CONFIGURATION, configuration.setProjectId("project")); + } + + private void compareStandardDiskConfiguration(StandardDiskConfiguration expected, + StandardDiskConfiguration value) { + assertEquals(expected, value); + assertEquals(expected.diskType(), value.diskType()); + assertEquals(expected.sizeGb(), value.sizeGb()); + assertEquals(expected.type(), value.type()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} From f085a41528bd13f255b42e3ec3291975071fa684 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 11 Apr 2016 23:38:52 +0200 Subject: [PATCH 310/375] Add functional methods for disks and Disk class (#870) * Add functional methods for disks and Disk class * Refactor Disk functional methods - Update compute dependency - Add resize method for disks - Udpate zone and remove MaintenanceWindow - make create(Snapshot) throw if disk is not found - Minor fixes to javadoc and tests --- gcloud-java-compute/pom.xml | 2 +- .../com/google/gcloud/compute/Compute.java | 205 ++++++- .../google/gcloud/compute/ComputeImpl.java | 175 ++++++ .../java/com/google/gcloud/compute/Disk.java | 256 +++++++++ .../java/com/google/gcloud/compute/Zone.java | 138 ----- .../com/google/gcloud/spi/ComputeRpc.java | 51 +- .../google/gcloud/spi/DefaultComputeRpc.java | 99 +++- .../gcloud/compute/ComputeImplTest.java | 321 ++++++++++- .../com/google/gcloud/compute/DiskTest.java | 475 +++++++++++++++++ .../gcloud/compute/SerializationTest.java | 25 +- .../com/google/gcloud/compute/ZoneTest.java | 15 - .../gcloud/compute/it/ITComputeTest.java | 503 +++++++++++++++++- 12 files changed, 2085 insertions(+), 180 deletions(-) create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/Disk.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTest.java diff --git a/gcloud-java-compute/pom.xml b/gcloud-java-compute/pom.xml index 5bf336e01a2f..6fc456442024 100644 --- a/gcloud-java-compute/pom.xml +++ b/gcloud-java-compute/pom.xml @@ -24,7 +24,7 @@ com.google.apis google-api-services-compute - v1-rev97-1.21.0 + v1-rev103-1.21.0 compile diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java index 300d38908a8b..aaedbccf13bb 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java @@ -161,7 +161,6 @@ enum ZoneField { CREATION_TIMESTAMP("creationTimestamp"), DESCRIPTION("description"), ID("id"), - MAINTENANCE_WINDOWS("maintenanceWindows"), NAME("name"), REGION("region"), SELF_LINK("selfLink"), @@ -917,6 +916,54 @@ public static ImageFilter notEquals(ImageField field, long value) { } } + /** + * Class for filtering disk lists. + */ + class DiskFilter extends ListFilter { + + private static final long serialVersionUID = 5856790665396877913L; + + private DiskFilter(DiskField field, ComparisonOperator operator, Object value) { + super(field.selector(), operator, value); + } + + /** + * Returns an equals filter for the given field and string value. For string fields, + * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must + * match the entire field. + * + * @see RE2 + */ + public static DiskFilter equals(DiskField field, String value) { + return new DiskFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value)); + } + + /** + * Returns a not-equals filter for the given field and string value. For string fields, + * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must + * match the entire field. + * + * @see RE2 + */ + public static DiskFilter notEquals(DiskField field, String value) { + return new DiskFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value)); + } + + /** + * Returns an equals filter for the given field and long value. + */ + public static DiskFilter equals(DiskField field, long value) { + return new DiskFilter(checkNotNull(field), ComparisonOperator.EQ, value); + } + + /** + * Returns a not-equals filter for the given field and long value. + */ + public static DiskFilter notEquals(DiskField field, long value) { + return new DiskFilter(checkNotNull(field), ComparisonOperator.NE, value); + } + } + /** * Class for specifying disk type get options. */ @@ -1585,6 +1632,112 @@ public static ImageListOption fields(ImageField... fields) { } } + /** + * Class for specifying disk get options. + */ + class DiskOption extends Option { + + private static final long serialVersionUID = -4354796876226661667L; + + private DiskOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify the disk's fields to be returned by the RPC call. If this option + * is not provided, all disk's fields are returned. {@code DiskOption.fields} can be used to + * specify only the fields of interest. {@link Disk#diskId()}, + * {@link DiskConfiguration#diskType()} and either + * {@link SnapshotDiskConfiguration#sourceSnapshot()} or + * {@link ImageDiskConfiguration#sourceImage()} are always returned, even if not specified. + */ + public static DiskOption fields(DiskField... fields) { + return new DiskOption(ComputeRpc.Option.FIELDS, DiskField.selector(fields)); + } + } + + /** + * Class for specifying disk list options. + */ + class DiskListOption extends Option { + + private static final long serialVersionUID = -5148497888688645905L; + + private DiskListOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify a filter on the disks being listed. + */ + public static DiskListOption filter(DiskFilter filter) { + return new DiskListOption(ComputeRpc.Option.FILTER, filter.toPb()); + } + + /** + * Returns an option to specify the maximum number of disks returned per page. {@code pageSize} + * must be between 0 and 500 (inclusive). If not specified 500 is used. + */ + public static DiskListOption pageSize(long pageSize) { + return new DiskListOption(ComputeRpc.Option.MAX_RESULTS, pageSize); + } + + /** + * Returns an option to specify the page token from which to start listing disks. + */ + public static DiskListOption pageToken(String pageToken) { + return new DiskListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); + } + + /** + * Returns an option to specify the disk's fields to be returned by the RPC call. If this option + * is not provided, all disk's fields are returned. {@code DiskListOption.fields} can be used to + * specify only the fields of interest. {@link Disk#diskId()}, + * {@link DiskConfiguration#diskType()} and either + * {@link SnapshotDiskConfiguration#sourceSnapshot()} or + * {@link ImageDiskConfiguration#sourceImage()} are always returned, even if not specified. + */ + public static DiskListOption fields(DiskField... fields) { + StringBuilder builder = new StringBuilder(); + builder.append("items(").append(DiskField.selector(fields)).append("),nextPageToken"); + return new DiskListOption(ComputeRpc.Option.FIELDS, builder.toString()); + } + } + + /** + * Class for specifying disk aggregated list options. + */ + class DiskAggregatedListOption extends Option { + + private static final long serialVersionUID = 1163784797870242766L; + + private DiskAggregatedListOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify a filter on the disks being listed. + */ + public static DiskAggregatedListOption filter(DiskFilter filter) { + return new DiskAggregatedListOption(ComputeRpc.Option.FILTER, filter.toPb()); + } + + /** + * Returns an option to specify the maximum number of disks returned per page. {@code pageSize} + * must be between 0 and 500 (inclusive). If not specified 500 is used. + */ + public static DiskAggregatedListOption pageSize(long pageSize) { + return new DiskAggregatedListOption(ComputeRpc.Option.MAX_RESULTS, pageSize); + } + + /** + * Returns an option to specify the page token from which to start listing disks. + */ + public static DiskAggregatedListOption pageToken(String pageToken) { + return new DiskAggregatedListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); + } + } + /** * Returns the requested disk type or {@code null} if not found. * @@ -1770,8 +1923,7 @@ public static ImageListOption fields(ImageField... fields) { /** * Creates a new snapshot. * - * @return a zone operation if the create request was issued correctly, {@code null} if - * {@code snapshot.sourceDisk} was not found + * @return a zone operation for snapshot creation * @throws ComputeException upon failure */ Operation create(SnapshotInfo snapshot, OperationOption... options); @@ -1868,4 +2020,51 @@ public static ImageListOption fields(ImageField... fields) { */ Operation deprecate(ImageId image, DeprecationStatus deprecationStatus, OperationOption... options); + + /** + * Returns the requested disk or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + Disk get(DiskId diskId, DiskOption... options); + + /** + * Creates a new disk. + * + * @return a zone operation for disk's creation + * @throws ComputeException upon failure + */ + Operation create(DiskInfo disk, OperationOption... options); + + /** + * Lists disks for the provided zone. + * + * @throws ComputeException upon failure + */ + Page listDisks(String zone, DiskListOption... options); + + /** + * Lists disks for all zones. + * + * @throws ComputeException upon failure + */ + Page listDisks(DiskAggregatedListOption... options); + + /** + * Deletes the requested disk. + * + * @return a zone operation if the request was issued correctly, {@code null} if the disk was not + * found + * @throws ComputeException upon failure + */ + Operation delete(DiskId disk, OperationOption... options); + + /** + * Resizes the disk to the requested size. The new size must be larger than the previous one. + * + * @return a zone operation if the request was issued correctly, {@code null} if the disk was not + * found + * @throws ComputeException upon failure or if the new disk size is smaller than the previous one + */ + Operation resize(DiskId disk, long sizeGb, OperationOption... options); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java index 1f875ad337f1..84e42d33fe10 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java @@ -313,6 +313,46 @@ public Page nextPage() { } } + private static class DiskPageFetcher implements NextPageFetcher { + + private static final long serialVersionUID = 4146589787872718476L; + private final Map requestOptions; + private final ComputeOptions serviceOptions; + private final String zone; + + DiskPageFetcher(String zone, ComputeOptions serviceOptions, String cursor, + Map optionMap) { + this.requestOptions = + PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + this.zone = zone; + } + + @Override + public Page nextPage() { + return listDisks(zone, serviceOptions, requestOptions); + } + } + + private static class AggregatedDiskPageFetcher implements NextPageFetcher { + + private static final long serialVersionUID = -5240045334115926206L; + private final Map requestOptions; + private final ComputeOptions serviceOptions; + + AggregatedDiskPageFetcher(ComputeOptions serviceOptions, String cursor, + Map optionMap) { + this.requestOptions = + PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + } + + @Override + public Page nextPage() { + return listDisks(serviceOptions, requestOptions); + } + } + private final ComputeRpc computeRpc; ComputeImpl(ComputeOptions options) { @@ -1161,6 +1201,141 @@ public com.google.api.services.compute.model.Operation call() { } } + @Override + public Disk get(final DiskId diskId, DiskOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Disk answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Disk call() { + return computeRpc.getDisk(diskId.zone(), diskId.disk(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Disk.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation create(final DiskInfo disk, OperationOption... options) { + final com.google.api.services.compute.model.Disk diskPb = + disk.setProjectId(options().projectId()).toPb(); + final Map optionsMap = optionMap(options); + try { + return Operation.fromPb(this, + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.createDisk(disk.diskId().zone(), diskPb, optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER)); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + private static Function diskFromPb( + final ComputeOptions serviceOptions) { + return new Function() { + @Override + public Disk apply(com.google.api.services.compute.model.Disk disk) { + return Disk.fromPb(serviceOptions.service(), disk); + } + }; + } + + @Override + public Page listDisks(String zone, DiskListOption... options) { + return listDisks(zone, options(), optionMap(options)); + } + + private static Page listDisks(final String zone, final ComputeOptions serviceOptions, + final Map optionsMap) { + try { + ComputeRpc.Tuple> result = + runWithRetries(new Callable>>() { + @Override + public ComputeRpc.Tuple> call() { + return serviceOptions.rpc().listDisks(zone, optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.x(); + Iterable disks = Iterables.transform( + result.y() == null ? ImmutableList.of() + : result.y(), diskFromPb(serviceOptions)); + return new PageImpl<>(new DiskPageFetcher(zone, serviceOptions, cursor, optionsMap), + cursor, disks); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Page listDisks(DiskAggregatedListOption... options) { + return listDisks(options(), optionMap(options)); + } + + private static Page listDisks(final ComputeOptions serviceOptions, + final Map optionsMap) { + try { + ComputeRpc.Tuple> result = + runWithRetries(new Callable>>() { + @Override + public ComputeRpc.Tuple> call() { + return serviceOptions.rpc().listDisks(optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.x(); + Iterable disks = Iterables.transform( + result.y() == null ? ImmutableList.of() + : result.y(), diskFromPb(serviceOptions)); + return new PageImpl<>(new AggregatedDiskPageFetcher(serviceOptions, cursor, optionsMap), + cursor, disks); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation delete(final DiskId disk, OperationOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.deleteDisk(disk.zone(), disk.disk(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation resize(final DiskId disk, final long sizeGb, OperationOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.resizeDisk(disk.zone(), disk.disk(), sizeGb, optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + private Map optionMap(Option... options) { Map optionMap = Maps.newEnumMap(ComputeRpc.Option.class); for (Option option : options) { diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Disk.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Disk.java new file mode 100644 index 000000000000..265996a56af6 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Disk.java @@ -0,0 +1,256 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.gcloud.compute.Compute.DiskOption; +import com.google.gcloud.compute.Compute.OperationOption; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.util.List; +import java.util.Objects; + +/** + * A Google Compute Engine persistent disk. A disk can be used as primary storage for your virtual + * machine instances. Objects of this class are immutable. To get a {@code Disk} object with the + * most recent information use {@link #reload}. {@code Disk} adds a layer of service-related + * functionality over {@link DiskInfo}. + * + * @see Block Storage + */ +public class Disk extends DiskInfo { + + private static final long serialVersionUID = 7234747955588262204L; + + private final ComputeOptions options; + private transient Compute compute; + + /** + * A builder for {@code Disk} objects. + */ + public static class Builder extends DiskInfo.Builder { + + private final Compute compute; + private final DiskInfo.BuilderImpl infoBuilder; + + Builder(Compute compute, DiskId diskId, DiskConfiguration diskConfiguration) { + this.compute = compute; + this.infoBuilder = new DiskInfo.BuilderImpl(diskId, diskConfiguration); + } + + Builder(Disk disk) { + this.compute = disk.compute; + this.infoBuilder = new DiskInfo.BuilderImpl(disk); + } + + @Override + Builder id(String id) { + infoBuilder.id(id); + return this; + } + + @Override + public Builder configuration(DiskConfiguration configuration) { + infoBuilder.configuration(configuration); + return this; + } + + @Override + public Builder diskId(DiskId diskId) { + infoBuilder.diskId(diskId); + return this; + } + + @Override + Builder creationTimestamp(Long creationTimestamp) { + infoBuilder.creationTimestamp(creationTimestamp); + return this; + } + + @Override + Builder creationStatus(CreationStatus creationStatus) { + infoBuilder.creationStatus(creationStatus); + return this; + } + + @Override + public Builder description(String description) { + infoBuilder.description(description); + return this; + } + + @Override + Builder licenses(List licenses) { + infoBuilder.licenses(licenses); + return this; + } + + @Override + Builder attachedInstances(List attachedInstances) { + infoBuilder.attachedInstances(attachedInstances); + return this; + } + + @Override + Builder lastAttachTimestamp(Long lastAttachTimestamp) { + infoBuilder.lastAttachTimestamp(lastAttachTimestamp); + return this; + } + + @Override + Builder lastDetachTimestamp(Long lastDetachTimestamp) { + infoBuilder.lastDetachTimestamp(lastDetachTimestamp); + return this; + } + + @Override + public Disk build() { + return new Disk(compute, infoBuilder); + } + } + + Disk(Compute compute, DiskInfo.BuilderImpl infoBuilder) { + super(infoBuilder); + this.compute = checkNotNull(compute); + this.options = compute.options(); + } + + /** + * Checks if this disk exists. + * + * @return {@code true} if this disk exists, {@code false} otherwise + * @throws ComputeException upon failure + */ + public boolean exists() { + return reload(DiskOption.fields()) != null; + } + + /** + * Fetches current disk's latest information. Returns {@code null} if the disk does not exist. + * + * @param options disk options + * @return a {@code Disk} object with latest information or {@code null} if not found + * @throws ComputeException upon failure + */ + public Disk reload(DiskOption... options) { + return compute.get(diskId(), options); + } + + /** + * Deletes this disk. + * + * @return a zone operation if the delete request was successfully sent, {@code null} if the disk + * was not found + * @throws ComputeException upon failure + */ + public Operation delete(OperationOption... options) { + return compute.delete(diskId(), options); + } + + /** + * Creates a snapshot for this disk given the snapshot's name. + * + * @return a zone operation for snapshot creation + * @throws ComputeException upon failure + */ + public Operation createSnapshot(String snapshot, OperationOption... options) { + return compute.create(SnapshotInfo.of(SnapshotId.of(snapshot), diskId()), options); + } + + /** + * Creates a snapshot for this disk given the snapshot's name and description. + * + * @return a zone operation for snapshot creation + * @throws ComputeException upon failure + */ + public Operation createSnapshot(String snapshot, String description, OperationOption... options) { + SnapshotInfo snapshotInfo = SnapshotInfo.builder(SnapshotId.of(snapshot), diskId()) + .description(description) + .build(); + return compute.create(snapshotInfo, options); + } + + /** + * Creates an image for this disk given the image's name. + * + * @return a global operation if the image creation was successfully requested + * @throws ComputeException upon failure + */ + public Operation createImage(String image, OperationOption... options) { + ImageInfo imageInfo = ImageInfo.of(ImageId.of(image), DiskImageConfiguration.of(diskId())); + return compute.create(imageInfo, options); + } + + /** + * Creates an image for this disk given the image's name and description. + * + * @return a global operation if the image creation was successfully requested + * @throws ComputeException upon failure + */ + public Operation createImage(String image, String description, OperationOption... options) { + ImageInfo imageInfo = ImageInfo.builder(ImageId.of(image), DiskImageConfiguration.of(diskId())) + .description(description) + .build(); + return compute.create(imageInfo, options); + } + + /** + * Resizes this disk to the requested size. The new size must be larger than the previous one. + * + * @return a zone operation if the resize request was issued correctly, {@code null} if this disk + * was not found + * @throws ComputeException upon failure or if the new disk size is smaller than the previous one + */ + public Operation resize(long sizeGb, OperationOption... options) { + return compute.resize(diskId(), sizeGb, options); + } + + /** + * Returns the disk's {@code Compute} object used to issue requests. + */ + public Compute compute() { + return compute; + } + + @Override + public Builder toBuilder() { + return new Builder(this); + } + + @Override + public final boolean equals(Object obj) { + return obj instanceof Disk + && Objects.equals(toPb(), ((Disk) obj).toPb()) + && Objects.equals(options, ((Disk) obj).options); + } + + @Override + public final int hashCode() { + return Objects.hash(super.hashCode(), options); + } + + private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { + input.defaultReadObject(); + this.compute = options.service(); + } + + static Disk fromPb(Compute compute, com.google.api.services.compute.model.Disk diskPb) { + return new Disk(compute, new DiskInfo.BuilderImpl(diskPb)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java index 7c766bef27c9..80a6c08f4db1 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java @@ -16,17 +16,14 @@ package com.google.gcloud.compute; -import com.google.api.services.compute.model.Zone.MaintenanceWindows; import com.google.common.base.Function; import com.google.common.base.MoreObjects; -import com.google.common.collect.Lists; import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.ISODateTimeFormat; import java.io.Serializable; import java.math.BigInteger; -import java.util.List; import java.util.Objects; /** @@ -59,7 +56,6 @@ public com.google.api.services.compute.model.Zone apply(Zone region) { private final Long creationTimestamp; private final String description; private final Status status; - private final List maintenanceWindows; private final RegionId region; private final DeprecationStatus deprecationStatus; @@ -71,113 +67,6 @@ public enum Status { DOWN } - /** - * A scheduled maintenance windows for this zone. When a zone is in a maintenance window, all - * resources which reside in the zone will be unavailable. - * - * @see Maintenance - * Windows - */ - public static final class MaintenanceWindow implements Serializable { - - static final Function FROM_PB_FUNCTION = - new Function() { - @Override - public MaintenanceWindow apply(MaintenanceWindows pb) { - return MaintenanceWindow.fromPb(pb); - } - }; - static final Function TO_PB_FUNCTION = - new Function() { - @Override - public MaintenanceWindows apply(MaintenanceWindow maintenanceWindow) { - return maintenanceWindow.toPb(); - } - }; - - private static final long serialVersionUID = 2270641266683329963L; - - private final String name; - private final String description; - private final Long beginTime; - private final Long endTime; - - /** - * Returns a zone maintenance window object. - */ - MaintenanceWindow(String name, String description, Long beginTime, Long endTime) { - this.name = name; - this.description = description; - this.beginTime = beginTime; - this.endTime = endTime; - } - - /** - * Returns the name of the maintenance window. - */ - public String name() { - return name; - } - - /** - * Returns a textual description of the maintenance window. - */ - public String description() { - return description; - } - - /** - * Returns the starting time of the maintenance window in milliseconds since epoch. - */ - public Long beginTime() { - return beginTime; - } - - /** - * Returns the ending time of the maintenance window in milliseconds since epoch. - */ - public Long endTime() { - return endTime; - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("disk", name) - .add("description", description) - .add("beginTime", beginTime) - .add("endTime", endTime) - .toString(); - } - - @Override - public int hashCode() { - return Objects.hash(name, description, beginTime, endTime); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof MaintenanceWindow - && Objects.equals(toPb(), ((MaintenanceWindow) obj).toPb()); - } - - MaintenanceWindows toPb() { - return new MaintenanceWindows() - .setName(name) - .setDescription(description) - .setBeginTime(beginTime != null ? TIMESTAMP_FORMATTER.print(beginTime) : null) - .setEndTime(endTime != null ? TIMESTAMP_FORMATTER.print(endTime) : null); - } - - static MaintenanceWindow fromPb(MaintenanceWindows windowPb) { - return new MaintenanceWindow(windowPb.getName(), windowPb.getDescription(), - windowPb.getBeginTime() != null - ? TIMESTAMP_FORMATTER.parseMillis(windowPb.getBeginTime()) : null, - windowPb.getEndTime() != null - ? TIMESTAMP_FORMATTER.parseMillis(windowPb.getEndTime()) : null); - } - } - static final class Builder { private ZoneId zoneId; @@ -186,7 +75,6 @@ static final class Builder { private String description; private Status status; - private List maintenanceWindows; private RegionId region; private DeprecationStatus deprecationStatus; @@ -217,11 +105,6 @@ Builder status(Status status) { return this; } - Builder maintenanceWindows(List maintenanceWindows) { - this.maintenanceWindows = maintenanceWindows; - return this; - } - Builder region(RegionId region) { this.region = region; return this; @@ -243,7 +126,6 @@ private Zone(Builder builder) { this.creationTimestamp = builder.creationTimestamp; this.description = builder.description; this.status = builder.status; - this.maintenanceWindows = builder.maintenanceWindows; this.region = builder.region; this.deprecationStatus = builder.deprecationStatus; } @@ -283,17 +165,6 @@ public Status status() { return status; } - /** - * Returns the scheduled maintenance windows for this zone, if any. When the zone is in a - * maintenance window, all resources which reside in the zone will be unavailable. - * - * @see Maintenance - * Windows - */ - public List maintenanceWindows() { - return maintenanceWindows; - } - /** * Returns the identity of the region that hosts the zone. */ @@ -318,7 +189,6 @@ public String toString() { .add("creationTimestamp", creationTimestamp) .add("description", description) .add("status", status) - .add("maintenanceWindows", maintenanceWindows) .add("region", region) .add("deprecationStatus", deprecationStatus) .toString(); @@ -349,10 +219,6 @@ com.google.api.services.compute.model.Zone toPb() { if (status != null) { zonePb.setStatus(status.name()); } - if (maintenanceWindows != null) { - zonePb.setMaintenanceWindows( - Lists.transform(maintenanceWindows, MaintenanceWindow.TO_PB_FUNCTION)); - } if (region != null) { zonePb.setRegion(region.selfLink()); } @@ -379,10 +245,6 @@ static Zone fromPb(com.google.api.services.compute.model.Zone zonePb) { if (zonePb.getStatus() != null) { builder.status(Status.valueOf(zonePb.getStatus())); } - if (zonePb.getMaintenanceWindows() != null) { - builder.maintenanceWindows( - Lists.transform(zonePb.getMaintenanceWindows(), MaintenanceWindow.FROM_PB_FUNCTION)); - } if (zonePb.getRegion() != null) { builder.region(RegionId.fromUrl(zonePb.getRegion())); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java index 523686283db0..1066124e0638 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java @@ -18,6 +18,7 @@ import com.google.api.services.compute.model.Address; import com.google.api.services.compute.model.DeprecationStatus; +import com.google.api.services.compute.model.Disk; import com.google.api.services.compute.model.DiskType; import com.google.api.services.compute.model.Image; import com.google.api.services.compute.model.License; @@ -305,8 +306,7 @@ public Y y() { /** * Creates a snapshot for the specified disk. * - * @return a zone operation if the create request was issued correctly, {@code null} if the disk - * was not found + * @return a zone operation for snapshot creation * @throws ComputeException upon failure */ Operation createSnapshot(String zone, String disk, String snapshot, String description, @@ -377,4 +377,51 @@ Operation createSnapshot(String zone, String disk, String snapshot, String descr */ Operation deprecateImage(String project, String image, DeprecationStatus deprecationStatus, Map options); + + /** + * Returns the requested disk or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + Disk getDisk(String zone, String disk, Map options); + + /** + * Creates a new disk. + * + * @return a zone operation for disk's creation + * @throws ComputeException upon failure + */ + Operation createDisk(String zone, Disk disk, Map options); + + /** + * Lists the disks for the provided zone. + * + * @throws ComputeException upon failure + */ + Tuple> listDisks(String zone, Map options); + + /** + * Lists disks for all zones. + * + * @throws ComputeException upon failure + */ + Tuple> listDisks(Map options); + + /** + * Deletes the requested disk. + * + * @return a zone operation if the request was issued correctly, {@code null} if the disk was not + * found + * @throws ComputeException upon failure + */ + Operation deleteDisk(String zone, String disk, Map options); + + /** + * Resizes the disk to the requested size. The new size must be larger than the previous one. + * + * @return a zone operation if the request was issued correctly, {@code null} if the disk was not + * found + * @throws ComputeException upon failure or if the new disk size is smaller than the previous one + */ + Operation resizeDisk(String zone, String disk, long sizeGb, Map options); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java index 7d0b77a7a73a..4899ab9c8445 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java @@ -31,10 +31,15 @@ import com.google.api.services.compute.model.AddressList; import com.google.api.services.compute.model.AddressesScopedList; import com.google.api.services.compute.model.DeprecationStatus; +import com.google.api.services.compute.model.Disk; +import com.google.api.services.compute.model.DiskAggregatedList; +import com.google.api.services.compute.model.DiskList; import com.google.api.services.compute.model.DiskType; import com.google.api.services.compute.model.DiskTypeAggregatedList; import com.google.api.services.compute.model.DiskTypeList; import com.google.api.services.compute.model.DiskTypesScopedList; +import com.google.api.services.compute.model.DisksResizeRequest; +import com.google.api.services.compute.model.DisksScopedList; import com.google.api.services.compute.model.Image; import com.google.api.services.compute.model.ImageList; import com.google.api.services.compute.model.License; @@ -522,7 +527,7 @@ public Operation createSnapshot(String zone, String disk, String snapshot, Strin .setFields(FIELDS.getString(options)) .execute(); } catch (IOException ex) { - return nullForNotFound(ex); + throw translate(ex); } } @@ -633,6 +638,98 @@ public Operation deprecateImage(String project, String image, DeprecationStatus } } + @Override + public Disk getDisk(String zone, String disk, Map options) { + try { + return compute.disks() + .get(this.options.projectId(), zone, disk) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Operation createDisk(String zone, Disk disk, Map options) { + try { + return compute.disks() + .insert(this.options.projectId(), zone, disk) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Tuple> listDisks(String zone, Map options) { + try { + DiskList diskList = compute.disks() + .list(this.options.projectId(), zone) + .setFilter(FILTER.getString(options)) + .setMaxResults(MAX_RESULTS.getLong(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + .setFields(FIELDS.getString(options)) + .execute(); + Iterable disks = diskList.getItems(); + return Tuple.of(diskList.getNextPageToken(), disks); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Tuple> listDisks(Map options) { + try { + DiskAggregatedList aggregatedList = compute.disks() + .aggregatedList(this.options.projectId()) + .setFilter(FILTER.getString(options)) + .setMaxResults(MAX_RESULTS.getLong(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + // todo(mziccard): uncomment or remove once #711 is closed + // .setFields(FIELDS.getString(options)) + .execute(); + ImmutableList.Builder builder = ImmutableList.builder(); + Map scopedList = aggregatedList.getItems(); + if (scopedList != null) { + for (DisksScopedList disksScopedList : scopedList.values()) { + if (disksScopedList.getDisks() != null) { + builder.addAll(disksScopedList.getDisks()); + } + } + } + return Tuple.>of(aggregatedList.getNextPageToken(), + builder.build()); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Operation deleteDisk(String zone, String disk, Map options) { + try { + return compute.disks() + .delete(this.options.projectId(), zone, disk) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Operation resizeDisk(String zone, String disk, long sizeGb, Map options) { + try { + DisksResizeRequest resizeRequest = new DisksResizeRequest().setSizeGb(sizeGb); + return compute.disks().resize(this.options.projectId(), zone, disk, resizeRequest) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + /** * This method returns {@code null} if the error code of {@code exception} was 404, re-throws the * exception otherwise. diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java index ec981a95e0e7..277f8826b421 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java @@ -38,6 +38,11 @@ import com.google.gcloud.compute.Compute.AddressFilter; import com.google.gcloud.compute.Compute.AddressListOption; import com.google.gcloud.compute.Compute.AddressOption; +import com.google.gcloud.compute.Compute.DiskAggregatedListOption; +import com.google.gcloud.compute.Compute.DiskField; +import com.google.gcloud.compute.Compute.DiskFilter; +import com.google.gcloud.compute.Compute.DiskListOption; +import com.google.gcloud.compute.Compute.DiskOption; import com.google.gcloud.compute.Compute.DiskTypeAggregatedListOption; import com.google.gcloud.compute.Compute.DiskTypeFilter; import com.google.gcloud.compute.Compute.DiskTypeListOption; @@ -66,7 +71,6 @@ import com.google.gcloud.compute.Operation.OperationError; import com.google.gcloud.compute.Operation.OperationWarning; import com.google.gcloud.compute.Operation.Status; -import com.google.gcloud.compute.Zone.MaintenanceWindow; import com.google.gcloud.spi.ComputeRpc; import com.google.gcloud.spi.ComputeRpc.Tuple; import com.google.gcloud.spi.ComputeRpcFactory; @@ -137,18 +141,12 @@ public class ComputeImplTest { .build(); private static final ZoneId ZONE_ID = ZoneId.of("project", "zone"); private static final Zone.Status ZONE_STATUS = Zone.Status.DOWN; - private static final MaintenanceWindow WINDOW1 = new MaintenanceWindow("NAME1", "DESCRIPTION1", - 1453293420000L, 1453293480000L); - private static final MaintenanceWindow WINDOW2 = new MaintenanceWindow("NAME2", "DESCRIPTION2", - 1453293420000L, 1453293480000L); - private static final List WINDOWS = ImmutableList.of(WINDOW1, WINDOW2); private static final Zone ZONE = Zone.builder() .zoneId(ZONE_ID) .id(ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .status(ZONE_STATUS) - .maintenanceWindows(WINDOWS) .region(REGION_ID) .build(); private static final LicenseId LICENSE_ID = LicenseId.of("project", "license"); @@ -198,6 +196,8 @@ public class ComputeImplTest { private static final ImageInfo IMAGE = ImageInfo.of(IMAGE_ID, DiskImageConfiguration.of(DISK_ID)); private static final DeprecationStatus DEPRECATION_STATUS = DeprecationStatus.builder(DeprecationStatus.Status.DEPRECATED, IMAGE_ID).build(); + private static final DiskInfo DISK = + DiskInfo.of(DISK_ID, StandardDiskConfiguration.of(DISK_TYPE_ID)); // Empty ComputeRpc options private static final Map EMPTY_RPC_OPTIONS = ImmutableMap.of(); @@ -369,6 +369,28 @@ public class ComputeImplTest { MAX_RESULTS, 42L, FILTER, "diskSizeGb ne 500"); + // Disk options + private static final DiskOption DISK_OPTION_FIELDS = + DiskOption.fields(DiskField.ID, DiskField.DESCRIPTION); + + // Disk list options + private static final DiskFilter DISK_FILTER = DiskFilter.notEquals(DiskField.SIZE_GB, 500L); + private static final DiskListOption DISK_LIST_PAGE_TOKEN = DiskListOption.pageToken("cursor"); + private static final DiskListOption DISK_LIST_PAGE_SIZE = DiskListOption.pageSize(42L); + private static final DiskListOption DISK_LIST_FILTER = DiskListOption.filter(DISK_FILTER); + private static final Map DISK_LIST_OPTIONS = ImmutableMap.of( + PAGE_TOKEN, "cursor", + MAX_RESULTS, 42L, + FILTER, "sizeGb ne 500"); + + // Disk aggregated list options + private static final DiskAggregatedListOption DISK_AGGREGATED_LIST_PAGE_TOKEN = + DiskAggregatedListOption.pageToken("cursor"); + private static final DiskAggregatedListOption DISK_AGGREGATED_LIST_PAGE_SIZE = + DiskAggregatedListOption.pageSize(42L); + private static final DiskAggregatedListOption DISK_AGGREGATED_LIST_FILTER = + DiskAggregatedListOption.filter(DISK_FILTER); + private static final Function OPERATION_TO_PB_FUNCTION = new Function() { @@ -2376,6 +2398,291 @@ public void testListImagesForProjectWithOptions() { assertArrayEquals(imageList.toArray(), Iterables.toArray(page.values(), Image.class)); } + @Test + public void testGetDisk() { + EasyMock.expect(computeRpcMock.getDisk(DISK_ID.zone(), DISK_ID.disk(), EMPTY_RPC_OPTIONS)) + .andReturn(DISK.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Disk disk = compute.get(DISK_ID); + assertEquals(new Disk(compute, new DiskInfo.BuilderImpl(DISK)), disk); + } + + @Test + public void testGetDisk_Null() { + EasyMock.expect(computeRpcMock.getDisk(DISK_ID.zone(), DISK_ID.disk(), EMPTY_RPC_OPTIONS)) + .andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.get(DISK_ID)); + } + + @Test + public void testGetDiskWithSelectedFields() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.getDisk(eq(DISK_ID.zone()), eq(DISK_ID.disk()), + capture(capturedOptions))).andReturn(DISK.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Disk disk = compute.get(DISK_ID, DISK_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(DISK_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("type")); + assertTrue(selector.contains("sourceImage")); + assertTrue(selector.contains("sourceSnapshot")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(55, selector.length()); + assertEquals(new Disk(compute, new DiskInfo.BuilderImpl(DISK)), disk); + } + + @Test + public void testDeleteDisk_Operation() { + EasyMock.expect(computeRpcMock.deleteDisk(DISK_ID.zone(), DISK_ID.disk(), EMPTY_RPC_OPTIONS)) + .andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(zoneOperation, compute.delete(DISK_ID)); + } + + @Test + public void testDeleteDiskWithSelectedFields_Operation() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.deleteDisk(eq(DISK_ID.zone()), eq(DISK_ID.disk()), + capture(capturedOptions))).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.delete(DISK_ID, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(zoneOperation, operation); + } + + @Test + public void testDeleteDisk_Null() { + EasyMock.expect(computeRpcMock.deleteDisk(DISK_ID.zone(), DISK_ID.disk(), EMPTY_RPC_OPTIONS)) + .andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.delete(DISK_ID)); + } + + @Test + public void testListDisks() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList diskList = ImmutableList.of( + new Disk(compute, new DiskInfo.BuilderImpl(DISK)), + new Disk(compute, new DiskInfo.BuilderImpl(DISK))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(diskList, DiskInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listDisks(DISK_ID.zone(), EMPTY_RPC_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listDisks(DISK_ID.zone()); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(diskList.toArray(), Iterables.toArray(page.values(), Disk.class)); + } + + @Test + public void testListDisksNextPage() { + String cursor = "cursor"; + String nextCursor = "nextCursor"; + compute = options.service(); + ImmutableList diskList = ImmutableList.of( + new Disk(compute, new DiskInfo.BuilderImpl(DISK)), + new Disk(compute, new DiskInfo.BuilderImpl(DISK))); + ImmutableList nextDiskList = ImmutableList.of( + new Disk(compute, new DiskInfo.BuilderImpl(DISK))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(diskList, DiskInfo.TO_PB_FUNCTION)); + Tuple> nextResult = + Tuple.of(nextCursor, Iterables.transform(nextDiskList, DiskInfo.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + EasyMock.expect(computeRpcMock.listDisks(DISK_ID.zone(), EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.expect(computeRpcMock.listDisks(DISK_ID.zone(), nextOptions)).andReturn(nextResult); + EasyMock.replay(computeRpcMock); + Page page = compute.listDisks(DISK_ID.zone()); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(diskList.toArray(), Iterables.toArray(page.values(), Disk.class)); + page = page.nextPage(); + assertEquals(nextCursor, page.nextPageCursor()); + assertArrayEquals(nextDiskList.toArray(), Iterables.toArray(page.values(), Disk.class)); + } + + @Test + public void testListEmptyDisks() { + compute = options.service(); + ImmutableList disks = ImmutableList.of(); + Tuple> result = + Tuple.>of(null, disks); + EasyMock.expect(computeRpcMock.listDisks(DISK_ID.zone(), EMPTY_RPC_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listDisks(DISK_ID.zone()); + assertNull(page.nextPageCursor()); + assertArrayEquals(disks.toArray(), Iterables.toArray(page.values(), Disk.class)); + } + + @Test + public void testListDisksWithOptions() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList diskList = ImmutableList.of( + new Disk(compute, new DiskInfo.BuilderImpl(DISK)), + new Disk(compute, new DiskInfo.BuilderImpl(DISK))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(diskList, DiskInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listDisks(DISK_ID.zone(), DISK_LIST_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listDisks(DISK_ID.zone(), DISK_LIST_PAGE_SIZE, DISK_LIST_PAGE_TOKEN, + DISK_LIST_FILTER); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(diskList.toArray(), Iterables.toArray(page.values(), Disk.class)); + } + + @Test + public void testAggregatedListDisks() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList diskList = ImmutableList.of( + new Disk(compute, new DiskInfo.BuilderImpl(DISK)), + new Disk(compute, new DiskInfo.BuilderImpl(DISK))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(diskList, DiskInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listDisks(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listDisks(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(diskList.toArray(), Iterables.toArray(page.values(), Disk.class)); + } + + @Test + public void testAggregatedListDisksNextPage() { + String cursor = "cursor"; + String nextCursor = "nextCursor"; + compute = options.service(); + ImmutableList diskList = ImmutableList.of( + new Disk(compute, new DiskInfo.BuilderImpl(DISK)), + new Disk(compute, new DiskInfo.BuilderImpl(DISK))); + ImmutableList nextDiskList = ImmutableList.of( + new Disk(compute, new DiskInfo.BuilderImpl(DISK))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(diskList, DiskInfo.TO_PB_FUNCTION)); + Tuple> nextResult = + Tuple.of(nextCursor, Iterables.transform(nextDiskList, DiskInfo.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + EasyMock.expect(computeRpcMock.listDisks(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.expect(computeRpcMock.listDisks(nextOptions)).andReturn(nextResult); + EasyMock.replay(computeRpcMock); + Page page = compute.listDisks(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(diskList.toArray(), Iterables.toArray(page.values(), Disk.class)); + page = page.nextPage(); + assertEquals(nextCursor, page.nextPageCursor()); + assertArrayEquals(nextDiskList.toArray(), Iterables.toArray(page.values(), Disk.class)); + } + + @Test + public void testAggregatedListEmptyDisks() { + compute = options.service(); + ImmutableList diskList = ImmutableList.of(); + Tuple> result = + Tuple.>of(null, diskList); + EasyMock.expect(computeRpcMock.listDisks(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listDisks(); + assertNull(page.nextPageCursor()); + assertArrayEquals(diskList.toArray(), Iterables.toArray(page.values(), Disk.class)); + } + + @Test + public void testAggregatedListDisksWithOptions() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList diskList = ImmutableList.of( + new Disk(compute, new DiskInfo.BuilderImpl(DISK)), + new Disk(compute, new DiskInfo.BuilderImpl(DISK))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(diskList, DiskInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listDisks(DISK_LIST_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listDisks(DISK_AGGREGATED_LIST_PAGE_SIZE, + DISK_AGGREGATED_LIST_PAGE_TOKEN, DISK_AGGREGATED_LIST_FILTER); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(diskList.toArray(), Iterables.toArray(page.values(), Disk.class)); + } + + @Test + public void testCreateDisk() { + EasyMock.expect(computeRpcMock.createDisk(DISK_ID.zone(), DISK.toPb(), EMPTY_RPC_OPTIONS)) + .andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + DiskId diskId = DiskId.of("zone", "disk"); + DiskTypeId diskTypeId = DiskTypeId.of("zone", "diskType"); + DiskInfo disk = DISK.toBuilder() + .diskId(diskId) + .configuration(StandardDiskConfiguration.of(diskTypeId)) + .build(); + Operation operation = compute.create(disk); + assertEquals(zoneOperation, operation); + } + + @Test + public void testCreateDiskWithOptions() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.createDisk(eq(DISK_ID.zone()), eq(DISK.toPb()), + capture(capturedOptions))).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.create(DISK, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(zoneOperation, operation); + } + + @Test + public void testResizeDisk_Operation() { + EasyMock.expect(computeRpcMock.resizeDisk(DISK_ID.zone(), DISK_ID.disk(), 42L, + EMPTY_RPC_OPTIONS)).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(zoneOperation, compute.resize(DISK_ID, 42L)); + } + + @Test + public void testResizeDiskWithSelectedFields_Operation() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.resizeDisk(eq(DISK_ID.zone()), eq(DISK_ID.disk()), eq(42L), + capture(capturedOptions))).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.resize(DISK_ID, 42L, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(zoneOperation, operation); + } + + @Test + public void testResizeDisk_Null() { + EasyMock.expect(computeRpcMock.resizeDisk(DISK_ID.zone(), DISK_ID.disk(), 42L, + EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.resize(DISK_ID, 42L)); + } + @Test public void testRetryableException() { EasyMock.expect( diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTest.java new file mode 100644 index 000000000000..8915a7894147 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTest.java @@ -0,0 +1,475 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.createStrictMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import com.google.common.collect.ImmutableList; +import com.google.gcloud.compute.DiskInfo.CreationStatus; + +import org.junit.Test; + +import java.util.List; + +public class DiskTest { + + private static final String ID = "42"; + private static final DiskId DISK_ID = DiskId.of("project", "zone", "disk"); + private static final Long CREATION_TIMESTAMP = 1453293540000L; + private static final CreationStatus CREATION_STATUS = CreationStatus.READY; + private static final String DESCRIPTION = "description"; + private static final Long SIZE_GB = 500L; + private static final DiskTypeId TYPE = DiskTypeId.of("project", "zone", "disk"); + private static final List LICENSES = ImmutableList.of( + LicenseId.of("project", "license1"), LicenseId.of("project", "license2")); + private static final List ATTACHED_INSTANCES = ImmutableList.of( + InstanceId.of("project", "zone", "instance1"), + InstanceId.of("project", "zone", "instance2")); + private static final SnapshotId SNAPSHOT = SnapshotId.of("project", "snapshot"); + private static final ImageId IMAGE = ImageId.of("project", "image"); + private static final String SNAPSHOT_ID = "snapshotId"; + private static final String IMAGE_ID = "imageId"; + private static final Long LAST_ATTACH_TIMESTAMP = 1453293600000L; + private static final Long LAST_DETACH_TIMESTAMP = 1453293660000L; + private static final StandardDiskConfiguration DISK_CONFIGURATION = + StandardDiskConfiguration.builder() + .sizeGb(SIZE_GB) + .diskType(TYPE) + .build(); + private static final SnapshotDiskConfiguration SNAPSHOT_DISK_CONFIGURATION = + SnapshotDiskConfiguration.builder(SNAPSHOT) + .sizeGb(SIZE_GB) + .diskType(TYPE) + .sourceSnapshotId(SNAPSHOT_ID) + .build(); + private static final ImageDiskConfiguration IMAGE_DISK_CONFIGURATION = + ImageDiskConfiguration.builder(IMAGE) + .sizeGb(SIZE_GB) + .diskType(TYPE) + .sourceImageId(IMAGE_ID) + .build(); + + private final Compute serviceMockReturnsOptions = createStrictMock(Compute.class); + private final ComputeOptions mockOptions = createMock(ComputeOptions.class); + private Compute compute; + private Disk disk; + private Disk standardDisk; + private Disk snapshotDisk; + private Disk imageDisk; + + private void initializeExpectedDisk(int optionsCalls) { + expect(serviceMockReturnsOptions.options()).andReturn(mockOptions).times(optionsCalls); + replay(serviceMockReturnsOptions); + standardDisk = new Disk.Builder(serviceMockReturnsOptions, DISK_ID, DISK_CONFIGURATION) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .creationStatus(CREATION_STATUS) + .description(DESCRIPTION) + .licenses(LICENSES) + .attachedInstances(ATTACHED_INSTANCES) + .lastAttachTimestamp(LAST_ATTACH_TIMESTAMP) + .lastDetachTimestamp(LAST_DETACH_TIMESTAMP) + .build(); + snapshotDisk = new Disk.Builder(serviceMockReturnsOptions, DISK_ID, SNAPSHOT_DISK_CONFIGURATION) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .creationStatus(CREATION_STATUS) + .description(DESCRIPTION) + .licenses(LICENSES) + .attachedInstances(ATTACHED_INSTANCES) + .lastAttachTimestamp(LAST_ATTACH_TIMESTAMP) + .lastDetachTimestamp(LAST_DETACH_TIMESTAMP) + .build(); + imageDisk = new Disk.Builder(serviceMockReturnsOptions, DISK_ID, IMAGE_DISK_CONFIGURATION) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .creationStatus(CREATION_STATUS) + .description(DESCRIPTION) + .licenses(LICENSES) + .attachedInstances(ATTACHED_INSTANCES) + .lastAttachTimestamp(LAST_ATTACH_TIMESTAMP) + .lastDetachTimestamp(LAST_DETACH_TIMESTAMP) + .build(); + compute = createStrictMock(Compute.class); + } + + private void initializeDisk() { + disk = new Disk.Builder(compute, DISK_ID, DISK_CONFIGURATION) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .creationStatus(CREATION_STATUS) + .description(DESCRIPTION) + .licenses(LICENSES) + .attachedInstances(ATTACHED_INSTANCES) + .build(); + } + + @Test + public void testToBuilder() { + initializeExpectedDisk(16); + compareDisk(standardDisk, standardDisk.toBuilder().build()); + compareDisk(imageDisk, imageDisk.toBuilder().build()); + compareDisk(snapshotDisk, snapshotDisk.toBuilder().build()); + Disk newDisk = standardDisk.toBuilder().description("newDescription").build(); + assertEquals("newDescription", newDisk.description()); + newDisk = newDisk.toBuilder().description("description").build(); + compareDisk(standardDisk, newDisk); + } + + @Test + public void testToBuilderIncomplete() { + initializeExpectedDisk(18); + DiskInfo diskInfo = DiskInfo.of(DISK_ID, DISK_CONFIGURATION); + Disk disk = new Disk(serviceMockReturnsOptions, new DiskInfo.BuilderImpl(diskInfo)); + compareDisk(disk, disk.toBuilder().build()); + diskInfo = DiskInfo.of(DISK_ID, SNAPSHOT_DISK_CONFIGURATION); + disk = new Disk(serviceMockReturnsOptions, new DiskInfo.BuilderImpl(diskInfo)); + compareDisk(disk, disk.toBuilder().build()); + diskInfo = DiskInfo.of(DISK_ID, IMAGE_DISK_CONFIGURATION); + disk = new Disk(serviceMockReturnsOptions, new DiskInfo.BuilderImpl(diskInfo)); + compareDisk(disk, disk.toBuilder().build()); + } + + @Test + public void testBuilder() { + initializeExpectedDisk(4); + assertEquals(DISK_ID, standardDisk.diskId()); + assertEquals(ID, standardDisk.id()); + assertEquals(DISK_CONFIGURATION, standardDisk.configuration()); + assertEquals(CREATION_TIMESTAMP, standardDisk.creationTimestamp()); + assertEquals(CREATION_STATUS, standardDisk.creationStatus()); + assertEquals(DESCRIPTION, standardDisk.description()); + assertEquals(LICENSES, standardDisk.licenses()); + assertEquals(ATTACHED_INSTANCES, standardDisk.attachedInstances()); + assertEquals(LAST_ATTACH_TIMESTAMP, standardDisk.lastAttachTimestamp()); + assertEquals(LAST_DETACH_TIMESTAMP, standardDisk.lastDetachTimestamp()); + assertSame(serviceMockReturnsOptions, standardDisk.compute()); + assertEquals(DISK_ID, imageDisk.diskId()); + assertEquals(ID, imageDisk.id()); + assertEquals(IMAGE_DISK_CONFIGURATION, imageDisk.configuration()); + assertEquals(CREATION_TIMESTAMP, imageDisk.creationTimestamp()); + assertEquals(CREATION_STATUS, imageDisk.creationStatus()); + assertEquals(DESCRIPTION, imageDisk.description()); + assertEquals(LICENSES, imageDisk.licenses()); + assertEquals(ATTACHED_INSTANCES, imageDisk.attachedInstances()); + assertEquals(LAST_ATTACH_TIMESTAMP, imageDisk.lastAttachTimestamp()); + assertEquals(LAST_DETACH_TIMESTAMP, imageDisk.lastDetachTimestamp()); + assertSame(serviceMockReturnsOptions, imageDisk.compute()); + assertEquals(DISK_ID, snapshotDisk.diskId()); + assertEquals(ID, snapshotDisk.id()); + assertEquals(SNAPSHOT_DISK_CONFIGURATION, snapshotDisk.configuration()); + assertEquals(CREATION_TIMESTAMP, snapshotDisk.creationTimestamp()); + assertEquals(CREATION_STATUS, snapshotDisk.creationStatus()); + assertEquals(DESCRIPTION, snapshotDisk.description()); + assertEquals(LICENSES, snapshotDisk.licenses()); + assertEquals(ATTACHED_INSTANCES, snapshotDisk.attachedInstances()); + assertEquals(LAST_ATTACH_TIMESTAMP, snapshotDisk.lastAttachTimestamp()); + assertEquals(LAST_DETACH_TIMESTAMP, snapshotDisk.lastDetachTimestamp()); + assertSame(serviceMockReturnsOptions, snapshotDisk.compute()); + Disk disk = new Disk.Builder(serviceMockReturnsOptions, DISK_ID, DISK_CONFIGURATION) + .diskId(DiskId.of("newProject", "newZone")) + .configuration(SNAPSHOT_DISK_CONFIGURATION) + .build(); + assertEquals(DiskId.of("newProject", "newZone"), disk.diskId()); + assertNull(disk.id()); + assertEquals(SNAPSHOT_DISK_CONFIGURATION, disk.configuration()); + assertNull(disk.creationTimestamp()); + assertNull(disk.creationStatus()); + assertNull(disk.description()); + assertNull(disk.licenses()); + assertNull(disk.attachedInstances()); + assertNull(disk.lastAttachTimestamp()); + assertNull(disk.lastDetachTimestamp()); + assertSame(serviceMockReturnsOptions, disk.compute()); + } + + @Test + public void testToAndFromPb() { + initializeExpectedDisk(24); + compareDisk(standardDisk, Disk.fromPb(serviceMockReturnsOptions, standardDisk.toPb())); + compareDisk(imageDisk, Disk.fromPb(serviceMockReturnsOptions, imageDisk.toPb())); + compareDisk(snapshotDisk, Disk.fromPb(serviceMockReturnsOptions, snapshotDisk.toPb())); + Disk disk = new Disk.Builder(serviceMockReturnsOptions, DISK_ID, DISK_CONFIGURATION).build(); + compareDisk(disk, Disk.fromPb(serviceMockReturnsOptions, disk.toPb())); + disk = + new Disk.Builder(serviceMockReturnsOptions, DISK_ID, SNAPSHOT_DISK_CONFIGURATION).build(); + compareDisk(disk, Disk.fromPb(serviceMockReturnsOptions, disk.toPb())); + disk = new Disk.Builder(serviceMockReturnsOptions, DISK_ID, IMAGE_DISK_CONFIGURATION).build(); + compareDisk(disk, Disk.fromPb(serviceMockReturnsOptions, disk.toPb())); + } + + @Test + public void testDeleteOperation() { + initializeExpectedDisk(4); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "zone", "op")) + .build(); + expect(compute.delete(DISK_ID)).andReturn(operation); + replay(compute); + initializeDisk(); + assertSame(operation, disk.delete()); + } + + @Test + public void testDeleteNull() { + initializeExpectedDisk(3); + expect(compute.options()).andReturn(mockOptions); + expect(compute.delete(DISK_ID)).andReturn(null); + replay(compute); + initializeDisk(); + assertNull(disk.delete()); + } + + @Test + public void testExists_True() throws Exception { + initializeExpectedDisk(3); + Compute.DiskOption[] expectedOptions = {Compute.DiskOption.fields()}; + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(DISK_ID, expectedOptions)).andReturn(imageDisk); + replay(compute); + initializeDisk(); + assertTrue(disk.exists()); + verify(compute); + } + + @Test + public void testExists_False() throws Exception { + initializeExpectedDisk(3); + Compute.DiskOption[] expectedOptions = {Compute.DiskOption.fields()}; + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(DISK_ID, expectedOptions)).andReturn(null); + replay(compute); + initializeDisk(); + assertFalse(disk.exists()); + verify(compute); + } + + @Test + public void testReload() throws Exception { + initializeExpectedDisk(5); + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(DISK_ID)).andReturn(imageDisk); + replay(compute); + initializeDisk(); + Disk updatedDisk = disk.reload(); + compareDisk(imageDisk, updatedDisk); + verify(compute); + } + + @Test + public void testReloadNull() throws Exception { + initializeExpectedDisk(3); + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(DISK_ID)).andReturn(null); + replay(compute); + initializeDisk(); + assertNull(disk.reload()); + verify(compute); + } + + @Test + public void testReloadWithOptions() throws Exception { + initializeExpectedDisk(5); + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(DISK_ID, Compute.DiskOption.fields())).andReturn(imageDisk); + replay(compute); + initializeDisk(); + Disk updatedDisk = disk.reload(Compute.DiskOption.fields()); + compareDisk(imageDisk, updatedDisk); + verify(compute); + } + + @Test + public void testCreateSnapshot() { + initializeExpectedDisk(4); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "zone", "op")) + .build(); + SnapshotId snapshotId = SnapshotId.of(SNAPSHOT.snapshot()); + SnapshotInfo snapshot = SnapshotInfo.builder(snapshotId, DISK_ID).build(); + expect(compute.create(snapshot)).andReturn(operation); + replay(compute); + initializeDisk(); + assertSame(operation, disk.createSnapshot(SNAPSHOT.snapshot())); + } + + @Test + public void testCreateSnapshotWithDescription() { + initializeExpectedDisk(4); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "zone", "op")) + .build(); + SnapshotId snapshotId = SnapshotId.of(SNAPSHOT.snapshot()); + SnapshotInfo snapshot = SnapshotInfo.builder(snapshotId, DISK_ID) + .description("description") + .build(); + expect(compute.create(snapshot)).andReturn(operation); + replay(compute); + initializeDisk(); + assertSame(operation, disk.createSnapshot(SNAPSHOT.snapshot(), "description")); + } + + @Test + public void testCreateSnapshotWithOptions() { + initializeExpectedDisk(4); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "zone", "op")) + .build(); + SnapshotId snapshotId = SnapshotId.of(SNAPSHOT.snapshot()); + SnapshotInfo snapshot = SnapshotInfo.builder(snapshotId, DISK_ID).build(); + expect(compute.create(snapshot, Compute.OperationOption.fields())).andReturn(operation); + replay(compute); + initializeDisk(); + assertSame(operation, + disk.createSnapshot(SNAPSHOT.snapshot(), Compute.OperationOption.fields())); + } + + @Test + public void testCreateSnapshotWithDescriptionAndOptions() { + initializeExpectedDisk(4); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "zone", "op")) + .build(); + SnapshotId snapshotId = SnapshotId.of(SNAPSHOT.snapshot()); + SnapshotInfo snapshot = SnapshotInfo.builder(snapshotId, DISK_ID) + .description("description") + .build(); + expect(compute.create(snapshot, Compute.OperationOption.fields())).andReturn(operation); + replay(compute); + initializeDisk(); + assertSame(operation, + disk.createSnapshot(SNAPSHOT.snapshot(), "description", Compute.OperationOption.fields())); + } + + @Test + public void testCreateImage() { + initializeExpectedDisk(4); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(GlobalOperationId.of("project", "op")) + .build(); + ImageId imageId = ImageId.of(IMAGE.image()); + ImageInfo image = ImageInfo.of(imageId, DiskImageConfiguration.of(DISK_ID)); + expect(compute.create(image)).andReturn(operation); + replay(compute); + initializeDisk(); + assertSame(operation, disk.createImage(IMAGE.image())); + } + + @Test + public void testCreateImageWithDescription() { + initializeExpectedDisk(4); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(GlobalOperationId.of("project", "op")) + .build(); + ImageId imageId = ImageId.of(IMAGE.image()); + ImageInfo image = ImageInfo.builder(imageId, DiskImageConfiguration.of(DISK_ID)) + .description("description") + .build(); + expect(compute.create(image)).andReturn(operation); + replay(compute); + initializeDisk(); + assertSame(operation, disk.createImage(IMAGE.image(), "description")); + } + + @Test + public void testCreateImageWithOptions() { + initializeExpectedDisk(4); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(GlobalOperationId.of("project", "op")) + .build(); + ImageId imageId = ImageId.of(IMAGE.image()); + ImageInfo image = ImageInfo.of(imageId, DiskImageConfiguration.of(DISK_ID)); + expect(compute.create(image, Compute.OperationOption.fields())).andReturn(operation); + replay(compute); + initializeDisk(); + assertSame(operation, disk.createImage(IMAGE.image(), Compute.OperationOption.fields())); + } + + @Test + public void testCreateImageWithDescriptionAndOptions() { + initializeExpectedDisk(4); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(GlobalOperationId.of("project", "op")) + .build(); + ImageId imageId = ImageId.of(IMAGE.image()); + ImageInfo image = ImageInfo.builder(imageId, DiskImageConfiguration.of(DISK_ID)) + .description("description") + .build(); + expect(compute.create(image, Compute.OperationOption.fields())).andReturn(operation); + replay(compute); + initializeDisk(); + assertSame(operation, + disk.createImage(IMAGE.image(), "description", Compute.OperationOption.fields())); + } + + @Test + public void testResizeOperation() { + initializeExpectedDisk(4); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "zone", "op")) + .build(); + expect(compute.resize(DISK_ID, 42L)).andReturn(operation); + replay(compute); + initializeDisk(); + assertSame(operation, disk.resize(42L)); + } + + @Test + public void testResizeNull() { + initializeExpectedDisk(3); + expect(compute.options()).andReturn(mockOptions); + expect(compute.resize(DISK_ID, 42L)).andReturn(null); + replay(compute); + initializeDisk(); + assertNull(disk.resize(42L)); + } + + public void compareDisk(Disk expected, Disk value) { + assertEquals(expected, value); + assertEquals(expected.compute().options(), value.compute().options()); + assertEquals(expected.diskId(), value.diskId()); + assertEquals(expected.configuration(), value.configuration()); + assertEquals(expected.id(), value.id()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.creationStatus(), value.creationStatus()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.licenses(), value.licenses()); + assertEquals(expected.attachedInstances(), value.attachedInstances()); + assertEquals(expected.lastAttachTimestamp(), value.lastAttachTimestamp()); + assertEquals(expected.lastDetachTimestamp(), value.lastDetachTimestamp()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java index 57736854091f..bec8844ae111 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java @@ -22,7 +22,6 @@ import com.google.common.collect.ImmutableList; import com.google.gcloud.AuthCredentials; import com.google.gcloud.RetryParams; -import com.google.gcloud.compute.Zone.MaintenanceWindow; import org.junit.Test; @@ -89,20 +88,12 @@ public class SerializationTest { .build(); private static final ZoneId ZONE_ID = ZoneId.of("project", "zone"); private static final Zone.Status ZONE_STATUS = Zone.Status.DOWN; - private static final Long BEGIN_TIME = 1453293420000L; - private static final Long END_TIME = 1453293480000L; - private static final MaintenanceWindow WINDOW1 = new MaintenanceWindow("NAME1", "DESCRIPTION1", - BEGIN_TIME, END_TIME); - private static final MaintenanceWindow WINDOW2 = new MaintenanceWindow("NAME2", "DESCRIPTION2", - BEGIN_TIME, END_TIME); - private static final List WINDOWS = ImmutableList.of(WINDOW1, WINDOW2); private static final Zone ZONE = Zone.builder() .zoneId(ZONE_ID) .id(ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .status(ZONE_STATUS) - .maintenanceWindows(WINDOWS) .region(REGION_ID) .build(); private static final DeprecationStatus DEPRECATION_STATUS = @@ -163,6 +154,8 @@ public class SerializationTest { private static final SnapshotDiskConfiguration SNAPSHOT_DISK_CONFIGURATION = SnapshotDiskConfiguration.of(SNAPSHOT_ID); private static final DiskInfo DISK_INFO = DiskInfo.of(DISK_ID, STANDARD_DISK_CONFIGURATION); + private static final Disk DISK = + new Disk.Builder(COMPUTE, DISK_ID, STANDARD_DISK_CONFIGURATION).build(); private static final Compute.DiskTypeOption DISK_TYPE_OPTION = Compute.DiskTypeOption.fields(); private static final Compute.DiskTypeFilter DISK_TYPE_FILTER = @@ -212,6 +205,13 @@ public class SerializationTest { Compute.ImageFilter.equals(Compute.ImageField.SELF_LINK, "selfLink"); private static final Compute.ImageListOption IMAGE_LIST_OPTION = Compute.ImageListOption.filter(IMAGE_FILTER); + private static final Compute.DiskOption DISK_OPTION = Compute.DiskOption.fields(); + private static final Compute.DiskFilter DISK_FILTER = + Compute.DiskFilter.equals(Compute.DiskField.SELF_LINK, "selfLink"); + private static final Compute.DiskListOption DISK_LIST_OPTION = + Compute.DiskListOption.filter(DISK_FILTER); + private static final Compute.DiskAggregatedListOption DISK_AGGREGATED_LIST_OPTION = + Compute.DiskAggregatedListOption.filter(DISK_FILTER); @Test public void testServiceOptions() throws Exception { @@ -239,15 +239,16 @@ public void testModelAndRequests() throws Exception { INSTANCE_ID, REGION_FORWARDING_RULE_ID, GLOBAL_FORWARDING_RULE_ID, GLOBAL_ADDRESS_ID, REGION_ADDRESS_ID, INSTANCE_USAGE, GLOBAL_FORWARDING_USAGE, REGION_FORWARDING_USAGE, ADDRESS_INFO, ADDRESS, DISK_ID, SNAPSHOT_ID, SNAPSHOT_INFO, SNAPSHOT, IMAGE_ID, - DISK_IMAGE_CONFIGURATION, STORAGE_IMAGE_CONFIGURATION, IMAGE_INFO, + DISK_IMAGE_CONFIGURATION, STORAGE_IMAGE_CONFIGURATION, IMAGE_INFO, IMAGE, STANDARD_DISK_CONFIGURATION, IMAGE_DISK_CONFIGURATION, SNAPSHOT_DISK_CONFIGURATION, - DISK_INFO, IMAGE, DISK_TYPE_OPTION, DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, + DISK_INFO, DISK, DISK_TYPE_OPTION, DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, DISK_TYPE_AGGREGATED_LIST_OPTION, MACHINE_TYPE_OPTION, MACHINE_TYPE_FILTER, MACHINE_TYPE_LIST_OPTION, MACHINE_TYPE_AGGREGATED_LIST_OPTION, REGION_OPTION, REGION_FILTER, REGION_LIST_OPTION, ZONE_OPTION, ZONE_FILTER, ZONE_LIST_OPTION, LICENSE_OPTION, OPERATION_OPTION, OPERATION_FILTER, OPERATION_LIST_OPTION, ADDRESS_OPTION, ADDRESS_FILTER, ADDRESS_LIST_OPTION, ADDRESS_AGGREGATED_LIST_OPTION, SNAPSHOT_OPTION, SNAPSHOT_FILTER, - SNAPSHOT_LIST_OPTION, IMAGE_OPTION, IMAGE_FILTER, IMAGE_LIST_OPTION}; + SNAPSHOT_LIST_OPTION, IMAGE_OPTION, IMAGE_FILTER, IMAGE_LIST_OPTION, DISK_OPTION, + DISK_FILTER, DISK_LIST_OPTION, DISK_AGGREGATED_LIST_OPTION}; for (Serializable obj : objects) { Object copy = serializeAndDeserialize(obj); assertEquals(obj, obj); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java index 1224c607a567..97a80a4de05b 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java @@ -18,13 +18,8 @@ import static org.junit.Assert.assertEquals; -import com.google.common.collect.ImmutableList; -import com.google.gcloud.compute.Zone.MaintenanceWindow; - import org.junit.Test; -import java.util.List; - public class ZoneTest { private static final ZoneId ZONE_ID = ZoneId.of("project", "zone"); @@ -33,13 +28,6 @@ public class ZoneTest { private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final String DESCRIPTION = "description"; private static final Zone.Status STATUS = Zone.Status.DOWN; - private static final Long BEGIN_TIME = 1453293420000L; - private static final Long END_TIME = 1453293480000L; - private static final MaintenanceWindow WINDOW1 = new MaintenanceWindow("NAME1", "DESCRIPTION1", - BEGIN_TIME, END_TIME); - private static final MaintenanceWindow WINDOW2 = new MaintenanceWindow("NAME2", "DESCRIPTION2", - BEGIN_TIME, END_TIME); - private static final List WINDOWS = ImmutableList.of(WINDOW1, WINDOW2); private static final DeprecationStatus DEPRECATION_STATUS = DeprecationStatus.of(DeprecationStatus.Status.DELETED, ZONE_ID); private static final Zone ZONE = Zone.builder() @@ -48,7 +36,6 @@ public class ZoneTest { .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .status(STATUS) - .maintenanceWindows(WINDOWS) .deprecationStatus(DEPRECATION_STATUS) .region(REGION_ID) .build(); @@ -60,7 +47,6 @@ public void testBuilder() { assertEquals(CREATION_TIMESTAMP, ZONE.creationTimestamp()); assertEquals(DESCRIPTION, ZONE.description()); assertEquals(STATUS, ZONE.status()); - assertEquals(WINDOWS, ZONE.maintenanceWindows()); assertEquals(REGION_ID, ZONE.region()); assertEquals(DEPRECATION_STATUS, ZONE.deprecationStatus()); } @@ -84,7 +70,6 @@ private void compareZones(Zone expected, Zone value) { assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.description(), value.description()); assertEquals(expected.status(), value.status()); - assertEquals(expected.maintenanceWindows(), value.maintenanceWindows()); assertEquals(expected.region(), value.region()); assertEquals(expected.deprecationStatus(), value.deprecationStatus()); assertEquals(expected.hashCode(), value.hashCode()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java index 666fe8500704..a2f472cdcbb8 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java @@ -29,8 +29,20 @@ import com.google.gcloud.compute.AddressId; import com.google.gcloud.compute.AddressInfo; import com.google.gcloud.compute.Compute; +import com.google.gcloud.compute.DeprecationStatus; +import com.google.gcloud.compute.Disk; +import com.google.gcloud.compute.DiskConfiguration; +import com.google.gcloud.compute.DiskId; +import com.google.gcloud.compute.DiskImageConfiguration; +import com.google.gcloud.compute.DiskInfo; import com.google.gcloud.compute.DiskType; +import com.google.gcloud.compute.DiskTypeId; import com.google.gcloud.compute.GlobalAddressId; +import com.google.gcloud.compute.Image; +import com.google.gcloud.compute.ImageConfiguration; +import com.google.gcloud.compute.ImageDiskConfiguration; +import com.google.gcloud.compute.ImageId; +import com.google.gcloud.compute.ImageInfo; import com.google.gcloud.compute.License; import com.google.gcloud.compute.LicenseId; import com.google.gcloud.compute.MachineType; @@ -38,6 +50,12 @@ import com.google.gcloud.compute.Region; import com.google.gcloud.compute.RegionAddressId; import com.google.gcloud.compute.RegionOperationId; +import com.google.gcloud.compute.Snapshot; +import com.google.gcloud.compute.SnapshotDiskConfiguration; +import com.google.gcloud.compute.SnapshotId; +import com.google.gcloud.compute.SnapshotInfo; +import com.google.gcloud.compute.StandardDiskConfiguration; +import com.google.gcloud.compute.StorageImageConfiguration; import com.google.gcloud.compute.Zone; import com.google.gcloud.compute.ZoneOperationId; import com.google.gcloud.compute.testing.RemoteComputeHelper; @@ -58,6 +76,8 @@ public class ITComputeTest { private static final String MACHINE_TYPE = "f1-micro"; private static final LicenseId LICENSE_ID = LicenseId.of("ubuntu-os-cloud", "ubuntu-1404-trusty"); private static final String BASE_RESOURCE_NAME = RemoteComputeHelper.baseResourceName(); + private static final ImageId IMAGE_ID = ImageId.of("debian-cloud", "debian-8-jessie-v20160219"); + private static final String IMAGE_PROJECT = "debian-cloud"; private static Compute compute; @@ -411,7 +431,6 @@ public void testGetZoneWithSelectedFields() { assertNull(zone.creationTimestamp()); assertNull(zone.description()); assertNull(zone.status()); - assertNull(zone.maintenanceWindows()); assertNull(zone.region()); } @@ -855,4 +874,486 @@ public void testListGlobalAddresses() throws InterruptedException { compute.delete(firstAddressId); compute.delete(secondAddressId); } + + @Test + public void testCreateGetResizeAndDeleteStandardDisk() throws InterruptedException { + String name = BASE_RESOURCE_NAME + "create-and-get-standard-disk"; + DiskId diskId = DiskId.of(ZONE, name); + DiskInfo diskInfo = + DiskInfo.of(diskId, StandardDiskConfiguration.of(DiskTypeId.of(ZONE, "pd-ssd"), 100L)); + Operation operation = compute.create(diskInfo); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + // test get + Disk remoteDisk = compute.get(diskId); + assertNotNull(remoteDisk); + assertEquals(ZONE, remoteDisk.diskId().zone()); + assertEquals(diskId.disk(), remoteDisk.diskId().disk()); + assertNotNull(remoteDisk.creationTimestamp()); + assertNotNull(remoteDisk.id()); + assertTrue(remoteDisk.configuration() instanceof StandardDiskConfiguration); + StandardDiskConfiguration remoteConfiguration = remoteDisk.configuration(); + assertEquals(100L, (long) remoteConfiguration.sizeGb()); + assertEquals("pd-ssd", remoteConfiguration.diskType().diskType()); + assertEquals(DiskConfiguration.Type.STANDARD, remoteConfiguration.type()); + assertNull(remoteDisk.lastAttachTimestamp()); + assertNull(remoteDisk.lastDetachTimestamp()); + operation = remoteDisk.resize(200L); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + // test resize and get with selected fields + remoteDisk = compute.get(diskId, Compute.DiskOption.fields(Compute.DiskField.SIZE_GB)); + assertNotNull(remoteDisk); + assertEquals(ZONE, remoteDisk.diskId().zone()); + assertEquals(diskId.disk(), remoteDisk.diskId().disk()); + assertNull(remoteDisk.creationTimestamp()); + assertNull(remoteDisk.id()); + assertTrue(remoteDisk.configuration() instanceof StandardDiskConfiguration); + remoteConfiguration = remoteDisk.configuration(); + assertEquals(200L, (long) remoteConfiguration.sizeGb()); + assertEquals("pd-ssd", remoteConfiguration.diskType().diskType()); + assertEquals(DiskConfiguration.Type.STANDARD, remoteConfiguration.type()); + assertNull(remoteDisk.lastAttachTimestamp()); + assertNull(remoteDisk.lastDetachTimestamp()); + operation = remoteDisk.delete(); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + assertNull(compute.get(diskId)); + } + + @Test + public void testCreateGetAndDeleteImageDisk() throws InterruptedException { + String name = BASE_RESOURCE_NAME + "create-and-get-image-disk"; + DiskId diskId = DiskId.of(ZONE, name); + DiskInfo diskInfo = DiskInfo.of(diskId, ImageDiskConfiguration.of(IMAGE_ID)); + Operation operation = compute.create(diskInfo); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + // test get + Disk remoteDisk = compute.get(diskId); + assertNotNull(remoteDisk); + assertEquals(ZONE, remoteDisk.diskId().zone()); + assertEquals(diskId.disk(), remoteDisk.diskId().disk()); + assertEquals(DiskInfo.CreationStatus.READY, remoteDisk.creationStatus()); + assertNotNull(remoteDisk.creationTimestamp()); + assertNotNull(remoteDisk.id()); + assertTrue(remoteDisk.configuration() instanceof ImageDiskConfiguration); + ImageDiskConfiguration remoteConfiguration = remoteDisk.configuration(); + assertEquals(IMAGE_ID, remoteConfiguration.sourceImage()); + assertNotNull(remoteConfiguration.sourceImageId()); + assertEquals(DiskConfiguration.Type.IMAGE, remoteConfiguration.type()); + assertNotNull(remoteConfiguration.sizeGb()); + assertEquals("pd-standard", remoteConfiguration.diskType().diskType()); + assertNull(remoteDisk.lastAttachTimestamp()); + assertNull(remoteDisk.lastDetachTimestamp()); + // test get with selected fields + remoteDisk = compute.get(diskId, Compute.DiskOption.fields()); + assertNotNull(remoteDisk); + assertEquals(ZONE, remoteDisk.diskId().zone()); + assertEquals(diskId.disk(), remoteDisk.diskId().disk()); + assertNull(remoteDisk.creationTimestamp()); + assertNull(remoteDisk.id()); + assertTrue(remoteDisk.configuration() instanceof ImageDiskConfiguration); + remoteConfiguration = remoteDisk.configuration(); + assertEquals(IMAGE_ID, remoteConfiguration.sourceImage()); + assertNull(remoteConfiguration.sourceImageId()); + assertEquals(DiskConfiguration.Type.IMAGE, remoteConfiguration.type()); + assertNull(remoteConfiguration.sizeGb()); + assertEquals("pd-standard", remoteConfiguration.diskType().diskType()); + assertNull(remoteDisk.lastAttachTimestamp()); + assertNull(remoteDisk.lastDetachTimestamp()); + operation = remoteDisk.delete(); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + assertNull(compute.get(diskId)); + } + + @Test + public void testCreateGetAndDeleteSnapshotAndSnapshotDisk() throws InterruptedException { + String diskName = BASE_RESOURCE_NAME + "create-and-get-snapshot-disk1"; + String snapshotDiskName = BASE_RESOURCE_NAME + "create-and-get-snapshot-disk2"; + DiskId diskId = DiskId.of(ZONE, diskName); + DiskId snapshotDiskId = DiskId.of(ZONE, snapshotDiskName); + String snapshotName = BASE_RESOURCE_NAME + "create-and-get-snapshot"; + DiskInfo diskInfo = + DiskInfo.of(diskId, StandardDiskConfiguration.of(DiskTypeId.of(ZONE, "pd-ssd"), 100L)); + Operation operation = compute.create(diskInfo); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + Disk remoteDisk = compute.get(diskId); + operation = remoteDisk.createSnapshot(snapshotName); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + // test get snapshot with selected fields + Snapshot snapshot = compute.getSnapshot(snapshotName, + Compute.SnapshotOption.fields(Compute.SnapshotField.CREATION_TIMESTAMP)); + assertNull(snapshot.id()); + assertNotNull(snapshot.snapshotId()); + assertNotNull(snapshot.creationTimestamp()); + assertNull(snapshot.description()); + assertNull(snapshot.status()); + assertNull(snapshot.diskSizeGb()); + assertNull(snapshot.licenses()); + assertNull(snapshot.sourceDisk()); + assertNull(snapshot.sourceDiskId()); + assertNull(snapshot.storageBytes()); + assertNull(snapshot.storageBytesStatus()); + // test get snapshot + snapshot = compute.getSnapshot(snapshotName); + assertNotNull(snapshot.id()); + assertNotNull(snapshot.snapshotId()); + assertNotNull(snapshot.creationTimestamp()); + assertNotNull(snapshot.status()); + assertEquals(100L, (long) snapshot.diskSizeGb()); + assertEquals(diskName, snapshot.sourceDisk().disk()); + assertNotNull(snapshot.sourceDiskId()); + assertNotNull(snapshot.storageBytes()); + assertNotNull(snapshot.storageBytesStatus()); + remoteDisk.delete(); + diskInfo = + DiskInfo.of(snapshotDiskId, SnapshotDiskConfiguration.of(SnapshotId.of(snapshotName))); + operation = compute.create(diskInfo); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + // test get disk + remoteDisk = compute.get(snapshotDiskId); + assertNotNull(remoteDisk); + assertEquals(ZONE, remoteDisk.diskId().zone()); + assertEquals(snapshotDiskId.disk(), remoteDisk.diskId().disk()); + assertEquals(DiskInfo.CreationStatus.READY, remoteDisk.creationStatus()); + assertNotNull(remoteDisk.creationTimestamp()); + assertNotNull(remoteDisk.id()); + assertTrue(remoteDisk.configuration() instanceof SnapshotDiskConfiguration); + SnapshotDiskConfiguration remoteConfiguration = remoteDisk.configuration(); + assertEquals(DiskConfiguration.Type.SNAPSHOT, remoteConfiguration.type()); + assertEquals(snapshotName, remoteConfiguration.sourceSnapshot().snapshot()); + assertEquals(100L, (long) remoteConfiguration.sizeGb()); + assertEquals("pd-standard", remoteConfiguration.diskType().diskType()); + assertNotNull(remoteConfiguration.sourceSnapshotId()); + assertNull(remoteDisk.lastAttachTimestamp()); + assertNull(remoteDisk.lastDetachTimestamp()); + // test get disk with selected fields + remoteDisk = compute.get(snapshotDiskId, Compute.DiskOption.fields()); + assertNotNull(remoteDisk); + assertEquals(ZONE, remoteDisk.diskId().zone()); + assertEquals(snapshotDiskId.disk(), remoteDisk.diskId().disk()); + assertNull(remoteDisk.creationStatus()); + assertNull(remoteDisk.creationTimestamp()); + assertNull(remoteDisk.id()); + assertTrue(remoteDisk.configuration() instanceof SnapshotDiskConfiguration); + remoteConfiguration = remoteDisk.configuration(); + assertEquals(DiskConfiguration.Type.SNAPSHOT, remoteConfiguration.type()); + assertEquals(snapshotName, remoteConfiguration.sourceSnapshot().snapshot()); + assertNull(remoteConfiguration.sizeGb()); + assertEquals("pd-standard", remoteConfiguration.diskType().diskType()); + assertNull(remoteDisk.configuration().sourceSnapshotId()); + assertNull(remoteDisk.lastAttachTimestamp()); + assertNull(remoteDisk.lastDetachTimestamp()); + operation = remoteDisk.delete(); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + assertNull(compute.get(snapshotDiskId)); + operation = snapshot.delete(); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + assertNull(compute.getSnapshot(snapshotName)); + } + + @Test + public void testListDisksAndSnapshots() throws InterruptedException { + String prefix = BASE_RESOURCE_NAME + "list-disks-and-snapshots-disk"; + String[] diskNames = {prefix + "1", prefix + "2"}; + DiskId firstDiskId = DiskId.of(ZONE, diskNames[0]); + DiskId secondDiskId = DiskId.of(ZONE, diskNames[1]); + DiskConfiguration configuration = + StandardDiskConfiguration.of(DiskTypeId.of(ZONE, "pd-ssd"), 100L); + Operation firstOperation = compute.create(DiskInfo.of(firstDiskId, configuration)); + Operation secondOperation = compute.create(DiskInfo.of(secondDiskId, configuration)); + while (!firstOperation.isDone()) { + Thread.sleep(1000L); + } + while (!secondOperation.isDone()) { + Thread.sleep(1000L); + } + Set diskSet = ImmutableSet.copyOf(diskNames); + // test list disks + Compute.DiskFilter diskFilter = + Compute.DiskFilter.equals(Compute.DiskField.NAME, prefix + "\\d"); + Page diskPage = compute.listDisks(ZONE, Compute.DiskListOption.filter(diskFilter)); + Iterator diskIterator = diskPage.iterateAll(); + int count = 0; + while (diskIterator.hasNext()) { + Disk remoteDisk = diskIterator.next(); + assertEquals(ZONE, remoteDisk.diskId().zone()); + assertTrue(diskSet.contains(remoteDisk.diskId().disk())); + assertEquals(DiskInfo.CreationStatus.READY, remoteDisk.creationStatus()); + assertNotNull(remoteDisk.creationTimestamp()); + assertNotNull(remoteDisk.id()); + assertTrue(remoteDisk.configuration() instanceof StandardDiskConfiguration); + StandardDiskConfiguration remoteConfiguration = remoteDisk.configuration(); + assertEquals(100L, (long) remoteConfiguration.sizeGb()); + assertEquals("pd-ssd", remoteConfiguration.diskType().diskType()); + assertEquals(DiskConfiguration.Type.STANDARD, remoteConfiguration.type()); + assertNull(remoteDisk.lastAttachTimestamp()); + assertNull(remoteDisk.lastDetachTimestamp()); + count++; + } + assertEquals(2, count); + // test list disks with selected fields + count = 0; + diskPage = compute.listDisks(ZONE, Compute.DiskListOption.filter(diskFilter), + Compute.DiskListOption.fields(Compute.DiskField.STATUS)); + diskIterator = diskPage.iterateAll(); + while (diskIterator.hasNext()) { + Disk remoteDisk = diskIterator.next(); + assertEquals(ZONE, remoteDisk.diskId().zone()); + assertTrue(diskSet.contains(remoteDisk.diskId().disk())); + assertEquals(DiskInfo.CreationStatus.READY, remoteDisk.creationStatus()); + assertNull(remoteDisk.creationTimestamp()); + assertNull(remoteDisk.id()); + assertTrue(remoteDisk.configuration() instanceof StandardDiskConfiguration); + StandardDiskConfiguration remoteConfiguration = remoteDisk.configuration(); + assertNull(remoteConfiguration.sizeGb()); + assertEquals("pd-ssd", remoteConfiguration.diskType().diskType()); + assertEquals(DiskConfiguration.Type.STANDARD, remoteConfiguration.type()); + assertNull(remoteDisk.lastAttachTimestamp()); + assertNull(remoteDisk.lastDetachTimestamp()); + count++; + } + assertEquals(2, count); + // test snapshots + SnapshotId firstSnapshotId = SnapshotId.of(diskNames[0]); + SnapshotId secondSnapshotId = SnapshotId.of(diskNames[1]); + firstOperation = compute.create(SnapshotInfo.of(firstSnapshotId, firstDiskId)); + secondOperation = compute.create(SnapshotInfo.of(secondSnapshotId, secondDiskId)); + while (!firstOperation.isDone()) { + Thread.sleep(1000L); + } + while (!secondOperation.isDone()) { + Thread.sleep(1000L); + } + // test list snapshots + Compute.SnapshotFilter snapshotFilter = + Compute.SnapshotFilter.equals(Compute.SnapshotField.NAME, prefix + "\\d"); + Page snapshotPage = + compute.listSnapshots(Compute.SnapshotListOption.filter(snapshotFilter)); + Iterator snapshotIterator = snapshotPage.iterateAll(); + count = 0; + while (snapshotIterator.hasNext()) { + Snapshot remoteSnapshot = snapshotIterator.next(); + assertNotNull(remoteSnapshot.id()); + assertTrue(diskSet.contains(remoteSnapshot.snapshotId().snapshot())); + assertNotNull(remoteSnapshot.creationTimestamp()); + assertNotNull(remoteSnapshot.status()); + assertEquals(100L, (long) remoteSnapshot.diskSizeGb()); + assertTrue(diskSet.contains(remoteSnapshot.sourceDisk().disk())); + assertNotNull(remoteSnapshot.sourceDiskId()); + assertNotNull(remoteSnapshot.storageBytes()); + assertNotNull(remoteSnapshot.storageBytesStatus()); + count++; + } + assertEquals(2, count); + // test list snapshots with selected fields + snapshotPage = compute.listSnapshots(Compute.SnapshotListOption.filter(snapshotFilter), + Compute.SnapshotListOption.fields(Compute.SnapshotField.CREATION_TIMESTAMP)); + snapshotIterator = snapshotPage.iterateAll(); + count = 0; + while (snapshotIterator.hasNext()) { + Snapshot remoteSnapshot = snapshotIterator.next(); + assertNull(remoteSnapshot.id()); + assertTrue(diskSet.contains(remoteSnapshot.snapshotId().snapshot())); + assertNotNull(remoteSnapshot.creationTimestamp()); + assertNull(remoteSnapshot.status()); + assertNull(remoteSnapshot.diskSizeGb()); + assertNull(remoteSnapshot.sourceDisk()); + assertNull(remoteSnapshot.sourceDiskId()); + assertNull(remoteSnapshot.storageBytes()); + assertNull(remoteSnapshot.storageBytesStatus()); + count++; + } + assertEquals(2, count); + compute.delete(firstDiskId); + compute.delete(secondDiskId); + compute.deleteSnapshot(firstSnapshotId); + compute.deleteSnapshot(secondSnapshotId); + } + + @Test + public void testAggregatedListDisks() throws InterruptedException { + String prefix = BASE_RESOURCE_NAME + "list-aggregated-disk"; + String[] diskZones = {"us-central1-a", "us-east1-c"}; + String[] diskNames = {prefix + "1", prefix + "2"}; + DiskId firstDiskId = DiskId.of(diskZones[0], diskNames[0]); + DiskId secondDiskId = DiskId.of(diskZones[1], diskNames[1]); + DiskConfiguration configuration = + StandardDiskConfiguration.of(DiskTypeId.of(ZONE, "pd-ssd"), 100L); + Operation firstOperation = compute.create(DiskInfo.of(firstDiskId, configuration)); + Operation secondOperation = compute.create(DiskInfo.of(secondDiskId, configuration)); + while (!firstOperation.isDone()) { + Thread.sleep(1000L); + } + while (!secondOperation.isDone()) { + Thread.sleep(1000L); + } + Set zoneSet = ImmutableSet.copyOf(diskZones); + Set diskSet = ImmutableSet.copyOf(diskNames); + Compute.DiskFilter diskFilter = + Compute.DiskFilter.equals(Compute.DiskField.NAME, prefix + "\\d"); + Page diskPage = compute.listDisks(Compute.DiskAggregatedListOption.filter(diskFilter)); + Iterator diskIterator = diskPage.iterateAll(); + int count = 0; + while (diskIterator.hasNext()) { + Disk remoteDisk = diskIterator.next(); + assertTrue(zoneSet.contains(remoteDisk.diskId().zone())); + assertTrue(diskSet.contains(remoteDisk.diskId().disk())); + assertEquals(DiskInfo.CreationStatus.READY, remoteDisk.creationStatus()); + assertNotNull(remoteDisk.creationTimestamp()); + assertNotNull(remoteDisk.id()); + assertTrue(remoteDisk.configuration() instanceof StandardDiskConfiguration); + StandardDiskConfiguration remoteConfiguration = remoteDisk.configuration(); + assertEquals(100L, (long) remoteConfiguration.sizeGb()); + assertEquals("pd-ssd", remoteConfiguration.diskType().diskType()); + assertEquals(DiskConfiguration.Type.STANDARD, remoteConfiguration.type()); + count++; + } + assertEquals(2, count); + compute.delete(firstDiskId); + compute.delete(secondDiskId); + } + + @Test + public void testCreateGetAndDeprecateImage() throws InterruptedException { + String diskName = BASE_RESOURCE_NAME + "create-and-get-image-disk"; + String imageName = BASE_RESOURCE_NAME + "create-and-get-image"; + DiskId diskId = DiskId.of(ZONE, diskName); + ImageId imageId = ImageId.of(imageName); + DiskInfo diskInfo = + DiskInfo.of(diskId, StandardDiskConfiguration.of(DiskTypeId.of(ZONE, "pd-ssd"), 100L)); + Operation operation = compute.create(diskInfo); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + Disk remoteDisk = compute.get(diskId); + ImageInfo imageInfo = ImageInfo.of(imageId, DiskImageConfiguration.of(diskId)); + operation = compute.create(imageInfo); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + // test get image with selected fields + Image image = compute.get(imageId, + Compute.ImageOption.fields(Compute.ImageField.CREATION_TIMESTAMP)); + assertNull(image.id()); + assertNotNull(image.imageId()); + assertNotNull(image.creationTimestamp()); + assertNull(image.description()); + assertNotNull(image.configuration()); + assertTrue(image.configuration() instanceof DiskImageConfiguration); + DiskImageConfiguration remoteConfiguration = image.configuration(); + assertEquals(ImageConfiguration.Type.DISK, remoteConfiguration.type()); + assertEquals(diskName, remoteConfiguration.sourceDisk().disk()); + assertNull(image.status()); + assertNull(image.diskSizeGb()); + assertNull(image.licenses()); + assertNull(image.deprecationStatus()); + // test get image + image = compute.get(imageId); + assertNotNull(image.id()); + assertNotNull(image.imageId()); + assertNotNull(image.creationTimestamp()); + assertNotNull(image.configuration()); + assertTrue(image.configuration() instanceof DiskImageConfiguration); + remoteConfiguration = image.configuration(); + assertEquals(ImageConfiguration.Type.DISK, remoteConfiguration.type()); + assertEquals(diskName, remoteConfiguration.sourceDisk().disk()); + assertEquals(100L, (long) image.diskSizeGb()); + assertNotNull(image.status()); + assertNull(image.deprecationStatus()); + // test deprecate image + DeprecationStatus deprecationStatus = + DeprecationStatus.builder(DeprecationStatus.Status.DEPRECATED, imageId) + .deprecated(System.currentTimeMillis()) + .build(); + operation = image.deprecate(deprecationStatus); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + image = compute.get(imageId); + assertEquals(deprecationStatus, image.deprecationStatus()); + remoteDisk.delete(); + operation = image.delete(); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + assertNull(compute.get(imageId)); + } + + @Test + public void testListImages() { + Page imagePage = compute.listImages(IMAGE_PROJECT); + Iterator imageIterator = imagePage.iterateAll(); + int count = 0; + while (imageIterator.hasNext()) { + count++; + Image image = imageIterator.next(); + assertNotNull(image.id()); + assertNotNull(image.imageId()); + assertNotNull(image.creationTimestamp()); + assertNotNull(image.configuration()); + assertNotNull(image.status()); + assertNotNull(image.diskSizeGb()); + } + assertTrue(count > 0); + } + + @Test + public void testListImagesWithSelectedFields() { + Page imagePage = + compute.listImages(IMAGE_PROJECT, Compute.ImageListOption.fields(Compute.ImageField.ID)); + Iterator imageIterator = imagePage.iterateAll(); + int count = 0; + while (imageIterator.hasNext()) { + count++; + Image image = imageIterator.next(); + assertNotNull(image.id()); + assertNotNull(image.imageId()); + assertNull(image.creationTimestamp()); + assertNotNull(image.configuration()); + assertNull(image.status()); + assertNull(image.diskSizeGb()); + assertNull(image.licenses()); + assertNull(image.deprecationStatus()); + } + assertTrue(count > 0); + } + + @Test + public void testListImagesWithFilter() { + Page imagePage = compute.listImages(IMAGE_PROJECT, Compute.ImageListOption.filter( + Compute.ImageFilter.equals(Compute.ImageField.ARCHIVE_SIZE_BYTES, 365056004L))); + Iterator imageIterator = imagePage.iterateAll(); + int count = 0; + while (imageIterator.hasNext()) { + count++; + Image image = imageIterator.next(); + assertNotNull(image.id()); + assertNotNull(image.imageId()); + assertNotNull(image.creationTimestamp()); + assertNotNull(image.configuration()); + assertNotNull(image.status()); + assertNotNull(image.diskSizeGb()); + assertEquals(365056004L, + (long) image.configuration().archiveSizeBytes()); + } + assertTrue(count > 0); + } } From 5bb3e9d8a98a2c9b7aa09887da69413555710279 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 12 Apr 2016 23:59:36 +0200 Subject: [PATCH 311/375] Move Compute's spi package to compute.spi (#901) --- .../main/java/com/google/gcloud/compute/Compute.java | 2 +- .../java/com/google/gcloud/compute/ComputeImpl.java | 2 +- .../com/google/gcloud/compute/ComputeOptions.java | 6 +++--- .../main/java/com/google/gcloud/compute/Option.java | 2 +- .../google/gcloud/{ => compute}/spi/ComputeRpc.java | 2 +- .../gcloud/{ => compute}/spi/ComputeRpcFactory.java | 3 ++- .../gcloud/{ => compute}/spi/DefaultComputeRpc.java | 10 +++++----- .../com/google/gcloud/compute/ComputeImplTest.java | 12 ++++++------ 8 files changed, 20 insertions(+), 19 deletions(-) rename gcloud-java-compute/src/main/java/com/google/gcloud/{ => compute}/spi/ComputeRpc.java (99%) rename gcloud-java-compute/src/main/java/com/google/gcloud/{ => compute}/spi/ComputeRpcFactory.java (91%) rename gcloud-java-compute/src/main/java/com/google/gcloud/{ => compute}/spi/DefaultComputeRpc.java (98%) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java index aaedbccf13bb..5cdb7eb0e85e 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java @@ -23,7 +23,7 @@ import com.google.common.collect.Sets; import com.google.gcloud.Page; import com.google.gcloud.Service; -import com.google.gcloud.spi.ComputeRpc; +import com.google.gcloud.compute.spi.ComputeRpc; import java.io.Serializable; import java.util.Objects; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java index 84e42d33fe10..f453d0768e13 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java @@ -28,7 +28,7 @@ import com.google.gcloud.PageImpl; import com.google.gcloud.PageImpl.NextPageFetcher; import com.google.gcloud.RetryHelper; -import com.google.gcloud.spi.ComputeRpc; +import com.google.gcloud.compute.spi.ComputeRpc; import java.util.Map; import java.util.concurrent.Callable; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeOptions.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeOptions.java index 9fab138b26b4..2585cc42e3d0 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeOptions.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeOptions.java @@ -18,9 +18,9 @@ import com.google.common.collect.ImmutableSet; import com.google.gcloud.ServiceOptions; -import com.google.gcloud.spi.ComputeRpc; -import com.google.gcloud.spi.ComputeRpcFactory; -import com.google.gcloud.spi.DefaultComputeRpc; +import com.google.gcloud.compute.spi.ComputeRpc; +import com.google.gcloud.compute.spi.ComputeRpcFactory; +import com.google.gcloud.compute.spi.DefaultComputeRpc; import java.util.Set; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Option.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Option.java index ae100c9c9765..5a9ea946aeea 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Option.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Option.java @@ -19,7 +19,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.base.MoreObjects; -import com.google.gcloud.spi.ComputeRpc; +import com.google.gcloud.compute.spi.ComputeRpc; import java.io.Serializable; import java.util.Objects; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/ComputeRpc.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java rename to gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/ComputeRpc.java index 1066124e0638..b24384af37f2 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpc.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/ComputeRpc.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.spi; +package com.google.gcloud.compute.spi; import com.google.api.services.compute.model.Address; import com.google.api.services.compute.model.DeprecationStatus; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpcFactory.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/ComputeRpcFactory.java similarity index 91% rename from gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpcFactory.java rename to gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/ComputeRpcFactory.java index 5defc86199ef..e7a6cbe72d6f 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/ComputeRpcFactory.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/ComputeRpcFactory.java @@ -14,9 +14,10 @@ * limitations under the License. */ -package com.google.gcloud.spi; +package com.google.gcloud.compute.spi; import com.google.gcloud.compute.ComputeOptions; +import com.google.gcloud.spi.ServiceRpcFactory; /** * An interface for Compute RPC factory. diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/DefaultComputeRpc.java similarity index 98% rename from gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java rename to gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/DefaultComputeRpc.java index 4899ab9c8445..708e5fa2ceee 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/spi/DefaultComputeRpc.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/DefaultComputeRpc.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.google.gcloud.spi; +package com.google.gcloud.compute.spi; -import static com.google.gcloud.spi.ComputeRpc.Option.FIELDS; -import static com.google.gcloud.spi.ComputeRpc.Option.FILTER; -import static com.google.gcloud.spi.ComputeRpc.Option.MAX_RESULTS; -import static com.google.gcloud.spi.ComputeRpc.Option.PAGE_TOKEN; +import static com.google.gcloud.compute.spi.ComputeRpc.Option.FIELDS; +import static com.google.gcloud.compute.spi.ComputeRpc.Option.FILTER; +import static com.google.gcloud.compute.spi.ComputeRpc.Option.MAX_RESULTS; +import static com.google.gcloud.compute.spi.ComputeRpc.Option.PAGE_TOKEN; import static java.net.HttpURLConnection.HTTP_NOT_FOUND; import com.google.api.client.http.HttpRequestInitializer; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java index 277f8826b421..e193be1d8da5 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java @@ -16,9 +16,9 @@ package com.google.gcloud.compute; -import static com.google.gcloud.spi.ComputeRpc.Option.FILTER; -import static com.google.gcloud.spi.ComputeRpc.Option.MAX_RESULTS; -import static com.google.gcloud.spi.ComputeRpc.Option.PAGE_TOKEN; +import static com.google.gcloud.compute.spi.ComputeRpc.Option.FILTER; +import static com.google.gcloud.compute.spi.ComputeRpc.Option.MAX_RESULTS; +import static com.google.gcloud.compute.spi.ComputeRpc.Option.PAGE_TOKEN; import static org.easymock.EasyMock.capture; import static org.easymock.EasyMock.eq; import static org.junit.Assert.assertArrayEquals; @@ -71,9 +71,9 @@ import com.google.gcloud.compute.Operation.OperationError; import com.google.gcloud.compute.Operation.OperationWarning; import com.google.gcloud.compute.Operation.Status; -import com.google.gcloud.spi.ComputeRpc; -import com.google.gcloud.spi.ComputeRpc.Tuple; -import com.google.gcloud.spi.ComputeRpcFactory; +import com.google.gcloud.compute.spi.ComputeRpc; +import com.google.gcloud.compute.spi.ComputeRpc.Tuple; +import com.google.gcloud.compute.spi.ComputeRpcFactory; import org.easymock.Capture; import org.easymock.EasyMock; From 382ab772dabde28e2a80e03b58f3497e44b471af Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 13 Apr 2016 00:41:27 +0200 Subject: [PATCH 312/375] Add RemoteComputeHelperTest (#900) --- .../testing/RemoteComputeHelperTest.java | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/testing/RemoteComputeHelperTest.java diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/testing/RemoteComputeHelperTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/testing/RemoteComputeHelperTest.java new file mode 100644 index 000000000000..5714ce7e0224 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/testing/RemoteComputeHelperTest.java @@ -0,0 +1,98 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute.testing; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import com.google.gcloud.compute.ComputeOptions; +import com.google.gcloud.compute.testing.RemoteComputeHelper.ComputeHelperException; + +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.regex.Pattern; + +public class RemoteComputeHelperTest { + + private static final String PROJECT_ID = "project-id"; + private static final String JSON_KEY = "{\n" + + " \"private_key_id\": \"somekeyid\",\n" + + " \"private_key\": \"-----BEGIN PRIVATE KEY-----\\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggS" + + "kAgEAAoIBAQC+K2hSuFpAdrJI\\nnCgcDz2M7t7bjdlsadsasad+fvRSW6TjNQZ3p5LLQY1kSZRqBqylRkzteMOyHg" + + "aR\\n0Pmxh3ILCND5men43j3h4eDbrhQBuxfEMalkG92sL+PNQSETY2tnvXryOvmBRwa/\\nQP/9dJfIkIDJ9Fw9N4" + + "Bhhhp6mCcRpdQjV38H7JsyJ7lih/oNjECgYAt\\nknddadwkwewcVxHFhcZJO+XWf6ofLUXpRwiTZakGMn8EE1uVa2" + + "LgczOjwWHGi99MFjxSer5m9\\n1tCa3/KEGKiS/YL71JvjwX3mb+cewlkcmweBKZHM2JPTk0ZednFSpVZMtycjkbLa" + + "\\ndYOS8V85AgMBewECggEBAKksaldajfDZDV6nGqbFjMiizAKJolr/M3OQw16K6o3/\\n0S31xIe3sSlgW0+UbYlF" + + "4U8KifhManD1apVSC3csafaspP4RZUHFhtBywLO9pR5c\\nr6S5aLp+gPWFyIp1pfXbWGvc5VY/v9x7ya1VEa6rXvL" + + "sKupSeWAW4tMj3eo/64ge\\nsdaceaLYw52KeBYiT6+vpsnYrEkAHO1fF/LavbLLOFJmFTMxmsNaG0tuiJHgjshB\\" + + "n82DpMCbXG9YcCgI/DbzuIjsdj2JC1cascSP//3PmefWysucBQe7Jryb6NQtASmnv\\nCdDw/0jmZTEjpe4S1lxfHp" + + "lAhHFtdgYTvyYtaLZiVVkCgYEA8eVpof2rceecw/I6\\n5ng1q3Hl2usdWV/4mZMvR0fOemacLLfocX6IYxT1zA1FF" + + "JlbXSRsJMf/Qq39mOR2\\nSpW+hr4jCoHeRVYLgsbggtrevGmILAlNoqCMpGZ6vDmJpq6ECV9olliDvpPgWOP+\\nm" + + "YPDreFBGxWvQrADNbRt2dmGsrsCgYEAyUHqB2wvJHFqdmeBsaacewzV8x9WgmeX\\ngUIi9REwXlGDW0Mz50dxpxcK" + + "CAYn65+7TCnY5O/jmL0VRxU1J2mSWyWTo1C+17L0\\n3fUqjxL1pkefwecxwecvC+gFFYdJ4CQ/MHHXU81Lwl1iWdF" + + "Cd2UoGddYaOF+KNeM\\nHC7cmqra+JsCgYEAlUNywzq8nUg7282E+uICfCB0LfwejuymR93CtsFgb7cRd6ak\\nECR" + + "8FGfCpH8ruWJINllbQfcHVCX47ndLZwqv3oVFKh6pAS/vVI4dpOepP8++7y1u\\ncoOvtreXCX6XqfrWDtKIvv0vjl" + + "HBhhhp6mCcRpdQjV38H7JsyJ7lih/oNjECgYAt\\nkndj5uNl5SiuVxHFhcZJO+XWf6ofLUregtevZakGMn8EE1uVa" + + "2AY7eafmoU/nZPT\\n00YB0TBATdCbn/nBSuKDESkhSg9s2GEKQZG5hBmL5uCMfo09z3SfxZIhJdlerreP\\nJ7gSi" + + "dI12N+EZxYd4xIJh/HFDgp7RRO87f+WJkofMQKBgGTnClK1VMaCRbJZPriw\\nEfeFCoOX75MxKwXs6xgrw4W//AYG" + + "GUjDt83lD6AZP6tws7gJ2IwY/qP7+lyhjEqN\\nHtfPZRGFkGZsdaksdlaksd323423d+15/UvrlRSFPNj1tWQmNKk" + + "XyRDW4IG1Oa2p\\nrALStNBx5Y9t0/LQnFI4w3aG\\n-----END PRIVATE KEY-----\\n\",\n" + + " \"client_email\": \"someclientid@developer.gserviceaccount.com\",\n" + + " \"client_id\": \"someclientid.apps.googleusercontent.com\",\n" + + " \"type\": \"service_account\"\n" + + "}"; + private static final InputStream JSON_KEY_STREAM = new ByteArrayInputStream(JSON_KEY.getBytes()); + private static final String BASE_RESOURCE_NAME_REGEX = "test-[0-9a-f]{24}-"; + private static final Pattern BASE_RESOURCE_NAME_PATTERN = + Pattern.compile(BASE_RESOURCE_NAME_REGEX); + + @Test + public void testBaseResourceName() { + String baseResourceName = RemoteComputeHelper.baseResourceName(); + assertTrue(BASE_RESOURCE_NAME_PATTERN.matcher(baseResourceName).matches()); + } + + @Test + public void testCreateFromStream() { + RemoteComputeHelper helper = RemoteComputeHelper.create(PROJECT_ID, JSON_KEY_STREAM); + ComputeOptions options = helper.options(); + assertEquals(PROJECT_ID, options.projectId()); + assertEquals(60000, options.connectTimeout()); + assertEquals(60000, options.readTimeout()); + assertEquals(10, options.retryParams().retryMaxAttempts()); + assertEquals(6, options.retryParams().retryMinAttempts()); + assertEquals(30000, options.retryParams().maxRetryDelayMillis()); + assertEquals(120000, options.retryParams().totalRetryPeriodMillis()); + assertEquals(250, options.retryParams().initialRetryDelayMillis()); + } + + @Test + public void testComputeHelperException() { + ComputeHelperException exception = new ComputeHelperException("message", null); + assertEquals("message", exception.getMessage()); + assertNull(exception.getCause()); + IOException cause = new IOException("message"); + exception = ComputeHelperException.translate(cause); + assertEquals("message", exception.getMessage()); + assertSame(cause, exception.getCause()); + } +} From 6e2c262036ff5683ebc89cca0e321bdc4b3dccba Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 13 Apr 2016 23:55:17 +0200 Subject: [PATCH 313/375] Compute Operation: remove creationTimestamp field and fix isDone() (#914) * Remove Compute Operation's creation timestamp field * Compute's Operation.isDone() return true if operation does not exist --- .../com/google/gcloud/compute/Compute.java | 1 - .../com/google/gcloud/compute/Operation.java | 38 ++++--------------- .../gcloud/compute/ComputeImplTest.java | 3 -- .../google/gcloud/compute/OperationTest.java | 9 +---- .../gcloud/compute/it/ITComputeTest.java | 3 -- 5 files changed, 8 insertions(+), 46 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java index 5cdb7eb0e85e..dbc2f0d49366 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java @@ -232,7 +232,6 @@ static String selector(LicenseField... fields) { */ enum OperationField { CLIENT_OPERATION_ID("clientOperationId"), - CREATION_TIMESTAMP("creationTimestamp"), DESCRIPTION("description"), END_TIME("endTime"), ERROR("error"), diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java index 78afc170f671..2b35dac3fd2b 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java @@ -52,7 +52,6 @@ public class Operation implements Serializable { private final ComputeOptions options; private final String id; private final OperationId operationId; - private final Long creationTimestamp; private final String clientOperationId; private final String operationType; private final String targetLink; @@ -296,7 +295,6 @@ static final class Builder { private Compute compute; private String id; - private Long creationTimestamp; private OperationId operationId; private String clientOperationId; private String operationType; @@ -324,9 +322,6 @@ static final class Builder { if (operationPb.getId() != null) { id = operationPb.getId().toString(); } - if (operationPb.getCreationTimestamp() != null) { - creationTimestamp = TIMESTAMP_FORMATTER.parseMillis(operationPb.getCreationTimestamp()); - } if (RegionOperationId.matchesUrl(operationPb.getSelfLink())) { operationId = RegionOperationId.fromUrl(operationPb.getSelfLink()); } else if (ZoneOperationId.matchesUrl(operationPb.getSelfLink())) { @@ -372,11 +367,6 @@ Builder id(String id) { return this; } - Builder creationTimestamp(Long creationTimestamp) { - this.creationTimestamp = creationTimestamp; - return this; - } - Builder operationId(OperationId operationId) { this.operationId = checkNotNull(operationId); return this; @@ -471,7 +461,6 @@ private Operation(Builder builder) { this.compute = checkNotNull(builder.compute); this.options = compute.options(); this.id = builder.id; - this.creationTimestamp = builder.creationTimestamp; this.operationId = checkNotNull(builder.operationId); this.clientOperationId = builder.clientOperationId; this.operationType = builder.operationType; @@ -505,13 +494,6 @@ public String id() { return id; } - /** - * Returns the creation timestamp in milliseconds since epoch. - */ - public Long creationTimestamp() { - return creationTimestamp; - } - /** * Returns the operation's identity. This method returns an {@link GlobalOperationId} for global * operations, a {@link RegionOperationId} for region operations and a {@link ZoneOperationId} for @@ -658,23 +640,21 @@ public boolean exists() throws ComputeException { /** * Checks if this operation has completed its execution, either failing or succeeding. If the - * operation does not exist this method returns {@code false}. To correctly wait for operation's - * completion, check that the operation exists first using {@link #exists()}: + * operation does not exist this method returns {@code true}. You can wait for operation + * completion with: *
     {@code
    -   * if (operation.exists()) {
    -   *   while(!operation.isDone()) {
    -   *     Thread.sleep(1000L);
    -   *   }
    +   * while(!operation.isDone()) {
    +   *   Thread.sleep(1000L);
        * }}
    * - * @return {@code true} if this operation is in {@link Operation.Status#DONE} state, {@code false} - * if the state is not {@link Operation.Status#DONE} or the operation does not exist + * @return {@code true} if this operation is in {@link Operation.Status#DONE} state or if it does + * not exist, {@code false} if the state is not {@link Operation.Status#DONE} * @throws ComputeException upon failure */ public boolean isDone() throws ComputeException { Operation operation = compute.get(operationId, Compute.OperationOption.fields(Compute.OperationField.STATUS)); - return operation != null && operation.status() == Status.DONE; + return operation == null || operation.status() == Status.DONE; } /** @@ -705,7 +685,6 @@ public String toString() { return MoreObjects.toStringHelper(this) .add("id", id) .add("operationsId", operationId) - .add("creationTimestamp", creationTimestamp) .add("clientOperationId", clientOperationId) .add("operationType", operationType) .add("targetLink", targetLink) @@ -743,9 +722,6 @@ com.google.api.services.compute.model.Operation toPb() { if (id != null) { operationPb.setId(new BigInteger(id)); } - if (creationTimestamp != null) { - operationPb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); - } operationPb.setName(operationId.operation()); operationPb.setClientOperationId(clientOperationId); switch (operationId.type()) { diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java index e193be1d8da5..edd8b2bd0cef 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java @@ -427,7 +427,6 @@ public void setUp() { Compute otherService = options.toBuilder().build().service(); globalOperation = new Operation.Builder(otherService) .id(ID) - .creationTimestamp(CREATION_TIMESTAMP) .operationId(GLOBAL_OPERATION_ID) .clientOperationId(CLIENT_OPERATION_ID) .operationType(OPERATION_TYPE) @@ -448,7 +447,6 @@ public void setUp() { .build(); zoneOperation = new Operation.Builder(otherService) .id(ID) - .creationTimestamp(CREATION_TIMESTAMP) .operationId(ZONE_OPERATION_ID) .clientOperationId(CLIENT_OPERATION_ID) .operationType(OPERATION_TYPE) @@ -469,7 +467,6 @@ public void setUp() { .build(); regionOperation = new Operation.Builder(otherService) .id(ID) - .creationTimestamp(CREATION_TIMESTAMP) .operationId(REGION_OPERATION_ID) .clientOperationId(CLIENT_OPERATION_ID) .operationType(OPERATION_TYPE) diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java index 62899071ce32..450097c4ef30 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java @@ -89,7 +89,6 @@ private void initializeExpectedOperation(int optionsCalls) { replay(serviceMockReturnsOptions); globalOperation = new Operation.Builder(serviceMockReturnsOptions) .id(ID) - .creationTimestamp(CREATION_TIMESTAMP) .operationId(GLOBAL_OPERATION_ID) .clientOperationId(CLIENT_OPERATION_ID) .operationType(OPERATION_TYPE) @@ -110,7 +109,6 @@ private void initializeExpectedOperation(int optionsCalls) { .build(); zoneOperation = new Operation.Builder(serviceMockReturnsOptions) .id(ID) - .creationTimestamp(CREATION_TIMESTAMP) .operationId(ZONE_OPERATION_ID) .clientOperationId(CLIENT_OPERATION_ID) .operationType(OPERATION_TYPE) @@ -131,7 +129,6 @@ private void initializeExpectedOperation(int optionsCalls) { .build(); regionOperation = new Operation.Builder(serviceMockReturnsOptions) .id(ID) - .creationTimestamp(CREATION_TIMESTAMP) .operationId(REGION_OPERATION_ID) .clientOperationId(CLIENT_OPERATION_ID) .operationType(OPERATION_TYPE) @@ -157,7 +154,6 @@ private void initializeOperation() { operation = new Operation.Builder(compute) .id(ID) .operationId(GLOBAL_OPERATION_ID) - .creationTimestamp(CREATION_TIMESTAMP) .clientOperationId(CLIENT_OPERATION_ID) .operationType(OPERATION_TYPE) .targetLink(TARGET_LINK) @@ -183,7 +179,6 @@ public void tearDown() throws Exception { } private void assertEqualsCommonFields(Operation operation) { - assertEquals(CREATION_TIMESTAMP, operation.creationTimestamp()); assertEquals(ID, operation.id()); assertEquals(CLIENT_OPERATION_ID, operation.clientOperationId()); assertEquals(OPERATION_TYPE, operation.operationType()); @@ -205,7 +200,6 @@ private void assertEqualsCommonFields(Operation operation) { } private void assertNullCommonFields(Operation operation) { - assertNull(operation.creationTimestamp()); assertNull(operation.id()); assertNull(operation.clientOperationId()); assertNull(operation.operationType()); @@ -358,7 +352,7 @@ public void testIsDone_NotExists() throws Exception { expect(compute.get(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(null); replay(compute); initializeOperation(); - assertFalse(operation.isDone()); + assertTrue(operation.isDone()); verify(compute); } @@ -401,7 +395,6 @@ public void testReloadWithOptions() throws Exception { private void compareOperation(Operation expected, Operation value) { assertEquals(expected, value); assertEquals(expected.compute().options(), value.compute().options()); - assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.operationId(), value.operationId()); assertEquals(expected.clientOperationId(), value.clientOperationId()); assertEquals(expected.operationType(), value.operationType()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java index a2f472cdcbb8..39fdb622a59d 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java @@ -502,7 +502,6 @@ public void testListGlobalOperationsWithSelectedFields() { assertNull(operation.operationType()); assertNull(operation.targetLink()); assertNull(operation.targetId()); - assertNull(operation.creationTimestamp()); assertNull(operation.operationType()); assertNull(operation.status()); assertNull(operation.statusMessage()); @@ -564,7 +563,6 @@ public void testListRegionOperationsWithSelectedFields() { assertNull(operation.operationType()); assertNull(operation.targetLink()); assertNull(operation.targetId()); - assertNull(operation.creationTimestamp()); assertNull(operation.operationType()); assertNull(operation.status()); assertNull(operation.statusMessage()); @@ -628,7 +626,6 @@ public void testListZoneOperationsWithSelectedFields() { assertNull(operation.operationType()); assertNull(operation.targetLink()); assertNull(operation.targetId()); - assertNull(operation.creationTimestamp()); assertNull(operation.operationType()); assertNull(operation.status()); assertNull(operation.statusMessage()); From a4f9f2ddbaba540c7c6040d2c305d1de495d7337 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 15 Apr 2016 09:00:28 +0200 Subject: [PATCH 314/375] Fix compute homepage URL (#927) --- gcloud-java-compute/pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/gcloud-java-compute/pom.xml b/gcloud-java-compute/pom.xml index 6fc456442024..5b9b42efc731 100644 --- a/gcloud-java-compute/pom.xml +++ b/gcloud-java-compute/pom.xml @@ -4,6 +4,7 @@ gcloud-java-compute jar GCloud Java compute + https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-compute Java idiomatic client for Google Cloud Compute Engine. From 282f1fcf3792bcd835bbdd44a09fff688e7ee2dd Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 19 Apr 2016 08:46:50 +0200 Subject: [PATCH 315/375] Add SubnetworkInfo, NetworkId, SubnetworkId and test classes (#895) --- .../com/google/gcloud/compute/NetworkId.java | 137 +++++++ .../google/gcloud/compute/SubnetworkId.java | 179 +++++++++ .../google/gcloud/compute/SubnetworkInfo.java | 347 ++++++++++++++++++ .../google/gcloud/compute/NetworkIdTest.java | 79 ++++ .../gcloud/compute/SerializationTest.java | 16 +- .../gcloud/compute/SubnetworkIdTest.java | 87 +++++ .../gcloud/compute/SubnetworkInfoTest.java | 108 ++++++ 7 files changed, 948 insertions(+), 5 deletions(-) create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkId.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkId.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkInfo.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkIdTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkIdTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkInfoTest.java diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkId.java new file mode 100644 index 000000000000..09bf05fb6b9c --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkId.java @@ -0,0 +1,137 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects.ToStringHelper; + +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Identity for a Google Compute Engine network. + */ +public final class NetworkId extends ResourceId { + + private static final String REGEX = ResourceId.REGEX + "global/networks/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); + private static final long serialVersionUID = 2386765228138819506L; + + private final String network; + + NetworkId(String project, String network) { + super(project); + this.network = checkNotNull(network); + } + + private NetworkId(NetworkId networkId) { + super(networkId.project()); + this.network = checkNotNull(networkId.network()); + } + + /** + * Returns the name of the network. The network name must be 1-63 characters long and comply with + * RFC1035. Specifically, the name must match the regular expression + * {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a lowercase letter, + * and all following characters must be a dash, lowercase letter, or digit, except the last + * character, which cannot be a dash. + * + * @see RFC1035 + */ + public String network() { + return network; + } + + @Override + public String selfLink() { + return super.selfLink() + "/global/networks/" + network; + } + + @Override + ToStringHelper toStringHelper() { + return super.toStringHelper().add("network", network); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), network); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof NetworkId)) { + return false; + } + NetworkId other = (NetworkId) obj; + return baseEquals(other) && Objects.equals(network, other.network); + } + + @Override + NetworkId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return NetworkId.of(projectId, network); + } + + /** + * Returns a new network identity given project and network names. The network name must be 1-63 + * characters long and comply with RFC1035. Specifically, the name must match the regular + * expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a + * lowercase letter, and all following characters must be a dash, lowercase letter, or digit, + * except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public static NetworkId of(String project, String network) { + return new NetworkId(project, network); + } + + /** + * Returns a new network identity given network name. The network name must be 1-63 characters + * long and comply with RFC1035. Specifically, the name must match the regular expression + * {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a lowercase letter, + * and all following characters must be a dash, lowercase letter, or digit, except the last + * character, which cannot be a dash. + * + * @see RFC1035 + */ + public static NetworkId of(String network) { + return NetworkId.of(null, network); + } + + /** + * Returns {@code true} if the provided string matches the expected format of a network URL. + * Returns {@code false} otherwise. + */ + static boolean matchesUrl(String url) { + return PATTERN.matcher(url).matches(); + } + + static NetworkId fromUrl(String url) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { + throw new IllegalArgumentException(url + " is not a valid network URL"); + } + return NetworkId.of(matcher.group(1), matcher.group(2)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkId.java new file mode 100644 index 000000000000..7ed56f4ba3cf --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkId.java @@ -0,0 +1,179 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; + +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Identity for a Google Compute Engine subnetwork. + */ +public final class SubnetworkId extends ResourceId { + + static final Function FROM_URL_FUNCTION = + new Function() { + @Override + public SubnetworkId apply(String pb) { + return SubnetworkId.fromUrl(pb); + } + }; + static final Function TO_URL_FUNCTION = + new Function() { + @Override + public String apply(SubnetworkId zoneId) { + return zoneId.selfLink(); + } + }; + + private static final String REGEX = ResourceId.REGEX + "regions/([^/]+)/subnetworks/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); + private static final long serialVersionUID = -5451054513760540282L; + + private final String region; + private final String subnetwork; + + private SubnetworkId(String project, String region, String subnetwork) { + super(project); + this.region = checkNotNull(region); + this.subnetwork = checkNotNull(subnetwork); + } + + /** + * Returns the name of the region this subnetwork belongs to. + */ + public String region() { + return region; + } + + /** + * Returns the identity of the region this subnetwork belongs to. + */ + public RegionId regionId() { + return RegionId.of(project(), region); + } + + /** + * Returns the name of the subnetwork. The name must be 1-63 characters long and comply with + * RFC1035. Specifically, the name must match the regular expression + * {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a lowercase letter, + * and all following characters must be a dash, lowercase letter, or digit, except the last + * character, which cannot be a dash. + * + * @see RFC1035 + */ + public String subnetwork() { + return subnetwork; + } + + @Override + public String selfLink() { + return super.selfLink() + "/regions/" + region + "/subnetworks/" + subnetwork; + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return MoreObjects.toStringHelper(this).add("region", region).add("subnetwork", subnetwork); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), region, subnetwork); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof SubnetworkId)) { + return false; + } + SubnetworkId other = (SubnetworkId) obj; + return baseEquals(other) + && Objects.equals(region, other.region) + && Objects.equals(subnetwork, other.subnetwork); + } + + @Override + SubnetworkId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return SubnetworkId.of(projectId, region(), subnetwork); + } + + /** + * Returns a subnetwork identity given the region identity and the subnetwork name. The subnetwork + * name must be 1-63 characters long and comply with RFC1035. Specifically, the name must match + * the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must + * be a lowercase letter, and all following characters must be a dash, lowercase letter, or digit, + * except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public static SubnetworkId of(RegionId regionId, String subnetwork) { + return new SubnetworkId(regionId.project(), regionId.region(), subnetwork); + } + + /** + * Returns a subnetwork identity given the region and subnetwork names. The subnetwork name must + * be 1-63 characters long and comply with RFC1035. Specifically, the name must match the regular + * expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a + * lowercase letter, and all following characters must be a dash, lowercase letter, or digit, + * except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public static SubnetworkId of(String region, String subnetwork) { + return new SubnetworkId(null, region, subnetwork); + } + + /** + * Returns a subnetwork identity given project, region and subnetwork names. The subnetwork name + * must be 1-63 characters long and comply with RFC1035. Specifically, the name must match the + * regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a + * lowercase letter, and all following characters must be a dash, lowercase letter, or digit, + * except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public static SubnetworkId of(String project, String region, String subnetwork) { + return new SubnetworkId(project, region, subnetwork); + } + + /** + * Returns {@code true} if the provided string matches the expected format of a subnetwork URL. + * Returns {@code false} otherwise. + */ + static boolean matchesUrl(String url) { + return PATTERN.matcher(url).matches(); + } + + static SubnetworkId fromUrl(String url) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { + throw new IllegalArgumentException(url + " is not a valid subnetwork URL"); + } + return SubnetworkId.of(matcher.group(1), matcher.group(2), matcher.group(3)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkInfo.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkInfo.java new file mode 100644 index 000000000000..05eb0c95fc03 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkInfo.java @@ -0,0 +1,347 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.api.services.compute.model.Subnetwork; +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; + +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; + +import java.io.Serializable; +import java.math.BigInteger; +import java.util.Objects; + +/** + * A Google Compute Engine subnetwork. Compute Engine subnetworks allow you to segment your Compute + * Engine network IP space into subnetworks. Subnetworks for a Compute Engine network can be + * automatically allocated, or you can create a custom topology. + * + * @see Subnetworks + */ +public class SubnetworkInfo implements Serializable { + + static final Function FROM_PB_FUNCTION = + new Function() { + @Override + public SubnetworkInfo apply(Subnetwork pb) { + return SubnetworkInfo.fromPb(pb); + } + }; + static final Function TO_PB_FUNCTION = + new Function() { + @Override + public Subnetwork apply(SubnetworkInfo subnetwork) { + return subnetwork.toPb(); + } + }; + + private static final long serialVersionUID = 7491176262675441579L; + private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); + + private final String id; + private final SubnetworkId subnetworkId; + private final Long creationTimestamp; + private final String description; + private final String gatewayAddress; + private final NetworkId network; + private final String ipRange; + + /** + * A builder for {@code SubnetworkInfo} objects. + */ + public static abstract class Builder { + + abstract Builder id(String id); + + abstract Builder creationTimestamp(Long creationTimestamp); + + /** + * Sets the identity of the subnework. + */ + public abstract Builder subnetworkId(SubnetworkId subnetworkId); + + /** + * Sets an optional textual description of the subnetwork. + */ + abstract public Builder description(String description); + + abstract Builder gatewayAddress(String gatewayAddress); + + /** + * Sets the identity of the network to which this subnetwork belongs. Only networks that are in + * subnet mode can have subnetworks. + */ + abstract public Builder network(NetworkId network); + + /** + * Sets the range of internal IPv4 addresses that are owned by this subnetwork. This range must + * be a CIDR specification, for example: {@code 192.168.0.0/16}. Ranges must be unique and + * non-overlapping within a network. + * + * @see CIDR + */ + abstract public Builder ipRange(String ipRange); + + /** + * Creates a {@code SubnetworkInfo} object. + */ + abstract public SubnetworkInfo build(); + } + + static final class BuilderImpl extends Builder { + + private String id; + private SubnetworkId subnetworkId; + private Long creationTimestamp; + private String description; + private String gatewayAddress; + private NetworkId network; + private String ipRange; + + BuilderImpl(SubnetworkId subnetworkId, NetworkId network, String ipRange) { + this.subnetworkId = checkNotNull(subnetworkId); + this.network = checkNotNull(network); + this.ipRange = checkNotNull(ipRange); + } + + BuilderImpl(SubnetworkInfo subnetworkInfo) { + this.id = subnetworkInfo.id; + this.creationTimestamp = subnetworkInfo.creationTimestamp; + this.subnetworkId = subnetworkInfo.subnetworkId; + this.description = subnetworkInfo.description; + this.gatewayAddress = subnetworkInfo.gatewayAddress; + this.network = subnetworkInfo.network; + this.ipRange = subnetworkInfo.ipRange; + } + + BuilderImpl(Subnetwork subnetworkPb) { + if (subnetworkPb.getId() != null) { + this.id = subnetworkPb.getId().toString(); + } + if (subnetworkPb.getCreationTimestamp() != null) { + this.creationTimestamp = + TIMESTAMP_FORMATTER.parseMillis(subnetworkPb.getCreationTimestamp()); + } + this.subnetworkId = SubnetworkId.fromUrl(subnetworkPb.getSelfLink()); + this.description = subnetworkPb.getDescription(); + this.gatewayAddress = subnetworkPb.getGatewayAddress(); + if (subnetworkPb.getNetwork() != null) { + this.network = NetworkId.fromUrl(subnetworkPb.getNetwork()); + } + this.ipRange = subnetworkPb.getIpCidrRange(); + } + + @Override + BuilderImpl id(String id) { + this.id = id; + return this; + } + + @Override + BuilderImpl creationTimestamp(Long creationTimestamp) { + this.creationTimestamp = creationTimestamp; + return this; + } + + @Override + public BuilderImpl subnetworkId(SubnetworkId subnetworkId) { + this.subnetworkId = checkNotNull(subnetworkId); + return this; + } + + @Override + public BuilderImpl description(String description) { + this.description = description; + return this; + } + + @Override + BuilderImpl gatewayAddress(String gatewayAddress) { + this.gatewayAddress = gatewayAddress; + return this; + } + + @Override + public BuilderImpl network(NetworkId network) { + this.network = checkNotNull(network); + return this; + } + + @Override + public BuilderImpl ipRange(String ipRange) { + this.ipRange = checkNotNull(ipRange); + return this; + } + + @Override + public SubnetworkInfo build() { + return new SubnetworkInfo(this); + } + } + + SubnetworkInfo(BuilderImpl builder) { + this.id = builder.id; + this.creationTimestamp = builder.creationTimestamp; + this.subnetworkId = checkNotNull(builder.subnetworkId); + this.description = builder.description; + this.gatewayAddress = builder.gatewayAddress; + this.network = builder.network; + this.ipRange = builder.ipRange; + } + + /** + * Returns the unique identifier for the subnetwork; defined by the service. + */ + public String id() { + return id; + } + + /** + * Returns the creation timestamp in milliseconds since epoch. + */ + public Long creationTimestamp() { + return creationTimestamp; + } + + /** + * Returns the subnetwork identity. + */ + public SubnetworkId subnetworkId() { + return subnetworkId; + } + + /** + * Returns a textual description of the subnetwork. + */ + public String description() { + return description; + } + + /** + * Returns the gateway IPv4 address for this subnetwork, selected by the service. + */ + public String gatewayAddress() { + return gatewayAddress; + } + + /** + * Returns the identity of the network to which this subnetwork belongs. Only networks that are in + * subnet mode can have subnetworks. + */ + public NetworkId network() { + return network; + } + + /** + * Returns the range of internal IPv4 addresses that are owned by this subnetwork. This range is a + * CIDR specification, for example: {@code 192.168.0.0/16}. Ranges must be unique and + * non-overlapping within a network. + * + * @see CIDR + */ + public String ipRange() { + return ipRange; + } + + /** + * Returns a builder for the current subnetwork. + */ + public Builder toBuilder() { + return new BuilderImpl(this); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id) + .add("creationTimestamp", creationTimestamp) + .add("subnetworkId", subnetworkId) + .add("description", description) + .add("gatewayAddress", gatewayAddress) + .add("network", network) + .add("ipRange", ipRange) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(id, creationTimestamp, subnetworkId, description, gatewayAddress, network, + ipRange); + } + + @Override + public boolean equals(Object obj) { + return obj != null + && obj.getClass().equals(SubnetworkInfo.class) + && Objects.equals(toPb(), ((SubnetworkInfo) obj).toPb()); + } + + SubnetworkInfo setProjectId(String projectId) { + return toBuilder() + .subnetworkId(subnetworkId.setProjectId(projectId)) + .network(network.setProjectId(projectId)) + .build(); + } + + Subnetwork toPb() { + Subnetwork subnetworkPb = new Subnetwork(); + if (id != null) { + subnetworkPb.setId(new BigInteger(id)); + } + if (creationTimestamp != null) { + subnetworkPb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); + } + subnetworkPb.setName(subnetworkId.subnetwork()); + subnetworkPb.setDescription(description); + subnetworkPb.setSelfLink(subnetworkId.selfLink()); + subnetworkPb.setGatewayAddress(gatewayAddress); + subnetworkPb.setNetwork(network.selfLink()); + subnetworkPb.setIpCidrRange(ipRange); + return subnetworkPb; + } + + /** + * Returns a builder for a {@code SubnetworkInfo} object given the identity of the subnetwork, the + * identity of the network this subnetwork belongs to and the range of IPv4 addresses owned by + * this subnetwork. {@code ipRange} must be a CIDR specification, for example: + * {@code 192.168.0.0/16}. + * + * @see CIDR + */ + public static Builder builder(SubnetworkId subnetworkId, NetworkId network, String ipRange) { + return new BuilderImpl(subnetworkId, network, ipRange); + } + + /** + * Returns a {@code SubnetworkInfo} object given the identity of the subnetwork, the identity of + * the network this subnetwork belongs to and the range of IPv4 addresses owned by this + * subnetwork. {@code ipRange} must be a CIDR specification, for example: {@code 192.168.0.0/16}. + * + * @see CIDR + */ + public static SubnetworkInfo of(SubnetworkId subnetworkId, NetworkId network, String ipRange) { + return builder(subnetworkId, network, ipRange).build(); + } + + static SubnetworkInfo fromPb(Subnetwork subnetworkPb) { + return new BuilderImpl(subnetworkPb).build(); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkIdTest.java new file mode 100644 index 000000000000..08b012d25d62 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkIdTest.java @@ -0,0 +1,79 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class NetworkIdTest { + + private static final String PROJECT = "project"; + private static final String NETWORK = "network"; + private static final String URL = + "https://www.googleapis.com/compute/v1/projects/project/global/networks/network"; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testOf() { + NetworkId networkId = NetworkId.of(PROJECT, NETWORK); + assertEquals(PROJECT, networkId.project()); + assertEquals(NETWORK, networkId.network()); + assertEquals(URL, networkId.selfLink()); + networkId = NetworkId.of(NETWORK); + assertNull(networkId.project()); + assertEquals(NETWORK, networkId.network()); + } + + @Test + public void testToAndFromUrl() { + NetworkId networkId = NetworkId.of(PROJECT, NETWORK); + compareNetworkId(networkId, NetworkId.fromUrl(networkId.selfLink())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid network URL"); + NetworkId.fromUrl("notMatchingUrl"); + } + + @Test + public void testSetProjectId() { + NetworkId networkId = NetworkId.of(PROJECT, NETWORK); + assertSame(networkId, networkId.setProjectId(PROJECT)); + compareNetworkId(networkId, NetworkId.of(NETWORK).setProjectId(PROJECT)); + } + + @Test + public void testMatchesUrl() { + assertTrue(NetworkId.matchesUrl(NetworkId.of(PROJECT, NETWORK).selfLink())); + assertFalse(NetworkId.matchesUrl("notMatchingUrl")); + } + + private void compareNetworkId(NetworkId expected, NetworkId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.network(), expected.network()); + assertEquals(expected.selfLink(), expected.selfLink()); + assertEquals(expected.hashCode(), expected.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java index bec8844ae111..5f06d252af34 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java @@ -156,6 +156,11 @@ public class SerializationTest { private static final DiskInfo DISK_INFO = DiskInfo.of(DISK_ID, STANDARD_DISK_CONFIGURATION); private static final Disk DISK = new Disk.Builder(COMPUTE, DISK_ID, STANDARD_DISK_CONFIGURATION).build(); + private static final SubnetworkId SUBNETWORK_ID = + SubnetworkId.of("project", "region", "subnetwork"); + private static final NetworkId NETWORK_ID = NetworkId.of("project", "network"); + private static final SubnetworkInfo SUBNETWORK_INFO = + SubnetworkInfo.of(SUBNETWORK_ID, NETWORK_ID, "192.168.0.0/16"); private static final Compute.DiskTypeOption DISK_TYPE_OPTION = Compute.DiskTypeOption.fields(); private static final Compute.DiskTypeFilter DISK_TYPE_FILTER = @@ -241,11 +246,12 @@ public void testModelAndRequests() throws Exception { ADDRESS_INFO, ADDRESS, DISK_ID, SNAPSHOT_ID, SNAPSHOT_INFO, SNAPSHOT, IMAGE_ID, DISK_IMAGE_CONFIGURATION, STORAGE_IMAGE_CONFIGURATION, IMAGE_INFO, IMAGE, STANDARD_DISK_CONFIGURATION, IMAGE_DISK_CONFIGURATION, SNAPSHOT_DISK_CONFIGURATION, - DISK_INFO, DISK, DISK_TYPE_OPTION, DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, - DISK_TYPE_AGGREGATED_LIST_OPTION, MACHINE_TYPE_OPTION, MACHINE_TYPE_FILTER, - MACHINE_TYPE_LIST_OPTION, MACHINE_TYPE_AGGREGATED_LIST_OPTION, REGION_OPTION, REGION_FILTER, - REGION_LIST_OPTION, ZONE_OPTION, ZONE_FILTER, ZONE_LIST_OPTION, LICENSE_OPTION, - OPERATION_OPTION, OPERATION_FILTER, OPERATION_LIST_OPTION, ADDRESS_OPTION, ADDRESS_FILTER, + DISK_INFO, DISK, SUBNETWORK_ID, NETWORK_ID, SUBNETWORK_INFO, DISK_TYPE_OPTION, + DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, DISK_TYPE_AGGREGATED_LIST_OPTION, + MACHINE_TYPE_OPTION, MACHINE_TYPE_FILTER, MACHINE_TYPE_LIST_OPTION, + MACHINE_TYPE_AGGREGATED_LIST_OPTION, REGION_OPTION, REGION_FILTER, REGION_LIST_OPTION, + ZONE_OPTION, ZONE_FILTER, ZONE_LIST_OPTION, LICENSE_OPTION, OPERATION_OPTION, + OPERATION_FILTER, OPERATION_LIST_OPTION, ADDRESS_OPTION, ADDRESS_FILTER, ADDRESS_LIST_OPTION, ADDRESS_AGGREGATED_LIST_OPTION, SNAPSHOT_OPTION, SNAPSHOT_FILTER, SNAPSHOT_LIST_OPTION, IMAGE_OPTION, IMAGE_FILTER, IMAGE_LIST_OPTION, DISK_OPTION, DISK_FILTER, DISK_LIST_OPTION, DISK_AGGREGATED_LIST_OPTION}; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkIdTest.java new file mode 100644 index 000000000000..25e428c9009b --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkIdTest.java @@ -0,0 +1,87 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class SubnetworkIdTest { + + private static final String PROJECT = "project"; + private static final String REGION = "region"; + private static final String NAME = "subnet"; + private static final String URL = + "https://www.googleapis.com/compute/v1/projects/project/regions/region/subnetworks/subnet"; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testOf() { + SubnetworkId subnetworkId = SubnetworkId.of(PROJECT, REGION, NAME); + assertEquals(PROJECT, subnetworkId.project()); + assertEquals(REGION, subnetworkId.region()); + assertEquals(NAME, subnetworkId.subnetwork()); + assertEquals(URL, subnetworkId.selfLink()); + subnetworkId = SubnetworkId.of(REGION, NAME); + assertNull(subnetworkId.project()); + assertEquals(REGION, subnetworkId.region()); + assertEquals(NAME, subnetworkId.subnetwork()); + subnetworkId = SubnetworkId.of(RegionId.of(PROJECT, REGION), NAME); + assertEquals(PROJECT, subnetworkId.project()); + assertEquals(REGION, subnetworkId.region()); + assertEquals(NAME, subnetworkId.subnetwork()); + } + + @Test + public void testToAndFromUrl() { + SubnetworkId subnetworkId = SubnetworkId.of(PROJECT, REGION, NAME); + compareSubnetworkId(subnetworkId, SubnetworkId.fromUrl(subnetworkId.selfLink())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid subnetwork URL"); + SubnetworkId.fromUrl("notMatchingUrl"); + } + + @Test + public void testSetProjectId() { + SubnetworkId subnetworkId = SubnetworkId.of(PROJECT, REGION, NAME); + assertSame(subnetworkId, subnetworkId.setProjectId(PROJECT)); + compareSubnetworkId(subnetworkId, SubnetworkId.of(REGION, NAME).setProjectId(PROJECT)); + } + + @Test + public void testMatchesUrl() { + assertTrue(SubnetworkId.matchesUrl(SubnetworkId.of(PROJECT, REGION, NAME).selfLink())); + assertFalse(SubnetworkId.matchesUrl("notMatchingUrl")); + } + + private void compareSubnetworkId(SubnetworkId expected, SubnetworkId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.region(), expected.region()); + assertEquals(expected.subnetwork(), expected.subnetwork()); + assertEquals(expected.selfLink(), expected.selfLink()); + assertEquals(expected.hashCode(), expected.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkInfoTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkInfoTest.java new file mode 100644 index 000000000000..64d2e92852c9 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkInfoTest.java @@ -0,0 +1,108 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Test; + +public class SubnetworkInfoTest { + + private static final String ID = "42"; + private static final Long CREATION_TIMESTAMP = 1453293540000L; + private static final String DESCRIPTION = "description"; + private static final SubnetworkId SUBNETWORK_ID = + SubnetworkId.of("project", "region", "subnetwork"); + private static final String GATEWAY_ADDRESS = "192.168.1.1"; + private static final NetworkId NETWORK_ID = NetworkId.of("project", "network"); + private static final String IP_CIDR_RANGE = "192.168.0.0/16"; + private static final SubnetworkInfo SUBNETWORK_INFO = + SubnetworkInfo.builder(SUBNETWORK_ID, NETWORK_ID, IP_CIDR_RANGE) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .gatewayAddress(GATEWAY_ADDRESS) + .build(); + + @Test + public void testToBuilder() { + compareSubnetworkInfo(SUBNETWORK_INFO, SUBNETWORK_INFO.toBuilder().build()); + SubnetworkInfo subnetworkInfo = + SUBNETWORK_INFO.toBuilder().description("newDescription").build(); + assertEquals("newDescription", subnetworkInfo.description()); + subnetworkInfo = subnetworkInfo.toBuilder().description("description").build(); + compareSubnetworkInfo(SUBNETWORK_INFO, subnetworkInfo); + } + + @Test + public void testToBuilderIncomplete() { + SubnetworkInfo subnetworkInfo = SubnetworkInfo.of(SUBNETWORK_ID, NETWORK_ID, IP_CIDR_RANGE); + assertEquals(subnetworkInfo, subnetworkInfo.toBuilder().build()); + } + + @Test + public void testBuilder() { + assertEquals(ID, SUBNETWORK_INFO.id()); + assertEquals(SUBNETWORK_ID, SUBNETWORK_INFO.subnetworkId()); + assertEquals(CREATION_TIMESTAMP, SUBNETWORK_INFO.creationTimestamp()); + assertEquals(DESCRIPTION, SUBNETWORK_INFO.description()); + assertEquals(GATEWAY_ADDRESS, SUBNETWORK_INFO.gatewayAddress()); + assertEquals(NETWORK_ID, SUBNETWORK_INFO.network()); + assertEquals(IP_CIDR_RANGE, SUBNETWORK_INFO.ipRange()); + } + + @Test + public void testOf() { + SubnetworkInfo subnetworkInfo = SubnetworkInfo.of(SUBNETWORK_ID, NETWORK_ID, IP_CIDR_RANGE); + assertNull(subnetworkInfo.id()); + assertEquals(SUBNETWORK_ID, subnetworkInfo.subnetworkId()); + assertNull(subnetworkInfo.creationTimestamp()); + assertNull(subnetworkInfo.description()); + assertNull(subnetworkInfo.gatewayAddress()); + assertEquals(NETWORK_ID, subnetworkInfo.network()); + assertEquals(IP_CIDR_RANGE, subnetworkInfo.ipRange()); + } + + @Test + public void testToAndFromPb() { + compareSubnetworkInfo(SUBNETWORK_INFO, SubnetworkInfo.fromPb(SUBNETWORK_INFO.toPb())); + SubnetworkInfo subnetworkInfo = SubnetworkInfo.of(SUBNETWORK_ID, NETWORK_ID, IP_CIDR_RANGE); + compareSubnetworkInfo(subnetworkInfo, SubnetworkInfo.fromPb(subnetworkInfo.toPb())); + } + + @Test + public void testSetProjectId() { + SubnetworkInfo subnetworkInfo = SUBNETWORK_INFO.toBuilder() + .subnetworkId(SubnetworkId.of("region", "subnetwork")) + .network(NetworkId.of("network")) + .build(); + compareSubnetworkInfo(SUBNETWORK_INFO, subnetworkInfo.setProjectId("project")); + } + + public void compareSubnetworkInfo(SubnetworkInfo expected, SubnetworkInfo value) { + assertEquals(expected, value); + assertEquals(expected.id(), value.id()); + assertEquals(expected.subnetworkId(), value.subnetworkId()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.gatewayAddress(), value.gatewayAddress()); + assertEquals(expected.network(), value.network()); + assertEquals(expected.ipRange(), value.ipRange()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} From e15ed45f80d4fb7dd63b0d5213062f7b38cebdcf Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 19 Apr 2016 16:02:12 +0200 Subject: [PATCH 316/375] Add NetworkInfo, configuration classes and tests (#941) * Fix minor style issues with SubnetworkInfo and test class * Add NetworkInfo, configuration classes and tests --- .../gcloud/compute/NetworkConfiguration.java | 98 ++++++ .../google/gcloud/compute/NetworkInfo.java | 288 ++++++++++++++++++ .../compute/StandardNetworkConfiguration.java | 102 +++++++ .../compute/SubnetNetworkConfiguration.java | 111 +++++++ .../google/gcloud/compute/SubnetworkInfo.java | 10 +- .../gcloud/compute/NetworkInfoTest.java | 126 ++++++++ .../StandardNetworkConfigurationTest.java | 76 +++++ .../SubnetNetworkConfigurationTest.java | 83 +++++ .../gcloud/compute/SubnetworkInfoTest.java | 14 +- 9 files changed, 896 insertions(+), 12 deletions(-) create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkConfiguration.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInfo.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/StandardNetworkConfiguration.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetNetworkConfiguration.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkInfoTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/StandardNetworkConfigurationTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetNetworkConfigurationTest.java diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkConfiguration.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkConfiguration.java new file mode 100644 index 000000000000..f1d118347175 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkConfiguration.java @@ -0,0 +1,98 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import com.google.api.services.compute.model.Network; +import com.google.common.base.MoreObjects; +import com.google.common.base.MoreObjects.ToStringHelper; + +import java.io.Serializable; +import java.util.Objects; + +/** + * Base class for Google Compute Engine network configuration. Use + * {@link StandardNetworkConfiguration} to create a standard network with associated address range. + * Use {@link SubnetNetworkConfiguration} to create a network that supports subnetworks, up to one + * per region, each with its own address range. + * + * @see Using Networks and Firewalls + */ +public abstract class NetworkConfiguration implements Serializable { + + private static final long serialVersionUID = 6599798536784576564L; + + private final Type type; + + /** + * Type of a Google Compute Engine disk configuration. + */ + public enum Type { + /** + * A Google Compute Engine network with no subnetworks. + */ + STANDARD, + + /** + * A Google Compute Engine network that supports the creation of subnetworks (either automatic + * or manual). + */ + SUBNET + } + + NetworkConfiguration(Type type) { + this.type = type; + } + + /** + * Returns the network's type. This method returns {@link Type#STANDARD} for a standard networks + * with no subnetworks. This method returns {@link Type#SUBNET} for a network that supports the + * creation of subnetworks (either automatic or manual). + */ + public Type type() { + return type; + } + + ToStringHelper toStringHelper() { + return MoreObjects.toStringHelper(this).add("type", type); + } + + @Override + public String toString() { + return toStringHelper().toString(); + } + + final int baseHashCode() { + return Objects.hash(type); + } + + final boolean baseEquals(NetworkConfiguration networkConfiguration) { + return networkConfiguration != null + && getClass().equals(networkConfiguration.getClass()) + && Objects.equals(toPb(), networkConfiguration.toPb()); + } + + abstract Network toPb(); + + @SuppressWarnings("unchecked") + static T fromPb(Network networkPb) { + if (networkPb.getIPv4Range() != null) { + return (T) StandardNetworkConfiguration.fromPb(networkPb); + } else { + return (T) SubnetNetworkConfiguration.fromPb(networkPb); + } + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInfo.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInfo.java new file mode 100644 index 000000000000..1e1d4f4bf907 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInfo.java @@ -0,0 +1,288 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.api.services.compute.model.Network; +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; + +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; + +import java.io.Serializable; +import java.math.BigInteger; +import java.util.Objects; + +/** + * A Google Compute Engine Network. Every virtual machine instance is created as a member of a + * network. Networks connect instances to each other and to the Internet. You can segment your + * networks, use firewall rules to restrict access to instances, and create static routes to forward + * traffic to specific destinations. + * + * @see Using Networks and Firewalls + */ +public class NetworkInfo implements Serializable { + + static final Function FROM_PB_FUNCTION = + new Function() { + @Override + public NetworkInfo apply(Network pb) { + return NetworkInfo.fromPb(pb); + } + }; + static final Function TO_PB_FUNCTION = + new Function() { + @Override + public Network apply(NetworkInfo network) { + return network.toPb(); + } + }; + + private static final long serialVersionUID = 4336912581538114026L; + private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); + + private final String id; + private final NetworkId networkId; + private final Long creationTimestamp; + private final String description; + private final NetworkConfiguration configuration; + + /** + * A builder for {@code NetworkInfo} objects. + */ + public abstract static class Builder { + + abstract Builder id(String id); + + abstract Builder creationTimestamp(Long creationTimestamp); + + /** + * Sets the identity of the network. + */ + public abstract Builder networkId(NetworkId networkId); + + /** + * Sets an optional textual description of the network. + */ + public abstract Builder description(String description); + + /** + * Sets the network configuration. Use {@link StandardNetworkConfiguration} to create a standard + * network with associated IPv4 range. Use {@link SubnetNetworkConfiguration} to create a + * network that could be divided into subnetworks, up to one per region, each with its own + * address range. + */ + public abstract Builder configuration(NetworkConfiguration configuration); + + /** + * Creates a {@code NetworkInfo} object. + */ + public abstract NetworkInfo build(); + } + + static final class BuilderImpl extends Builder { + + private String id; + private NetworkId networkId; + private Long creationTimestamp; + private String description; + private NetworkConfiguration configuration; + + BuilderImpl(NetworkId networkId, NetworkConfiguration configuration) { + this.networkId = checkNotNull(networkId); + this.configuration = checkNotNull(configuration); + } + + BuilderImpl(NetworkInfo networkInfo) { + this.id = networkInfo.id; + this.creationTimestamp = networkInfo.creationTimestamp; + this.networkId = networkInfo.networkId; + this.description = networkInfo.description; + this.configuration = networkInfo.configuration; + } + + BuilderImpl(Network networkPb) { + if (networkPb.getId() != null) { + this.id = networkPb.getId().toString(); + } + if (networkPb.getCreationTimestamp() != null) { + this.creationTimestamp = TIMESTAMP_FORMATTER.parseMillis(networkPb.getCreationTimestamp()); + } + this.networkId = NetworkId.fromUrl(networkPb.getSelfLink()); + this.description = networkPb.getDescription(); + this.configuration = NetworkConfiguration.fromPb(networkPb); + } + + @Override + BuilderImpl id(String id) { + this.id = id; + return this; + } + + @Override + BuilderImpl creationTimestamp(Long creationTimestamp) { + this.creationTimestamp = creationTimestamp; + return this; + } + + @Override + public BuilderImpl networkId(NetworkId networkId) { + this.networkId = checkNotNull(networkId); + return this; + } + + @Override + public BuilderImpl description(String description) { + this.description = description; + return this; + } + + @Override + public BuilderImpl configuration(NetworkConfiguration configuration) { + this.configuration = checkNotNull(configuration); + return this; + } + + @Override + public NetworkInfo build() { + return new NetworkInfo(this); + } + } + + NetworkInfo(BuilderImpl builder) { + this.id = builder.id; + this.creationTimestamp = builder.creationTimestamp; + this.networkId = builder.networkId; + this.description = builder.description; + this.configuration = builder.configuration; + } + + /** + * Returns the unique identifier for the subnetwork; defined by the service. + */ + public String id() { + return id; + } + + /** + * Returns the creation timestamp in milliseconds since epoch. + */ + public Long creationTimestamp() { + return creationTimestamp; + } + + /** + * Returns the network identity. + */ + public NetworkId networkId() { + return networkId; + } + + /** + * Returns a textual description of the network. + */ + public String description() { + return description; + } + + /** + * Returns the network configuration. Returns a {@link StandardNetworkConfiguration} for standard + * networks with associated IPv4 range. Returns {@link SubnetNetworkConfiguration} for networks + * that could be divided into subnetworks, up to one per region, each with its own address range. + */ + @SuppressWarnings("unchecked") + public T configuration() { + return (T) configuration; + } + + /** + * Returns a builder for the current network. + */ + public Builder toBuilder() { + return new BuilderImpl(this); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id) + .add("creationTimestamp", creationTimestamp) + .add("networkId", networkId) + .add("description", description) + .add("configuration", configuration) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(id, networkId, creationTimestamp, description, configuration); + } + + @Override + public boolean equals(Object obj) { + return obj == this + || obj != null + && obj.getClass().equals(NetworkInfo.class) + && Objects.equals(toPb(), ((NetworkInfo) obj).toPb()); + } + + NetworkInfo setProjectId(String projectId) { + return toBuilder() + .networkId(networkId.setProjectId(projectId)) + .build(); + } + + Network toPb() { + Network networkPb = configuration.toPb(); + if (id != null) { + networkPb.setId(new BigInteger(id)); + } + if (creationTimestamp != null) { + networkPb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); + } + networkPb.setName(networkId.network()); + networkPb.setDescription(description); + networkPb.setSelfLink(networkId.selfLink()); + return networkPb; + } + + /** + * Returns a builder for a {@code NetworkInfo} object given the network identity and its + * configuration. Use {@link StandardNetworkConfiguration} to create a standard network with + * associated address range. Use {@link SubnetNetworkConfiguration} to create a network that + * supports subnetworks, up to one per region, each with its own address range. + */ + public static Builder builder(NetworkId networkId, NetworkConfiguration configuration) { + return new BuilderImpl(networkId, configuration); + } + + /** + * Returns a {@code NetworkInfo} object given the network identity. Use + * {@link StandardNetworkConfiguration} to create a standard network with associated address + * range. Use {@link SubnetNetworkConfiguration} to create a network that supports subnetworks, up + * to one per region, each with its own address range. + */ + public static NetworkInfo of(NetworkId networkId, NetworkConfiguration configuration) { + return builder(networkId, configuration).build(); + } + + static NetworkInfo fromPb(Network networkPb) { + return new BuilderImpl(networkPb).build(); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/StandardNetworkConfiguration.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/StandardNetworkConfiguration.java new file mode 100644 index 000000000000..d4595efb6eb6 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/StandardNetworkConfiguration.java @@ -0,0 +1,102 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.api.services.compute.model.Network; +import com.google.common.base.MoreObjects; + +import java.util.Objects; + +/** + * A Google Compute Engine standard network configuration. This class allows users to create a + * network with its own address range. A network created with a {@code StandardNetworkConfiguration} + * does not support the creation of subnetworks. + * + * @see Using Networks and Firewalls + */ +public class StandardNetworkConfiguration extends NetworkConfiguration { + + private static final long serialVersionUID = -5143748459659467966L; + + private final String ipRange; + private final String gatewayAddress; + + StandardNetworkConfiguration(String ipRange, String gatewayAddress) { + super(Type.STANDARD); + this.ipRange = checkNotNull(ipRange); + this.gatewayAddress = gatewayAddress; + } + + /** + * Returns the range of internal IPv4 addresses that are legal on this network. This range is a + * CIDR specification, for example: {@code 192.168.0.0/16}. + * + * @see CIDR + */ + public String ipRange() { + return ipRange; + } + + /** + * Returns the gateway IPv4 address for this networks. This value is read only and is selected by + * Google Compute Engine, typically as the first usable address in {@code ipRange}. + */ + public String gatewayAddress() { + return gatewayAddress; + } + + @Override + public final int hashCode() { + return Objects.hash(super.baseHashCode(), ipRange, gatewayAddress); + } + + @Override + public final boolean equals(Object obj) { + return obj == this + || obj != null + && obj.getClass().equals(StandardNetworkConfiguration.class) + && Objects.equals(toPb(), ((StandardNetworkConfiguration) obj).toPb()); + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper().add("ipRange", ipRange).add("gatewayAddress", gatewayAddress); + } + + @Override + Network toPb() { + return new Network().setIPv4Range(ipRange).setGatewayIPv4(gatewayAddress); + } + + /** + * Returns a {@code StandardNetworkConfiguration} object given the range of internal addresses + * that are legal on this network. {@code ipRange} must be a CIDR specification, for example: + * {@code 192.168.0.0/16}. + * + * @see CIDR + */ + public static StandardNetworkConfiguration of(String ipRange) { + return new StandardNetworkConfiguration(ipRange, null); + } + + @SuppressWarnings("unchecked") + static StandardNetworkConfiguration fromPb(Network networkPb) { + return new StandardNetworkConfiguration(networkPb.getIPv4Range(), networkPb.getGatewayIPv4()); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetNetworkConfiguration.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetNetworkConfiguration.java new file mode 100644 index 000000000000..0d4c9f07b85f --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetNetworkConfiguration.java @@ -0,0 +1,111 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import com.google.api.services.compute.model.Network; +import com.google.common.base.MoreObjects; +import com.google.common.collect.Lists; + +import java.util.List; +import java.util.Objects; + +/** + * A Google Compute Engine configuration for networks that support subnetworks, up to one per + * region, each with its own address range. Subnetworks can be either automatically or manually + * created, depending on the value of {@link SubnetNetworkConfiguration#autoCreateSubnetworks()}. + * + * @see Using Networks and Firewalls + */ +public class SubnetNetworkConfiguration extends NetworkConfiguration { + + private static final long serialVersionUID = -5286394393047479494L; + + private final Boolean autoCreateSubnetworks; + private final List subnetworks; + + SubnetNetworkConfiguration(boolean autoCreateSubnetworks, List subnetworks) { + super(Type.SUBNET); + this.autoCreateSubnetworks = autoCreateSubnetworks; + this.subnetworks = subnetworks; + } + + /** + * Returns whether the subnetworks should be automatically created. When set to {@code true}, the + * network is created in "auto subnet mode". When set to {@code false}, the network is in + * "custom subnet mode". In "auto subnet mode", a subnetwork per region is automatically created. + * In "custom subnet mode", a custom topology of subnetworks can be created by the user. + */ + public Boolean autoCreateSubnetworks() { + return autoCreateSubnetworks; + } + + /** + * Returns the identities of all networks in this network. + */ + public List subnetworks() { + return subnetworks; + } + + @Override + public final int hashCode() { + return Objects.hash(autoCreateSubnetworks, subnetworks); + } + + @Override + public final boolean equals(Object obj) { + return obj == this + || obj != null + && obj.getClass().equals(SubnetNetworkConfiguration.class) + && Objects.equals(toPb(), ((SubnetNetworkConfiguration) obj).toPb()); + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper() + .add("autoCreateSubnetworks", autoCreateSubnetworks) + .add("subnetworks", subnetworks); + } + + @Override + Network toPb() { + Network networkPb = new Network().setAutoCreateSubnetworks(autoCreateSubnetworks); + if (subnetworks != null) { + networkPb.setSubnetworks(Lists.transform(subnetworks, SubnetworkId.TO_URL_FUNCTION)); + } + return networkPb; + } + + /** + * Returns a {@code SubnetNetworkConfiguration} object. The {@code autoCreateSubnetworks} + * parameter sets whether subnetworks should be automatically created. When set to {@code true}, + * the network is created in "auto subnet mode". When set to {@code false}, the network is in + * "custom subnet mode". In "auto subnet mode", a subnetwork per region is automatically created. + * In "custom subnet mode", a custom topology of subnetworks can be created by the user. + */ + public static SubnetNetworkConfiguration of(boolean autoCreateSubnetworks) { + return new SubnetNetworkConfiguration(autoCreateSubnetworks, null); + } + + @SuppressWarnings("unchecked") + static SubnetNetworkConfiguration fromPb(Network networkPb) { + List subnetworks = null; + if (networkPb.getSubnetworks() != null) { + subnetworks = Lists.transform(networkPb.getSubnetworks(), SubnetworkId.FROM_URL_FUNCTION); + } + return new SubnetNetworkConfiguration(networkPb.getAutoCreateSubnetworks(), subnetworks); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkInfo.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkInfo.java index 05eb0c95fc03..5be0d875d738 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkInfo.java @@ -67,7 +67,7 @@ public Subnetwork apply(SubnetworkInfo subnetwork) { /** * A builder for {@code SubnetworkInfo} objects. */ - public static abstract class Builder { + public abstract static class Builder { abstract Builder id(String id); @@ -81,7 +81,7 @@ public static abstract class Builder { /** * Sets an optional textual description of the subnetwork. */ - abstract public Builder description(String description); + public abstract Builder description(String description); abstract Builder gatewayAddress(String gatewayAddress); @@ -89,7 +89,7 @@ public static abstract class Builder { * Sets the identity of the network to which this subnetwork belongs. Only networks that are in * subnet mode can have subnetworks. */ - abstract public Builder network(NetworkId network); + public abstract Builder network(NetworkId network); /** * Sets the range of internal IPv4 addresses that are owned by this subnetwork. This range must @@ -98,12 +98,12 @@ public static abstract class Builder { * * @see CIDR */ - abstract public Builder ipRange(String ipRange); + public abstract Builder ipRange(String ipRange); /** * Creates a {@code SubnetworkInfo} object. */ - abstract public SubnetworkInfo build(); + public abstract SubnetworkInfo build(); } static final class BuilderImpl extends Builder { diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkInfoTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkInfoTest.java new file mode 100644 index 000000000000..3886e13816fe --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkInfoTest.java @@ -0,0 +1,126 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import com.google.common.collect.ImmutableList; + +import org.junit.Test; + +import java.util.List; + +public class NetworkInfoTest { + + private static final String ID = "42"; + private static final Long CREATION_TIMESTAMP = 1453293540000L; + private static final String DESCRIPTION = "description"; + private static final SubnetworkId SUBNETWORK1 = SubnetworkId.of("project", "region1", "network1"); + private static final SubnetworkId SUBNETWORK2 = SubnetworkId.of("project", "region2", "network2"); + private static final List SUBNETWORKS = ImmutableList.of(SUBNETWORK1, SUBNETWORK2); + private static final String GATEWAY_ADDRESS = "192.168.1.1"; + private static final NetworkId NETWORK_ID = NetworkId.of("project", "network"); + private static final String IP_RANGE = "192.168.0.0/16"; + private static final Boolean AUTO_CREATE_SUBNETWORKS = true; + private static final StandardNetworkConfiguration NETWORK_CONFIGURATION = + new StandardNetworkConfiguration(IP_RANGE, GATEWAY_ADDRESS); + private static final SubnetNetworkConfiguration SUBNET_NETWORK_CONFIGURATION = + new SubnetNetworkConfiguration(AUTO_CREATE_SUBNETWORKS, SUBNETWORKS); + private static final NetworkInfo NETWORK_INFO = + NetworkInfo.builder(NETWORK_ID, NETWORK_CONFIGURATION) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .build(); + private static final NetworkInfo SUBNET_NETWORK_INFO = + NetworkInfo.builder(NETWORK_ID, SUBNET_NETWORK_CONFIGURATION) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .build(); + + @Test + public void testToBuilder() { + compareNetworkInfo(NETWORK_INFO, NETWORK_INFO.toBuilder().build()); + NetworkInfo networkInfo = NETWORK_INFO.toBuilder().description("newDescription").build(); + assertEquals("newDescription", networkInfo.description()); + networkInfo = networkInfo.toBuilder().description("description").build(); + compareNetworkInfo(NETWORK_INFO, networkInfo); + compareNetworkInfo(SUBNET_NETWORK_INFO, SUBNET_NETWORK_INFO.toBuilder().build()); + networkInfo = SUBNET_NETWORK_INFO.toBuilder().description("newDescription").build(); + assertEquals("newDescription", networkInfo.description()); + networkInfo = networkInfo.toBuilder().description("description").build(); + compareNetworkInfo(SUBNET_NETWORK_INFO, networkInfo); + } + + @Test + public void testToBuilderIncomplete() { + NetworkInfo networkInfo = NetworkInfo.of(NETWORK_ID, NETWORK_CONFIGURATION); + assertEquals(networkInfo, networkInfo.toBuilder().build()); + } + + @Test + public void testBuilder() { + assertEquals(ID, NETWORK_INFO.id()); + assertEquals(NETWORK_ID, NETWORK_INFO.networkId()); + assertEquals(CREATION_TIMESTAMP, NETWORK_INFO.creationTimestamp()); + assertEquals(DESCRIPTION, NETWORK_INFO.description()); + assertEquals(NETWORK_CONFIGURATION, NETWORK_INFO.configuration()); + assertEquals(ID, SUBNET_NETWORK_INFO.id()); + assertEquals(NETWORK_ID, SUBNET_NETWORK_INFO.networkId()); + assertEquals(CREATION_TIMESTAMP, SUBNET_NETWORK_INFO.creationTimestamp()); + assertEquals(DESCRIPTION, SUBNET_NETWORK_INFO.description()); + assertEquals(SUBNET_NETWORK_CONFIGURATION, SUBNET_NETWORK_INFO.configuration()); + } + + @Test + public void testOf() { + NetworkInfo networkInfo = NetworkInfo.of(NETWORK_ID, NETWORK_CONFIGURATION); + assertNull(networkInfo.id()); + assertEquals(NETWORK_ID, NETWORK_INFO.networkId()); + assertEquals(NETWORK_CONFIGURATION, NETWORK_INFO.configuration()); + assertNull(networkInfo.creationTimestamp()); + assertNull(networkInfo.description()); + } + + @Test + public void testToAndFromPb() { + compareNetworkInfo(NETWORK_INFO, NetworkInfo.fromPb(NETWORK_INFO.toPb())); + compareNetworkInfo(SUBNET_NETWORK_INFO, NetworkInfo.fromPb(SUBNET_NETWORK_INFO.toPb())); + NetworkInfo networkInfo = NetworkInfo.of(NETWORK_ID, NETWORK_CONFIGURATION); + compareNetworkInfo(networkInfo, NetworkInfo.fromPb(networkInfo.toPb())); + } + + @Test + public void testSetProjectId() { + NetworkInfo networkInfo = NETWORK_INFO.toBuilder() + .networkId(NetworkId.of("network")) + .build(); + compareNetworkInfo(NETWORK_INFO, networkInfo.setProjectId("project")); + } + + public void compareNetworkInfo(NetworkInfo expected, NetworkInfo value) { + assertEquals(expected, value); + assertEquals(expected.id(), value.id()); + assertEquals(expected.networkId(), value.networkId()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.configuration(), value.configuration()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/StandardNetworkConfigurationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/StandardNetworkConfigurationTest.java new file mode 100644 index 000000000000..7546f0b70494 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/StandardNetworkConfigurationTest.java @@ -0,0 +1,76 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import com.google.gcloud.compute.NetworkConfiguration.Type; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class StandardNetworkConfigurationTest { + + private static final String IP_RANGE = "192.168.0.0/16"; + private static final String GATEWAY_ADDRESS = "192.168.1.1"; + private static final StandardNetworkConfiguration NETWORK_CONFIGURATION = + new StandardNetworkConfiguration(IP_RANGE, GATEWAY_ADDRESS); + + @Test + public void testConstructor() { + assertEquals(Type.STANDARD, NETWORK_CONFIGURATION.type()); + assertEquals(IP_RANGE, NETWORK_CONFIGURATION.ipRange()); + assertEquals(GATEWAY_ADDRESS, NETWORK_CONFIGURATION.gatewayAddress()); + StandardNetworkConfiguration networkConfiguration = + new StandardNetworkConfiguration(IP_RANGE, null); + assertEquals(Type.STANDARD, networkConfiguration.type()); + assertEquals(IP_RANGE, networkConfiguration.ipRange()); + assertNull(networkConfiguration.gatewayAddress()); + } + + @Test + public void testToAndFromPb() { + assertTrue(NetworkConfiguration.fromPb(NETWORK_CONFIGURATION.toPb()) + instanceof StandardNetworkConfiguration); + compareNetworkConfiguration(NETWORK_CONFIGURATION, + NetworkConfiguration.fromPb(NETWORK_CONFIGURATION.toPb())); + StandardNetworkConfiguration networkConfiguration = + new StandardNetworkConfiguration(IP_RANGE, null); + assertTrue(NetworkConfiguration.fromPb(networkConfiguration.toPb()) + instanceof StandardNetworkConfiguration); + compareNetworkConfiguration(networkConfiguration, + NetworkConfiguration.fromPb(networkConfiguration.toPb())); + } + + @Test + public void testOf() { + StandardNetworkConfiguration configuration = StandardNetworkConfiguration.of(IP_RANGE); + assertEquals(Type.STANDARD, configuration.type()); + assertEquals(IP_RANGE, configuration.ipRange()); + assertNull(configuration.gatewayAddress()); + } + + private void compareNetworkConfiguration(StandardNetworkConfiguration expected, + StandardNetworkConfiguration value) { + assertEquals(expected, value); + assertEquals(expected.ipRange(), value.ipRange()); + assertEquals(expected.gatewayAddress(), value.gatewayAddress()); + assertEquals(expected.type(), value.type()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetNetworkConfigurationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetNetworkConfigurationTest.java new file mode 100644 index 000000000000..c2a5ddafcd0e --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetNetworkConfigurationTest.java @@ -0,0 +1,83 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import com.google.common.collect.ImmutableList; +import com.google.gcloud.compute.NetworkConfiguration.Type; + +import org.junit.Test; + +import java.util.List; + +public class SubnetNetworkConfigurationTest { + + private static final Boolean AUTO_CREATE_SUBNETWORKS = true; + private static final List SUBNETWORKS = ImmutableList.of( + SubnetworkId.of("project", "region", "subnetwork1"), + SubnetworkId.of("project", "region", "subnetwork2")); + private static final SubnetNetworkConfiguration NETWORK_CONFIGURATION = + new SubnetNetworkConfiguration(AUTO_CREATE_SUBNETWORKS, SUBNETWORKS); + + @Test + public void testConstructor() { + assertEquals(AUTO_CREATE_SUBNETWORKS, NETWORK_CONFIGURATION.autoCreateSubnetworks()); + assertEquals(Type.SUBNET, NETWORK_CONFIGURATION.type()); + assertEquals(SUBNETWORKS, NETWORK_CONFIGURATION.subnetworks()); + assertEquals(Type.SUBNET, NETWORK_CONFIGURATION.type()); + SubnetNetworkConfiguration networkConfiguration = + new SubnetNetworkConfiguration(AUTO_CREATE_SUBNETWORKS, null); + assertEquals(Type.SUBNET, networkConfiguration.type()); + assertEquals(AUTO_CREATE_SUBNETWORKS, networkConfiguration.autoCreateSubnetworks()); + assertNull(networkConfiguration.subnetworks()); + } + + @Test + public void testToAndFromPb() { + assertTrue(NetworkConfiguration.fromPb(NETWORK_CONFIGURATION.toPb()) + instanceof SubnetNetworkConfiguration); + compareNetworkConfiguration(NETWORK_CONFIGURATION, + NetworkConfiguration.fromPb(NETWORK_CONFIGURATION.toPb())); + SubnetNetworkConfiguration networkConfiguration = + new SubnetNetworkConfiguration(AUTO_CREATE_SUBNETWORKS, null); + assertTrue(NetworkConfiguration.fromPb(networkConfiguration.toPb()) + instanceof SubnetNetworkConfiguration); + compareNetworkConfiguration(networkConfiguration, + NetworkConfiguration.fromPb(networkConfiguration.toPb())); + } + + @Test + public void testOf() { + SubnetNetworkConfiguration configuration = + SubnetNetworkConfiguration.of(AUTO_CREATE_SUBNETWORKS); + assertEquals(AUTO_CREATE_SUBNETWORKS, configuration.autoCreateSubnetworks()); + assertNull(configuration.subnetworks()); + assertEquals(Type.SUBNET, configuration.type()); + } + + private void compareNetworkConfiguration(SubnetNetworkConfiguration expected, + SubnetNetworkConfiguration value) { + assertEquals(expected, value); + assertEquals(expected.autoCreateSubnetworks(), value.autoCreateSubnetworks()); + assertEquals(expected.subnetworks(), value.subnetworks()); + assertEquals(expected.type(), value.type()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkInfoTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkInfoTest.java index 64d2e92852c9..83ba0bf9baab 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkInfoTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkInfoTest.java @@ -30,9 +30,9 @@ public class SubnetworkInfoTest { SubnetworkId.of("project", "region", "subnetwork"); private static final String GATEWAY_ADDRESS = "192.168.1.1"; private static final NetworkId NETWORK_ID = NetworkId.of("project", "network"); - private static final String IP_CIDR_RANGE = "192.168.0.0/16"; + private static final String IP_RANGE = "192.168.0.0/16"; private static final SubnetworkInfo SUBNETWORK_INFO = - SubnetworkInfo.builder(SUBNETWORK_ID, NETWORK_ID, IP_CIDR_RANGE) + SubnetworkInfo.builder(SUBNETWORK_ID, NETWORK_ID, IP_RANGE) .id(ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) @@ -51,7 +51,7 @@ public void testToBuilder() { @Test public void testToBuilderIncomplete() { - SubnetworkInfo subnetworkInfo = SubnetworkInfo.of(SUBNETWORK_ID, NETWORK_ID, IP_CIDR_RANGE); + SubnetworkInfo subnetworkInfo = SubnetworkInfo.of(SUBNETWORK_ID, NETWORK_ID, IP_RANGE); assertEquals(subnetworkInfo, subnetworkInfo.toBuilder().build()); } @@ -63,25 +63,25 @@ public void testBuilder() { assertEquals(DESCRIPTION, SUBNETWORK_INFO.description()); assertEquals(GATEWAY_ADDRESS, SUBNETWORK_INFO.gatewayAddress()); assertEquals(NETWORK_ID, SUBNETWORK_INFO.network()); - assertEquals(IP_CIDR_RANGE, SUBNETWORK_INFO.ipRange()); + assertEquals(IP_RANGE, SUBNETWORK_INFO.ipRange()); } @Test public void testOf() { - SubnetworkInfo subnetworkInfo = SubnetworkInfo.of(SUBNETWORK_ID, NETWORK_ID, IP_CIDR_RANGE); + SubnetworkInfo subnetworkInfo = SubnetworkInfo.of(SUBNETWORK_ID, NETWORK_ID, IP_RANGE); assertNull(subnetworkInfo.id()); assertEquals(SUBNETWORK_ID, subnetworkInfo.subnetworkId()); assertNull(subnetworkInfo.creationTimestamp()); assertNull(subnetworkInfo.description()); assertNull(subnetworkInfo.gatewayAddress()); assertEquals(NETWORK_ID, subnetworkInfo.network()); - assertEquals(IP_CIDR_RANGE, subnetworkInfo.ipRange()); + assertEquals(IP_RANGE, subnetworkInfo.ipRange()); } @Test public void testToAndFromPb() { compareSubnetworkInfo(SUBNETWORK_INFO, SubnetworkInfo.fromPb(SUBNETWORK_INFO.toPb())); - SubnetworkInfo subnetworkInfo = SubnetworkInfo.of(SUBNETWORK_ID, NETWORK_ID, IP_CIDR_RANGE); + SubnetworkInfo subnetworkInfo = SubnetworkInfo.of(SUBNETWORK_ID, NETWORK_ID, IP_RANGE); compareSubnetworkInfo(subnetworkInfo, SubnetworkInfo.fromPb(subnetworkInfo.toPb())); } From ec9c0f19b2210902398b25287386bfcdabd3fb44 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 20 Apr 2016 16:30:37 +0200 Subject: [PATCH 317/375] Add functional methods for networks and subnetworks (#944) --- .../com/google/gcloud/compute/Compute.java | 331 ++++++++++++ .../google/gcloud/compute/ComputeImpl.java | 270 ++++++++++ .../com/google/gcloud/compute/Network.java | 194 +++++++ .../com/google/gcloud/compute/Subnetwork.java | 190 +++++++ .../google/gcloud/compute/SubnetworkInfo.java | 3 +- .../google/gcloud/compute/spi/ComputeRpc.java | 72 +++ .../gcloud/compute/spi/DefaultComputeRpc.java | 139 +++++ .../gcloud/compute/ComputeImplTest.java | 486 ++++++++++++++++++ .../google/gcloud/compute/NetworkTest.java | 259 ++++++++++ .../gcloud/compute/SerializationTest.java | 33 +- .../google/gcloud/compute/SubnetworkTest.java | 210 ++++++++ .../gcloud/compute/it/ITComputeTest.java | 246 +++++++++ 12 files changed, 2429 insertions(+), 4 deletions(-) create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/Network.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/Subnetwork.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkTest.java diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java index dbc2f0d49366..ee0c327da8dc 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java @@ -963,6 +963,88 @@ public static DiskFilter notEquals(DiskField field, long value) { } } + /** + * Class for filtering subnetwork lists. + */ + class SubnetworkFilter extends ListFilter { + + private static final long serialVersionUID = 979448583739105481L; + + private SubnetworkFilter(SubnetworkField field, ComparisonOperator operator, Object value) { + super(field.selector(), operator, value); + } + + /** + * Returns an equals filter for the given field and string value. For string fields, + * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must + * match the entire field. + * + * @see RE2 + */ + public static SubnetworkFilter equals(SubnetworkField field, String value) { + return new SubnetworkFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value)); + } + + /** + * Returns a not-equals filter for the given field and string value. For string fields, + * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must + * match the entire field. + * + * @see RE2 + */ + public static SubnetworkFilter notEquals(SubnetworkField field, String value) { + return new SubnetworkFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value)); + } + } + + /** + * Class for filtering network lists. + */ + class NetworkFilter extends ListFilter { + + private static final long serialVersionUID = 7921406498804130930L; + + private NetworkFilter(NetworkField field, ComparisonOperator operator, Object value) { + super(field.selector(), operator, value); + } + + /** + * Returns an equals filter for the given field and string value. For string fields, + * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must + * match the entire field. + * + * @see RE2 + */ + public static NetworkFilter equals(NetworkField field, String value) { + return new NetworkFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value)); + } + + /** + * Returns a not-equals filter for the given field and string value. For string fields, + * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must + * match the entire field. + * + * @see RE2 + */ + public static NetworkFilter notEquals(NetworkField field, String value) { + return new NetworkFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value)); + } + + /** + * Returns a equals filter for the given field and boolean value. + */ + public static NetworkFilter equals(NetworkField field, boolean value) { + return new NetworkFilter(checkNotNull(field), ComparisonOperator.EQ, value); + } + + /** + * Returns a not-equals filter for the given field and boolean value. + */ + public static NetworkFilter notEquals(NetworkField field, boolean value) { + return new NetworkFilter(checkNotNull(field), ComparisonOperator.NE, value); + } + } + /** * Class for specifying disk type get options. */ @@ -1737,6 +1819,176 @@ public static DiskAggregatedListOption pageToken(String pageToken) { } } + /** + * Class for specifying subnetwork get options. + */ + class SubnetworkOption extends Option { + + private static final long serialVersionUID = 1994416967962074717L; + + private SubnetworkOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify the subnetwork's fields to be returned by the RPC call. If this + * option is not provided, all subnetwork's fields are returned. {@code SubnetworkOption.fields} + * can be used to specify only the fields of interest. {@link Subnetwork#subnetworkId()} is + * always returned, even if not specified. + */ + public static SubnetworkOption fields(SubnetworkField... fields) { + return new SubnetworkOption(ComputeRpc.Option.FIELDS, SubnetworkField.selector(fields)); + } + } + + /** + * Class for specifying subnetwork list options. + */ + class SubnetworkListOption extends Option { + + private static final long serialVersionUID = -2978666213373829606L; + + private SubnetworkListOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify a filter on the subnetworks being listed. + */ + public static SubnetworkListOption filter(SubnetworkFilter filter) { + return new SubnetworkListOption(ComputeRpc.Option.FILTER, filter.toPb()); + } + + /** + * Returns an option to specify the maximum number of subnetworks returned per page. + * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used. + */ + public static SubnetworkListOption pageSize(long pageSize) { + return new SubnetworkListOption(ComputeRpc.Option.MAX_RESULTS, pageSize); + } + + /** + * Returns an option to specify the page token from which to start listing subnetworks. + */ + public static SubnetworkListOption pageToken(String pageToken) { + return new SubnetworkListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); + } + + /** + * Returns an option to specify the subnetwork's fields to be returned by the RPC call. If this + * option is not provided, all subnetwork's fields are returned. + * {@code SubnetworListkOption.fields} can be used to specify only the fields of interest. + * {@link Subnetwork#subnetworkId()} is always returned, even if not specified. + */ + public static SubnetworkListOption fields(SubnetworkField... fields) { + StringBuilder builder = new StringBuilder(); + builder.append("items(").append(SubnetworkField.selector(fields)).append("),nextPageToken"); + return new SubnetworkListOption(ComputeRpc.Option.FIELDS, builder.toString()); + } + } + + /** + * Class for specifying subnetwork aggregated list options. + */ + class SubnetworkAggregatedListOption extends Option { + + private static final long serialVersionUID = -4033514850525545027L; + + private SubnetworkAggregatedListOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify a filter on the subnetworks being listed. + */ + public static SubnetworkAggregatedListOption filter(SubnetworkFilter filter) { + return new SubnetworkAggregatedListOption(ComputeRpc.Option.FILTER, filter.toPb()); + } + + /** + * Returns an option to specify the maximum number of subnetworks returned per page. + * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used. + */ + public static SubnetworkAggregatedListOption pageSize(long pageSize) { + return new SubnetworkAggregatedListOption(ComputeRpc.Option.MAX_RESULTS, pageSize); + } + + /** + * Returns an option to specify the page token from which to start listing subnetworks. + */ + public static SubnetworkAggregatedListOption pageToken(String pageToken) { + return new SubnetworkAggregatedListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); + } + } + + /** + * Class for specifying network get options. + */ + class NetworkOption extends Option { + + private static final long serialVersionUID = 5346750551643875754L; + + private NetworkOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify the network's fields to be returned by the RPC call. If this + * option is not provided, all network's fields are returned. {@code NetworkOption.fields} + * can be used to specify only the fields of interest. {@link Network#networkId()} and + * {@link Network#configuration()} are always returned, even if not specified. + */ + public static NetworkOption fields(NetworkField... fields) { + return new NetworkOption(ComputeRpc.Option.FIELDS, NetworkField.selector(fields)); + } + } + + /** + * Class for specifying network list options. + */ + class NetworkListOption extends Option { + + private static final long serialVersionUID = -4291731916527773896L; + + private NetworkListOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify a filter on the networks being listed. + */ + public static NetworkListOption filter(NetworkFilter filter) { + return new NetworkListOption(ComputeRpc.Option.FILTER, filter.toPb()); + } + + /** + * Returns an option to specify the maximum number of networks returned per page. + * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used. + */ + public static NetworkListOption pageSize(long pageSize) { + return new NetworkListOption(ComputeRpc.Option.MAX_RESULTS, pageSize); + } + + /** + * Returns an option to specify the page token from which to start listing networks. + */ + public static NetworkListOption pageToken(String pageToken) { + return new NetworkListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); + } + + /** + * Returns an option to specify the network's fields to be returned by the RPC call. If this + * option is not provided, all network's fields are returned. {@code NetworkListOption.fields} + * can be used to specify only the fields of interest. {@link Network#networkId()} and + * {@link Network#configuration()} are always returned, even if not specified. + */ + public static NetworkListOption fields(NetworkField... fields) { + StringBuilder builder = new StringBuilder(); + builder.append("items(").append(NetworkField.selector(fields)).append("),nextPageToken"); + return new NetworkListOption(ComputeRpc.Option.FIELDS, builder.toString()); + } + } + /** * Returns the requested disk type or {@code null} if not found. * @@ -2066,4 +2318,83 @@ Operation deprecate(ImageId image, DeprecationStatus deprecationStatus, * @throws ComputeException upon failure or if the new disk size is smaller than the previous one */ Operation resize(DiskId disk, long sizeGb, OperationOption... options); + + /* + * Creates a new subnetwork. + * + * @return a region operation for subnetwork's creation + * @throws ComputeException upon failure + */ + Operation create(SubnetworkInfo subnetwork, OperationOption... options); + + /** + * Returns the requested subnetwork or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + Subnetwork get(SubnetworkId subnetworkId, SubnetworkOption... options); + + /** + * Lists subnetworks for the provided region. + * + * @throws ComputeException upon failure + */ + Page listSubnetworks(String project, SubnetworkListOption... options); + + /** + * Lists subnetworks for all regions. + * + * @throws ComputeException upon failure + */ + Page listSubnetworks(SubnetworkAggregatedListOption... options); + + /** + * Deletes the requested subnetwork. Any attempt to delete an automatically created subnetwork + * will fail. + * + * @return a region operation if the delete request was issued correctly, {@code null} if the + * subnetwork was not found + * @throws ComputeException upon failure + */ + Operation delete(SubnetworkId subnetwork, OperationOption... options); + + /** + * Creates a new network. + * + * @return a global operation for network's creation + * @throws ComputeException upon failure + */ + Operation create(NetworkInfo network, OperationOption... options); + + /** + * Returns the requested network or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + Network getNetwork(String network, NetworkOption... options); + + /** + * Lists networks. + * + * @throws ComputeException upon failure + */ + Page listNetworks(NetworkListOption... options); + + /** + * Deletes the requested network. + * + * @return a global operation if the delete request was issued correctly, {@code null} if the + * network was not found + * @throws ComputeException upon failure + */ + Operation deleteNetwork(String network, OperationOption... options); + + /** + * Deletes the requested network. + * + * @return a global operation if the delete request was issued correctly, {@code null} if the + * network was not found + * @throws ComputeException upon failure + */ + Operation deleteNetwork(NetworkId network, OperationOption... options); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java index f453d0768e13..f19b6ee641a1 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java @@ -353,6 +353,65 @@ public Page nextPage() { } } + private static class SubnetworkPageFetcher implements NextPageFetcher { + + private static final long serialVersionUID = 3674038457884412651L; + private final Map requestOptions; + private final ComputeOptions serviceOptions; + private final String region; + + SubnetworkPageFetcher(String region, ComputeOptions serviceOptions, String cursor, + Map optionMap) { + this.requestOptions = + PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + this.region = region; + } + + @Override + public Page nextPage() { + return listSubnetworks(region, serviceOptions, requestOptions); + } + } + + private static class AggregatedSubnetworkPageFetcher implements NextPageFetcher { + + private static final long serialVersionUID = 771343548833894551L; + private final Map requestOptions; + private final ComputeOptions serviceOptions; + + AggregatedSubnetworkPageFetcher(ComputeOptions serviceOptions, String cursor, + Map optionMap) { + this.requestOptions = + PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + } + + @Override + public Page nextPage() { + return listSubnetworks(serviceOptions, requestOptions); + } + } + + private static class NetworkPageFetcher implements NextPageFetcher { + + private static final long serialVersionUID = 5580210850353114531L; + private final Map requestOptions; + private final ComputeOptions serviceOptions; + + NetworkPageFetcher(ComputeOptions serviceOptions, String cursor, + Map optionMap) { + this.requestOptions = + PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + } + + @Override + public Page nextPage() { + return listNetworks(serviceOptions, requestOptions); + } + } + private final ComputeRpc computeRpc; ComputeImpl(ComputeOptions options) { @@ -1336,6 +1395,217 @@ public com.google.api.services.compute.model.Operation call() { } } + public Operation create(SubnetworkInfo subnetwork, OperationOption... options) { + final SubnetworkInfo completeSubnetwork = subnetwork.setProjectId(options().projectId()); + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.createSubnetwork(completeSubnetwork.subnetworkId().region(), + completeSubnetwork.toPb(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Subnetwork get(final SubnetworkId subnetworkId, SubnetworkOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Subnetwork answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Subnetwork call() { + return computeRpc.getSubnetwork(subnetworkId.region(), subnetworkId.subnetwork(), + optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Subnetwork.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + private static Function + subnetworkFromPb(final ComputeOptions serviceOptions) { + return new Function() { + @Override + public Subnetwork apply(com.google.api.services.compute.model.Subnetwork subnetwork) { + return Subnetwork.fromPb(serviceOptions.service(), subnetwork); + } + }; + } + + @Override + public Page listSubnetworks(String region, SubnetworkListOption... options) { + return listSubnetworks(region, options(), optionMap(options)); + } + + private static Page listSubnetworks(final String region, + final ComputeOptions serviceOptions, final Map optionsMap) { + try { + ComputeRpc.Tuple> result = + runWithRetries(new Callable>>() { + @Override + public ComputeRpc.Tuple> call() { + return serviceOptions.rpc().listSubnetworks(region, optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.x(); + Iterable subnetworks = Iterables.transform( + result.y() == null ? ImmutableList.of() + : result.y(), subnetworkFromPb(serviceOptions)); + return new PageImpl<>(new SubnetworkPageFetcher(region, serviceOptions, cursor, optionsMap), + cursor, subnetworks); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Page listSubnetworks(SubnetworkAggregatedListOption... options) { + return listSubnetworks(options(), optionMap(options)); + } + + private static Page listSubnetworks(final ComputeOptions serviceOptions, + final Map optionsMap) { + try { + ComputeRpc.Tuple> result = + runWithRetries(new Callable>>() { + @Override + public ComputeRpc.Tuple> call() { + return serviceOptions.rpc().listSubnetworks(optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.x(); + Iterable subnetworks = Iterables.transform( + result.y() == null ? ImmutableList.of() + : result.y(), subnetworkFromPb(serviceOptions)); + return new PageImpl<>(new AggregatedSubnetworkPageFetcher(serviceOptions, cursor, optionsMap), + cursor, subnetworks); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation delete(final SubnetworkId subnetwork, OperationOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.deleteSubnetwork(subnetwork.region(), subnetwork.subnetwork(), + optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation create(NetworkInfo network, OperationOption... options) { + final NetworkInfo completeNetwork = network.setProjectId(options().projectId()); + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.createNetwork(completeNetwork.toPb(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Network getNetwork(final String network, NetworkOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Network answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Network call() { + return computeRpc.getNetwork(network, optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Network.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Page listNetworks(NetworkListOption... options) { + return listNetworks(options(), optionMap(options)); + } + + private static Page listNetworks(final ComputeOptions serviceOptions, + final Map optionsMap) { + try { + ComputeRpc.Tuple> result = + runWithRetries(new Callable>>() { + @Override + public ComputeRpc.Tuple> call() { + return serviceOptions.rpc().listNetworks(optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.x(); + Iterable networks = Iterables.transform( + result.y() == null ? ImmutableList.of() + : result.y(), + new Function() { + @Override + public Network apply(com.google.api.services.compute.model.Network network) { + return Network.fromPb(serviceOptions.service(), network); + } + }); + return new PageImpl<>(new NetworkPageFetcher(serviceOptions, cursor, optionsMap), + cursor, networks); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation deleteNetwork(final NetworkId network, OperationOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.deleteNetwork(network.network(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation deleteNetwork(String network, OperationOption... options) { + return deleteNetwork(NetworkId.of(network)); + } + private Map optionMap(Option... options) { Map optionMap = Maps.newEnumMap(ComputeRpc.Option.class); for (Option option : options) { diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Network.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Network.java new file mode 100644 index 000000000000..f438f2b8d3df --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Network.java @@ -0,0 +1,194 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.gcloud.compute.Compute.NetworkOption; +import com.google.gcloud.compute.Compute.OperationOption; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.util.Objects; + +/** + * A Google Compute Engine Network. Every virtual machine instance is created as a member of a + * network. Networks connect instances to each other and to the Internet. You can segment your + * networks, use firewall rules to restrict access to instances, and create static routes to forward + * traffic to specific destinations. Objects of this class are immutable. To get a {@code Network} + * object with the most recent information use {@link #reload}. {@code Network} adds a layer of + * service-related functionality over {@link NetworkInfo}. + * + * @see Using Networks and Firewalls + */ +public class Network extends NetworkInfo { + + private static final long serialVersionUID = 8608280908101278096L; + + private final ComputeOptions options; + private transient Compute compute; + + /** + * A builder for {@code Network} objects. + */ + public static class Builder extends NetworkInfo.Builder { + + private final Compute compute; + private final NetworkInfo.BuilderImpl infoBuilder; + + Builder(Compute compute, NetworkId networkId, NetworkConfiguration configuration) { + this.compute = compute; + this.infoBuilder = new NetworkInfo.BuilderImpl(networkId, configuration); + this.infoBuilder.networkId(networkId); + this.infoBuilder.configuration(configuration); + } + + Builder(Network subnetwork) { + this.compute = subnetwork.compute; + this.infoBuilder = new NetworkInfo.BuilderImpl(subnetwork); + } + + @Override + Builder id(String id) { + infoBuilder.id(id); + return this; + } + + @Override + Builder creationTimestamp(Long creationTimestamp) { + infoBuilder.creationTimestamp(creationTimestamp); + return this; + } + + @Override + public Builder networkId(NetworkId networkId) { + infoBuilder.networkId(networkId); + return this; + } + + @Override + public Builder description(String description) { + infoBuilder.description(description); + return this; + } + + @Override + public Builder configuration(NetworkConfiguration configuration) { + infoBuilder.configuration(configuration); + return this; + } + + @Override + public Network build() { + return new Network(compute, infoBuilder); + } + } + + Network(Compute compute, NetworkInfo.BuilderImpl infoBuilder) { + super(infoBuilder); + this.compute = checkNotNull(compute); + this.options = compute.options(); + } + + /** + * Checks if this network exists. + * + * @return {@code true} if this network exists, {@code false} otherwise + * @throws ComputeException upon failure + */ + public boolean exists() { + return reload(NetworkOption.fields()) != null; + } + + /** + * Fetches current network' latest information. Returns {@code null} if the network does not + * exist. + * + * @param options network options + * @return a {@code Network} object with latest information or {@code null} if not found + * @throws ComputeException upon failure + */ + public Network reload(NetworkOption... options) { + return compute.getNetwork(networkId().network(), options); + } + + /** + * Deletes this network. + * + * @return an operation object if delete request was successfully sent, {@code null} if the + * network was not found + * @throws ComputeException upon failure + */ + public Operation delete(OperationOption... options) { + return compute.deleteNetwork(networkId().network(), options); + } + + /** + * Creates a subnetwork for this network given its identity and the range of IPv4 addresses in + * CIDR format. Subnetwork creation is only supported for networks in "custom subnet mode" (i.e. + * {@link #configuration()} returns a {@link SubnetNetworkConfiguration}) with automatic creation + * of subnetworks disabled (i.e. {@link SubnetNetworkConfiguration#autoCreateSubnetworks()} + * returns {@code false}). + * + * @return an operation object if creation request was successfully sent + * @throws ComputeException upon failure + * @see CIDR + */ + public Operation createSubnetwork(SubnetworkId subnetworkId, String ipRange, + OperationOption... options) { + return compute.create(SubnetworkInfo.of(subnetworkId, networkId(), ipRange), options); + } + + /** + * Returns the network's {@code Compute} object used to issue requests. + */ + public Compute compute() { + return compute; + } + + @Override + public Builder toBuilder() { + return new Builder(this); + } + + @Override + public final boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null || !obj.getClass().equals(Network.class)) { + return false; + } + Network other = (Network) obj; + return Objects.equals(toPb(), other.toPb()) && Objects.equals(options, other.options); + } + + @Override + public final int hashCode() { + return Objects.hash(super.hashCode(), options); + } + + private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { + input.defaultReadObject(); + this.compute = options.service(); + } + + static Network fromPb(Compute compute, + com.google.api.services.compute.model.Network networkPb) { + return new Network(compute, new NetworkInfo.BuilderImpl(networkPb)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Subnetwork.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Subnetwork.java new file mode 100644 index 000000000000..6a42d8663ea3 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Subnetwork.java @@ -0,0 +1,190 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.gcloud.compute.Compute.OperationOption; +import com.google.gcloud.compute.Compute.SubnetworkOption; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.util.Objects; + +/** + * A Google Compute Engine Subnetwork. Subnetworks segments your cloud network IP space into + * subnetworks. Subnetwork prefixes can be automatically allocated, or you can create a custom + * topology. Objects of this class are immutable. To get a {@code Subnetwork} object with the most + * recent information use {@link #reload}. {@code Subnetwork} adds a layer of service-related + * functionality over {@link SubnetworkInfo}. + * + * @see Subnetworks + */ +public class Subnetwork extends SubnetworkInfo { + + private static final long serialVersionUID = 8608280908101278096L; + + private final ComputeOptions options; + private transient Compute compute; + + /** + * A builder for {@code Subnetwork} objects. + */ + public static class Builder extends SubnetworkInfo.Builder { + + private final Compute compute; + private final SubnetworkInfo.BuilderImpl infoBuilder; + + Builder(Compute compute, SubnetworkId subnetworkId, NetworkId networkId, String ipRange) { + this.compute = compute; + this.infoBuilder = new SubnetworkInfo.BuilderImpl(subnetworkId, networkId, ipRange); + this.infoBuilder.subnetworkId(subnetworkId); + this.infoBuilder.network(networkId); + this.infoBuilder.ipRange(ipRange); + } + + Builder(Subnetwork subnetwork) { + this.compute = subnetwork.compute; + this.infoBuilder = new SubnetworkInfo.BuilderImpl(subnetwork); + } + + @Override + Builder id(String id) { + infoBuilder.id(id); + return this; + } + + @Override + Builder creationTimestamp(Long creationTimestamp) { + infoBuilder.creationTimestamp(creationTimestamp); + return this; + } + + @Override + public Builder subnetworkId(SubnetworkId subnetworkId) { + infoBuilder.subnetworkId(subnetworkId); + return this; + } + + @Override + public Builder description(String description) { + infoBuilder.description(description); + return this; + } + + @Override + Builder gatewayAddress(String gatewayAddress) { + infoBuilder.gatewayAddress(gatewayAddress); + return this; + } + + @Override + public Builder network(NetworkId network) { + infoBuilder.network(network); + return this; + } + + @Override + public Builder ipRange(String ipRange) { + infoBuilder.ipRange(ipRange); + return this; + } + + @Override + public Subnetwork build() { + return new Subnetwork(compute, infoBuilder); + } + } + + Subnetwork(Compute compute, SubnetworkInfo.BuilderImpl infoBuilder) { + super(infoBuilder); + this.compute = checkNotNull(compute); + this.options = compute.options(); + } + + /** + * Checks if this subnetwork exists. + * + * @return {@code true} if this subnetwork exists, {@code false} otherwise + * @throws ComputeException upon failure + */ + public boolean exists() { + return reload(SubnetworkOption.fields()) != null; + } + + /** + * Fetches current subnetwork' latest information. Returns {@code null} if the subnetwork does not + * exist. + * + * @param options subnetwork options + * @return an {@code Subnetwork} object with latest information or {@code null} if not found + * @throws ComputeException upon failure + */ + public Subnetwork reload(SubnetworkOption... options) { + return compute.get(subnetworkId(), options); + } + + /** + * Deletes this subnetwork. If this subnetwork was auto-generated deletion will fail. + * + * @return an operation object if delete request was successfully sent, {@code null} if the + * subnetwork was not found + * @throws ComputeException upon failure + */ + public Operation delete(OperationOption... options) { + return compute.delete(subnetworkId(), options); + } + + /** + * Returns the subnetwork's {@code Compute} object used to issue requests. + */ + public Compute compute() { + return compute; + } + + @Override + public Builder toBuilder() { + return new Builder(this); + } + + @Override + public final boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null || !obj.getClass().equals(Subnetwork.class)) { + return false; + } + Subnetwork other = (Subnetwork) obj; + return Objects.equals(toPb(), other.toPb()) && Objects.equals(options, other.options); + } + + @Override + public final int hashCode() { + return Objects.hash(super.hashCode(), options); + } + + private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { + input.defaultReadObject(); + this.compute = options.service(); + } + + static Subnetwork fromPb(Compute compute, + com.google.api.services.compute.model.Subnetwork subnetworkPb) { + return new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(subnetworkPb)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkInfo.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkInfo.java index 5be0d875d738..d6988ee7eea8 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkInfo.java @@ -289,7 +289,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj != null + return obj == this + || obj != null && obj.getClass().equals(SubnetworkInfo.class) && Objects.equals(toPb(), ((SubnetworkInfo) obj).toPb()); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/ComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/ComputeRpc.java index b24384af37f2..f3e51266aa50 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/ComputeRpc.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/ComputeRpc.java @@ -23,9 +23,11 @@ import com.google.api.services.compute.model.Image; import com.google.api.services.compute.model.License; import com.google.api.services.compute.model.MachineType; +import com.google.api.services.compute.model.Network; import com.google.api.services.compute.model.Operation; import com.google.api.services.compute.model.Region; import com.google.api.services.compute.model.Snapshot; +import com.google.api.services.compute.model.Subnetwork; import com.google.api.services.compute.model.Zone; import com.google.gcloud.compute.ComputeException; @@ -424,4 +426,74 @@ Operation deprecateImage(String project, String image, DeprecationStatus depreca * @throws ComputeException upon failure or if the new disk size is smaller than the previous one */ Operation resizeDisk(String zone, String disk, long sizeGb, Map options); + + /* + * Creates a new subnetwork. + * + * @return a region operation for subnetwork's creation + * @throws ComputeException upon failure + */ + Operation createSubnetwork(String region, Subnetwork subnetwork, Map options); + + /** + * Returns the requested subnetwork or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + Subnetwork getSubnetwork(String region, String subnetwork, Map options); + + /** + * Lists subnetworks for the provided region. + * + * @throws ComputeException upon failure + */ + Tuple> listSubnetworks(String region, Map options); + + /** + * Lists subnetworks. + * + * @throws ComputeException upon failure + */ + Tuple> listSubnetworks(Map options); + + /** + * Deletes the requested subnetwork. Any attempt to delete an automatically created subnetwork + * will fail. + * + * @return a region operation if the delete request was issued correctly, {@code null} if the + * subnetwork was not found + * @throws ComputeException upon failure + */ + Operation deleteSubnetwork(String region, String subnetwork, Map options); + + /** + * Creates a new network. + * + * @return a global operation for network's creation + * @throws ComputeException upon failure + */ + Operation createNetwork(Network network, Map options); + + /** + * Returns the requested network or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + Network getNetwork(String network, Map options); + + /** + * Lists networks. + * + * @throws ComputeException upon failure + */ + Tuple> listNetworks(Map options); + + /** + * Deletes the requested network. + * + * @return a global operation if the delete request was issued correctly, {@code null} if the + * network was not found + * @throws ComputeException upon failure + */ + Operation deleteNetwork(String network, Map options); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/DefaultComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/DefaultComputeRpc.java index 708e5fa2ceee..9db50af5db4c 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/DefaultComputeRpc.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/DefaultComputeRpc.java @@ -47,12 +47,18 @@ import com.google.api.services.compute.model.MachineTypeAggregatedList; import com.google.api.services.compute.model.MachineTypeList; import com.google.api.services.compute.model.MachineTypesScopedList; +import com.google.api.services.compute.model.Network; +import com.google.api.services.compute.model.NetworkList; import com.google.api.services.compute.model.Operation; import com.google.api.services.compute.model.OperationList; import com.google.api.services.compute.model.Region; import com.google.api.services.compute.model.RegionList; import com.google.api.services.compute.model.Snapshot; import com.google.api.services.compute.model.SnapshotList; +import com.google.api.services.compute.model.Subnetwork; +import com.google.api.services.compute.model.SubnetworkAggregatedList; +import com.google.api.services.compute.model.SubnetworkList; +import com.google.api.services.compute.model.SubnetworksScopedList; import com.google.api.services.compute.model.Zone; import com.google.api.services.compute.model.ZoneList; import com.google.common.collect.ImmutableList; @@ -730,6 +736,139 @@ public Operation resizeDisk(String zone, String disk, long sizeGb, Map options) { + try { + return compute.subnetworks() + .insert(this.options.projectId(), region, subnetwork) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Subnetwork getSubnetwork(String region, String subnetwork, Map options) { + try { + return compute.subnetworks() + .get(this.options.projectId(), region, subnetwork) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Tuple> listSubnetworks(String region, + Map options) { + try { + SubnetworkList subnetworkList = compute.subnetworks() + .list(this.options.projectId(), region) + .setFilter(FILTER.getString(options)) + .setMaxResults(MAX_RESULTS.getLong(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + .setFields(FIELDS.getString(options)) + .execute(); + Iterable subnetworks = subnetworkList.getItems(); + return Tuple.of(subnetworkList.getNextPageToken(), subnetworks); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Tuple> listSubnetworks(Map options) { + try { + SubnetworkAggregatedList aggregatedList = compute.subnetworks() + .aggregatedList(this.options.projectId()) + .setFilter(FILTER.getString(options)) + .setMaxResults(MAX_RESULTS.getLong(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + // todo(mziccard): uncomment or remove once #711 is closed + // .setFields(FIELDS.getString(options)) + .execute(); + ImmutableList.Builder builder = ImmutableList.builder(); + Map scopedList = aggregatedList.getItems(); + if (scopedList != null) { + for (SubnetworksScopedList subnetworksScopedList : scopedList.values()) { + if (subnetworksScopedList.getSubnetworks() != null) { + builder.addAll(subnetworksScopedList.getSubnetworks()); + } + } + } + return Tuple.>of(aggregatedList.getNextPageToken(), + builder.build()); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Operation deleteSubnetwork(String region, String subnetwork, Map options) { + try { + return compute.subnetworks() + .delete(this.options.projectId(), region, subnetwork) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Operation createNetwork(Network network, Map options) { + try { + return compute.networks() + .insert(this.options.projectId(), network) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Network getNetwork(String network, Map options) { + try { + return compute.networks() + .get(this.options.projectId(), network) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Tuple> listNetworks(Map options) { + try { + NetworkList networkList = compute.networks() + .list(this.options.projectId()) + .setFilter(FILTER.getString(options)) + .setMaxResults(MAX_RESULTS.getLong(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + .setFields(FIELDS.getString(options)) + .execute(); + Iterable networks = networkList.getItems(); + return Tuple.of(networkList.getNextPageToken(), networks); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Operation deleteNetwork(String network, Map options) { + try { + return compute.networks() + .delete(this.options.projectId(), network) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + /** * This method returns {@code null} if the error code of {@code exception} was 404, re-throws the * exception otherwise. diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java index edd8b2bd0cef..85ddd0e3595b 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java @@ -56,6 +56,10 @@ import com.google.gcloud.compute.Compute.MachineTypeFilter; import com.google.gcloud.compute.Compute.MachineTypeListOption; import com.google.gcloud.compute.Compute.MachineTypeOption; +import com.google.gcloud.compute.Compute.NetworkField; +import com.google.gcloud.compute.Compute.NetworkFilter; +import com.google.gcloud.compute.Compute.NetworkListOption; +import com.google.gcloud.compute.Compute.NetworkOption; import com.google.gcloud.compute.Compute.OperationFilter; import com.google.gcloud.compute.Compute.OperationListOption; import com.google.gcloud.compute.Compute.OperationOption; @@ -65,6 +69,11 @@ import com.google.gcloud.compute.Compute.SnapshotFilter; import com.google.gcloud.compute.Compute.SnapshotListOption; import com.google.gcloud.compute.Compute.SnapshotOption; +import com.google.gcloud.compute.Compute.SubnetworkAggregatedListOption; +import com.google.gcloud.compute.Compute.SubnetworkField; +import com.google.gcloud.compute.Compute.SubnetworkFilter; +import com.google.gcloud.compute.Compute.SubnetworkListOption; +import com.google.gcloud.compute.Compute.SubnetworkOption; import com.google.gcloud.compute.Compute.ZoneFilter; import com.google.gcloud.compute.Compute.ZoneListOption; import com.google.gcloud.compute.Compute.ZoneOption; @@ -198,6 +207,12 @@ public class ComputeImplTest { DeprecationStatus.builder(DeprecationStatus.Status.DEPRECATED, IMAGE_ID).build(); private static final DiskInfo DISK = DiskInfo.of(DISK_ID, StandardDiskConfiguration.of(DISK_TYPE_ID)); + private static final NetworkId NETWORK_ID = NetworkId.of("project", "network"); + private static final SubnetworkId SUBNETWORK_ID = SubnetworkId.of("project", "region", "network"); + private static final SubnetworkInfo SUBNETWORK = + SubnetworkInfo.of(SUBNETWORK_ID, NETWORK_ID, "192.168.0.0/16"); + private static final NetworkInfo NETWORK = + NetworkInfo.of(NETWORK_ID, StandardNetworkConfiguration.of("192.168.0.0/16")); // Empty ComputeRpc options private static final Map EMPTY_RPC_OPTIONS = ImmutableMap.of(); @@ -391,6 +406,50 @@ public class ComputeImplTest { private static final DiskAggregatedListOption DISK_AGGREGATED_LIST_FILTER = DiskAggregatedListOption.filter(DISK_FILTER); + // Subnetwork options + private static final SubnetworkOption SUBNETWORK_OPTION_FIELDS = + SubnetworkOption.fields(SubnetworkField.ID, SubnetworkField.DESCRIPTION); + + // Subnetwork list options + private static final SubnetworkFilter SUBNETWORK_FILTER = + SubnetworkFilter.equals(SubnetworkField.IP_CIDR_RANGE, "192.168.0.0/16"); + private static final SubnetworkListOption SUBNETWORK_LIST_PAGE_TOKEN = + SubnetworkListOption.pageToken("cursor"); + private static final SubnetworkListOption SUBNETWORK_LIST_PAGE_SIZE = + SubnetworkListOption.pageSize(42L); + private static final SubnetworkListOption SUBNETWORK_LIST_FILTER = + SubnetworkListOption.filter(SUBNETWORK_FILTER); + private static final Map SUBNETWORK_LIST_OPTIONS = ImmutableMap.of( + PAGE_TOKEN, "cursor", + MAX_RESULTS, 42L, + FILTER, "ipCidrRange eq 192.168.0.0/16"); + + // Subnetwork aggregated list options + private static final SubnetworkAggregatedListOption SUBNETWORK_AGGREGATED_LIST_PAGE_TOKEN = + SubnetworkAggregatedListOption.pageToken("cursor"); + private static final SubnetworkAggregatedListOption SUBNETWORK_AGGREGATED_LIST_PAGE_SIZE = + SubnetworkAggregatedListOption.pageSize(42L); + private static final SubnetworkAggregatedListOption SUBNETWORK_AGGREGATED_LIST_FILTER = + SubnetworkAggregatedListOption.filter(SUBNETWORK_FILTER); + + // Network options + private static final NetworkOption NETWORK_OPTION_FIELDS = + NetworkOption.fields(NetworkField.ID, NetworkField.DESCRIPTION); + + // Network list options + private static final NetworkFilter NETWORK_FILTER = + NetworkFilter.equals(NetworkField.IPV4_RANGE, "192.168.0.0/16"); + private static final NetworkListOption NETWORK_LIST_PAGE_TOKEN = + NetworkListOption.pageToken("cursor"); + private static final NetworkListOption NETWORK_LIST_PAGE_SIZE = + NetworkListOption.pageSize(42L); + private static final NetworkListOption NETWORK_LIST_FILTER = + NetworkListOption.filter(NETWORK_FILTER); + private static final Map NETWORK_LIST_OPTIONS = ImmutableMap.of( + PAGE_TOKEN, "cursor", + MAX_RESULTS, 42L, + FILTER, "IPv4Range eq 192.168.0.0/16"); + private static final Function OPERATION_TO_PB_FUNCTION = new Function() { @@ -2680,6 +2739,433 @@ public void testResizeDisk_Null() { assertNull(compute.resize(DISK_ID, 42L)); } + @Test + public void testGetSubnetwork() { + EasyMock.expect(computeRpcMock.getSubnetwork(SUBNETWORK_ID.region(), SUBNETWORK_ID.subnetwork(), + EMPTY_RPC_OPTIONS)).andReturn(SUBNETWORK.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Subnetwork subnetwork = compute.get(SUBNETWORK_ID); + assertEquals(new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK)), subnetwork); + } + + @Test + public void testGetSubnetwork_Null() { + EasyMock.expect(computeRpcMock.getSubnetwork(SUBNETWORK_ID.region(), SUBNETWORK_ID.subnetwork(), + EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.get(SUBNETWORK_ID)); + } + + @Test + public void testGetSubnetworkWithSelectedFields() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.getSubnetwork(eq(SUBNETWORK_ID.region()), + eq(SUBNETWORK_ID.subnetwork()), capture(capturedOptions))).andReturn(SUBNETWORK.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Subnetwork subnetwork = compute.get(SUBNETWORK_ID, SUBNETWORK_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(SUBNETWORK_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK)), subnetwork); + } + + @Test + public void testDeleteSubnetwork_Operation() { + EasyMock.expect(computeRpcMock.deleteSubnetwork(SUBNETWORK_ID.region(), + SUBNETWORK_ID.subnetwork(), EMPTY_RPC_OPTIONS)).andReturn(regionOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(regionOperation, compute.delete(SUBNETWORK_ID)); + } + + @Test + public void testDeleteSubnetworkWithSelectedFields_Operation() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.deleteSubnetwork(eq(SUBNETWORK_ID.region()), + eq(SUBNETWORK_ID.subnetwork()), capture(capturedOptions))) + .andReturn(regionOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.delete(SUBNETWORK_ID, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(regionOperation, operation); + } + + @Test + public void testDeleteSubnetwork_Null() { + EasyMock.expect(computeRpcMock.deleteSubnetwork(SUBNETWORK_ID.region(), + SUBNETWORK_ID.subnetwork(), EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.delete(SUBNETWORK_ID)); + } + + @Test + public void testListSubnetworks() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList subnetworkList = ImmutableList.of( + new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK)), + new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(subnetworkList, SubnetworkInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listSubnetworks(SUBNETWORK_ID.region(), EMPTY_RPC_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listSubnetworks(SUBNETWORK_ID.region()); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(subnetworkList.toArray(), Iterables.toArray(page.values(), Subnetwork.class)); + } + + @Test + public void testListSubnetworksNextPage() { + String cursor = "cursor"; + String nextCursor = "nextCursor"; + compute = options.service(); + ImmutableList subnetworkList = ImmutableList.of( + new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK)), + new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK))); + ImmutableList nextSubnetworkList = ImmutableList.of( + new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(subnetworkList, SubnetworkInfo.TO_PB_FUNCTION)); + Tuple> nextResult = + Tuple.of(nextCursor, + Iterables.transform(nextSubnetworkList, SubnetworkInfo.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + EasyMock.expect(computeRpcMock.listSubnetworks(SUBNETWORK_ID.region(), EMPTY_RPC_OPTIONS)) + .andReturn(result); + EasyMock.expect(computeRpcMock.listSubnetworks(SUBNETWORK_ID.region(), nextOptions)) + .andReturn(nextResult); + EasyMock.replay(computeRpcMock); + Page page = compute.listSubnetworks(SUBNETWORK_ID.region()); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(subnetworkList.toArray(), Iterables.toArray(page.values(), Subnetwork.class)); + page = page.nextPage(); + assertEquals(nextCursor, page.nextPageCursor()); + assertArrayEquals(nextSubnetworkList.toArray(), + Iterables.toArray(page.values(), Subnetwork.class)); + } + + @Test + public void testListEmptySubnetworks() { + compute = options.service(); + ImmutableList subnetworks = + ImmutableList.of(); + Tuple> result = + Tuple.>of(null, + subnetworks); + EasyMock.expect(computeRpcMock.listSubnetworks(SUBNETWORK_ID.region(), EMPTY_RPC_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listSubnetworks(SUBNETWORK_ID.region()); + assertNull(page.nextPageCursor()); + assertArrayEquals(subnetworks.toArray(), Iterables.toArray(page.values(), Subnetwork.class)); + } + + @Test + public void testListSubnetworksWithOptions() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList subnetworkList = ImmutableList.of( + new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK)), + new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(subnetworkList, SubnetworkInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listSubnetworks(SUBNETWORK_ID.region(), SUBNETWORK_LIST_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listSubnetworks(SUBNETWORK_ID.region(), + SUBNETWORK_LIST_PAGE_SIZE, SUBNETWORK_LIST_PAGE_TOKEN, SUBNETWORK_LIST_FILTER); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(subnetworkList.toArray(), Iterables.toArray(page.values(), Subnetwork.class)); + } + + @Test + public void testAggregatedListSubnetworks() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList subnetworkList = ImmutableList.of( + new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK)), + new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(subnetworkList, SubnetworkInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listSubnetworks(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listSubnetworks(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(subnetworkList.toArray(), Iterables.toArray(page.values(), Subnetwork.class)); + } + + @Test + public void testAggregatedListSubnetworksNextPage() { + String cursor = "cursor"; + String nextCursor = "nextCursor"; + compute = options.service(); + ImmutableList subnetworkList = ImmutableList.of( + new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK)), + new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK))); + ImmutableList nextSubnetworkList = ImmutableList.of( + new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(subnetworkList, SubnetworkInfo.TO_PB_FUNCTION)); + Tuple> nextResult = + Tuple.of(nextCursor, + Iterables.transform(nextSubnetworkList, SubnetworkInfo.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + EasyMock.expect(computeRpcMock.listSubnetworks(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.expect(computeRpcMock.listSubnetworks(nextOptions)).andReturn(nextResult); + EasyMock.replay(computeRpcMock); + Page page = compute.listSubnetworks(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(subnetworkList.toArray(), Iterables.toArray(page.values(), Subnetwork.class)); + page = page.nextPage(); + assertEquals(nextCursor, page.nextPageCursor()); + assertArrayEquals(nextSubnetworkList.toArray(), + Iterables.toArray(page.values(), Subnetwork.class)); + } + + @Test + public void testAggregatedListEmptySubnetworks() { + compute = options.service(); + ImmutableList subnetworks = + ImmutableList.of(); + Tuple> result = + Tuple.>of(null, + subnetworks); + EasyMock.expect(computeRpcMock.listSubnetworks(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listSubnetworks(); + assertNull(page.nextPageCursor()); + assertArrayEquals(subnetworks.toArray(), Iterables.toArray(page.values(), Subnetwork.class)); + } + + @Test + public void testAggregatedListSubnetworksWithOptions() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList subnetworkList = ImmutableList.of( + new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK)), + new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(subnetworkList, SubnetworkInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listSubnetworks(SUBNETWORK_LIST_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listSubnetworks(SUBNETWORK_AGGREGATED_LIST_PAGE_SIZE, + SUBNETWORK_AGGREGATED_LIST_PAGE_TOKEN, SUBNETWORK_AGGREGATED_LIST_FILTER); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(subnetworkList.toArray(), Iterables.toArray(page.values(), Subnetwork.class)); + } + + @Test + public void testCreateSubnetwork() { + EasyMock.expect(computeRpcMock.createSubnetwork(SUBNETWORK_ID.region(), SUBNETWORK.toPb(), + EMPTY_RPC_OPTIONS)).andReturn(regionOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + SubnetworkId subnetworkId = SubnetworkId.of("region", "network"); + NetworkId networkId = NetworkId.of("network"); + SubnetworkInfo subnetwork = SubnetworkInfo.of(subnetworkId, networkId, "192.168.0.0/16"); + Operation operation = compute.create(subnetwork); + assertEquals(regionOperation, operation); + } + + @Test + public void testCreateSubnetworkWithOptions() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.createSubnetwork(eq(SUBNETWORK_ID.region()), + eq(SUBNETWORK.toPb()), capture(capturedOptions))).andReturn(regionOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.create(SUBNETWORK, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(regionOperation, operation); + } + + @Test + public void testGetNetwork() { + EasyMock.expect(computeRpcMock.getNetwork(NETWORK_ID.network(), EMPTY_RPC_OPTIONS)) + .andReturn(NETWORK.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Network network = compute.getNetwork(NETWORK_ID.network()); + assertEquals(new Network(compute, new NetworkInfo.BuilderImpl(NETWORK)), network); + } + + @Test + public void testGetNetwork_Null() { + EasyMock.expect(computeRpcMock.getNetwork(NETWORK_ID.network(), EMPTY_RPC_OPTIONS)) + .andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.getNetwork(NETWORK_ID.network())); + } + + @Test + public void testGetNetworkWithSelectedFields() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.getNetwork(eq(NETWORK_ID.network()), capture(capturedOptions))) + .andReturn(NETWORK.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Network network = compute.getNetwork(NETWORK_ID.network(), NETWORK_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(NETWORK_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertTrue(selector.contains("IPv4Range")); + assertTrue(selector.contains("autoCreateSubnetworks")); + assertEquals(55, selector.length()); + assertEquals(new Network(compute, new NetworkInfo.BuilderImpl(NETWORK)), network); + } + + @Test + public void testDeleteNetwork_Operation() { + EasyMock.expect(computeRpcMock.deleteNetwork(NETWORK_ID.network(), EMPTY_RPC_OPTIONS)) + .andReturn(globalOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(globalOperation, compute.deleteNetwork(NETWORK_ID)); + } + + @Test + public void testDeleteNetworkWithSelectedFields_Operation() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.deleteNetwork(eq(NETWORK_ID.network()), + capture(capturedOptions))).andReturn(globalOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.deleteNetwork(NETWORK_ID, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(globalOperation, operation); + } + + @Test + public void testDeleteNetwork_Null() { + EasyMock.expect(computeRpcMock.deleteNetwork(NETWORK_ID.network(), EMPTY_RPC_OPTIONS)) + .andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.deleteNetwork(NETWORK_ID)); + } + + @Test + public void testListNetworks() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList networkList = ImmutableList.of( + new Network(compute, new NetworkInfo.BuilderImpl(NETWORK)), + new Network(compute, new NetworkInfo.BuilderImpl(NETWORK))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(networkList, NetworkInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listNetworks(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listNetworks(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(networkList.toArray(), Iterables.toArray(page.values(), Network.class)); + } + + @Test + public void testListNetworksNextPage() { + String cursor = "cursor"; + String nextCursor = "nextCursor"; + compute = options.service(); + ImmutableList networkList = ImmutableList.of( + new Network(compute, new NetworkInfo.BuilderImpl(NETWORK)), + new Network(compute, new NetworkInfo.BuilderImpl(NETWORK))); + ImmutableList nextNetworkList = ImmutableList.of( + new Network(compute, new NetworkInfo.BuilderImpl(NETWORK))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(networkList, NetworkInfo.TO_PB_FUNCTION)); + Tuple> nextResult = + Tuple.of(nextCursor, Iterables.transform(nextNetworkList, NetworkInfo.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + EasyMock.expect(computeRpcMock.listNetworks(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.expect(computeRpcMock.listNetworks(nextOptions)).andReturn(nextResult); + EasyMock.replay(computeRpcMock); + Page page = compute.listNetworks(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(networkList.toArray(), Iterables.toArray(page.values(), Network.class)); + page = page.nextPage(); + assertEquals(nextCursor, page.nextPageCursor()); + assertArrayEquals(nextNetworkList.toArray(), Iterables.toArray(page.values(), Network.class)); + } + + @Test + public void testListEmptyNetworks() { + compute = options.service(); + ImmutableList networks = ImmutableList.of(); + Tuple> result = + Tuple.>of(null, networks); + EasyMock.expect(computeRpcMock.listNetworks(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listNetworks(); + assertNull(page.nextPageCursor()); + assertArrayEquals(networks.toArray(), Iterables.toArray(page.values(), Network.class)); + } + + @Test + public void testListNetworksWithOptions() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList networkList = ImmutableList.of( + new Network(compute, new NetworkInfo.BuilderImpl(NETWORK)), + new Network(compute, new NetworkInfo.BuilderImpl(NETWORK))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(networkList, NetworkInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listNetworks(NETWORK_LIST_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listNetworks(NETWORK_LIST_PAGE_SIZE, NETWORK_LIST_PAGE_TOKEN, + NETWORK_LIST_FILTER); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(networkList.toArray(), Iterables.toArray(page.values(), Network.class)); + } + + @Test + public void testCreateNetwork() { + EasyMock.expect(computeRpcMock.createNetwork(NETWORK.toPb(), EMPTY_RPC_OPTIONS)) + .andReturn(globalOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + NetworkInfo network = + NetworkInfo.of(NetworkId.of("network"), StandardNetworkConfiguration.of("192.168.0.0/16")); + Operation operation = compute.create(network); + assertEquals(globalOperation, operation); + } + + @Test + public void testCreateNetworkWithOptions() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.createNetwork(eq(NETWORK.toPb()), capture(capturedOptions))) + .andReturn(globalOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.create(NETWORK, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(globalOperation, operation); + } + @Test public void testRetryableException() { EasyMock.expect( diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkTest.java new file mode 100644 index 000000000000..3d303702ecc4 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkTest.java @@ -0,0 +1,259 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.createStrictMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import com.google.common.collect.ImmutableList; + +import org.junit.Test; + +import java.util.List; + +public class NetworkTest { + + private static final String ID = "42"; + private static final Long CREATION_TIMESTAMP = 1453293540000L; + private static final String DESCRIPTION = "description"; + private static final SubnetworkId SUBNETWORK1 = SubnetworkId.of("project", "region1", "network1"); + private static final SubnetworkId SUBNETWORK2 = SubnetworkId.of("project", "region2", "network2"); + private static final List SUBNETWORKS = ImmutableList.of(SUBNETWORK1, SUBNETWORK2); + private static final String GATEWAY_ADDRESS = "192.168.1.1"; + private static final NetworkId NETWORK_ID = NetworkId.of("project", "network"); + private static final String IP_RANGE = "192.168.0.0/16"; + private static final Boolean AUTO_CREATE_SUBNETWORKS = true; + private static final StandardNetworkConfiguration NETWORK_CONFIGURATION = + new StandardNetworkConfiguration(IP_RANGE, GATEWAY_ADDRESS); + private static final SubnetNetworkConfiguration SUBNET_NETWORK_CONFIGURATION = + new SubnetNetworkConfiguration(AUTO_CREATE_SUBNETWORKS, SUBNETWORKS); + + private final Compute serviceMockReturnsOptions = createStrictMock(Compute.class); + private final ComputeOptions mockOptions = createMock(ComputeOptions.class); + private Compute compute; + private Network network; + private Network standardNetwork; + private Network subnetNetwork; + + private void initializeExpectedNetwork(int optionsCalls) { + expect(serviceMockReturnsOptions.options()).andReturn(mockOptions).times(optionsCalls); + replay(serviceMockReturnsOptions); + standardNetwork = + new Network.Builder(serviceMockReturnsOptions, NETWORK_ID, NETWORK_CONFIGURATION) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .build(); + subnetNetwork = + new Network.Builder(serviceMockReturnsOptions, NETWORK_ID, SUBNET_NETWORK_CONFIGURATION) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .build(); + compute = createStrictMock(Compute.class); + } + + private void initializeNetwork() { + network = new Network.Builder(compute, NETWORK_ID, NETWORK_CONFIGURATION) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .build(); + } + + @Test + public void testToBuilder() { + initializeExpectedNetwork(9); + compareNetwork(standardNetwork, standardNetwork.toBuilder().build()); + Network newNetwork = standardNetwork.toBuilder().description("newDescription").build(); + assertEquals("newDescription", newNetwork.description()); + newNetwork = newNetwork.toBuilder().description("description").build(); + compareNetwork(standardNetwork, newNetwork); + } + + @Test + public void testToBuilderIncomplete() { + initializeExpectedNetwork(6); + NetworkInfo networkInfo = NetworkInfo.of(NETWORK_ID, NETWORK_CONFIGURATION); + Network network = + new Network(serviceMockReturnsOptions, new NetworkInfo.BuilderImpl(networkInfo)); + compareNetwork(network, network.toBuilder().build()); + } + + @Test + public void testBuilder() { + initializeExpectedNetwork(2); + assertEquals(ID, standardNetwork.id()); + assertEquals(NETWORK_ID, standardNetwork.networkId()); + assertEquals(CREATION_TIMESTAMP, standardNetwork.creationTimestamp()); + assertEquals(DESCRIPTION, standardNetwork.description()); + assertEquals(NETWORK_CONFIGURATION, standardNetwork.configuration()); + assertSame(serviceMockReturnsOptions, standardNetwork.compute()); + assertEquals(ID, subnetNetwork.id()); + assertEquals(NETWORK_ID, subnetNetwork.networkId()); + assertEquals(CREATION_TIMESTAMP, subnetNetwork.creationTimestamp()); + assertEquals(DESCRIPTION, subnetNetwork.description()); + assertEquals(SUBNET_NETWORK_CONFIGURATION, subnetNetwork.configuration()); + assertSame(serviceMockReturnsOptions, subnetNetwork.compute()); + } + + @Test + public void testToAndFromPb() { + initializeExpectedNetwork(12); + compareNetwork(standardNetwork, + Network.fromPb(serviceMockReturnsOptions, standardNetwork.toPb())); + compareNetwork(subnetNetwork, + Network.fromPb(serviceMockReturnsOptions, subnetNetwork.toPb())); + Network network = + new Network.Builder(serviceMockReturnsOptions, NETWORK_ID, NETWORK_CONFIGURATION).build(); + compareNetwork(network, Network.fromPb(serviceMockReturnsOptions, network.toPb())); + } + + @Test + public void testDeleteOperation() { + initializeExpectedNetwork(3); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(GlobalOperationId.of("project", "op")) + .build(); + expect(compute.deleteNetwork(NETWORK_ID.network())).andReturn(operation); + replay(compute); + initializeNetwork(); + assertSame(operation, network.delete()); + } + + @Test + public void testDeleteNull() { + initializeExpectedNetwork(2); + expect(compute.options()).andReturn(mockOptions); + expect(compute.deleteNetwork(NETWORK_ID.network())).andReturn(null); + replay(compute); + initializeNetwork(); + assertNull(network.delete()); + } + + @Test + public void testExists_True() throws Exception { + initializeExpectedNetwork(2); + Compute.NetworkOption[] expectedOptions = {Compute.NetworkOption.fields()}; + expect(compute.options()).andReturn(mockOptions); + expect(compute.getNetwork(NETWORK_ID.network(), expectedOptions)) + .andReturn(standardNetwork); + replay(compute); + initializeNetwork(); + assertTrue(network.exists()); + verify(compute); + } + + @Test + public void testExists_False() throws Exception { + initializeExpectedNetwork(2); + Compute.NetworkOption[] expectedOptions = {Compute.NetworkOption.fields()}; + expect(compute.options()).andReturn(mockOptions); + expect(compute.getNetwork(NETWORK_ID.network(), expectedOptions)).andReturn(null); + replay(compute); + initializeNetwork(); + assertFalse(network.exists()); + verify(compute); + } + + @Test + public void testReload() throws Exception { + initializeExpectedNetwork(4); + expect(compute.options()).andReturn(mockOptions); + expect(compute.getNetwork(NETWORK_ID.network())).andReturn(standardNetwork); + replay(compute); + initializeNetwork(); + Network updatedNetwork = network.reload(); + compareNetwork(standardNetwork, updatedNetwork); + verify(compute); + } + + @Test + public void testReloadNull() throws Exception { + initializeExpectedNetwork(2); + expect(compute.options()).andReturn(mockOptions); + expect(compute.getNetwork(NETWORK_ID.network())).andReturn(null); + replay(compute); + initializeNetwork(); + assertNull(network.reload()); + verify(compute); + } + + @Test + public void testReloadWithOptions() throws Exception { + initializeExpectedNetwork(4); + expect(compute.options()).andReturn(mockOptions); + expect(compute.getNetwork(NETWORK_ID.network(), Compute.NetworkOption.fields())) + .andReturn(standardNetwork); + replay(compute); + initializeNetwork(); + Network updatedNetwork = network.reload(Compute.NetworkOption.fields()); + compareNetwork(standardNetwork, updatedNetwork); + verify(compute); + } + + @Test + public void testCreateSubnetwork() throws Exception { + initializeExpectedNetwork(3); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(RegionOperationId.of(SUBNETWORK1.regionId(), "op")) + .build(); + expect(compute.options()).andReturn(mockOptions); + expect(compute.create(SubnetworkInfo.of(SUBNETWORK1, NETWORK_ID, IP_RANGE))) + .andReturn(operation); + replay(compute); + initializeNetwork(); + assertSame(operation, network.createSubnetwork(SUBNETWORK1, IP_RANGE)); + verify(compute); + } + + @Test + public void testCreateSubnetworkWithOptions() throws Exception { + initializeExpectedNetwork(3); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(RegionOperationId.of(SUBNETWORK1.regionId(), "op")) + .build(); + expect(compute.options()).andReturn(mockOptions); + expect(compute.create(SubnetworkInfo.of(SUBNETWORK1, NETWORK_ID, IP_RANGE), + Compute.OperationOption.fields())).andReturn(operation); + replay(compute); + initializeNetwork(); + assertSame(operation, + network.createSubnetwork(SUBNETWORK1, IP_RANGE, Compute.OperationOption.fields())); + verify(compute); + } + + public void compareNetwork(Network expected, Network value) { + assertEquals(expected, value); + assertEquals(expected.compute().options(), value.compute().options()); + assertEquals(expected.id(), value.id()); + assertEquals(expected.networkId(), value.networkId()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.configuration(), value.configuration()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java index 5f06d252af34..2e5dbdca6ceb 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java @@ -161,6 +161,16 @@ public class SerializationTest { private static final NetworkId NETWORK_ID = NetworkId.of("project", "network"); private static final SubnetworkInfo SUBNETWORK_INFO = SubnetworkInfo.of(SUBNETWORK_ID, NETWORK_ID, "192.168.0.0/16"); + private static final Subnetwork SUBNETWORK = + new Subnetwork.Builder(COMPUTE, SUBNETWORK_ID, NETWORK_ID, "192.168.0.0/16").build(); + private static final StandardNetworkConfiguration STANDARD_NETWORK_CONFIGURATION = + StandardNetworkConfiguration.of("192.168.0.0/16"); + private static final SubnetNetworkConfiguration SUBNET_NETWORK_CONFIGURATION = + SubnetNetworkConfiguration.of(false); + private static final NetworkInfo NETWORK_INFO = + NetworkInfo.of(NETWORK_ID, STANDARD_NETWORK_CONFIGURATION); + private static final Network NETWORK = + new Network.Builder(COMPUTE, NETWORK_ID, STANDARD_NETWORK_CONFIGURATION).build(); private static final Compute.DiskTypeOption DISK_TYPE_OPTION = Compute.DiskTypeOption.fields(); private static final Compute.DiskTypeFilter DISK_TYPE_FILTER = @@ -217,6 +227,20 @@ public class SerializationTest { Compute.DiskListOption.filter(DISK_FILTER); private static final Compute.DiskAggregatedListOption DISK_AGGREGATED_LIST_OPTION = Compute.DiskAggregatedListOption.filter(DISK_FILTER); + private static final Compute.SubnetworkOption SUBNETWORK_OPTION = + Compute.SubnetworkOption.fields(); + private static final Compute.SubnetworkFilter SUBNETWORK_FILTER = + Compute.SubnetworkFilter.equals(Compute.SubnetworkField.SELF_LINK, "selfLink"); + private static final Compute.SubnetworkListOption SUBNETWORK_LIST_OPTION = + Compute.SubnetworkListOption.filter(SUBNETWORK_FILTER); + private static final Compute.SubnetworkAggregatedListOption SUBNETWORK_AGGREGATED_LIST_OPTION = + Compute.SubnetworkAggregatedListOption.filter(SUBNETWORK_FILTER); + private static final Compute.NetworkOption NETWORK_OPTION = + Compute.NetworkOption.fields(); + private static final Compute.NetworkFilter NETWORK_FILTER = + Compute.NetworkFilter.equals(Compute.NetworkField.SELF_LINK, "selfLink"); + private static final Compute.NetworkListOption NETWORK_LIST_OPTION = + Compute.NetworkListOption.filter(NETWORK_FILTER); @Test public void testServiceOptions() throws Exception { @@ -246,15 +270,18 @@ public void testModelAndRequests() throws Exception { ADDRESS_INFO, ADDRESS, DISK_ID, SNAPSHOT_ID, SNAPSHOT_INFO, SNAPSHOT, IMAGE_ID, DISK_IMAGE_CONFIGURATION, STORAGE_IMAGE_CONFIGURATION, IMAGE_INFO, IMAGE, STANDARD_DISK_CONFIGURATION, IMAGE_DISK_CONFIGURATION, SNAPSHOT_DISK_CONFIGURATION, - DISK_INFO, DISK, SUBNETWORK_ID, NETWORK_ID, SUBNETWORK_INFO, DISK_TYPE_OPTION, - DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, DISK_TYPE_AGGREGATED_LIST_OPTION, + DISK_INFO, DISK, SUBNETWORK_ID, NETWORK_ID, SUBNETWORK_INFO, SUBNETWORK, + STANDARD_NETWORK_CONFIGURATION, SUBNET_NETWORK_CONFIGURATION, NETWORK_INFO, NETWORK, + DISK_TYPE_OPTION, DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, DISK_TYPE_AGGREGATED_LIST_OPTION, MACHINE_TYPE_OPTION, MACHINE_TYPE_FILTER, MACHINE_TYPE_LIST_OPTION, MACHINE_TYPE_AGGREGATED_LIST_OPTION, REGION_OPTION, REGION_FILTER, REGION_LIST_OPTION, ZONE_OPTION, ZONE_FILTER, ZONE_LIST_OPTION, LICENSE_OPTION, OPERATION_OPTION, OPERATION_FILTER, OPERATION_LIST_OPTION, ADDRESS_OPTION, ADDRESS_FILTER, ADDRESS_LIST_OPTION, ADDRESS_AGGREGATED_LIST_OPTION, SNAPSHOT_OPTION, SNAPSHOT_FILTER, SNAPSHOT_LIST_OPTION, IMAGE_OPTION, IMAGE_FILTER, IMAGE_LIST_OPTION, DISK_OPTION, - DISK_FILTER, DISK_LIST_OPTION, DISK_AGGREGATED_LIST_OPTION}; + DISK_FILTER, DISK_LIST_OPTION, DISK_AGGREGATED_LIST_OPTION, SUBNETWORK_OPTION, + SUBNETWORK_FILTER, SUBNETWORK_LIST_OPTION, SUBNETWORK_AGGREGATED_LIST_OPTION, + NETWORK_OPTION, NETWORK_FILTER, NETWORK_LIST_OPTION}; for (Serializable obj : objects) { Object copy = serializeAndDeserialize(obj); assertEquals(obj, obj); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkTest.java new file mode 100644 index 000000000000..4e47c9aa1198 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkTest.java @@ -0,0 +1,210 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.createStrictMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class SubnetworkTest { + + private static final String ID = "42"; + private static final Long CREATION_TIMESTAMP = 1453293540000L; + private static final String DESCRIPTION = "description"; + private static final SubnetworkId SUBNETWORK_ID = SubnetworkId.of("project", "region", "network"); + private static final String GATEWAY_ADDRESS = "192.168.1.1"; + private static final NetworkId NETWORK_ID = NetworkId.of("project", "network"); + private static final String IP_RANGE = "192.168.0.0/16"; + + private final Compute serviceMockReturnsOptions = createStrictMock(Compute.class); + private final ComputeOptions mockOptions = createMock(ComputeOptions.class); + private Compute compute; + private Subnetwork subnetwork; + private Subnetwork expectedSubnetwork; + + private void initializeExpectedSubnetwork(int optionsCalls) { + expect(serviceMockReturnsOptions.options()).andReturn(mockOptions).times(optionsCalls); + replay(serviceMockReturnsOptions); + expectedSubnetwork = + new Subnetwork.Builder(serviceMockReturnsOptions, SUBNETWORK_ID, NETWORK_ID, IP_RANGE) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .gatewayAddress(GATEWAY_ADDRESS) + .build(); + compute = createStrictMock(Compute.class); + } + + private void initializeSubnetwork() { + subnetwork = + new Subnetwork.Builder(compute, SUBNETWORK_ID, NETWORK_ID, IP_RANGE) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .gatewayAddress(GATEWAY_ADDRESS) + .build(); + } + + @Test + public void testToBuilder() { + initializeExpectedSubnetwork(8); + compareSubnetwork(expectedSubnetwork, expectedSubnetwork.toBuilder().build()); + Subnetwork newSubnetwork = expectedSubnetwork.toBuilder().description("newDescription").build(); + assertEquals("newDescription", newSubnetwork.description()); + newSubnetwork = newSubnetwork.toBuilder().description("description").build(); + compareSubnetwork(expectedSubnetwork, newSubnetwork); + } + + @Test + public void testToBuilderIncomplete() { + initializeExpectedSubnetwork(5); + SubnetworkInfo subnetworkInfo = SubnetworkInfo.of(SUBNETWORK_ID, NETWORK_ID, IP_RANGE); + Subnetwork subnetwork = + new Subnetwork(serviceMockReturnsOptions, new SubnetworkInfo.BuilderImpl(subnetworkInfo)); + compareSubnetwork(subnetwork, subnetwork.toBuilder().build()); + } + + @Test + public void testBuilder() { + initializeExpectedSubnetwork(1); + assertEquals(ID, expectedSubnetwork.id()); + assertEquals(SUBNETWORK_ID, expectedSubnetwork.subnetworkId()); + assertEquals(CREATION_TIMESTAMP, expectedSubnetwork.creationTimestamp()); + assertEquals(DESCRIPTION, expectedSubnetwork.description()); + assertEquals(GATEWAY_ADDRESS, expectedSubnetwork.gatewayAddress()); + assertEquals(NETWORK_ID, expectedSubnetwork.network()); + assertEquals(IP_RANGE, expectedSubnetwork.ipRange()); + assertSame(serviceMockReturnsOptions, expectedSubnetwork.compute()); + } + + @Test + public void testToAndFromPb() { + initializeExpectedSubnetwork(8); + compareSubnetwork(expectedSubnetwork, + Subnetwork.fromPb(serviceMockReturnsOptions, expectedSubnetwork.toPb())); + Subnetwork subnetwork = + new Subnetwork.Builder(serviceMockReturnsOptions, SUBNETWORK_ID, NETWORK_ID, IP_RANGE) + .build(); + compareSubnetwork(subnetwork, Subnetwork.fromPb(serviceMockReturnsOptions, subnetwork.toPb())); + } + + @Test + public void testDeleteOperation() { + initializeExpectedSubnetwork(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(GlobalOperationId.of("project", "op")) + .build(); + expect(compute.delete(SUBNETWORK_ID)).andReturn(operation); + replay(compute); + initializeSubnetwork(); + assertSame(operation, subnetwork.delete()); + } + + @Test + public void testDeleteNull() { + initializeExpectedSubnetwork(1); + expect(compute.options()).andReturn(mockOptions); + expect(compute.delete(SUBNETWORK_ID)).andReturn(null); + replay(compute); + initializeSubnetwork(); + assertNull(subnetwork.delete()); + } + + @Test + public void testExists_True() throws Exception { + initializeExpectedSubnetwork(1); + Compute.SubnetworkOption[] expectedOptions = {Compute.SubnetworkOption.fields()}; + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(SUBNETWORK_ID, expectedOptions)) + .andReturn(expectedSubnetwork); + replay(compute); + initializeSubnetwork(); + assertTrue(subnetwork.exists()); + verify(compute); + } + + @Test + public void testExists_False() throws Exception { + initializeExpectedSubnetwork(1); + Compute.SubnetworkOption[] expectedOptions = {Compute.SubnetworkOption.fields()}; + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(SUBNETWORK_ID, expectedOptions)).andReturn(null); + replay(compute); + initializeSubnetwork(); + assertFalse(subnetwork.exists()); + verify(compute); + } + + @Test + public void testReload() throws Exception { + initializeExpectedSubnetwork(3); + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(SUBNETWORK_ID)).andReturn(expectedSubnetwork); + replay(compute); + initializeSubnetwork(); + Subnetwork updatedSubnetwork = subnetwork.reload(); + compareSubnetwork(expectedSubnetwork, updatedSubnetwork); + verify(compute); + } + + @Test + public void testReloadNull() throws Exception { + initializeExpectedSubnetwork(1); + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(SUBNETWORK_ID)).andReturn(null); + replay(compute); + initializeSubnetwork(); + assertNull(subnetwork.reload()); + verify(compute); + } + + @Test + public void testReloadWithOptions() throws Exception { + initializeExpectedSubnetwork(3); + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(SUBNETWORK_ID, Compute.SubnetworkOption.fields())) + .andReturn(expectedSubnetwork); + replay(compute); + initializeSubnetwork(); + Subnetwork updatedSubnetwork = subnetwork.reload(Compute.SubnetworkOption.fields()); + compareSubnetwork(expectedSubnetwork, updatedSubnetwork); + verify(compute); + } + + public void compareSubnetwork(Subnetwork expected, Subnetwork value) { + assertEquals(expected, value); + assertEquals(expected.compute().options(), value.compute().options()); + assertEquals(expected.id(), value.id()); + assertEquals(expected.subnetworkId(), value.subnetworkId()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.gatewayAddress(), value.gatewayAddress()); + assertEquals(expected.network(), value.network()); + assertEquals(expected.ipRange(), value.ipRange()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java index 39fdb622a59d..aa94baf9809e 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java @@ -46,6 +46,10 @@ import com.google.gcloud.compute.License; import com.google.gcloud.compute.LicenseId; import com.google.gcloud.compute.MachineType; +import com.google.gcloud.compute.Network; +import com.google.gcloud.compute.NetworkConfiguration; +import com.google.gcloud.compute.NetworkId; +import com.google.gcloud.compute.NetworkInfo; import com.google.gcloud.compute.Operation; import com.google.gcloud.compute.Region; import com.google.gcloud.compute.RegionAddressId; @@ -55,7 +59,12 @@ import com.google.gcloud.compute.SnapshotId; import com.google.gcloud.compute.SnapshotInfo; import com.google.gcloud.compute.StandardDiskConfiguration; +import com.google.gcloud.compute.StandardNetworkConfiguration; import com.google.gcloud.compute.StorageImageConfiguration; +import com.google.gcloud.compute.SubnetNetworkConfiguration; +import com.google.gcloud.compute.Subnetwork; +import com.google.gcloud.compute.SubnetworkId; +import com.google.gcloud.compute.SubnetworkInfo; import com.google.gcloud.compute.Zone; import com.google.gcloud.compute.ZoneOperationId; import com.google.gcloud.compute.testing.RemoteComputeHelper; @@ -1353,4 +1362,241 @@ public void testListImagesWithFilter() { } assertTrue(count > 0); } + + @Test + public void testCreateAndGetNetwork() throws InterruptedException { + String name = BASE_RESOURCE_NAME + "create-and-get-network"; + NetworkId networkId = NetworkId.of(name); + NetworkInfo networkInfo = + NetworkInfo.of(networkId, StandardNetworkConfiguration.of("192.168.0.0/16")); + Operation operation = compute.create(networkInfo); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + // test get network with selected fields + Network network = compute.getNetwork(networkId.network(), + Compute.NetworkOption.fields(Compute.NetworkField.CREATION_TIMESTAMP)); + assertEquals(networkId.network(), network.networkId().network()); + assertNull(network.id()); + assertNotNull(network.creationTimestamp()); + assertNull(network.description()); + assertEquals(NetworkConfiguration.Type.STANDARD, network.configuration().type()); + StandardNetworkConfiguration remoteConfiguration = network.configuration(); + assertEquals("192.168.0.0/16", remoteConfiguration.ipRange()); + // test get network + network = compute.getNetwork(networkId.network()); + assertEquals(networkId.network(), network.networkId().network()); + assertNotNull(network.id()); + assertNotNull(network.creationTimestamp()); + assertEquals(NetworkConfiguration.Type.STANDARD, network.configuration().type()); + remoteConfiguration = network.configuration(); + assertEquals("192.168.0.0/16", remoteConfiguration.ipRange()); + operation = network.delete(); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + assertNull(compute.getNetwork(name)); + } + + @Test + public void testListNetworks() throws InterruptedException { + String name = BASE_RESOURCE_NAME + "list-network"; + NetworkId networkId = NetworkId.of(name); + NetworkInfo networkInfo = + NetworkInfo.of(networkId, StandardNetworkConfiguration.of("192.168.0.0/16")); + Operation operation = compute.create(networkInfo); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + // test list + Compute.NetworkFilter filter = Compute.NetworkFilter.equals(Compute.NetworkField.NAME, name); + Page networkPage = compute.listNetworks(Compute.NetworkListOption.filter(filter)); + Iterator networkIterator = networkPage.iterateAll(); + int count = 0; + while (networkIterator.hasNext()) { + Network network = networkIterator.next(); + assertEquals(networkId.network(), network.networkId().network()); + assertNotNull(network.id()); + assertNotNull(network.creationTimestamp()); + assertEquals(NetworkConfiguration.Type.STANDARD, network.configuration().type()); + StandardNetworkConfiguration remoteConfiguration = network.configuration(); + assertEquals("192.168.0.0/16", remoteConfiguration.ipRange()); + count++; + } + assertEquals(1, count); + // test list with selected fields + count = 0; + networkPage = compute.listNetworks(Compute.NetworkListOption.filter(filter), + Compute.NetworkListOption.fields(Compute.NetworkField.CREATION_TIMESTAMP)); + networkIterator = networkPage.iterateAll(); + while (networkIterator.hasNext()) { + Network network = networkIterator.next(); + assertEquals(networkId.network(), network.networkId().network()); + assertNull(network.id()); + assertNotNull(network.creationTimestamp()); + assertNull(network.description()); + assertEquals(NetworkConfiguration.Type.STANDARD, network.configuration().type()); + StandardNetworkConfiguration remoteConfiguration = network.configuration(); + assertEquals("192.168.0.0/16", remoteConfiguration.ipRange()); + count++; + } + assertEquals(1, count); + operation = compute.deleteNetwork(networkId); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + assertNull(compute.getNetwork(name)); + } + + @Test + public void testCreateNetworkAndSubnetwork() throws InterruptedException { + String networkName = BASE_RESOURCE_NAME + "create-subnetwork-network"; + NetworkId networkId = NetworkId.of(networkName); + NetworkInfo networkInfo = NetworkInfo.of(networkId, SubnetNetworkConfiguration.of(false)); + Operation operation = compute.create(networkInfo); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + // test get network + Network network = compute.getNetwork(networkId.network()); + assertEquals(networkId.network(), network.networkId().network()); + assertNotNull(network.id()); + assertNotNull(network.creationTimestamp()); + assertEquals(NetworkConfiguration.Type.SUBNET, network.configuration().type()); + assertTrue(network.configuration() instanceof SubnetNetworkConfiguration); + assertFalse(network.configuration().autoCreateSubnetworks()); + String subnetworkName = BASE_RESOURCE_NAME + "create-subnetwork-subnetwork"; + SubnetworkId subnetworkId = SubnetworkId.of(REGION, subnetworkName); + SubnetworkInfo subnetworkInfo = SubnetworkInfo.of(subnetworkId, networkId, "192.168.0.0/16"); + operation = compute.create(subnetworkInfo); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + // test get subnetwork with selected fields + Subnetwork subnetwork = compute.get(subnetworkId, + Compute.SubnetworkOption.fields(Compute.SubnetworkField.CREATION_TIMESTAMP)); + assertNull(subnetwork.id()); + assertEquals(subnetworkId.subnetwork(), subnetwork.subnetworkId().subnetwork()); + assertNotNull(subnetwork.creationTimestamp()); + assertNull(subnetwork.description()); + assertNull(subnetwork.gatewayAddress()); + assertNull(subnetwork.network()); + assertNull(subnetwork.ipRange()); + // test get subnetwork + subnetwork = compute.get(subnetworkId); + assertNotNull(subnetwork.id()); + assertEquals(subnetworkId.subnetwork(), subnetwork.subnetworkId().subnetwork()); + assertNotNull(subnetwork.creationTimestamp()); + assertNotNull(subnetwork.gatewayAddress()); + assertEquals(networkId.network(), subnetwork.network().network()); + assertEquals("192.168.0.0/16", subnetwork.ipRange()); + // test list subnetworks + Compute.SubnetworkFilter filter = + Compute.SubnetworkFilter.equals(Compute.SubnetworkField.NAME, subnetworkName); + Page subnetworkPage = + compute.listSubnetworks(REGION, Compute.SubnetworkListOption.filter(filter)); + Iterator subnetworkIterator = subnetworkPage.iterateAll(); + int count = 0; + while (subnetworkIterator.hasNext()) { + Subnetwork remoteSubnetwork = subnetworkIterator.next(); + assertNotNull(remoteSubnetwork.id()); + assertEquals(subnetworkId.subnetwork(), remoteSubnetwork.subnetworkId().subnetwork()); + assertNotNull(remoteSubnetwork.creationTimestamp()); + assertNotNull(remoteSubnetwork.gatewayAddress()); + assertEquals(networkId.network(), remoteSubnetwork.network().network()); + assertEquals("192.168.0.0/16", remoteSubnetwork.ipRange()); + count++; + } + assertEquals(1, count); + // test list subnetworks with selected fields + subnetworkPage = compute.listSubnetworks(REGION, Compute.SubnetworkListOption.filter(filter), + Compute.SubnetworkListOption.fields(Compute.SubnetworkField.CREATION_TIMESTAMP)); + subnetworkIterator = subnetworkPage.iterateAll(); + count = 0; + while (subnetworkIterator.hasNext()) { + Subnetwork remoteSubnetwork = subnetworkIterator.next(); + assertNull(remoteSubnetwork.id()); + assertEquals(subnetworkId.subnetwork(), remoteSubnetwork.subnetworkId().subnetwork()); + assertNotNull(remoteSubnetwork.creationTimestamp()); + assertNull(remoteSubnetwork.description()); + assertNull(remoteSubnetwork.gatewayAddress()); + assertNull(remoteSubnetwork.network()); + assertNull(remoteSubnetwork.ipRange()); + count++; + } + assertEquals(1, count); + operation = subnetwork.delete(); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + operation = compute.deleteNetwork(networkId); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + assertNull(compute.get(subnetworkId)); + assertNull(compute.getNetwork(networkName)); + } + + @Test + public void testAggregatedListSubnetworks() throws InterruptedException { + String networkName = BASE_RESOURCE_NAME + "list-subnetwork-network"; + NetworkId networkId = NetworkId.of(networkName); + NetworkInfo networkInfo = NetworkInfo.of(networkId, SubnetNetworkConfiguration.of(false)); + Operation operation = compute.create(networkInfo); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + String prefix = BASE_RESOURCE_NAME + "list-subnetwork"; + String[] regionNames = {"us-central1", "us-east1"}; + String[] subnetworkNames = {prefix + "1", prefix + "2"}; + String[] ipRanges = {"10.128.0.0/20", "10.132.0.0/20"}; + SubnetworkId firstSubnetworkId = SubnetworkId.of(regionNames[0], subnetworkNames[0]); + SubnetworkId secondSubnetworkId = SubnetworkId.of(regionNames[1], subnetworkNames[1]); + SubnetworkInfo firstSubnetworkInfo = + SubnetworkInfo.of(firstSubnetworkId, networkId, ipRanges[0]); + SubnetworkInfo secondSubnetworkInfo = + SubnetworkInfo.of(secondSubnetworkId, networkId, ipRanges[1]); + Operation firstOperation = compute.create(firstSubnetworkInfo); + Operation secondOperation = compute.create(secondSubnetworkInfo); + while (!firstOperation.isDone()) { + Thread.sleep(1000L); + } + while (!secondOperation.isDone()) { + Thread.sleep(1000L); + } + Set regionSet = ImmutableSet.copyOf(regionNames); + Set subnetworkSet = ImmutableSet.copyOf(subnetworkNames); + Set rangeSet = ImmutableSet.copyOf(ipRanges); + Compute.SubnetworkFilter subnetworkFilter = + Compute.SubnetworkFilter.equals(Compute.SubnetworkField.NAME, prefix + "\\d"); + Page subnetworkPage = + compute.listSubnetworks(Compute.SubnetworkAggregatedListOption.filter(subnetworkFilter)); + Iterator subnetworkIterator = subnetworkPage.iterateAll(); + int count = 0; + while (subnetworkIterator.hasNext()) { + Subnetwork remoteSubnetwork = subnetworkIterator.next(); + assertNotNull(remoteSubnetwork.id()); + assertTrue(regionSet.contains(remoteSubnetwork.subnetworkId().region())); + assertTrue(subnetworkSet.contains(remoteSubnetwork.subnetworkId().subnetwork())); + assertNotNull(remoteSubnetwork.creationTimestamp()); + assertNotNull(remoteSubnetwork.gatewayAddress()); + assertEquals(networkId.network(), remoteSubnetwork.network().network()); + assertTrue(rangeSet.contains(remoteSubnetwork.ipRange())); + count++; + } + assertEquals(2, count); + firstOperation = compute.delete(firstSubnetworkId); + secondOperation = compute.delete(secondSubnetworkId); + while (!firstOperation.isDone()) { + Thread.sleep(1000L); + } + while (!secondOperation.isDone()) { + Thread.sleep(1000L); + } + operation = compute.deleteNetwork(networkId); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + assertNull(compute.getNetwork(networkName)); + } } From 19227df5bb8f8da0ece06757218bb95f70c1aecb Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 20 Apr 2016 22:08:14 +0200 Subject: [PATCH 318/375] Chain cause in ComputeException.translateAndThrow, add tests (#948) Chain cause in ComputeException.translateAndThrow, add tests and make ComputeException constructors package scoped. --- .../gcloud/compute/ComputeException.java | 10 +- .../gcloud/compute/ComputeExceptionTest.java | 105 ++++++++++++++++++ 2 files changed, 112 insertions(+), 3 deletions(-) create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeExceptionTest.java diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeException.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeException.java index 94a409305338..c6e7ef734442 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeException.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeException.java @@ -32,8 +32,12 @@ public class ComputeException extends BaseServiceException { private static final Set RETRYABLE_ERRORS = ImmutableSet.of(new Error(500, null)); private static final long serialVersionUID = -8039359778707845810L; - public ComputeException(int code, String message) { - super(code, message, null, true); + ComputeException(int code, String message) { + super(code, message, null, true, null); + } + + ComputeException(int code, String message, Throwable cause) { + super(code, message, null, true, cause); } public ComputeException(IOException exception) { @@ -54,6 +58,6 @@ protected Set retryableErrors() { */ static BaseServiceException translateAndThrow(RetryHelperException ex) { BaseServiceException.translateAndPropagateIfPossible(ex); - throw new ComputeException(UNKNOWN_CODE, ex.getMessage()); + throw new ComputeException(UNKNOWN_CODE, ex.getMessage(), ex.getCause()); } } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeExceptionTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeExceptionTest.java new file mode 100644 index 000000000000..f98bfa150d8c --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeExceptionTest.java @@ -0,0 +1,105 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import com.google.gcloud.BaseServiceException; +import com.google.gcloud.RetryHelper.RetryHelperException; + +import org.junit.Test; + +import java.io.IOException; +import java.net.SocketTimeoutException; + +public class ComputeExceptionTest { + + @Test + public void testResourceManagerException() { + ComputeException exception = new ComputeException(500, "message"); + assertEquals(500, exception.code()); + assertEquals("message", exception.getMessage()); + assertNull(exception.reason()); + assertTrue(exception.retryable()); + assertTrue(exception.idempotent()); + + exception = new ComputeException(403, "message"); + assertEquals(403, exception.code()); + assertEquals("message", exception.getMessage()); + assertNull(exception.reason()); + assertFalse(exception.retryable()); + assertTrue(exception.idempotent()); + + IOException cause = new SocketTimeoutException(); + exception = new ComputeException(cause); + assertNull(exception.reason()); + assertNull(exception.getMessage()); + assertTrue(exception.retryable()); + assertTrue(exception.idempotent()); + assertSame(cause, exception.getCause()); + + exception = new ComputeException(403, "message", cause); + assertEquals(403, exception.code()); + assertEquals("message", exception.getMessage()); + assertNull(exception.reason()); + assertFalse(exception.retryable()); + assertTrue(exception.idempotent()); + assertSame(cause, exception.getCause()); + } + + @Test + public void testTranslateAndThrow() throws Exception { + Exception cause = new ComputeException(500, "message"); + RetryHelperException exceptionMock = createMock(RetryHelperException.class); + expect(exceptionMock.getCause()).andReturn(cause).times(2); + replay(exceptionMock); + try { + ComputeException.translateAndThrow(exceptionMock); + } catch (BaseServiceException ex) { + assertEquals(500, ex.code()); + assertEquals("message", ex.getMessage()); + assertTrue(ex.retryable()); + assertTrue(ex.idempotent()); + } finally { + verify(exceptionMock); + } + cause = new IllegalArgumentException("message"); + exceptionMock = createMock(RetryHelperException.class); + expect(exceptionMock.getMessage()).andReturn("message").times(1); + expect(exceptionMock.getCause()).andReturn(cause).times(2); + replay(exceptionMock); + try { + ComputeException.translateAndThrow(exceptionMock); + } catch (BaseServiceException ex) { + assertEquals(ComputeException.UNKNOWN_CODE, ex.code()); + assertEquals("message", ex.getMessage()); + assertFalse(ex.retryable()); + assertTrue(ex.idempotent()); + assertSame(cause, ex.getCause()); + } finally { + verify(exceptionMock); + } + } +} From 4fb78d8544b398d2ee9fe8f118f1dc3770901da5 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 22 Apr 2016 15:32:02 +0200 Subject: [PATCH 319/375] Add NetworkInterface, AccessConfig classes and related tests (#947) --- .../gcloud/compute/NetworkInterface.java | 505 ++++++++++++++++++ .../gcloud/compute/NetworkInterfaceTest.java | 179 +++++++ .../gcloud/compute/SerializationTest.java | 15 +- 3 files changed, 694 insertions(+), 5 deletions(-) create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInterface.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkInterfaceTest.java diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInterface.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInterface.java new file mode 100644 index 000000000000..cf937de68ed6 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInterface.java @@ -0,0 +1,505 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +/** + * A network interface for a Google Compute Engine instance. Network interfaces specify how + * the instance is configured to interact with other network services, such as connecting to the + * internet. + * + * @see Configuring an + * Instance's IP Addresses + */ +public class NetworkInterface implements Serializable { + + static final Function + FROM_PB_FUNCTION = + new Function() { + @Override + public NetworkInterface apply( + com.google.api.services.compute.model.NetworkInterface pb) { + return NetworkInterface.fromPb(pb); + } + }; + static final Function + TO_PB_FUNCTION = + new Function() { + @Override + public com.google.api.services.compute.model.NetworkInterface apply( + NetworkInterface networkInterface) { + return networkInterface.toPb(); + } + }; + + private static final long serialVersionUID = 936741262053605581L; + + private final String name; + private final NetworkId network; + private final String networkIp; + private final SubnetworkId subnetwork; + private final List accessConfigurations; + + /** + * Access configuration for a Google Compute Engine instance's network interface. Objects of this + * class can be used to assign either a static or an ephemeral external IP address to Google + * Compute Engine instances. + * + * @see + * Static external IP addresses + * @see + * Ephemeral external IP addresses + */ + public static final class AccessConfig implements Serializable { + + static final Function + FROM_PB_FUNCTION = + new Function() { + @Override + public AccessConfig apply(com.google.api.services.compute.model.AccessConfig pb) { + return AccessConfig.fromPb(pb); + } + }; + static final Function + TO_PB_FUNCTION = + new Function() { + @Override + public com.google.api.services.compute.model.AccessConfig apply( + AccessConfig instance) { + return instance.toPb(); + } + }; + + private static final long serialVersionUID = -5438060668934041567L; + + private final String name; + private final String natIp; + private final Type type; + + /** + * The type of network access configuration. The only supported value is {@code ONE_TO_ONE_NAT}. + */ + public enum Type { + ONE_TO_ONE_NAT + } + + public static final class Builder { + + private String name; + private String natIp; + private Type type; + + private Builder() {} + + private Builder(AccessConfig accessConfig) { + this.name = accessConfig.name; + this.natIp = accessConfig.natIp; + this.type = accessConfig.type; + } + + /** + * Sets the name of the access configuration. + */ + public Builder name(String name) { + this.name = name; + return this; + } + + /** + * Sets an external IP address associated with this instance. Specify an unused static + * external IP address available to the project or leave this field undefined to use an IP + * from a shared ephemeral IP address pool. If you specify a static external IP address, it + * must live in the same region as the zone of the instance. + * + * @see + * Ephemeral external IP addresses + * @see + * Ephemeral external IP addresses + */ + public Builder natIp(String natIp) { + this.natIp = natIp; + return this; + } + + /** + * Sets the type of the access configuration. The only supported value is + * {@link Type#ONE_TO_ONE_NAT}. + */ + public Builder type(Type type) { + this.type = type; + return this; + } + + /** + * Creates an {@code AccessConfig} object. + */ + public AccessConfig build() { + return new AccessConfig(this); + } + } + + AccessConfig(Builder builder) { + this.name = builder.name; + this.natIp = builder.natIp; + this.type = builder.type; + } + + /** + * Returns the name of the access configuration. + */ + public String name() { + return name; + } + + /** + * Returns an external IP address associated with this instance. + */ + public String natIp() { + return natIp; + } + + /** + * Returns the type of network access configuration. The only supported value is + * {@link Type#ONE_TO_ONE_NAT}. + */ + public Type type() { + return type; + } + + /** + * Returns a builder for the current access configuration. + */ + public Builder toBuilder() { + return new Builder(this); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("name", name) + .add("natIp", natIp) + .add("type", type) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(name, natIp, type); + } + + @Override + public boolean equals(Object obj) { + return obj == this + || obj instanceof AccessConfig + && Objects.equals(toPb(), ((AccessConfig) obj).toPb()); + } + + com.google.api.services.compute.model.AccessConfig toPb() { + com.google.api.services.compute.model.AccessConfig accessConfigPb = + new com.google.api.services.compute.model.AccessConfig(); + accessConfigPb.setName(name); + accessConfigPb.setNatIP(natIp); + if (type != null) { + accessConfigPb.setType(type.name()); + } + return accessConfigPb; + } + + /** + * Returns a builder for an {@code AccessConfig} object. + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Returns an {@code AccessConfig} object given the static external IP address. + * + * @see + * Static external IP addresses + */ + public static AccessConfig of(String natIp) { + return builder().natIp(natIp).build(); + } + + /** + * Returns an {@code AccessConfig} object. IP address for this access configuration will be + * taken from a pool of ephemeral addresses. + * + * @see + * Ephemeral external IP addresses + */ + public static AccessConfig of() { + return builder().build(); + } + + static AccessConfig fromPb(com.google.api.services.compute.model.AccessConfig configPb) { + Builder builder = builder(); + builder.name(configPb.getName()); + if (configPb.getNatIP() != null) { + builder.natIp(configPb.getNatIP()); + } + if (configPb.getType() != null) { + builder.type(Type.valueOf(configPb.getType())); + } + return builder.build(); + } + } + + public static final class Builder { + + private String name; + private NetworkId network; + private String networkIp; + private SubnetworkId subnetwork; + private List accessConfigurations; + + private Builder(NetworkId network) { + this.network = checkNotNull(network); + } + + private Builder(NetworkInterface networkInterface) { + this.name = networkInterface.name; + this.network = networkInterface.network; + this.networkIp = networkInterface.networkIp; + this.subnetwork = networkInterface.subnetwork; + this.accessConfigurations = networkInterface.accessConfigurations; + } + + Builder name(String name) { + this.name = name; + return this; + } + + /** + * Sets the identity of the network this interface applies to. + */ + public Builder network(NetworkId network) { + this.network = checkNotNull(network); + return this; + } + + Builder networkIp(String networkIp) { + this.networkIp = networkIp; + return this; + } + + /** + * Sets the identity of the subnetwork this interface applies to. Setting the subnetwork is + * not necessary when the network is in "automatic subnet mode". + */ + public Builder subnetwork(SubnetworkId subnetwork) { + this.subnetwork = subnetwork; + return this; + } + + /** + * Sets a list of access configurations for the network interface. Access configurations can be + * used to assign either a static or an ephemeral external IP address to Google Compute Engine + * instances. At the moment, network interfaces only support one access configuration. + * + * @see + * Static external IP addresses + * @see + * Ephemeral external IP addresses + */ + public Builder accessConfigurations(List accessConfigurations) { + this.accessConfigurations = ImmutableList.copyOf(accessConfigurations); + return this; + } + + /** + * Sets a list of access configurations for the network interface. Access configurations can be + * used to assign either a static or an ephemeral external IP address to Google Compute Engine + * instances. At the moment, network interfaces only support one access configuration. + * + * @see + * Static external IP addresses + * @see + * Ephemeral external IP addresses + */ + public Builder accessConfigurations(AccessConfig... accessConfigurations) { + accessConfigurations(Arrays.asList(accessConfigurations)); + return this; + } + + /** + * Creates a {@code NetworkInterface} object. + */ + public NetworkInterface build() { + return new NetworkInterface(this); + } + } + + private NetworkInterface(Builder builder) { + this.name = builder.name; + this.network = builder.network; + this.networkIp = builder.networkIp; + this.subnetwork = builder.subnetwork; + this.accessConfigurations = builder.accessConfigurations != null + ? builder.accessConfigurations : ImmutableList.of(); + } + + /** + * Returns the name of the network interface, generated by the service. For network devices, + * these are {@code eth0}, {@code eth1}, etc. + */ + public String name() { + return name; + } + + /** + * Returns the identity of the network this interface applies to. + */ + public NetworkId network() { + return network; + } + + /** + * An optional IPv4 internal network address assigned by the service to the instance for this + * network interface. + */ + public String networkIp() { + return networkIp; + } + + /** + * Returns the identity of the subnetwork this interface applies to. + */ + public SubnetworkId subnetwork() { + return subnetwork; + } + + /** + * Returns a list of access configurations for the network interface. + */ + public List accessConfigurations() { + return accessConfigurations; + } + + /** + * Returns a builder for the current network interface. + */ + public Builder toBuilder() { + return new Builder(this); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("name", name) + .add("network", network) + .add("networkIp", networkIp) + .add("subnetwork", subnetwork) + .add("accessConfigurations", accessConfigurations) + .toString(); + } + + @Override + public final int hashCode() { + return Objects.hash(name, network, networkIp, subnetwork, accessConfigurations); + } + + @Override + public final boolean equals(Object obj) { + return obj == this + || obj != null + && obj.getClass().equals(NetworkInterface.class) + && Objects.equals(toPb(), ((NetworkInterface) obj).toPb()); + } + + com.google.api.services.compute.model.NetworkInterface toPb() { + com.google.api.services.compute.model.NetworkInterface interfacePb = + new com.google.api.services.compute.model.NetworkInterface(); + interfacePb.setName(name); + interfacePb.setNetwork(network.selfLink()); + if (subnetwork != null) { + interfacePb.setSubnetwork(subnetwork.selfLink()); + } + interfacePb.setNetworkIP(networkIp); + if (accessConfigurations != null) { + interfacePb.setAccessConfigs( + Lists.transform(accessConfigurations, AccessConfig.TO_PB_FUNCTION)); + } + return interfacePb; + } + + NetworkInterface setProjectId(String projectId) { + Builder builder = toBuilder(); + builder.network(network.setProjectId(projectId)); + if (subnetwork != null) { + builder.subnetwork(subnetwork.setProjectId(projectId)); + } + return builder.build(); + } + + /** + * Returns a builder for a {@code NetworkInterface} object given the network's identity. + */ + public static Builder builder(NetworkId networkId) { + return new Builder(networkId); + } + + /** + * Returns a builder for a {@code NetworkInterface} object given the network's name. + */ + public static Builder builder(String network) { + return builder(NetworkId.of(network)); + } + + /** + * Returns a {@code NetworkInterface} object given the network's identity. + */ + public static NetworkInterface of(NetworkId networkId) { + return builder(networkId).build(); + } + + /** + * Returns a {@code NetworkInterface} object given the network's name. + */ + public static NetworkInterface of(String network) { + return builder(network).build(); + } + + static NetworkInterface fromPb( + com.google.api.services.compute.model.NetworkInterface interfacePb) { + Builder builder = builder(NetworkId.fromUrl(interfacePb.getNetwork())) + .name(interfacePb.getName()); + if (interfacePb.getSubnetwork() != null){ + builder.subnetwork(SubnetworkId.fromUrl(interfacePb.getSubnetwork())); + } + builder.networkIp(interfacePb.getNetworkIP()); + builder.accessConfigurations(interfacePb.getAccessConfigs() != null + ? Lists.transform(interfacePb.getAccessConfigs(), AccessConfig.FROM_PB_FUNCTION) : + ImmutableList.of()); + return builder.build(); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkInterfaceTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkInterfaceTest.java new file mode 100644 index 000000000000..22913937d0b1 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkInterfaceTest.java @@ -0,0 +1,179 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import com.google.common.collect.ImmutableList; +import com.google.gcloud.compute.NetworkInterface.AccessConfig; +import com.google.gcloud.compute.NetworkInterface.AccessConfig.Type; + +import org.junit.Test; + +import java.util.List; + +public class NetworkInterfaceTest { + + private static final String NAME = "networkInterface"; + private static final NetworkId NETWORK = NetworkId.of("project", "network"); + private static final String NETWORK_IP = "192.168.1.1"; + private static final SubnetworkId SUBNETWORK = SubnetworkId.of("project", "region", "subnetwork"); + private static final AccessConfig ACCESS_CONFIG = AccessConfig.builder() + .name("accessConfig") + .natIp("192.168.1.1") + .type(Type.ONE_TO_ONE_NAT) + .build(); + private static final List ACCESS_CONFIGURATIONS = + ImmutableList.of(ACCESS_CONFIG); + private static final NetworkInterface NETWORK_INTERFACE = NetworkInterface.builder(NETWORK) + .name(NAME) + .networkIp(NETWORK_IP) + .subnetwork(SUBNETWORK) + .accessConfigurations(ACCESS_CONFIGURATIONS) + .build(); + + @Test + public void testAccessConfigToBuilder() { + AccessConfig accessConfig = ACCESS_CONFIG.toBuilder().name("newName").build(); + assertEquals("newName", accessConfig.name()); + compareAccessConfig(ACCESS_CONFIG, accessConfig.toBuilder().name("accessConfig").build()); + } + + @Test + public void testAccessConfigToBuilderIncomplete() { + AccessConfig accessConfig = AccessConfig.of(); + compareAccessConfig(accessConfig, accessConfig.toBuilder().build()); + } + + @Test + public void testToBuilder() { + compareNetworkInterface(NETWORK_INTERFACE, NETWORK_INTERFACE.toBuilder().build()); + NetworkInterface networkInterface = NETWORK_INTERFACE.toBuilder().name("newInterface").build(); + assertEquals("newInterface", networkInterface.name()); + networkInterface = networkInterface.toBuilder().name(NAME).build(); + compareNetworkInterface(NETWORK_INTERFACE, networkInterface); + } + + @Test + public void testToBuilderIncomplete() { + NetworkInterface networkInterface = NetworkInterface.of(NETWORK); + assertEquals(networkInterface, networkInterface.toBuilder().build()); + networkInterface = NetworkInterface.of(NETWORK.network()); + assertEquals(networkInterface, networkInterface.toBuilder().build()); + } + + @Test + public void testAccessConfigBuilder() { + assertEquals("accessConfig", ACCESS_CONFIG.name()); + assertEquals("192.168.1.1", ACCESS_CONFIG.natIp()); + assertEquals(Type.ONE_TO_ONE_NAT, ACCESS_CONFIG.type()); + } + + @Test + public void testBuilder() { + assertEquals(NAME, NETWORK_INTERFACE.name()); + assertEquals(NETWORK, NETWORK_INTERFACE.network()); + assertEquals(NETWORK_IP, NETWORK_INTERFACE.networkIp()); + assertEquals(SUBNETWORK, NETWORK_INTERFACE.subnetwork()); + assertEquals(ACCESS_CONFIGURATIONS, NETWORK_INTERFACE.accessConfigurations()); + NetworkInterface networkInterface = NetworkInterface.builder("network") + .name(NAME) + .networkIp(NETWORK_IP) + .subnetwork(SUBNETWORK) + .accessConfigurations(ACCESS_CONFIG) + .build(); + assertEquals(NAME, networkInterface.name()); + assertEquals(NetworkId.of("network"), networkInterface.network()); + assertEquals(NETWORK_IP, networkInterface.networkIp()); + assertEquals(SUBNETWORK, networkInterface.subnetwork()); + assertEquals(ACCESS_CONFIGURATIONS, networkInterface.accessConfigurations()); + } + + @Test + public void testAccessConfigOf() { + AccessConfig accessConfig = AccessConfig.of("192.168.1.1"); + assertNull(accessConfig.name()); + assertEquals("192.168.1.1", accessConfig.natIp()); + assertNull(accessConfig.type()); + accessConfig = AccessConfig.of(); + assertNull(accessConfig.name()); + assertNull(accessConfig.natIp()); + assertNull(accessConfig.type()); + } + + @Test + public void testOf() { + NetworkInterface networkInterface = NetworkInterface.of(NETWORK); + assertNull(networkInterface.name()); + assertEquals(NETWORK, networkInterface.network()); + assertNull(networkInterface.networkIp()); + assertNull(networkInterface.subnetwork()); + networkInterface = NetworkInterface.of(NETWORK.network()); + assertNull(networkInterface.name()); + assertNull(networkInterface.network().project()); + assertEquals(NETWORK.network(), networkInterface.network().network()); + assertNull(networkInterface.networkIp()); + assertNull(networkInterface.subnetwork()); + } + + @Test + public void testAccessConfigToAndFromPb() { + AccessConfig accessConfig = AccessConfig.fromPb(ACCESS_CONFIG.toPb()); + compareAccessConfig(ACCESS_CONFIG, accessConfig); + accessConfig = AccessConfig.of(); + compareAccessConfig(accessConfig, AccessConfig.fromPb(accessConfig.toPb())); + } + + @Test + public void testToAndFromPb() { + NetworkInterface networkInterface = NetworkInterface.fromPb(NETWORK_INTERFACE.toPb()); + compareNetworkInterface(NETWORK_INTERFACE, networkInterface); + networkInterface = NetworkInterface.of(NETWORK); + compareNetworkInterface(networkInterface, NetworkInterface.fromPb(networkInterface.toPb())); + } + + @Test + public void testSetProjectId() { + NetworkInterface networkInterface = NetworkInterface.of(NETWORK); + compareNetworkInterface(networkInterface, + NetworkInterface.of(NetworkId.of("network")).setProjectId("project")); + networkInterface = NETWORK_INTERFACE.toBuilder() + .network(NetworkId.of("network")) + .subnetwork(SubnetworkId.of("region", "subnetwork")) + .build(); + compareNetworkInterface(NETWORK_INTERFACE, networkInterface.setProjectId("project")); + } + + public void compareAccessConfig(AccessConfig expected, AccessConfig value) { + assertEquals(expected, value); + assertEquals(expected.name(), value.name()); + assertEquals(expected.natIp(), value.natIp()); + assertEquals(expected.type(), value.type()); + assertEquals(expected.hashCode(), value.hashCode()); + } + + public void compareNetworkInterface(NetworkInterface expected, NetworkInterface value) { + assertEquals(expected, value); + assertEquals(expected.name(), value.name()); + assertEquals(expected.network(), value.network()); + assertEquals(expected.networkIp(), value.networkIp()); + assertEquals(expected.subnetwork(), value.subnetwork()); + assertEquals(expected.accessConfigurations(), value.accessConfigurations()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java index 2e5dbdca6ceb..7ab0ff597222 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java @@ -22,6 +22,7 @@ import com.google.common.collect.ImmutableList; import com.google.gcloud.AuthCredentials; import com.google.gcloud.RetryParams; +import com.google.gcloud.compute.NetworkInterface.AccessConfig; import org.junit.Test; @@ -171,6 +172,10 @@ public class SerializationTest { NetworkInfo.of(NETWORK_ID, STANDARD_NETWORK_CONFIGURATION); private static final Network NETWORK = new Network.Builder(COMPUTE, NETWORK_ID, STANDARD_NETWORK_CONFIGURATION).build(); + private static final AccessConfig ACCESS_CONFIG = AccessConfig.of("192.168.1.1"); + private static final NetworkInterface NETWORK_INTERFACE = NetworkInterface.builder(NETWORK_ID) + .accessConfigurations(ACCESS_CONFIG) + .build(); private static final Compute.DiskTypeOption DISK_TYPE_OPTION = Compute.DiskTypeOption.fields(); private static final Compute.DiskTypeFilter DISK_TYPE_FILTER = @@ -272,11 +277,11 @@ public void testModelAndRequests() throws Exception { STANDARD_DISK_CONFIGURATION, IMAGE_DISK_CONFIGURATION, SNAPSHOT_DISK_CONFIGURATION, DISK_INFO, DISK, SUBNETWORK_ID, NETWORK_ID, SUBNETWORK_INFO, SUBNETWORK, STANDARD_NETWORK_CONFIGURATION, SUBNET_NETWORK_CONFIGURATION, NETWORK_INFO, NETWORK, - DISK_TYPE_OPTION, DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, DISK_TYPE_AGGREGATED_LIST_OPTION, - MACHINE_TYPE_OPTION, MACHINE_TYPE_FILTER, MACHINE_TYPE_LIST_OPTION, - MACHINE_TYPE_AGGREGATED_LIST_OPTION, REGION_OPTION, REGION_FILTER, REGION_LIST_OPTION, - ZONE_OPTION, ZONE_FILTER, ZONE_LIST_OPTION, LICENSE_OPTION, OPERATION_OPTION, - OPERATION_FILTER, OPERATION_LIST_OPTION, ADDRESS_OPTION, ADDRESS_FILTER, + ACCESS_CONFIG, NETWORK_INTERFACE, DISK_TYPE_OPTION, DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, + DISK_TYPE_AGGREGATED_LIST_OPTION, MACHINE_TYPE_OPTION, MACHINE_TYPE_FILTER, + MACHINE_TYPE_LIST_OPTION, MACHINE_TYPE_AGGREGATED_LIST_OPTION, REGION_OPTION, REGION_FILTER, + REGION_LIST_OPTION, ZONE_OPTION, ZONE_FILTER, ZONE_LIST_OPTION, LICENSE_OPTION, + OPERATION_OPTION, OPERATION_FILTER, OPERATION_LIST_OPTION, ADDRESS_OPTION, ADDRESS_FILTER, ADDRESS_LIST_OPTION, ADDRESS_AGGREGATED_LIST_OPTION, SNAPSHOT_OPTION, SNAPSHOT_FILTER, SNAPSHOT_LIST_OPTION, IMAGE_OPTION, IMAGE_FILTER, IMAGE_LIST_OPTION, DISK_OPTION, DISK_FILTER, DISK_LIST_OPTION, DISK_AGGREGATED_LIST_OPTION, SUBNETWORK_OPTION, From 428fdbd890af9743fb0799228eb7763b11e88a3c Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 25 Apr 2016 07:32:00 +0200 Subject: [PATCH 320/375] Add AttachedDisk class, related configurations and tests (#917) * Add AttachedDisk class, related configurations and tests * Minor changes to AttachedDisk --- .../google/gcloud/compute/AttachedDisk.java | 926 ++++++++++++++++++ .../gcloud/compute/AttachedDiskTest.java | 392 ++++++++ .../gcloud/compute/SerializationTest.java | 31 +- 3 files changed, 1339 insertions(+), 10 deletions(-) create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/AttachedDisk.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/AttachedDiskTest.java diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AttachedDisk.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AttachedDisk.java new file mode 100644 index 000000000000..376b2738df39 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AttachedDisk.java @@ -0,0 +1,926 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.api.services.compute.model.AttachedDiskInitializeParams; +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; +import com.google.common.collect.Lists; + +import java.io.Serializable; +import java.util.List; +import java.util.Objects; + +/** + * A disk attached to a Google Compute Engine instance. To create a new disk to attach when an image + * is being created use {@link CreateDiskConfiguration}. To attach an existing persistent disk use + * {@link PersistentDiskConfiguration}. To attach a scratch disk use + * {@link ScratchDiskConfiguration}. + */ +public class AttachedDisk implements Serializable { + + static final Function + FROM_PB_FUNCTION = + new Function() { + @Override + public AttachedDisk apply( + com.google.api.services.compute.model.AttachedDisk pb) { + return AttachedDisk.fromPb(pb); + } + }; + static final Function + TO_PB_FUNCTION = + new Function() { + @Override + public com.google.api.services.compute.model.AttachedDisk apply( + AttachedDisk attachedDisk) { + return attachedDisk.toPb(); + } + }; + private static final long serialVersionUID = 2969789134157943798L; + + private final String deviceName; + private final Integer index; + private final AttachedDiskConfiguration configuration; + private final List licenses; + + /** + * Base class for {@code AttachedDisk} configuration. Use {@link PersistentDiskConfiguration} to + * attach an existing persistent disk. Use {@link CreateDiskConfiguration} to create a boot + * persistent disk to attach to the instance. Use {@link ScratchDiskConfiguration} to attach a + * scratch disk. + */ + public abstract static class AttachedDiskConfiguration implements Serializable { + + private static final long serialVersionUID = 8813134841283115565L; + + private final Type type; + private final InterfaceType interfaceType; + private final Boolean boot; + private final Boolean autoDelete; + + /** + * Specifies the type of the attached disk. + */ + public enum Type { + /** + * A persistent disk attached to a VM instance. Such an attached disk must already exist or + * can be created along with the instance by using {@link CreateDiskConfiguration}. A + * persistent disk can be attached to other VM instances. + */ + PERSISTENT, + + /** + * A scratch disk is created with the VM instance it is attached to. Scratch disks are only + * available to their VM instance. + */ + SCRATCH + } + + /** + * Specifies the disk interface to use for attaching this disk, which is either {@code SCSI} + * or {@code NVME}. Persistent disks must always use {@code SCSI}. Scratch SSDs can use either + * {@code NVME} or {@code SCSI}. + */ + public enum InterfaceType { + SCSI, + NVME + } + + AttachedDiskConfiguration(Type type, InterfaceType interfaceType, Boolean boot, + Boolean autoDelete) { + this.type = checkNotNull(type); + this.interfaceType = interfaceType; + this.boot = boot; + this.autoDelete = autoDelete; + } + + /** + * Returns the type of the attached disk. + */ + public Type type() { + return type; + } + + /** + * Returns the interface to use to attach the disk. If not specified, {@link InterfaceType#SCSI} + * is used. + */ + public InterfaceType interfaceType() { + return interfaceType; + } + + /** + * Returns whether to use the attached disk as a boot disk. If {@code true} the virtual machine + * will use the first partition of the disk for its root filesystem. If not specified, the + * disk is not used as a boot disk. + */ + public Boolean boot() { + return boot; + } + + /** + * Returns whether the disk should auto-delete when the instance to which it's attached is + * deleted. If not specified, the disk is not deleted automatically. + */ + public Boolean autoDelete() { + return autoDelete; + } + + MoreObjects.ToStringHelper toStringHelper() { + return MoreObjects.toStringHelper(this) + .add("type", type) + .add("interfaceType", interfaceType) + .add("boot", boot) + .add("autoDelete", autoDelete); + } + + @Override + public String toString() { + return toStringHelper().toString(); + } + + final int baseHashCode() { + return Objects.hash(type, interfaceType); + } + + final boolean baseEquals(AttachedDiskConfiguration diskConfiguration) { + return Objects.equals(toPb(), diskConfiguration.toPb()); + } + + abstract AttachedDiskConfiguration setProjectId(String projectId); + + com.google.api.services.compute.model.AttachedDisk toPb() { + com.google.api.services.compute.model.AttachedDisk attachedDiskPb = + new com.google.api.services.compute.model.AttachedDisk(); + attachedDiskPb.setType(type.name()); + if (interfaceType != null) { + attachedDiskPb.setInterface(interfaceType.name()); + } + attachedDiskPb.setBoot(boot); + attachedDiskPb.setAutoDelete(autoDelete); + return attachedDiskPb; + } + + @SuppressWarnings("unchecked") + static T fromPb( + com.google.api.services.compute.model.AttachedDisk diskPb) { + switch (Type.valueOf(diskPb.getType())) { + case PERSISTENT: + if (diskPb.getSource() == null) { + return (T) CreateDiskConfiguration.fromPb(diskPb); + } else { + return (T) PersistentDiskConfiguration.fromPb(diskPb); + } + case SCRATCH: + return (T) ScratchDiskConfiguration.fromPb(diskPb); + default: + // should be unreachable + throw new IllegalArgumentException("Unrecognized attached disk type"); + } + } + } + + /** + * An attached disk configuration for existing persistent disks. + */ + public static final class PersistentDiskConfiguration extends AttachedDiskConfiguration { + + private static final long serialVersionUID = 6367613188140104726L; + + private final DiskId sourceDisk; + private final Mode mode; + + /** + * Specifies the mode in which to attach the disk. + */ + public enum Mode { + /** + * The instance can both read and write to the disk. + */ + READ_WRITE, + + /** + * The instance is only allowed to read the disk. + */ + READ_ONLY + } + + /** + * A builder for {@code PersistentDiskConfiguration} objects. + */ + public static final class Builder { + + private DiskId sourceDisk; + private Mode mode; + private Boolean boot; + private Boolean autoDelete; + + private Builder(DiskId sourceDisk) { + this.sourceDisk = checkNotNull(sourceDisk); + } + + private Builder(PersistentDiskConfiguration configuration) { + sourceDisk = configuration.sourceDisk; + mode = configuration.mode; + boot = configuration.boot(); + autoDelete = configuration.autoDelete(); + } + + /** + * Sets the identity of the persistent disk to be attached. + */ + public Builder sourceDisk(DiskId sourceDisk) { + this.sourceDisk = checkNotNull(sourceDisk); + return this; + } + + /** + * Sets the mode in which to attach this disk. If not specified, the disk is attached in + * {@link Mode#READ_WRITE} mode. + */ + public Builder mode(Mode mode) { + this.mode = mode; + return this; + } + + /** + * Sets whether to use the attached disk as a boot disk. If {@code true} the virtual machine + * instance will use the first partition of the disk for its root filesystem. If not + * specified, the isk is not used as a boot disk. + */ + public Builder boot(boolean boot) { + this.boot = boot; + return this; + } + + /** + * Sets whether the disk should auto-delete when the instance to which it's attached is + * deleted. If not specified, the disk is not deleted automatically. + */ + public Builder autoDelete(boolean autoDelete) { + this.autoDelete = autoDelete; + return this; + } + + /** + * Creates a {@code PersistentDiskConfiguration} object. + */ + public PersistentDiskConfiguration build() { + return new PersistentDiskConfiguration(this); + } + } + + private PersistentDiskConfiguration(Builder builder) { + super(Type.PERSISTENT, null, builder.boot, builder.autoDelete); + this.sourceDisk = builder.sourceDisk; + this.mode = builder.mode; + } + + /** + * Returns the identity of the persistent disk to be attached. + */ + public DiskId sourceDisk() { + return sourceDisk; + } + + /** + * Returns the mode in which to attach this disk. If not specified, the disk is attached in + * {@link Mode#READ_WRITE} mode. + */ + public Mode mode() { + return mode; + } + + /** + * Returns a builder for the current configuration. + */ + public Builder toBuilder() { + return new Builder(this); + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper().add("sourceDisk", sourceDisk).add("mode", mode); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), sourceDisk, mode); + } + + @Override + public boolean equals(Object obj) { + return obj == this + || obj != null + && obj.getClass().equals(PersistentDiskConfiguration.class) + && baseEquals((PersistentDiskConfiguration) obj); + } + + @Override + PersistentDiskConfiguration setProjectId(String projectId) { + if (sourceDisk.project() != null) { + return this; + } + return toBuilder().sourceDisk(sourceDisk.setProjectId(projectId)).build(); + } + + @Override + com.google.api.services.compute.model.AttachedDisk toPb() { + com.google.api.services.compute.model.AttachedDisk attachedDiskPb = super.toPb(); + attachedDiskPb.setSource(sourceDisk.selfLink()); + attachedDiskPb.setMode(mode != null ? mode.toString() : null); + return attachedDiskPb; + } + + /** + * Returns a builder for a {@code PersistentDiskConfiguration} object given the identity of the + * persistent disk to attach. + */ + public static Builder builder(DiskId sourceDisk) { + return new Builder(sourceDisk); + } + + /** + * Returns a {@code PersistentDiskConfiguration} object given the identity of the persistent + * disk to attach. + */ + public static PersistentDiskConfiguration of(DiskId sourceDisk) { + return builder(sourceDisk).build(); + } + + @SuppressWarnings("unchecked") + static PersistentDiskConfiguration fromPb( + com.google.api.services.compute.model.AttachedDisk diskPb) { + Builder builder = new Builder(DiskId.fromUrl(diskPb.getSource())); + if (diskPb.getMode() != null) { + builder.mode(Mode.valueOf(diskPb.getMode())); + } + if (diskPb.getBoot() != null) { + builder.boot(diskPb.getBoot()); + } + if (diskPb.getAutoDelete() != null) { + builder.autoDelete(diskPb.getAutoDelete()); + } + return builder.build(); + } + } + + /** + * An attached disk configuration for bootable persistent disks that must be created with the + * instance they are attached to. Attached disks that use this configuration can only be attached + * to an instance upon creation. A {@code CreateDiskConfiguration} object is never returned by the + * service: after the instance is created the corresponding attached disk will be returned with a + * {@link PersistentDiskConfiguration}. + */ + public static final class CreateDiskConfiguration extends AttachedDiskConfiguration { + + private static final long serialVersionUID = 961995522284348824L; + + private final String diskName; + private final DiskTypeId diskType; + private final Long diskSizeGb; + private final ImageId sourceImage; + + /** + * A builder for {@code CreateDiskConfiguration} objects. + */ + public static final class Builder { + + private String diskName; + private DiskTypeId diskType; + private Long diskSizeGb; + private ImageId sourceImage; + private Boolean autoDelete; + + private Builder(ImageId sourceImage) { + this.sourceImage = checkNotNull(sourceImage); + } + + private Builder(CreateDiskConfiguration configuration) { + this.diskName = configuration.diskName; + this.diskType = configuration.diskType; + this.diskSizeGb = configuration.diskSizeGb; + this.sourceImage = configuration.sourceImage; + this.autoDelete = configuration.autoDelete(); + } + + /** + * Sets the name to be assigned to the disk. If not specified, the disk is given the + * instance's name. + */ + public Builder diskName(String diskName) { + this.diskName = diskName; + return this; + } + + /** + * Sets the identity of the disk type. If not specified, {@code pd-standard} is used. + */ + public Builder diskType(DiskTypeId diskType) { + this.diskType = diskType; + return this; + } + + /** + * Sets the size of the persistent disk, in GB. If not set the disk will have the size of the + * source image. This value can be larger than the image's size. If the provided size is + * smaller than the image's size, then instance creation will fail. + */ + public Builder diskSizeGb(Long diskSizeGb) { + this.diskSizeGb = diskSizeGb; + return this; + } + + /** + * Sets the identity of the source image used to create the disk. + */ + public Builder sourceImage(ImageId sourceImage) { + this.sourceImage = checkNotNull(sourceImage); + return this; + } + + /** + * Sets whether the disk should auto-delete when the instance to which it's attached is + * deleted. If not specified, the disk is not deleted automatically. + */ + public Builder autoDelete(Boolean autoDelete) { + this.autoDelete = autoDelete; + return this; + } + + /** + * Creates a {@code CreateDiskConfiguration} object. + */ + public CreateDiskConfiguration build() { + return new CreateDiskConfiguration(this); + } + } + + private CreateDiskConfiguration(Builder builder) { + super(Type.PERSISTENT, null, true, builder.autoDelete); + this.diskName = builder.diskName; + this.diskType = builder.diskType; + this.diskSizeGb = builder.diskSizeGb; + this.sourceImage = builder.sourceImage; + } + + /** + * Returns the name to be assigned to the disk. If not specified, the disk is given the + * instance's name. + */ + public String diskName() { + return diskName; + } + + /** + * Returns the identity of the disk type. If not specified, {@code pd-standard} is used. + */ + public DiskTypeId diskType() { + return diskType; + } + + /** + * Returns the size of the persistent disk, in GB. If not set the disk will have the size of the + * source image. This value can be larger than the image's size. If the provided size is smaller + * than the image's size then instance creation will fail. + */ + public Long diskSizeGb() { + return diskSizeGb; + } + + /** + * Returns the identity of the source image used to create the disk. + */ + public ImageId sourceImage() { + return sourceImage; + } + + /** + * Returns a builder for the current configuration. + */ + public Builder toBuilder() { + return new Builder(this); + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper() + .add("diskName", diskName) + .add("diskType", diskType) + .add("diskSizeGb", diskSizeGb) + .add("sourceImage", sourceImage); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), diskName, diskType, diskSizeGb, sourceImage); + } + + @Override + public boolean equals(Object obj) { + return obj == this + || obj != null + && obj.getClass().equals(CreateDiskConfiguration.class) + && baseEquals((CreateDiskConfiguration) obj); + } + + @Override + CreateDiskConfiguration setProjectId(String projectId) { + Builder builder = toBuilder(); + if (builder.diskType != null) { + builder.diskType(diskType.setProjectId(projectId)); + } + if (builder.sourceImage != null) { + builder.sourceImage(sourceImage.setProjectId(projectId)); + } + return builder.build(); + } + + @Override + com.google.api.services.compute.model.AttachedDisk toPb() { + AttachedDiskInitializeParams initializeParamsPb = new AttachedDiskInitializeParams(); + initializeParamsPb.setDiskName(diskName); + initializeParamsPb.setDiskSizeGb(diskSizeGb); + initializeParamsPb.setSourceImage(sourceImage.selfLink()); + if (diskType != null) { + initializeParamsPb.setDiskType(diskType.selfLink()); + } + com.google.api.services.compute.model.AttachedDisk attachedDiskPb = super.toPb(); + attachedDiskPb.setInitializeParams(initializeParamsPb); + return attachedDiskPb; + } + + /** + * Returns a builder for a {@code CreateDiskConfiguration} object given the source image that + * will be used to create the disk. + */ + public static Builder builder(ImageId sourceImage) { + return new Builder(sourceImage); + } + + /** + * Returns a {@code CreateDiskConfiguration} object given the source image that will be used to + * create the disk. + */ + public static CreateDiskConfiguration of(ImageId sourceImage) { + return builder(sourceImage).build(); + } + + @SuppressWarnings("unchecked") + static CreateDiskConfiguration fromPb( + com.google.api.services.compute.model.AttachedDisk diskPb) { + AttachedDiskInitializeParams initializeParamsPb = diskPb.getInitializeParams(); + Builder builder = builder(ImageId.fromUrl(initializeParamsPb.getSourceImage())); + if (initializeParamsPb.getDiskType() != null) { + builder.diskType(DiskTypeId.fromUrl(initializeParamsPb.getDiskType())); + } + builder.diskName(initializeParamsPb.getDiskName()); + builder.diskSizeGb(initializeParamsPb.getDiskSizeGb()); + builder.autoDelete(diskPb.getAutoDelete()); + if (initializeParamsPb.getDiskType() != null) { + builder.diskType(DiskTypeId.fromUrl(initializeParamsPb.getDiskType())); + } + return builder.build(); + } + } + + /** + * An attached disk configuration for scratch disks. Attached disks that use this configuration + * can only be attached to an instance upon creation. + */ + public static final class ScratchDiskConfiguration extends AttachedDiskConfiguration { + + private static final long serialVersionUID = -8445453507234691254L; + + private final DiskTypeId diskType; + + /** + * A builder for {@code ScratchDiskConfiguration} objects. + */ + public static final class Builder { + + private DiskTypeId diskType; + private InterfaceType interfaceType; + + private Builder() {} + + private Builder(ScratchDiskConfiguration configuration) { + this.diskType = configuration.diskType; + this.interfaceType = configuration.interfaceType(); + } + + /** + * Sets the identity of the disk type for the scratch disk to attach. + */ + public Builder diskType(DiskTypeId diskType) { + this.diskType = diskType; + return this; + } + + /** + * Sets the interface type. If not specified, {@code SCSI} is used. + */ + public Builder interfaceType(InterfaceType interfaceType) { + this.interfaceType = interfaceType; + return this; + } + + /** + * Creates a {@code ScratchDiskConfiguration} object. + */ + public ScratchDiskConfiguration build() { + return new ScratchDiskConfiguration(this); + } + } + + private ScratchDiskConfiguration(Builder builder) { + super(Type.SCRATCH, builder.interfaceType, false, true); + this.diskType = builder.diskType; + } + + /** + * Returns the identity of the disk type for the scratch disk to attach. + */ + public DiskTypeId diskType() { + return diskType; + } + + /** + * Returns a builder for the current configuration. + */ + public Builder toBuilder() { + return new Builder(this); + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return super.toStringHelper().add("diskType", diskType); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode()); + } + + @Override + public boolean equals(Object obj) { + return obj == this + || obj != null + && obj.getClass().equals(ScratchDiskConfiguration.class) + && baseEquals((ScratchDiskConfiguration) obj); + } + + @Override + ScratchDiskConfiguration setProjectId(String projectId) { + if (diskType.project() != null) { + return this; + } + return toBuilder().diskType(diskType.setProjectId(projectId)).build(); + } + + @Override + com.google.api.services.compute.model.AttachedDisk toPb() { + com.google.api.services.compute.model.AttachedDisk attachedDiskPb = super.toPb(); + if (diskType != null) { + AttachedDiskInitializeParams initializeParamsPb = new AttachedDiskInitializeParams(); + initializeParamsPb.setDiskType(diskType.selfLink()); + attachedDiskPb.setInitializeParams(initializeParamsPb); + } + return attachedDiskPb; + } + + /** + * Returns a builder for {@code ScratchDiskConfiguration} objects given the disk type identity. + */ + public static Builder builder(DiskTypeId diskType) { + return new Builder().diskType(diskType); + } + + /** + * Returns a {@code ScratchDiskConfiguration} object given the disk type identity. The disk will + * be attached via the default interface ({@link InterfaceType#SCSI}). + */ + public static ScratchDiskConfiguration of(DiskTypeId diskType) { + return builder(diskType).build(); + } + + @SuppressWarnings("unchecked") + static ScratchDiskConfiguration fromPb( + com.google.api.services.compute.model.AttachedDisk diskPb) { + Builder builder = new Builder(); + if (diskPb.getInterface() != null) { + builder.interfaceType(InterfaceType.valueOf(diskPb.getInterface())); + } + if (diskPb.getInitializeParams() != null + && diskPb.getInitializeParams().getDiskType() != null) { + builder.diskType(DiskTypeId.fromUrl(diskPb.getInitializeParams().getDiskType())); + } + return builder.build(); + } + } + + /** + * A builder for {@code AttachedDisk} objects. + */ + public static final class Builder { + + private String deviceName; + private Integer index; + private AttachedDiskConfiguration configuration; + private List licenses; + + Builder(AttachedDiskConfiguration configuration) { + this.configuration = checkNotNull(configuration); + } + + Builder(AttachedDisk attachedDisk) { + this.deviceName = attachedDisk.deviceName; + this.index = attachedDisk.index; + this.configuration = attachedDisk.configuration; + this.licenses = attachedDisk.licenses; + } + + /** + * Sets the unique device name of your choice that is reflected into the + * {@code /dev/disk/by-id/google-*} tree of a Linux operating system running within the + * instance. This name can be used to reference the device for mounting, resizing, and so on, + * from within the instance. If not specified, the service chooses a default device name to + * apply to this disk, in the form {@code persistent-disks-x}, where x is a number assigned by + * Google Compute Engine. + */ + public Builder deviceName(String deviceName) { + this.deviceName = deviceName; + return this; + } + + /** + * Sets a zero-based index to this disk, where 0 is reserved for the boot disk. For example, + * if you have many disks attached to an instance, each disk would have an unique index number. + * If not specified, the service will choose an appropriate value. + */ + public Builder index(Integer index) { + this.index = index; + return this; + } + + /** + * Sets the attached disk configuration. Use {@link ScratchDiskConfiguration} to attach a + * scratch disk to the instance. Use {@link PersistentDiskConfiguration} to attach a + * persistent disk to the instance. Use {@link CreateDiskConfiguration} to create and attach + * a new persistent disk. + */ + public Builder configuration(AttachedDiskConfiguration configuration) { + this.configuration = checkNotNull(configuration); + return this; + } + + Builder licenses(List licenses) { + this.licenses = licenses; + return this; + } + + /** + * Creates an {@code AttachedDisk} object. + */ + public AttachedDisk build() { + return new AttachedDisk(this); + } + } + + private AttachedDisk(Builder builder) { + this.deviceName = builder.deviceName; + this.index = builder.index; + this.configuration = builder.configuration; + this.licenses = builder.licenses; + } + + /** + * Returns the unique device name of your choice that is reflected into the + * {@code /dev/disk/by-id/google-*} tree of a Linux operating system running within the + * instance. This name can be used to reference the device for mounting, resizing, and so on, + * from within the instance. If not specified, the service chooses a default device name to + * apply to this disk, in the form {@code persistent-disks-x}, where x is a number assigned by + * Google Compute Engine. + */ + public String deviceName() { + return deviceName; + } + + /** + * Returns a zero-based index to this disk, where 0 is reserved for the boot disk. + */ + public Integer index() { + return index; + } + + /** + * Returns the attached disk configuration. Returns {@link ScratchDiskConfiguration} to attach a + * scratch disk to the instance. Returns {@link PersistentDiskConfiguration} to attach a + * persistent disk to the instance. Returns {@link CreateDiskConfiguration} to create and attach + * a new persistent disk. + */ + @SuppressWarnings("unchecked") + public T configuration() { + return (T) configuration; + } + + /** + * Returns a list of publicly accessible licenses for the attached disk. + */ + public List licenses() { + return licenses; + } + + /** + * Returns a builder for the current attached disk. + */ + public Builder toBuilder() { + return new Builder(this); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("deviceName", deviceName) + .add("index", index) + .add("configuration", configuration) + .add("licenses", licenses) + .toString(); + } + + @Override + public final int hashCode() { + return Objects.hash(deviceName, index, configuration, licenses); + } + + @Override + public final boolean equals(Object obj) { + return obj == this + || obj != null + && obj.getClass().equals(AttachedDisk.class) + && Objects.equals(toPb(), ((AttachedDisk) obj).toPb()); + } + + AttachedDisk setProjectId(String projectId) { + return toBuilder().configuration(configuration.setProjectId(projectId)).build(); + } + + com.google.api.services.compute.model.AttachedDisk toPb() { + com.google.api.services.compute.model.AttachedDisk attachedDiskPb = configuration.toPb(); + attachedDiskPb.setDeviceName(deviceName); + attachedDiskPb.setIndex(index); + if (licenses != null) { + attachedDiskPb.setLicenses(Lists.transform(licenses, LicenseId.TO_URL_FUNCTION)); + } + return attachedDiskPb; + } + + /** + * Returns a builder for an {@code AttachedDisk} object given its configuration. + */ + public static Builder builder(AttachedDiskConfiguration configuration) { + return new Builder(configuration).configuration(configuration); + } + + /** + * Returns an {@code AttachedDisk} object given its configuration. + */ + public static AttachedDisk of(AttachedDiskConfiguration configuration) { + return builder(configuration).build(); + } + + /** + * Returns an {@code AttachedDisk} object given the device name and its configuration. + */ + public static AttachedDisk of(String deviceName, AttachedDiskConfiguration configuration) { + return builder(configuration).deviceName(deviceName).build(); + } + + static AttachedDisk fromPb(com.google.api.services.compute.model.AttachedDisk diskPb) { + AttachedDiskConfiguration configuration = AttachedDiskConfiguration.fromPb(diskPb); + Builder builder = builder(configuration); + builder.deviceName(diskPb.getDeviceName()); + builder.index(diskPb.getIndex()); + if (diskPb.getLicenses() != null) { + builder.licenses(Lists.transform(diskPb.getLicenses(), LicenseId.FROM_URL_FUNCTION)); + } + return builder.build(); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AttachedDiskTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AttachedDiskTest.java new file mode 100644 index 000000000000..4a9cfbfdc7a9 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AttachedDiskTest.java @@ -0,0 +1,392 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import com.google.common.collect.ImmutableList; +import com.google.gcloud.compute.AttachedDisk.AttachedDiskConfiguration.InterfaceType; +import com.google.gcloud.compute.AttachedDisk.AttachedDiskConfiguration.Type; +import com.google.gcloud.compute.AttachedDisk.CreateDiskConfiguration; +import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; +import com.google.gcloud.compute.AttachedDisk.ScratchDiskConfiguration; + +import org.junit.Test; + +import java.util.List; + +public class AttachedDiskTest { + + private static final Boolean AUTO_DELETE = true; + private static final Boolean BOOT = true; + private static final Integer INDEX = 0; + private static final String DEVICE_NAME = "deviceName"; + private static final String DISK_NAME = "diskName"; + private static final DiskTypeId DISK_TYPE_ID = DiskTypeId.of("project", "zone", "diskType"); + private static final Long DISK_SIZE_GB = 42L; + private static final DiskId DISK_ID = DiskId.of("project", "zone", "disk"); + private static final ImageId IMAGE_ID = ImageId.of("project", "image"); + private static final InterfaceType INTERFACE_TYPE = InterfaceType.NVME; + private static final PersistentDiskConfiguration.Mode MODE = + PersistentDiskConfiguration.Mode.READ_ONLY; + private static final PersistentDiskConfiguration PERSISTENT_DISK_CONFIGURATION = + PersistentDiskConfiguration.builder(DISK_ID) + .boot(BOOT) + .autoDelete(AUTO_DELETE) + .mode(MODE) + .build(); + private static final ScratchDiskConfiguration SCRATCH_DISK_CONFIGURATION = + ScratchDiskConfiguration.builder(DISK_TYPE_ID).interfaceType(INTERFACE_TYPE).build(); + private static final CreateDiskConfiguration CREATE_DISK_CONFIGURATION = + CreateDiskConfiguration.builder(IMAGE_ID) + .autoDelete(AUTO_DELETE) + .diskName(DISK_NAME) + .diskType(DISK_TYPE_ID) + .diskSizeGb(DISK_SIZE_GB) + .sourceImage(IMAGE_ID) + .build(); + private static final List LICENSES = ImmutableList.of( + LicenseId.of("project", "license1"), LicenseId.of("project", "license2")); + private static final AttachedDisk PERSISTENT_DISK = + AttachedDisk.builder(PERSISTENT_DISK_CONFIGURATION) + .deviceName(DEVICE_NAME) + .index(INDEX) + .licenses(LICENSES) + .build(); + private static final AttachedDisk SCRATCH_DISK = + AttachedDisk.builder(SCRATCH_DISK_CONFIGURATION) + .deviceName(DEVICE_NAME) + .index(INDEX) + .licenses(LICENSES) + .build(); + private static final AttachedDisk CREATED_DISK = + AttachedDisk.builder(CREATE_DISK_CONFIGURATION) + .deviceName(DEVICE_NAME) + .index(INDEX) + .licenses(LICENSES) + .build(); + + @Test + public void testConfigurationToBuilder() { + comparePersistentDiskConfiguration(PERSISTENT_DISK_CONFIGURATION, + PERSISTENT_DISK_CONFIGURATION.toBuilder().build()); + compareScratchDiskConfiguration(SCRATCH_DISK_CONFIGURATION, + SCRATCH_DISK_CONFIGURATION.toBuilder().build()); + compareCreateDiskConfiguration(CREATE_DISK_CONFIGURATION, + CREATE_DISK_CONFIGURATION.toBuilder().build()); + PersistentDiskConfiguration persistentDiskConfiguration = + PERSISTENT_DISK_CONFIGURATION.toBuilder().autoDelete(false).build(); + assertFalse(persistentDiskConfiguration.autoDelete()); + persistentDiskConfiguration = + persistentDiskConfiguration.toBuilder().autoDelete(AUTO_DELETE).build(); + assertEquals(PERSISTENT_DISK_CONFIGURATION, persistentDiskConfiguration); + ScratchDiskConfiguration scratchDiskConfiguration = + SCRATCH_DISK_CONFIGURATION.toBuilder().interfaceType(InterfaceType.SCSI).build(); + assertEquals(InterfaceType.SCSI, scratchDiskConfiguration.interfaceType()); + scratchDiskConfiguration = + scratchDiskConfiguration.toBuilder().interfaceType(INTERFACE_TYPE).build(); + assertEquals(SCRATCH_DISK_CONFIGURATION, scratchDiskConfiguration); + CreateDiskConfiguration createDiskConfiguration = + CREATE_DISK_CONFIGURATION.toBuilder().autoDelete(false).build(); + assertFalse(createDiskConfiguration.autoDelete()); + createDiskConfiguration = createDiskConfiguration.toBuilder().autoDelete(AUTO_DELETE).build(); + assertEquals(CREATE_DISK_CONFIGURATION, createDiskConfiguration); + } + + @Test + public void testConfigurationToBuilderIncomplete() { + PersistentDiskConfiguration persistentConfiguration = PersistentDiskConfiguration.of(DISK_ID); + comparePersistentDiskConfiguration(persistentConfiguration, + AttachedDisk.AttachedDiskConfiguration.fromPb( + persistentConfiguration.toPb())); + ScratchDiskConfiguration scratchDiskConfiguration = ScratchDiskConfiguration.of(DISK_TYPE_ID); + compareScratchDiskConfiguration(scratchDiskConfiguration, + AttachedDisk.AttachedDiskConfiguration.fromPb( + scratchDiskConfiguration.toPb())); + CreateDiskConfiguration createDiskConfiguration = CreateDiskConfiguration.of(IMAGE_ID); + compareCreateDiskConfiguration(createDiskConfiguration, + AttachedDisk.AttachedDiskConfiguration.fromPb( + createDiskConfiguration.toPb())); + } + + @Test + public void testToBuilder() { + compareAttachedDisk(PERSISTENT_DISK, PERSISTENT_DISK.toBuilder().build()); + compareAttachedDisk(SCRATCH_DISK, SCRATCH_DISK.toBuilder().build()); + compareAttachedDisk(CREATED_DISK, CREATED_DISK.toBuilder().build()); + AttachedDisk attachedDisk = PERSISTENT_DISK.toBuilder().deviceName("newDeviceName").build(); + assertEquals("newDeviceName", attachedDisk.deviceName()); + attachedDisk = attachedDisk.toBuilder().deviceName(DEVICE_NAME).build(); + compareAttachedDisk(PERSISTENT_DISK, attachedDisk); + } + + @Test + public void testToBuilderIncomplete() { + AttachedDisk attachedDisk = AttachedDisk.of(PERSISTENT_DISK_CONFIGURATION); + assertEquals(attachedDisk, attachedDisk.toBuilder().build()); + attachedDisk = AttachedDisk.of(SCRATCH_DISK_CONFIGURATION); + assertEquals(attachedDisk, attachedDisk.toBuilder().build()); + attachedDisk = AttachedDisk.of(CREATE_DISK_CONFIGURATION); + assertEquals(attachedDisk, attachedDisk.toBuilder().build()); + } + + @Test + public void testConfigurationBuilder() { + assertTrue(CREATE_DISK_CONFIGURATION.boot()); + assertEquals(AUTO_DELETE, CREATE_DISK_CONFIGURATION.autoDelete()); + assertNull(CREATE_DISK_CONFIGURATION.interfaceType()); + assertEquals(Type.PERSISTENT, CREATE_DISK_CONFIGURATION.type()); + assertEquals(IMAGE_ID, CREATE_DISK_CONFIGURATION.sourceImage()); + assertEquals(DISK_NAME, CREATE_DISK_CONFIGURATION.diskName()); + assertEquals(DISK_TYPE_ID, CREATE_DISK_CONFIGURATION.diskType()); + assertEquals(DISK_SIZE_GB, CREATE_DISK_CONFIGURATION.diskSizeGb()); + assertEquals(IMAGE_ID, CREATE_DISK_CONFIGURATION.sourceImage()); + + assertEquals(BOOT, PERSISTENT_DISK_CONFIGURATION.boot()); + assertEquals(AUTO_DELETE, PERSISTENT_DISK_CONFIGURATION.autoDelete()); + assertNull(PERSISTENT_DISK_CONFIGURATION.interfaceType()); + assertEquals(Type.PERSISTENT, PERSISTENT_DISK_CONFIGURATION.type()); + assertEquals(MODE, PERSISTENT_DISK_CONFIGURATION.mode()); + assertEquals(DISK_ID, PERSISTENT_DISK_CONFIGURATION.sourceDisk()); + + assertFalse(SCRATCH_DISK_CONFIGURATION.boot()); + assertTrue(SCRATCH_DISK_CONFIGURATION.autoDelete()); + assertEquals(INTERFACE_TYPE, SCRATCH_DISK_CONFIGURATION.interfaceType()); + assertEquals(Type.SCRATCH, SCRATCH_DISK_CONFIGURATION.type()); + assertEquals(DISK_TYPE_ID, SCRATCH_DISK_CONFIGURATION.diskType()); + } + + @Test + public void testBuilder() { + assertEquals(PERSISTENT_DISK_CONFIGURATION, PERSISTENT_DISK.configuration()); + assertEquals(DEVICE_NAME, PERSISTENT_DISK.deviceName()); + assertEquals(INDEX, PERSISTENT_DISK.index()); + assertEquals(LICENSES, PERSISTENT_DISK.licenses()); + assertEquals(SCRATCH_DISK_CONFIGURATION, SCRATCH_DISK.configuration()); + assertEquals(DEVICE_NAME, SCRATCH_DISK.deviceName()); + assertEquals(INDEX, SCRATCH_DISK.index()); + assertEquals(LICENSES, SCRATCH_DISK.licenses()); + assertEquals(CREATE_DISK_CONFIGURATION, CREATED_DISK.configuration()); + assertEquals(DEVICE_NAME, CREATED_DISK.deviceName()); + assertEquals(INDEX, CREATED_DISK.index()); + assertEquals(LICENSES, CREATED_DISK.licenses()); + } + + @Test + public void testConfigurationOf() { + PersistentDiskConfiguration persistentConfiguration = PersistentDiskConfiguration.of(DISK_ID); + assertEquals(DISK_ID, persistentConfiguration.sourceDisk()); + assertEquals(Type.PERSISTENT, persistentConfiguration.type()); + assertNull(persistentConfiguration.autoDelete()); + assertNull(persistentConfiguration.boot()); + assertNull(persistentConfiguration.interfaceType()); + ScratchDiskConfiguration scratchDiskConfiguration = ScratchDiskConfiguration.of(DISK_TYPE_ID); + assertEquals(DISK_TYPE_ID, scratchDiskConfiguration.diskType()); + assertNull(scratchDiskConfiguration.interfaceType()); + assertEquals(Type.SCRATCH, scratchDiskConfiguration.type()); + assertTrue(scratchDiskConfiguration.autoDelete()); + assertFalse(scratchDiskConfiguration.boot()); + assertNull(scratchDiskConfiguration.interfaceType()); + CreateDiskConfiguration createDiskConfiguration = CreateDiskConfiguration.of(IMAGE_ID); + assertEquals(IMAGE_ID, createDiskConfiguration.sourceImage()); + assertNull(createDiskConfiguration.diskType()); + assertNull(createDiskConfiguration.diskName()); + assertNull(createDiskConfiguration.diskSizeGb()); + assertNull(createDiskConfiguration.interfaceType()); + assertEquals(Type.PERSISTENT, createDiskConfiguration.type()); + assertNull(createDiskConfiguration.autoDelete()); + assertTrue(createDiskConfiguration.boot()); + assertNull(createDiskConfiguration.interfaceType()); + } + + @Test + public void testOf() { + AttachedDisk attachedDisk = AttachedDisk.of(DEVICE_NAME, PERSISTENT_DISK_CONFIGURATION); + assertEquals(PERSISTENT_DISK_CONFIGURATION, attachedDisk.configuration()); + assertEquals(DEVICE_NAME, attachedDisk.deviceName()); + assertNull(attachedDisk.index()); + assertNull(attachedDisk.licenses()); + attachedDisk = AttachedDisk.of(PERSISTENT_DISK_CONFIGURATION); + assertEquals(PERSISTENT_DISK_CONFIGURATION, attachedDisk.configuration()); + assertNull(attachedDisk.deviceName()); + assertNull(attachedDisk.index()); + assertNull(attachedDisk.licenses()); + attachedDisk = AttachedDisk.of(DEVICE_NAME, SCRATCH_DISK_CONFIGURATION); + assertEquals(SCRATCH_DISK_CONFIGURATION, attachedDisk.configuration()); + assertEquals(DEVICE_NAME, attachedDisk.deviceName()); + assertNull(attachedDisk.index()); + assertNull(attachedDisk.licenses()); + attachedDisk = AttachedDisk.of(SCRATCH_DISK_CONFIGURATION); + assertEquals(SCRATCH_DISK_CONFIGURATION, attachedDisk.configuration()); + assertNull(attachedDisk.deviceName()); + assertNull(attachedDisk.index()); + assertNull(attachedDisk.licenses()); + attachedDisk = AttachedDisk.of(DEVICE_NAME, CREATE_DISK_CONFIGURATION); + assertEquals(CREATE_DISK_CONFIGURATION, attachedDisk.configuration()); + assertEquals(DEVICE_NAME, attachedDisk.deviceName()); + assertNull(attachedDisk.index()); + assertNull(attachedDisk.licenses()); + attachedDisk = AttachedDisk.of(CREATE_DISK_CONFIGURATION); + assertEquals(CREATE_DISK_CONFIGURATION, attachedDisk.configuration()); + assertNull(attachedDisk.deviceName()); + assertNull(attachedDisk.index()); + assertNull(attachedDisk.licenses()); + } + + @Test + public void testConfigurationToAndFromPb() { + PersistentDiskConfiguration persistentConfiguration = + PersistentDiskConfiguration.of(DISK_ID); + comparePersistentDiskConfiguration(persistentConfiguration, + AttachedDisk.AttachedDiskConfiguration.fromPb( + persistentConfiguration.toPb())); + comparePersistentDiskConfiguration(PERSISTENT_DISK_CONFIGURATION, + AttachedDisk.AttachedDiskConfiguration.fromPb( + PERSISTENT_DISK_CONFIGURATION.toPb())); + ScratchDiskConfiguration scratchDiskConfiguration = + ScratchDiskConfiguration.of(DISK_TYPE_ID); + compareScratchDiskConfiguration(scratchDiskConfiguration, + AttachedDisk.AttachedDiskConfiguration.fromPb( + scratchDiskConfiguration.toPb())); + compareScratchDiskConfiguration(SCRATCH_DISK_CONFIGURATION, + AttachedDisk.AttachedDiskConfiguration.fromPb( + SCRATCH_DISK_CONFIGURATION.toPb())); + CreateDiskConfiguration createDiskConfiguration = + CreateDiskConfiguration.of(IMAGE_ID); + compareCreateDiskConfiguration(createDiskConfiguration, + AttachedDisk.AttachedDiskConfiguration.fromPb( + createDiskConfiguration.toPb())); + compareCreateDiskConfiguration(CREATE_DISK_CONFIGURATION, + AttachedDisk.AttachedDiskConfiguration.fromPb( + CREATE_DISK_CONFIGURATION.toPb())); + } + + @Test + public void testToAndFromPb() { + AttachedDisk attachedDisk = AttachedDisk.fromPb(PERSISTENT_DISK.toPb()); + compareAttachedDisk(PERSISTENT_DISK, attachedDisk); + attachedDisk = AttachedDisk.fromPb(SCRATCH_DISK.toPb()); + compareAttachedDisk(SCRATCH_DISK, attachedDisk); + attachedDisk = AttachedDisk.fromPb(CREATED_DISK.toPb()); + compareAttachedDisk(CREATED_DISK, attachedDisk); + attachedDisk = AttachedDisk.of(DEVICE_NAME, PERSISTENT_DISK_CONFIGURATION); + compareAttachedDisk(attachedDisk, AttachedDisk.fromPb(attachedDisk.toPb())); + attachedDisk = AttachedDisk.of(PERSISTENT_DISK_CONFIGURATION); + compareAttachedDisk(attachedDisk, AttachedDisk.fromPb(attachedDisk.toPb())); + attachedDisk = AttachedDisk.of(DEVICE_NAME, SCRATCH_DISK_CONFIGURATION); + compareAttachedDisk(attachedDisk, AttachedDisk.fromPb(attachedDisk.toPb())); + attachedDisk = AttachedDisk.of(SCRATCH_DISK_CONFIGURATION); + compareAttachedDisk(attachedDisk, AttachedDisk.fromPb(attachedDisk.toPb())); + attachedDisk = AttachedDisk.of(DEVICE_NAME, CREATE_DISK_CONFIGURATION); + compareAttachedDisk(attachedDisk, AttachedDisk.fromPb(attachedDisk.toPb())); + attachedDisk = AttachedDisk.of(CREATE_DISK_CONFIGURATION); + compareAttachedDisk(attachedDisk, AttachedDisk.fromPb(attachedDisk.toPb())); + } + + @Test + public void testConfigurationSetProjectId() { + PersistentDiskConfiguration persistentConfiguration = + PersistentDiskConfiguration.of(DiskId.of("zone", "disk")); + comparePersistentDiskConfiguration( + PersistentDiskConfiguration.of(DiskId.of("project", "zone", "disk")), + persistentConfiguration.setProjectId("project")); + ScratchDiskConfiguration scratchDiskConfiguration = + ScratchDiskConfiguration.of(DiskTypeId.of("zone", "diskType")); + compareScratchDiskConfiguration( + ScratchDiskConfiguration.of(DiskTypeId.of("project", "zone", "diskType")), + scratchDiskConfiguration.setProjectId("project")); + CreateDiskConfiguration createDiskConfiguration = CREATE_DISK_CONFIGURATION.toBuilder() + .diskType(DiskTypeId.of("zone", "diskType")) + .sourceImage(ImageId.of("image")) + .build(); + compareCreateDiskConfiguration(CREATE_DISK_CONFIGURATION, + createDiskConfiguration.setProjectId("project")); + } + + @Test + public void testSetProjectId() { + PersistentDiskConfiguration persistentConfiguration = + PersistentDiskConfiguration.of(DiskId.of("zone", "disk")); + PersistentDiskConfiguration persistentConfigurationWithProject = + PersistentDiskConfiguration.of(DiskId.of("project", "zone", "disk")); + AttachedDisk attachedDisk = AttachedDisk.of(persistentConfiguration); + compareAttachedDisk(AttachedDisk.of(persistentConfigurationWithProject), + attachedDisk.setProjectId("project")); + ScratchDiskConfiguration scratchDiskConfiguration = + ScratchDiskConfiguration.of(DiskTypeId.of("zone", "diskType")); + ScratchDiskConfiguration scratchDiskConfigurationWithProject = + ScratchDiskConfiguration.of(DiskTypeId.of("project", "zone", "diskType")); + compareAttachedDisk(AttachedDisk.of(scratchDiskConfigurationWithProject), + AttachedDisk.of(scratchDiskConfiguration).setProjectId("project")); + CreateDiskConfiguration createDiskConfiguration = + CreateDiskConfiguration.of(ImageId.of("image")); + CreateDiskConfiguration createDiskConfigurationWithProject = + CreateDiskConfiguration.of(ImageId.of("project", "image")); + compareAttachedDisk(AttachedDisk.of(createDiskConfigurationWithProject), + AttachedDisk.of(createDiskConfiguration).setProjectId("project")); + createDiskConfiguration = CREATE_DISK_CONFIGURATION.toBuilder() + .diskType(DiskTypeId.of("zone", "diskType")) + .sourceImage(ImageId.of("image")) + .build(); + compareAttachedDisk(AttachedDisk.of(CREATE_DISK_CONFIGURATION), + AttachedDisk.of(createDiskConfiguration).setProjectId("project")); + } + + public void compareAttachedDiskConfiguration(AttachedDisk.AttachedDiskConfiguration expected, + AttachedDisk.AttachedDiskConfiguration value) { + assertEquals(expected, value); + assertEquals(expected.type(), value.type()); + assertEquals(expected.interfaceType(), value.interfaceType()); + assertEquals(expected.boot(), value.boot()); + assertEquals(expected.autoDelete(), value.autoDelete()); + assertEquals(expected.hashCode(), value.hashCode()); + } + + public void comparePersistentDiskConfiguration(PersistentDiskConfiguration expected, + PersistentDiskConfiguration value) { + compareAttachedDiskConfiguration(expected, value); + assertEquals(expected.mode(), value.mode()); + assertEquals(expected.sourceDisk(), value.sourceDisk()); + } + + public void compareCreateDiskConfiguration(CreateDiskConfiguration expected, + CreateDiskConfiguration value) { + compareAttachedDiskConfiguration(expected, value); + assertEquals(expected.diskName(), value.diskName()); + assertEquals(expected.diskType(), value.diskType()); + assertEquals(expected.diskSizeGb(), value.diskSizeGb()); + assertEquals(expected.sourceImage(), value.sourceImage()); + } + + public void compareScratchDiskConfiguration(ScratchDiskConfiguration expected, + ScratchDiskConfiguration value) { + compareAttachedDiskConfiguration(expected, value); + assertEquals(expected.diskType(), value.diskType()); + } + + public void compareAttachedDisk(AttachedDisk expected, AttachedDisk value) { + assertEquals(expected, value); + assertEquals(expected.deviceName(), value.deviceName()); + assertEquals(expected.index(), value.index()); + assertEquals(expected.configuration(), value.configuration()); + assertEquals(expected.licenses(), value.licenses()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java index 7ab0ff597222..73a572141b2a 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java @@ -22,6 +22,9 @@ import com.google.common.collect.ImmutableList; import com.google.gcloud.AuthCredentials; import com.google.gcloud.RetryParams; +import com.google.gcloud.compute.AttachedDisk.CreateDiskConfiguration; +import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; +import com.google.gcloud.compute.AttachedDisk.ScratchDiskConfiguration; import com.google.gcloud.compute.NetworkInterface.AccessConfig; import org.junit.Test; @@ -176,6 +179,13 @@ public class SerializationTest { private static final NetworkInterface NETWORK_INTERFACE = NetworkInterface.builder(NETWORK_ID) .accessConfigurations(ACCESS_CONFIG) .build(); + private static final CreateDiskConfiguration CREATE_DISK_CONFIGURATION = + CreateDiskConfiguration.of(IMAGE_ID); + private static final PersistentDiskConfiguration PERSISTENT_DISK_CONFIGURATION = + PersistentDiskConfiguration.of(DISK_ID); + private static final ScratchDiskConfiguration SCRATCH_DISK_CONFIGURATION = + ScratchDiskConfiguration.of(DISK_TYPE_ID); + private static final AttachedDisk ATTACHED_DISK = AttachedDisk.of(CREATE_DISK_CONFIGURATION); private static final Compute.DiskTypeOption DISK_TYPE_OPTION = Compute.DiskTypeOption.fields(); private static final Compute.DiskTypeFilter DISK_TYPE_FILTER = @@ -277,16 +287,17 @@ public void testModelAndRequests() throws Exception { STANDARD_DISK_CONFIGURATION, IMAGE_DISK_CONFIGURATION, SNAPSHOT_DISK_CONFIGURATION, DISK_INFO, DISK, SUBNETWORK_ID, NETWORK_ID, SUBNETWORK_INFO, SUBNETWORK, STANDARD_NETWORK_CONFIGURATION, SUBNET_NETWORK_CONFIGURATION, NETWORK_INFO, NETWORK, - ACCESS_CONFIG, NETWORK_INTERFACE, DISK_TYPE_OPTION, DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, - DISK_TYPE_AGGREGATED_LIST_OPTION, MACHINE_TYPE_OPTION, MACHINE_TYPE_FILTER, - MACHINE_TYPE_LIST_OPTION, MACHINE_TYPE_AGGREGATED_LIST_OPTION, REGION_OPTION, REGION_FILTER, - REGION_LIST_OPTION, ZONE_OPTION, ZONE_FILTER, ZONE_LIST_OPTION, LICENSE_OPTION, - OPERATION_OPTION, OPERATION_FILTER, OPERATION_LIST_OPTION, ADDRESS_OPTION, ADDRESS_FILTER, - ADDRESS_LIST_OPTION, ADDRESS_AGGREGATED_LIST_OPTION, SNAPSHOT_OPTION, SNAPSHOT_FILTER, - SNAPSHOT_LIST_OPTION, IMAGE_OPTION, IMAGE_FILTER, IMAGE_LIST_OPTION, DISK_OPTION, - DISK_FILTER, DISK_LIST_OPTION, DISK_AGGREGATED_LIST_OPTION, SUBNETWORK_OPTION, - SUBNETWORK_FILTER, SUBNETWORK_LIST_OPTION, SUBNETWORK_AGGREGATED_LIST_OPTION, - NETWORK_OPTION, NETWORK_FILTER, NETWORK_LIST_OPTION}; + ACCESS_CONFIG, NETWORK_INTERFACE, CREATE_DISK_CONFIGURATION, PERSISTENT_DISK_CONFIGURATION, + SCRATCH_DISK_CONFIGURATION, ATTACHED_DISK, DISK_TYPE_OPTION, DISK_TYPE_FILTER, + DISK_TYPE_LIST_OPTION, DISK_TYPE_AGGREGATED_LIST_OPTION, MACHINE_TYPE_OPTION, + MACHINE_TYPE_FILTER, MACHINE_TYPE_LIST_OPTION, MACHINE_TYPE_AGGREGATED_LIST_OPTION, + REGION_OPTION, REGION_FILTER, REGION_LIST_OPTION, ZONE_OPTION, ZONE_FILTER, + ZONE_LIST_OPTION, LICENSE_OPTION, OPERATION_OPTION, OPERATION_FILTER, OPERATION_LIST_OPTION, + ADDRESS_OPTION, ADDRESS_FILTER, ADDRESS_LIST_OPTION, ADDRESS_AGGREGATED_LIST_OPTION, + SNAPSHOT_OPTION, SNAPSHOT_FILTER, SNAPSHOT_LIST_OPTION, IMAGE_OPTION, IMAGE_FILTER, + IMAGE_LIST_OPTION, DISK_OPTION, DISK_FILTER, DISK_LIST_OPTION, DISK_AGGREGATED_LIST_OPTION, + SUBNETWORK_OPTION, SUBNETWORK_FILTER, SUBNETWORK_LIST_OPTION, + SUBNETWORK_AGGREGATED_LIST_OPTION, NETWORK_OPTION, NETWORK_FILTER, NETWORK_LIST_OPTION}; for (Serializable obj : objects) { Object copy = serializeAndDeserialize(obj); assertEquals(obj, obj); From 20032e73faf9cf0e78f1b855e863b1dd4ad511d6 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 26 Apr 2016 15:13:32 +0200 Subject: [PATCH 321/375] Add InstanceInfo, related classes and tests (#955) * Add InstanceInfo, related classes and tests * Move InstanceInfo inner classes outside --- .../com/google/gcloud/compute/Compute.java | 2 +- .../google/gcloud/compute/InstanceInfo.java | 674 ++++++++++++++++++ .../com/google/gcloud/compute/Metadata.java | 212 ++++++ .../google/gcloud/compute/NetworkInfo.java | 3 + .../gcloud/compute/NetworkInterface.java | 2 +- .../gcloud/compute/SchedulingOptions.java | 150 ++++ .../google/gcloud/compute/ServiceAccount.java | 123 ++++ .../java/com/google/gcloud/compute/Tags.java | 227 ++++++ .../gcloud/compute/InstanceInfoTest.java | 184 +++++ .../google/gcloud/compute/MetadataTest.java | 81 +++ .../gcloud/compute/SchedulingOptionsTest.java | 57 ++ .../gcloud/compute/SerializationTest.java | 10 +- .../gcloud/compute/ServiceAccountTest.java | 47 ++ .../com/google/gcloud/compute/TagsTest.java | 69 ++ 14 files changed, 1838 insertions(+), 3 deletions(-) create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceInfo.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/Metadata.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/SchedulingOptions.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/ServiceAccount.java create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/Tags.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceInfoTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/MetadataTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/SchedulingOptionsTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/ServiceAccountTest.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/TagsTest.java diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java index ee0c327da8dc..907f581fcca6 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java @@ -2339,7 +2339,7 @@ Operation deprecate(ImageId image, DeprecationStatus deprecationStatus, * * @throws ComputeException upon failure */ - Page listSubnetworks(String project, SubnetworkListOption... options); + Page listSubnetworks(String region, SubnetworkListOption... options); /** * Lists subnetworks for all regions. diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceInfo.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceInfo.java new file mode 100644 index 000000000000..0ce3e8f1bb76 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceInfo.java @@ -0,0 +1,674 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.api.services.compute.model.Instance; +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; + +import java.io.Serializable; +import java.math.BigInteger; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +/** + * A Google Compute Engine VM Instance. An instance is a virtual machine (VM) hosted on Google's + * infrastructure. Instances can run Linux and Windows Server images provided by Google, or any + * customized versions of these images. You can also build and run images of other operating + * systems. Google Compute Engine also lets you choose the machine properties of your instances, + * such as the number of virtual CPUs and the amount of memory + * + *

    By default, each Compute Engine instance has a small root persistent disk that contains the + * operating system. When your applications require additional storage space, you can add one or + * more additional disks to your instance. + * + *

    Instances communicate with other instances in the same network through a local area network. + * Instances communicate with the rest of the world through the Internet. A network lives in a + * project and is isolated from other networks in the project. A project can have up to five + * different networks. + * + * @see Virtual Machine Instances + */ +public class InstanceInfo implements Serializable { + + static final Function FROM_PB_FUNCTION = + new Function() { + @Override + public InstanceInfo apply(Instance pb) { + return InstanceInfo.fromPb(pb); + } + }; + static final Function TO_PB_FUNCTION = + new Function() { + @Override + public Instance apply(InstanceInfo instance) { + return instance.toPb(); + } + }; + + private static final long serialVersionUID = -6601223112628977168L; + private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); + + private final String id; + private final InstanceId instanceId; + private final Long creationTimestamp; + private final String description; + private final Status status; + private final String statusMessage; + private final Tags tags; + private final MachineTypeId machineType; + private final Boolean canIpForward; + private final List networkInterfaces; + private final List attachedDisks; + private final Metadata metadata; + private final List serviceAccounts; + private final SchedulingOptions schedulingOptions; + private final String cpuPlatform; + + /** + * The status of the instance. + */ + public enum Status { + /** + * Indicates that resources are being reserved for the instance. The instance isn't running yet. + */ + PROVISIONING, + + /** + * Indicates that resources have been acquired and the instance is being prepared for launch. + */ + STAGING, + + /** + * Indicates that the instance is booting up or running. You should be able to {@code ssh} into + * the instance soon, though not immediately, after it enters this state. + */ + RUNNING, + + /** + * Indicates that the instance is being stopped either due to a failure, or the instance being + * shut down. This is a temporary status and the instance will move to {@code TERMINATED}. + */ + STOPPING, + + /** + * Indicates that the instance was shut down or encountered a failure, either through the API or + * from inside the guest. You can choose to restart the instance or delete it. + */ + TERMINATED + } + + /** + * A builder for {@code InstanceInfo} objects. + */ + public abstract static class Builder { + + abstract Builder id(String id); + + /** + * Sets the identity of the virtual machine instance. + */ + public abstract Builder instanceId(InstanceId instanceId); + + abstract Builder creationTimestamp(Long creationTimestamp); + + /** + * Sets an optional description of this Google Compute Engine instance. + */ + public abstract Builder description(String description); + + abstract Builder status(Status status); + + abstract Builder statusMessage(String statusMessage); + + /** + * Sets the tags to apply to this instance. Tags are used to identify valid sources or targets + * for network firewalls. + */ + public abstract Builder tags(Tags tags); + + /** + * Sets the machine type identity. + */ + public abstract Builder machineType(MachineTypeId machineType); + + /** + * Sets whether to allow this instance to send and receive packets with non-matching destination + * or source IPs. This is required if you plan to use this instance to forward routes. + * + * @see Enabling IP + * Forwarding + */ + public abstract Builder canIpForward(Boolean canIpForward); + + /** + * Sets a list of network interfaces. This specifies how this instance is configured to interact + * with other network services, such as connecting to the internet. At the moment, instances + * only support one network interface. + */ + public abstract Builder networkInterfaces(List networkInterfaces); + + /** + * Sets a list of network interfaces. This specifies how this instance is configured to interact + * with other network services, such as connecting to the internet. At the moment, instances + * only support one network interface. + */ + public abstract Builder networkInterfaces(NetworkInterface... networkInterfaces); + + /** + * Sets a list of disks to attach to the instance. One boot disk must be provided (i.e. an + * attached disk such that {@link AttachedDisk.AttachedDiskConfiguration#boot()} returns + * {@code true}). + */ + public abstract Builder attachedDisks(List attachedDisks); + + /** + * Sets a list of disks to attach to the instance. One boot disk must be provided. + */ + public abstract Builder attachedDisks(AttachedDisk... attachedDisks); + + /** + * Sets the instance metadata. + */ + public abstract Builder metadata(Metadata metadata); + + /** + * Sets a list of service accounts, with their specified scopes, authorized for this instance. + * Service accounts generate access tokens that can be accessed through the metadata server and + * used to authenticate applications on the instance. + * + * @see Authenticating from + * Google Compute Engine + */ + public abstract Builder serviceAccounts(List serviceAccounts); + + /** + * Sets the scheduling options for the instance. + */ + public abstract Builder schedulingOptions(SchedulingOptions schedulingOptions); + + abstract Builder cpuPlatform(String cpuPlatform); + + /** + * Creates an {@code InstanceInfo} object. + */ + public abstract InstanceInfo build(); + } + + public static final class BuilderImpl extends Builder { + + private String id; + private InstanceId instanceId; + private Long creationTimestamp; + private String description; + private Status status; + private String statusMessage; + private Tags tags; + private MachineTypeId machineType; + private Boolean canIpForward; + private List networkInterfaces; + private List attachedDisks; + private Metadata metadata; + private List serviceAccounts; + private SchedulingOptions schedulingOptions; + private String cpuPlatform; + + BuilderImpl(InstanceId instanceId) { + this.instanceId = checkNotNull(instanceId); + } + + BuilderImpl(InstanceInfo instance) { + this.id = instance.id; + this.instanceId = instance.instanceId; + this.creationTimestamp = instance.creationTimestamp; + this.description = instance.description; + this.status = instance.status; + this.statusMessage = instance.statusMessage; + this.tags = instance.tags; + this.machineType = instance.machineType; + this.canIpForward = instance.canIpForward; + this.networkInterfaces = instance.networkInterfaces; + this.attachedDisks = instance.attachedDisks; + this.metadata = instance.metadata; + this.serviceAccounts = instance.serviceAccounts; + this.schedulingOptions = instance.schedulingOptions; + this.cpuPlatform = instance.cpuPlatform; + } + + BuilderImpl(Instance instancePb) { + if (instancePb.getId() != null) { + this.id = instancePb.getId().toString(); + } + this.instanceId = InstanceId.fromUrl(instancePb.getSelfLink()); + if (instancePb.getCreationTimestamp() != null) { + this.creationTimestamp = TIMESTAMP_FORMATTER.parseMillis(instancePb.getCreationTimestamp()); + } + this.description = instancePb.getDescription(); + if (instancePb.getStatus() != null) { + this.status = Status.valueOf(instancePb.getStatus()); + } + this.statusMessage = instancePb.getStatusMessage(); + if (instancePb.getTags() != null) { + this.tags = Tags.fromPb(instancePb.getTags()); + } + if (instancePb.getMachineType() != null) { + this.machineType = MachineTypeId.fromUrl(instancePb.getMachineType()); + } + this.canIpForward = instancePb.getCanIpForward(); + if (instancePb.getNetworkInterfaces() != null) { + this.networkInterfaces = + Lists.transform(instancePb.getNetworkInterfaces(), NetworkInterface.FROM_PB_FUNCTION); + } + if (instancePb.getDisks() != null) { + this.attachedDisks = Lists.transform(instancePb.getDisks(), AttachedDisk.FROM_PB_FUNCTION); + } + if (instancePb.getMetadata() != null) { + this.metadata = Metadata.fromPb(instancePb.getMetadata()); + } + if (instancePb.getServiceAccounts() != null) { + this.serviceAccounts = + Lists.transform(instancePb.getServiceAccounts(), ServiceAccount.FROM_PB_FUNCTION); + } + if (instancePb.getScheduling() != null) { + this.schedulingOptions = SchedulingOptions.fromPb(instancePb.getScheduling()); + } + this.cpuPlatform = instancePb.getCpuPlatform(); + } + + @Override + Builder id(String id) { + this.id = id; + return this; + } + + @Override + public Builder instanceId(InstanceId instanceId) { + this.instanceId = checkNotNull(instanceId); + return this; + } + + @Override + Builder creationTimestamp(Long creationTimestamp) { + this.creationTimestamp = creationTimestamp; + return this; + } + + @Override + public Builder description(String description) { + this.description = description; + return this; + } + + @Override + Builder status(Status status) { + this.status = status; + return this; + } + + @Override + Builder statusMessage(String statusMessage) { + this.statusMessage = statusMessage; + return this; + } + + @Override + public Builder tags(Tags tags) { + this.tags = tags; + return this; + } + + @Override + public Builder machineType(MachineTypeId machineType) { + this.machineType = checkNotNull(machineType); + return this; + } + + @Override + public Builder canIpForward(Boolean canIpForward) { + this.canIpForward = canIpForward; + return this; + } + + @Override + public Builder networkInterfaces(List networkInterfaces) { + this.networkInterfaces = ImmutableList.copyOf(checkNotNull(networkInterfaces)); + return this; + } + + @Override + public Builder networkInterfaces(NetworkInterface... networkInterfaces) { + this.networkInterfaces = Arrays.asList(networkInterfaces); + return this; + } + + @Override + public Builder attachedDisks(List attachedDisks) { + this.attachedDisks = ImmutableList.copyOf(checkNotNull(attachedDisks)); + return this; + } + + @Override + public Builder attachedDisks(AttachedDisk... attachedDisks) { + this.attachedDisks = Arrays.asList(attachedDisks); + return this; + } + + @Override + public Builder metadata(Metadata metadata) { + this.metadata = metadata; + return this; + } + + @Override + public Builder serviceAccounts(List serviceAccounts) { + this.serviceAccounts = ImmutableList.copyOf(checkNotNull(serviceAccounts)); + return this; + } + + @Override + public Builder schedulingOptions(SchedulingOptions schedulingOptions) { + this.schedulingOptions = schedulingOptions; + return this; + } + + @Override + Builder cpuPlatform(String cpuPlatform) { + this.cpuPlatform = cpuPlatform; + return this; + } + + @Override + public InstanceInfo build() { + checkNotNull(attachedDisks); + checkNotNull(networkInterfaces); + return new InstanceInfo(this); + } + } + + InstanceInfo(BuilderImpl builder) { + this.id = builder.id; + this.instanceId = builder.instanceId; + this.creationTimestamp = builder.creationTimestamp; + this.description = builder.description; + this.status = builder.status; + this.statusMessage = builder.statusMessage; + this.tags = builder.tags; + this.machineType = builder.machineType; + this.canIpForward = builder.canIpForward; + this.networkInterfaces = builder.networkInterfaces; + this.attachedDisks = builder.attachedDisks; + this.metadata = builder.metadata; + this.serviceAccounts = builder.serviceAccounts; + this.schedulingOptions = builder.schedulingOptions; + this.cpuPlatform = builder.cpuPlatform; + } + + /** + * Returns the unique identifier for the instance; defined by the service. + */ + public String id() { + return id; + } + + /** + * Returns the instance identity. + */ + public InstanceId instanceId() { + return instanceId; + } + + /** + * Returns the creation timestamp in milliseconds since epoch. + */ + public Long creationTimestamp() { + return creationTimestamp; + } + + /** + * Returns a textual description of the instance. + */ + public String description() { + return description; + } + + /** + * Returns the status of the instance. + */ + public Status status() { + return status; + } + + /** + * Returns an optional, human-readable explanation of the status. + */ + public String statusMessage() { + return statusMessage; + } + + /** + * Returns the tags of this instance. Tags are used to identify valid sources or targets for + * network firewalls. + */ + public Tags tags() { + return tags; + } + + /** + * Returns the machine type identity. + */ + public MachineTypeId machineType() { + return machineType; + } + + /** + * Returns whether to allow this instance to send and receive packets with non-matching + * destination or source IPs. This is required if you plan to use this instance to forward routes. + * + * @see Enabling IP + * Forwarding + */ + public Boolean canIpForward() { + return canIpForward; + } + + /** + * Returns a list of network interfaces. This specifies how this instance is configured to + * interact with other network services, such as connecting to the internet. + */ + public List networkInterfaces() { + return networkInterfaces; + } + + /** + * Returns a list of disks attached to the instance. + */ + public List attachedDisks() { + return attachedDisks; + } + + /** + * Returns the instance metadata. + */ + public Metadata metadata() { + return metadata; + } + + /** + * Returns a list of service accounts, with their specified scopes, authorized for this instance. + * Service accounts generate access tokens that can be accessed through the metadata server and + * used to authenticate applications on the instance. + * + * @see Authenticating from + * Google Compute Engine + */ + public List serviceAccounts() { + return serviceAccounts; + } + + /** + * Returns the scheduling options for the instance. + */ + public SchedulingOptions schedulingOptions() { + return schedulingOptions; + } + + /** + * Returns the CPU platform used by this instance. + */ + public String cpuPlatform() { + return cpuPlatform; + } + + /** + * Returns a builder for the current instance. + */ + public Builder toBuilder() { + return new BuilderImpl(this); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id) + .add("instanceId", instanceId) + .add("creationTimestamp", creationTimestamp) + .add("description", description) + .add("status", status) + .add("statusMessage", statusMessage) + .add("tags", tags) + .add("machineType", machineType) + .add("canIpForward", canIpForward) + .add("networkInterfaces", networkInterfaces) + .add("attachedDisks", attachedDisks) + .add("metadata", metadata) + .add("serviceAccounts", serviceAccounts) + .add("schedulingOptions", schedulingOptions) + .add("cpuPlatform", cpuPlatform) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(id, instanceId, creationTimestamp, description, status, statusMessage, tags, + machineType, canIpForward, networkInterfaces, attachedDisks, metadata, serviceAccounts, + schedulingOptions, cpuPlatform); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof InstanceInfo + && Objects.equals(toPb(), ((InstanceInfo) obj).toPb()); + } + + InstanceInfo setProjectId(final String projectId) { + Builder builder = toBuilder(); + builder.networkInterfaces(Lists.transform(networkInterfaces, + new Function() { + @Override + public NetworkInterface apply(NetworkInterface networkInterface) { + return networkInterface.setProjectId(projectId); + } + })); + builder.attachedDisks(Lists.transform(attachedDisks, + new Function() { + @Override + public AttachedDisk apply(AttachedDisk attachedDisk) { + return attachedDisk.setProjectId(projectId); + } + })); + return builder.instanceId(instanceId.setProjectId(projectId)) + .machineType(machineType.setProjectId(projectId)) + .build(); + } + + Instance toPb() { + Instance instancePb = new Instance(); + if (id != null) { + instancePb.setId(new BigInteger(id)); + } + if (creationTimestamp != null) { + instancePb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); + } + instancePb.setName(instanceId.instance()); + instancePb.setDescription(description); + instancePb.setSelfLink(instanceId.selfLink()); + instancePb.setZone(instanceId.zoneId().selfLink()); + if (status != null) { + instancePb.setStatus(status.name()); + } + instancePb.setStatusMessage(statusMessage); + if (tags != null) { + instancePb.setTags(tags.toPb()); + } + if (machineType != null) { + instancePb.setMachineType(machineType.selfLink()); + } + instancePb.setCanIpForward(canIpForward); + if (networkInterfaces != null) { + instancePb.setNetworkInterfaces( + Lists.transform(networkInterfaces, NetworkInterface.TO_PB_FUNCTION)); + } + if (attachedDisks != null) { + instancePb.setDisks(Lists.transform(attachedDisks, AttachedDisk.TO_PB_FUNCTION)); + } + if (metadata != null) { + instancePb.setMetadata(metadata.toPb()); + } + if (serviceAccounts != null) { + instancePb.setServiceAccounts( + Lists.transform(serviceAccounts, ServiceAccount.TO_PB_FUNCTION)); + } + if (schedulingOptions != null) { + instancePb.setScheduling(schedulingOptions.toPb()); + } + instancePb.setCpuPlatform(cpuPlatform); + return instancePb; + } + + /** + * Returns a builder for an {@code InstanceInfo} object given the instance identity and the + * machine type. + */ + public static Builder builder(InstanceId instanceId, MachineTypeId machineType) { + return new BuilderImpl(instanceId).machineType(machineType); + } + + /** + * Returns an {@code InstanceInfo} object given the instance identity, the machine type, a disk + * to attach to the instance and a network interface. {@code disk} must be a boot disk (i.e. + * {@link AttachedDisk.AttachedDiskConfiguration#boot()} returns {@code true}). + */ + public static InstanceInfo of(InstanceId instanceId, MachineTypeId machineType, AttachedDisk disk, + NetworkInterface networkInterface) { + return builder(instanceId, machineType) + .attachedDisks(ImmutableList.of(disk)) + .networkInterfaces(ImmutableList.of(networkInterface)) + .build(); + } + + static InstanceInfo fromPb(Instance instancePb) { + return new BuilderImpl(instancePb).build(); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Metadata.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Metadata.java new file mode 100644 index 000000000000..bf489caf141d --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Metadata.java @@ -0,0 +1,212 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * Metadata for Google Compute Engine Instance as ket/value pairs. This includes custom metadata + * and predefined keys. + * + * @see Metadata + */ +public final class Metadata implements Serializable { + + static final Function + FROM_PB_FUNCTION = + new Function() { + @Override + public Metadata apply(com.google.api.services.compute.model.Metadata pb) { + return Metadata.fromPb(pb); + } + }; + static final Function TO_PB_FUNCTION = + new Function() { + @Override + public com.google.api.services.compute.model.Metadata apply(Metadata metadata) { + return metadata.toPb(); + } + }; + + private static final long serialVersionUID = -945038809838910107L; + + private final Map values; + private final String fingerprint; + + /** + * A builder for {@code Metadata} objects. + */ + public static final class Builder { + + private Map values; + private String fingerprint; + + Builder() { + values = Maps.newHashMap(); + } + + Builder(Metadata metadata) { + this.values = metadata.values != null ? Maps.newHashMap(metadata.values) + : Maps.newHashMap(); + this.fingerprint = metadata.fingerprint; + } + + /** + * Sets the metadata for the instance as key/value pairs. The total size of all keys and + * values must be less than 512 KB. Keys must conform to the following regexp: + * {@code [a-zA-Z0-9-_]+}, and be less than 128 bytes in length. This is reflected as part of + * a URL in the metadata server. Additionally, to avoid ambiguity, keys must not conflict with + * any other metadata keys for the project. Values must be less than or equal to 32768 bytes. + */ + public Builder values(Map values) { + this.values = Maps.newHashMap(checkNotNull(values)); + return this; + } + + /** + * Adds a key/value pair to the instance metadata. The total size of all keys and values must + * be less than 512 KB. Keys must conform to the following regexp: {@code [a-zA-Z0-9-_]+}, and + * be less than 128 bytes in length. This is reflected as part of a URL in the metadata + * server. Additionally, to avoid ambiguity, keys must not conflict with any other metadata + * keys for the project. Values must be less than or equal to 32768 bytes. + */ + public Builder add(String key, String value) { + this.values.put(key, value); + return this; + } + + /** + * Sets the fingerprint for the metadata. This value can be used to update instance's + * metadata. + */ + public Builder fingerprint(String fingerprint) { + this.fingerprint = fingerprint; + return this; + } + + /** + * Creates a {@code Metadata} object. + */ + public Metadata build() { + return new Metadata(this); + } + } + + private Metadata(Builder builder) { + this.values = ImmutableMap.copyOf(builder.values); + this.fingerprint = builder.fingerprint; + } + + /** + * Returns instance's metadata as key/value pairs. + */ + public Map values() { + return values; + } + + /** + * Returns the fingerprint for the metadata. This value can be used to update instance's + * metadata. + */ + public String fingerprint() { + return fingerprint; + } + + /** + * Returns a builder for the current instance metadata. + */ + public Builder toBuilder() { + return new Builder(this); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("values", values) + .add("fingerprint", fingerprint) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(values, fingerprint); + } + + @Override + public boolean equals(Object obj) { + return obj == this + || obj instanceof Metadata + && Objects.equals(toPb(), ((Metadata) obj).toPb()); + } + + com.google.api.services.compute.model.Metadata toPb() { + com.google.api.services.compute.model.Metadata metadataPb = + new com.google.api.services.compute.model.Metadata(); + metadataPb.setFingerprint(fingerprint); + List itemsPb = + Lists.newArrayListWithCapacity(values.size()); + for (Map.Entry entry : values.entrySet()) { + itemsPb.add(new com.google.api.services.compute.model.Metadata.Items() + .setKey(entry.getKey()).setValue(entry.getValue())); + } + metadataPb.setItems(itemsPb); + metadataPb.setFingerprint(fingerprint); + return metadataPb; + } + + /** + * Returns a builder for a {@code Metadata} object. + */ + public static Builder builder() { + return new Builder(); + } + + /** + * Returns a {@code Metadata} object given the the metadata as a map. The total size of all keys + * and values must be less than 512 KB. Keys must conform to the following regexp: + * {@code [a-zA-Z0-9-_]+}, and be less than 128 bytes in length. This is reflected as part of a + * URL in the metadata server. Additionally, to avoid ambiguity, keys must not conflict with any + * other metadata keys for the project. Values must be less than or equal to 32768 bytes. + */ + public static Metadata of(Map values) { + return builder().values(values).build(); + } + + static Metadata fromPb(com.google.api.services.compute.model.Metadata metadataPb) { + Builder builder = builder(); + if (metadataPb.getItems() != null) { + Map metadataValues = + Maps.newHashMapWithExpectedSize(metadataPb.getItems().size()); + for (com.google.api.services.compute.model.Metadata.Items item : metadataPb.getItems()) { + metadataValues.put(item.getKey(), item.getValue()); + } + builder.values(metadataValues); + } + return builder.fingerprint(metadataPb.getFingerprint()).build(); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInfo.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInfo.java index 1e1d4f4bf907..d3e1cddcd6be 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInfo.java @@ -35,6 +35,9 @@ * networks, use firewall rules to restrict access to instances, and create static routes to forward * traffic to specific destinations. * + *

    A network lives in a project and is isolated from other networks in the project. A project can + * have up to five different networks. + * * @see Using Networks and Firewalls */ public class NetworkInfo implements Serializable { diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInterface.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInterface.java index cf937de68ed6..8226eae7b56c 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInterface.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInterface.java @@ -493,7 +493,7 @@ static NetworkInterface fromPb( com.google.api.services.compute.model.NetworkInterface interfacePb) { Builder builder = builder(NetworkId.fromUrl(interfacePb.getNetwork())) .name(interfacePb.getName()); - if (interfacePb.getSubnetwork() != null){ + if (interfacePb.getSubnetwork() != null) { builder.subnetwork(SubnetworkId.fromUrl(interfacePb.getSubnetwork())); } builder.networkIp(interfacePb.getNetworkIP()); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SchedulingOptions.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SchedulingOptions.java new file mode 100644 index 000000000000..c5d7c293cc10 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SchedulingOptions.java @@ -0,0 +1,150 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import com.google.common.base.MoreObjects; + +import java.io.Serializable; +import java.util.Objects; + +/** + * A Google Compute Engine instance scheduling options. When there are system events that might + * cause your instances to be disrupted, Google Compute Engine automatically manages the + * scheduling decisions for your instances. Use {@code SchedulingOptions.preemptible()} to create + * a preemptible instance. Use {@code SchedulingOptions.standard()} to configure scheduling + * options for a standard instance. + * + * @see + * Setting Instance Scheduling Options + */ +public final class SchedulingOptions implements Serializable { + + private static final long serialVersionUID = 4199610694227857331L; + + private final boolean automaticRestart; + private final Maintenance maintenance; + private final boolean isPreemptible; + + /** + * Defines the maintenance behavior for this instance. + */ + public enum Maintenance { + /** + * The default behavior for standard instances. + */ + MIGRATE, + + /** + * The default and only possible behavior for preemptible instances. + */ + TERMINATE + } + + private SchedulingOptions(Boolean automaticRestart, Maintenance maintenance, + Boolean isPreemptible) { + this.automaticRestart = automaticRestart; + this.maintenance = maintenance; + this.isPreemptible = isPreemptible; + } + + /** + * Returns whether the instance should be automatically restarted if it is terminated by Compute + * Engine (not terminated by a user). + */ + public Boolean automaticRestart() { + return automaticRestart; + } + + /** + * Returns the maintenance behavior for the instance. + */ + public Maintenance maintenance() { + return maintenance; + } + + /** + * Returns {@code true} if the instance is preemptible, {@code false} otherwhise. + * + * @see Preemptible + * Instance + */ + public boolean isPreemptible() { + return isPreemptible; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("automaticRestart", automaticRestart) + .add("maintenance", maintenance) + .add("isPreemptible", isPreemptible) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(automaticRestart, maintenance, isPreemptible); + } + + @Override + public boolean equals(Object obj) { + return obj == this + || obj instanceof SchedulingOptions + && Objects.equals(toPb(), ((SchedulingOptions) obj).toPb()); + } + + com.google.api.services.compute.model.Scheduling toPb() { + com.google.api.services.compute.model.Scheduling schedulingPb = + new com.google.api.services.compute.model.Scheduling(); + schedulingPb.setAutomaticRestart(automaticRestart); + schedulingPb.setPreemptible(isPreemptible); + if (maintenance != null) { + schedulingPb.setOnHostMaintenance(maintenance.name()); + } + return schedulingPb; + } + + /** + * Returns a {@code SchedulingOptions} object for a preemptible instance. + * + * @see Preemptible + * Instance + */ + public static SchedulingOptions preemptible() { + return new SchedulingOptions(false, Maintenance.TERMINATE, true); + } + + /** + * Returns a {@code SchedulingOptions} object for a standard instance. + * + * @param automaticRestart specifies whether the instance should be automatically restarted if + * it is terminated by Compute Engine (not terminated by a user) + * @param maintenance defines the maintenance behavior for the instance + */ + public static SchedulingOptions standard(boolean automaticRestart, Maintenance maintenance) { + return new SchedulingOptions(automaticRestart, maintenance, false); + } + + static SchedulingOptions fromPb(com.google.api.services.compute.model.Scheduling schedPb) { + Maintenance maintenance = null; + if (schedPb.getOnHostMaintenance() != null) { + maintenance = Maintenance.valueOf(schedPb.getOnHostMaintenance()); + } + return new SchedulingOptions(schedPb.getAutomaticRestart(), maintenance, + schedPb.getPreemptible()); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ServiceAccount.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ServiceAccount.java new file mode 100644 index 000000000000..ccdb2ecb0d79 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ServiceAccount.java @@ -0,0 +1,123 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableList; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +/** + * A service account, with its specified scopes, authorized for this instance. + * + * @see Authenticating from Google + * Compute Engine + */ +public final class ServiceAccount implements Serializable { + + static final Function + FROM_PB_FUNCTION = + new Function() { + @Override + public ServiceAccount apply(com.google.api.services.compute.model.ServiceAccount pb) { + return ServiceAccount.fromPb(pb); + } + }; + static final Function + TO_PB_FUNCTION = + new Function() { + @Override + public com.google.api.services.compute.model.ServiceAccount apply( + ServiceAccount metadata) { + return metadata.toPb(); + } + }; + + private static final long serialVersionUID = 4199610694227857331L; + + private final String email; + private final List scopes; + + private ServiceAccount(String email, List scopes) { + this.email = email; + this.scopes = ImmutableList.copyOf(scopes); + } + + /** + * Returns the email address of the service account. + */ + public String email() { + return email; + } + + /** + * Returns the list of scopes to be made available for this service account. + */ + public List scopes() { + return scopes; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("email", email) + .add("scopes", scopes) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(email, scopes); + } + + @Override + public boolean equals(Object obj) { + return obj == this + || obj instanceof ServiceAccount + && Objects.equals(toPb(), ((ServiceAccount) obj).toPb()); + } + + com.google.api.services.compute.model.ServiceAccount toPb() { + com.google.api.services.compute.model.ServiceAccount serviceAccountPb = + new com.google.api.services.compute.model.ServiceAccount(); + serviceAccountPb.setEmail(email); + serviceAccountPb.setScopes(scopes); + return serviceAccountPb; + } + + /** + * Returns a {@code ServiceAccount} object for the provided email and scopes. + */ + public static ServiceAccount of(String email, List scopes) { + return new ServiceAccount(email, scopes); + } + + /** + * Returns a {@code ServiceAccount} object for the provided email and scopes. + */ + public static ServiceAccount of(String email, String... scopes) { + return of(email, Arrays.asList(scopes)); + } + + static ServiceAccount fromPb(com.google.api.services.compute.model.ServiceAccount accountPb) { + return new ServiceAccount(accountPb.getEmail(), accountPb.getScopes()); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Tags.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Tags.java new file mode 100644 index 000000000000..275bad05f4fe --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Tags.java @@ -0,0 +1,227 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +/** + * A list of tags for a Google Compute Engine Instance; with associated fingerprint. Tags are used + * to identify valid sources or targets for network firewalls and are specified by the client + * during instance creation. Each tag within the list must comply with RFC1035. + * + * @see RFC1035 + */ +public final class Tags implements Serializable { + + static final Function FROM_PB_FUNCTION = + new Function() { + @Override + public Tags apply(com.google.api.services.compute.model.Tags pb) { + return Tags.fromPb(pb); + } + }; + static final Function TO_PB_FUNCTION = + new Function() { + @Override + public com.google.api.services.compute.model.Tags apply(Tags tags) { + return tags.toPb(); + } + }; + + private static final long serialVersionUID = 5627093820497225322L; + + private final List values; + private final String fingerprint; + + /** + * A builder for {@code Tags} objects. + */ + public static final class Builder { + + private List values; + private String fingerprint; + + private Builder() { + values = Lists.newArrayList(); + } + + private Builder(Tags tags) { + this.values = tags.values != null ? Lists.newArrayList(tags.values) + : Lists.newArrayList(); + this.fingerprint = tags.fingerprint; + } + + /** + * Sets a list of tags to apply to an instance. Tags are used to identify valid sources or + * targets for network firewalls. Each tag within the list must comply with RFC1035. + * + * @see RFC1035 + */ + public Builder values(Iterable values) { + this.values = Lists.newArrayList(values); + return this; + } + + /** + * Sets a list of tags to apply to an instance. Tags are used to identify valid sources or + * targets for network firewalls. Each tag within the list must comply with RFC1035. + * + * @see RFC1035 + */ + public Builder values(String... values) { + this.values = Lists.newArrayList(Arrays.asList(checkNotNull(values))); + return this; + } + + /** + * Adds a tag to the list of tags. Tags are used to identify valid sources or targets for + * network firewalls. The tag must comply with RFC1035. + * + * @see RFC1035 + */ + public Builder add(String tag) { + this.values.add(tag); + return this; + } + + /** + * Sets the fingerprint for the tags. This value is needed to update instance's tags. + */ + public Builder fingerprint(String fingerprint) { + this.fingerprint = fingerprint; + return this; + } + + /** + * Creates a {@code Tags} object. + */ + public Tags build() { + return new Tags(this); + } + } + + private Tags(Builder builder) { + this.values = ImmutableList.copyOf(builder.values); + this.fingerprint = builder.fingerprint; + } + + /** + * Returns a list of tags to apply to an instance. Tags are used to identify valid sources or + * targets for network firewalls. Each tag within the list must comply with RFC1035. + * + * @see RFC1035 + */ + public List values() { + return values; + } + + /** + * Returns the fingerprint for the tags. This value is needed to update instance's tags. + */ + public String fingerprint() { + return fingerprint; + } + + /** + * Returns a builder for the current instance tags. + */ + public Builder toBuilder() { + return new Builder(this); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("values", values) + .add("fingerprint", fingerprint) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(values, fingerprint); + } + + @Override + public boolean equals(Object obj) { + return obj == this || obj instanceof Tags && Objects.equals(toPb(), ((Tags) obj).toPb()); + } + + com.google.api.services.compute.model.Tags toPb() { + com.google.api.services.compute.model.Tags tagsPb = + new com.google.api.services.compute.model.Tags(); + tagsPb.setFingerprint(fingerprint); + tagsPb.setItems(values); + return tagsPb; + } + + /** + * Returns a builder for a {@code Tags} object given the tags to apply to the instance. Each tag + * within the list must comply with RFC1035. + * + * @see RFC1035 + */ + public static Builder builder(Iterable values) { + return new Builder().values(values); + } + + /** + * Returns a builder for a {@code Tags} object given the tags to apply to the instance. Each tag + * within the list must comply with RFC1035. + * + * @see RFC1035 + */ + public static Builder builder(String... values) { + return new Builder().values(values); + } + + /** + * Returns a {@code Tags} object given the tags to apply to the instance. Each tag within the + * list must comply with RFC1035. + * + * @see RFC1035 + */ + public static Tags of(Iterable values) { + return builder(values).build(); + } + + /** + * Returns a {@code Tags} object given the tags to apply to the instance. Each tag within the + * list must comply with RFC1035. + * + * @see RFC1035 + */ + public static Tags of(String... values) { + return builder(values).build(); + } + + static Tags fromPb(com.google.api.services.compute.model.Tags tagsPb) { + Builder builder = + builder(tagsPb.getItems() != null ? tagsPb.getItems() : ImmutableList.of()); + return builder.fingerprint(tagsPb.getFingerprint()).build(); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceInfoTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceInfoTest.java new file mode 100644 index 000000000000..51b2dcb91c72 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceInfoTest.java @@ -0,0 +1,184 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import com.google.common.collect.ImmutableList; +import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; + +import org.junit.Test; + +import java.util.List; + +public class InstanceInfoTest { + + private static final String ID = "42"; + private static final Long CREATION_TIMESTAMP = 1453293540000L; + private static final String DESCRIPTION = "description"; + private static final InstanceId INSTANCE_ID = InstanceId.of("project", "zone", "instance"); + private static final InstanceInfo.Status STATUS = InstanceInfo.Status.RUNNING; + private static final String STATUS_MESSAGE = "statusMessage"; + private static final Tags TAGS = Tags.of("tag1", "tag2"); + private static final MachineTypeId MACHINE_TYPE = MachineTypeId.of("project", "zone", "type"); + private static final Boolean CAN_IP_FORWARD = true; + private static final NetworkInterface NETWORK_INTERFACE = + NetworkInterface.of(NetworkId.of("project", "network")); + private static final List NETWORK_INTERFACES = + ImmutableList.of(NETWORK_INTERFACE); + private static final DiskId DISK_ID = DiskId.of("project", "zone", "disk"); + private static final AttachedDisk ATTACHED_DISK = + AttachedDisk.of(PersistentDiskConfiguration.of(DISK_ID)); + private static final List ATTACHED_DISKS = ImmutableList.of(ATTACHED_DISK); + private static final Metadata METADATA = Metadata.builder() + .add("key1", "value1") + .add("key2", "value2") + .build(); + private static final ServiceAccount SERVICE_ACCOUNT = + ServiceAccount.of("email", ImmutableList.of("scope1")); + private static final List SERVICE_ACCOUNTS = ImmutableList.of(SERVICE_ACCOUNT); + private static final SchedulingOptions SCHEDULING_OPTIONS = SchedulingOptions.preemptible(); + private static final String CPU_PLATFORM = "cpuPlatform"; + private static final InstanceInfo INSTANCE_INFO = InstanceInfo.builder(INSTANCE_ID, MACHINE_TYPE) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .status(STATUS) + .statusMessage(STATUS_MESSAGE) + .tags(TAGS) + .canIpForward(CAN_IP_FORWARD) + .networkInterfaces(NETWORK_INTERFACES) + .attachedDisks(ATTACHED_DISKS) + .metadata(METADATA) + .serviceAccounts(SERVICE_ACCOUNTS) + .schedulingOptions(SCHEDULING_OPTIONS) + .cpuPlatform(CPU_PLATFORM) + .build(); + + @Test + public void testToBuilder() { + compareInstanceInfo(INSTANCE_INFO, INSTANCE_INFO.toBuilder().build()); + InstanceInfo instance = INSTANCE_INFO.toBuilder().description("newDescription").build(); + assertEquals("newDescription", instance.description()); + instance = instance.toBuilder().description(DESCRIPTION).build(); + compareInstanceInfo(INSTANCE_INFO, instance); + } + + @Test + public void testToBuilderIncomplete() { + InstanceInfo instanceInfo = InstanceInfo.of(INSTANCE_ID, MACHINE_TYPE, ATTACHED_DISK, + NETWORK_INTERFACE); + assertEquals(instanceInfo, instanceInfo.toBuilder().build()); + } + + @Test + public void testBuilder() { + assertEquals(ID, INSTANCE_INFO.id()); + assertEquals(INSTANCE_ID, INSTANCE_INFO.instanceId()); + assertEquals(CREATION_TIMESTAMP, INSTANCE_INFO.creationTimestamp()); + assertEquals(DESCRIPTION, INSTANCE_INFO.description()); + assertEquals(STATUS, INSTANCE_INFO.status()); + assertEquals(STATUS_MESSAGE, INSTANCE_INFO.statusMessage()); + assertEquals(TAGS, INSTANCE_INFO.tags()); + assertEquals(MACHINE_TYPE, INSTANCE_INFO.machineType()); + assertEquals(CAN_IP_FORWARD, INSTANCE_INFO.canIpForward()); + assertEquals(NETWORK_INTERFACES, INSTANCE_INFO.networkInterfaces()); + assertEquals(ATTACHED_DISKS, INSTANCE_INFO.attachedDisks()); + assertEquals(METADATA, INSTANCE_INFO.metadata()); + assertEquals(SERVICE_ACCOUNTS, INSTANCE_INFO.serviceAccounts()); + assertEquals(SCHEDULING_OPTIONS, INSTANCE_INFO.schedulingOptions()); + assertEquals(CPU_PLATFORM, INSTANCE_INFO.cpuPlatform()); + InstanceInfo instanceInfo = InstanceInfo.builder(INSTANCE_ID, MACHINE_TYPE) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .status(STATUS) + .statusMessage(STATUS_MESSAGE) + .tags(TAGS) + .canIpForward(CAN_IP_FORWARD) + .networkInterfaces(NETWORK_INTERFACE) + .attachedDisks(ATTACHED_DISK) + .metadata(METADATA) + .serviceAccounts(SERVICE_ACCOUNTS) + .schedulingOptions(SCHEDULING_OPTIONS) + .cpuPlatform(CPU_PLATFORM) + .build(); + compareInstanceInfo(INSTANCE_INFO, instanceInfo); + } + + @Test + public void testOf() { + InstanceInfo instance = + InstanceInfo.of(INSTANCE_ID, MACHINE_TYPE, ATTACHED_DISK, NETWORK_INTERFACE); + assertNull(instance.id()); + assertEquals(INSTANCE_ID, instance.instanceId()); + assertNull(instance.creationTimestamp()); + assertNull(instance.description()); + assertNull(instance.status()); + assertNull(instance.statusMessage()); + assertNull(instance.tags()); + assertEquals(MACHINE_TYPE, instance.machineType()); + assertNull(instance.canIpForward()); + assertEquals(NETWORK_INTERFACES, instance.networkInterfaces()); + assertEquals(ATTACHED_DISKS, instance.attachedDisks()); + assertNull(instance.metadata()); + assertNull(instance.serviceAccounts()); + assertNull(instance.schedulingOptions()); + assertNull(instance.cpuPlatform()); + } + + @Test + public void testToAndFromPb() { + compareInstanceInfo(INSTANCE_INFO, InstanceInfo.fromPb(INSTANCE_INFO.toPb())); + InstanceInfo instance = + InstanceInfo.of(INSTANCE_ID, MACHINE_TYPE, ATTACHED_DISK, NETWORK_INTERFACE); + compareInstanceInfo(instance, InstanceInfo.fromPb(instance.toPb())); + } + + @Test + public void testSetProjectId() { + InstanceInfo instance = InstanceInfo.of( + InstanceId.of("zone", "instance"), + MachineTypeId.of("zone", "type"), + AttachedDisk.of(PersistentDiskConfiguration.of(DiskId.of("zone", "disk"))), + NetworkInterface.of(NetworkId.of("project", "network"))); + InstanceInfo instanceWithProject = + InstanceInfo.of(INSTANCE_ID, MACHINE_TYPE, ATTACHED_DISK, NETWORK_INTERFACE); + compareInstanceInfo(instanceWithProject, instance.setProjectId("project")); + } + + public void compareInstanceInfo(InstanceInfo expected, InstanceInfo value) { + assertEquals(expected, value); + assertEquals(expected.id(), value.id()); + assertEquals(expected.instanceId(), value.instanceId()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.status(), value.status()); + assertEquals(expected.statusMessage(), value.statusMessage()); + assertEquals(expected.tags(), value.tags()); + assertEquals(expected.machineType(), value.machineType()); + assertEquals(expected.canIpForward(), value.canIpForward()); + assertEquals(expected.networkInterfaces(), value.networkInterfaces()); + assertEquals(expected.attachedDisks(), value.attachedDisks()); + assertEquals(expected.metadata(), value.metadata()); + assertEquals(expected.serviceAccounts(), value.serviceAccounts()); + assertEquals(expected.schedulingOptions(), value.schedulingOptions()); + assertEquals(expected.cpuPlatform(), value.cpuPlatform()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MetadataTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MetadataTest.java new file mode 100644 index 000000000000..be43c4fd433f --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MetadataTest.java @@ -0,0 +1,81 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import com.google.common.collect.ImmutableMap; + +import org.junit.Test; + +import java.util.Map; + +public class MetadataTest { + + private static final Metadata METADATA = Metadata.builder() + .add("key1", "value1") + .add("key2", "value2") + .build(); + + @Test + public void testToBuilder() { + Metadata metadata = METADATA.toBuilder().fingerprint("newFingerprint").build(); + assertEquals("newFingerprint", metadata.fingerprint()); + compareMetadata(METADATA, metadata.toBuilder().fingerprint(null).build()); + } + + @Test + public void testBuilder() { + assertEquals(ImmutableMap.of("key1", "value1", "key2", "value2"), METADATA.values()); + assertNull(METADATA.fingerprint()); + Metadata metadata = Metadata.builder() + .values(ImmutableMap.of("key1", "value1", "key2", "value2")) + .build(); + assertEquals(ImmutableMap.of("key1", "value1", "key2", "value2"), metadata.values()); + assertNull(metadata.fingerprint()); + metadata = Metadata.builder() + .values(ImmutableMap.of("key1", "value1", "key2", "value2")) + .fingerprint("fingerprint") + .build(); + assertEquals(ImmutableMap.of("key1", "value1", "key2", "value2"), metadata.values()); + assertEquals("fingerprint", metadata.fingerprint()); + } + + @Test + public void testOf() { + Map map = ImmutableMap.of("key1", "value1", "key2", "value2"); + compareMetadata(METADATA, Metadata.of(map)); + } + + @Test + public void testToAndFromPb() { + compareMetadata(METADATA, Metadata.fromPb(METADATA.toPb())); + Metadata metadata = Metadata.builder() + .values(ImmutableMap.of("key1", "value1", "key2", "value2")) + .fingerprint("fingerprint") + .build(); + compareMetadata(metadata, Metadata.fromPb(metadata.toPb())); + } + + public void compareMetadata(Metadata expected, Metadata value) { + assertEquals(expected, value); + assertEquals(expected.fingerprint(), value.fingerprint()); + assertEquals(expected.values(), value.values()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SchedulingOptionsTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SchedulingOptionsTest.java new file mode 100644 index 000000000000..258c880d783f --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SchedulingOptionsTest.java @@ -0,0 +1,57 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class SchedulingOptionsTest { + + private static final SchedulingOptions SCHEDULING_OPTIONS = SchedulingOptions.preemptible(); + + @Test + public void testFactoryMethods() { + assertTrue(SCHEDULING_OPTIONS.isPreemptible()); + assertFalse(SCHEDULING_OPTIONS.automaticRestart()); + assertEquals(SchedulingOptions.Maintenance.TERMINATE, SCHEDULING_OPTIONS.maintenance()); + SchedulingOptions schedulingOptions = + SchedulingOptions.standard(true, SchedulingOptions.Maintenance.MIGRATE); + assertFalse(schedulingOptions.isPreemptible()); + assertTrue(schedulingOptions.automaticRestart()); + assertEquals(SchedulingOptions.Maintenance.MIGRATE, schedulingOptions.maintenance()); + } + + @Test + public void testToAndFromPb() { + compareSchedulingOptions(SCHEDULING_OPTIONS, + SchedulingOptions.fromPb(SCHEDULING_OPTIONS.toPb())); + SchedulingOptions schedulingOptions = + SchedulingOptions.standard(true, SchedulingOptions.Maintenance.MIGRATE); + compareSchedulingOptions(schedulingOptions, SchedulingOptions.fromPb(schedulingOptions.toPb())); + } + + public void compareSchedulingOptions(SchedulingOptions expected, SchedulingOptions value) { + assertEquals(expected, value); + assertEquals(expected.isPreemptible(), value.isPreemptible()); + assertEquals(expected.maintenance(), value.maintenance()); + assertEquals(expected.automaticRestart(), value.automaticRestart()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java index 73a572141b2a..92b1128ac6c4 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java @@ -20,6 +20,7 @@ import static org.junit.Assert.assertNotSame; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.gcloud.AuthCredentials; import com.google.gcloud.RetryParams; import com.google.gcloud.compute.AttachedDisk.CreateDiskConfiguration; @@ -186,6 +187,12 @@ public class SerializationTest { private static final ScratchDiskConfiguration SCRATCH_DISK_CONFIGURATION = ScratchDiskConfiguration.of(DISK_TYPE_ID); private static final AttachedDisk ATTACHED_DISK = AttachedDisk.of(CREATE_DISK_CONFIGURATION); + private static final Tags TAGS = Tags.of("tag1", "tag2"); + private static final Metadata METADATA = Metadata.of(ImmutableMap.of("key1", "val1")); + private static final ServiceAccount SERVICE_ACCOUNT = ServiceAccount.of("email"); + private static final SchedulingOptions SCHEDULING_OPTIONS = SchedulingOptions.preemptible(); + private static final InstanceInfo INSTANCE_INFO = + InstanceInfo.of(INSTANCE_ID, MACHINE_TYPE_ID, ATTACHED_DISK, NETWORK_INTERFACE); private static final Compute.DiskTypeOption DISK_TYPE_OPTION = Compute.DiskTypeOption.fields(); private static final Compute.DiskTypeFilter DISK_TYPE_FILTER = @@ -288,7 +295,8 @@ public void testModelAndRequests() throws Exception { DISK_INFO, DISK, SUBNETWORK_ID, NETWORK_ID, SUBNETWORK_INFO, SUBNETWORK, STANDARD_NETWORK_CONFIGURATION, SUBNET_NETWORK_CONFIGURATION, NETWORK_INFO, NETWORK, ACCESS_CONFIG, NETWORK_INTERFACE, CREATE_DISK_CONFIGURATION, PERSISTENT_DISK_CONFIGURATION, - SCRATCH_DISK_CONFIGURATION, ATTACHED_DISK, DISK_TYPE_OPTION, DISK_TYPE_FILTER, + SCRATCH_DISK_CONFIGURATION, ATTACHED_DISK, TAGS, METADATA, SERVICE_ACCOUNT, + SCHEDULING_OPTIONS, INSTANCE_INFO, DISK_TYPE_OPTION, DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, DISK_TYPE_AGGREGATED_LIST_OPTION, MACHINE_TYPE_OPTION, MACHINE_TYPE_FILTER, MACHINE_TYPE_LIST_OPTION, MACHINE_TYPE_AGGREGATED_LIST_OPTION, REGION_OPTION, REGION_FILTER, REGION_LIST_OPTION, ZONE_OPTION, ZONE_FILTER, diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ServiceAccountTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ServiceAccountTest.java new file mode 100644 index 000000000000..4d7c08d79f55 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ServiceAccountTest.java @@ -0,0 +1,47 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; + +import com.google.common.collect.ImmutableList; + +import org.junit.Test; + +public class ServiceAccountTest { + + private static final ServiceAccount SERVICE_ACCOUNT = + ServiceAccount.of("email", ImmutableList.of("scope1")); + + @Test + public void testOf() { + compareServiceAccount(SERVICE_ACCOUNT, ServiceAccount.of("email", ImmutableList.of("scope1"))); + compareServiceAccount(SERVICE_ACCOUNT, ServiceAccount.of("email", "scope1")); + } + + @Test + public void testToAndFromPb() { + compareServiceAccount(SERVICE_ACCOUNT, ServiceAccount.fromPb(SERVICE_ACCOUNT.toPb())); + } + + public void compareServiceAccount(ServiceAccount expected, ServiceAccount value) { + assertEquals(expected, value); + assertEquals(expected.email(), value.email()); + assertEquals(expected.scopes(), value.scopes()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/TagsTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/TagsTest.java new file mode 100644 index 000000000000..d9e998fd47e7 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/TagsTest.java @@ -0,0 +1,69 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import com.google.common.collect.ImmutableList; + +import org.junit.Test; + +public class TagsTest { + + private static final Tags TAGS = Tags.of("tag1", "tag2"); + + @Test + public void testToBuilder() { + Tags tags = TAGS.toBuilder().values("tag1").build(); + assertEquals(ImmutableList.of("tag1"), tags.values()); + compareTags(TAGS, tags.toBuilder().values("tag1", "tag2").build()); + } + + @Test + public void testBuilder() { + Tags tags = Tags.builder().values(ImmutableList.of("tag1", "tag2")).build(); + assertEquals(ImmutableList.of("tag1", "tag2"), tags.values()); + assertNull(tags.fingerprint()); + tags = Tags.builder().add("tag1").add("tag2").build(); + assertEquals(ImmutableList.of("tag1", "tag2"), tags.values()); + assertNull(tags.fingerprint()); + tags = Tags.builder().add("tag1").add("tag2").fingerprint("fingerprint").build(); + assertEquals(ImmutableList.of("tag1", "tag2"), tags.values()); + assertEquals("fingerprint", tags.fingerprint()); + } + + @Test + public void testOf() { + compareTags(TAGS, Tags.of("tag1", "tag2")); + compareTags(TAGS, Tags.of(ImmutableList.of("tag1", "tag2"))); + } + + @Test + public void testToAndFromPb() { + compareTags(TAGS, Tags.fromPb(TAGS.toPb())); + Tags tags = Tags.builder().add("tag1").add("tag2").fingerprint("fingerprint").build(); + compareTags(tags, Tags.fromPb(tags.toPb())); + } + + public void compareTags(Tags expected, Tags value) { + assertEquals(expected, value); + assertEquals(expected.fingerprint(), value.fingerprint()); + assertEquals(expected.values(), value.values()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} From cdf660c611e17c10d470b2492edae999b8d0f3c2 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 26 Apr 2016 17:40:26 +0200 Subject: [PATCH 322/375] Rename type name getters (#957) * Rename DiskTypeId.diskType() to type() * Rename MachineTypeId.machineType() to type() --- .../google/gcloud/compute/ComputeImpl.java | 5 ++- .../com/google/gcloud/compute/DiskTypeId.java | 32 ++++++++--------- .../google/gcloud/compute/MachineType.java | 2 +- .../google/gcloud/compute/MachineTypeId.java | 28 +++++++-------- .../gcloud/compute/ComputeImplTest.java | 34 +++++++++---------- .../google/gcloud/compute/DiskInfoTest.java | 6 ++-- .../google/gcloud/compute/DiskTypeIdTest.java | 6 ++-- .../compute/ImageDiskConfigurationTest.java | 2 +- .../gcloud/compute/MachineTypeIdTest.java | 6 ++-- .../SnapshotDiskConfigurationTest.java | 2 +- .../StandardDiskConfigurationTest.java | 2 +- .../gcloud/compute/it/ITComputeTest.java | 26 +++++++------- 12 files changed, 75 insertions(+), 76 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java index f19b6ee641a1..d8ac3a840761 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java @@ -427,7 +427,7 @@ public DiskType getDiskType(final DiskTypeId diskTypeId, DiskTypeOption... optio runWithRetries(new Callable() { @Override public com.google.api.services.compute.model.DiskType call() { - return computeRpc.getDiskType(diskTypeId.zone(), diskTypeId.diskType(), optionsMap); + return computeRpc.getDiskType(diskTypeId.zone(), diskTypeId.type(), optionsMap); } }, options().retryParams(), EXCEPTION_HANDLER); return answer == null ? null : DiskType.fromPb(answer); @@ -515,8 +515,7 @@ public MachineType getMachineType(final MachineTypeId machineType, MachineTypeOp runWithRetries(new Callable() { @Override public com.google.api.services.compute.model.MachineType call() { - return computeRpc.getMachineType(machineType.zone(), machineType.machineType(), - optionsMap); + return computeRpc.getMachineType(machineType.zone(), machineType.type(), optionsMap); } }, options().retryParams(), EXCEPTION_HANDLER); return answer == null ? null : MachineType.fromPb(answer); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java index 039565ec827f..836ee907abe3 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java @@ -48,19 +48,19 @@ public String apply(DiskTypeId diskTypeId) { private static final long serialVersionUID = 7337881474103686219L; private final String zone; - private final String diskType; + private final String type; - private DiskTypeId(String project, String zone, String diskType) { + private DiskTypeId(String project, String zone, String type) { super(project); this.zone = checkNotNull(zone); - this.diskType = checkNotNull(diskType); + this.type = checkNotNull(type); } /** * Returns the name of the disk type. */ - public String diskType() { - return diskType; + public String type() { + return type; } /** @@ -79,17 +79,17 @@ public ZoneId zoneId() { @Override public String selfLink() { - return super.selfLink() + "/zones/" + zone + "/diskTypes/" + diskType; + return super.selfLink() + "/zones/" + zone + "/diskTypes/" + type; } @Override MoreObjects.ToStringHelper toStringHelper() { - return super.toStringHelper().add("zone", zone).add("diskType", diskType); + return super.toStringHelper().add("zone", zone).add("type", type); } @Override public int hashCode() { - return Objects.hash(super.baseHashCode(), zone, diskType); + return Objects.hash(super.baseHashCode(), zone, type); } @Override @@ -103,7 +103,7 @@ public boolean equals(Object obj) { DiskTypeId other = (DiskTypeId) obj; return baseEquals(other) && Objects.equals(zone, other.zone) - && Objects.equals(diskType, other.diskType); + && Objects.equals(type, other.type); } @Override @@ -111,28 +111,28 @@ DiskTypeId setProjectId(String projectId) { if (project() != null) { return this; } - return DiskTypeId.of(projectId, zone, diskType); + return DiskTypeId.of(projectId, zone, type); } /** * Returns a disk type identity given the zone identity and the disk type name. */ - public static DiskTypeId of(ZoneId zoneId, String diskType) { - return new DiskTypeId(zoneId.project(), zoneId.zone(), diskType); + public static DiskTypeId of(ZoneId zoneId, String type) { + return new DiskTypeId(zoneId.project(), zoneId.zone(), type); } /** * Returns a disk type identity given the zone and disk type names. */ - public static DiskTypeId of(String zone, String diskType) { - return of(ZoneId.of(null, zone), diskType); + public static DiskTypeId of(String zone, String type) { + return of(ZoneId.of(null, zone), type); } /** * Returns a disk type identity given project disk, zone and disk type names. */ - public static DiskTypeId of(String project, String zone, String diskType) { - return of(ZoneId.of(project, zone), diskType); + public static DiskTypeId of(String project, String zone, String type) { + return of(ZoneId.of(project, zone), type); } /** diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java index 2d7bfa7d26c8..a381ec1de6b4 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java @@ -260,7 +260,7 @@ com.google.api.services.compute.model.MachineType toPb() { if (creationTimestamp != null) { machineTypePb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); } - machineTypePb.setName(machineTypeId.machineType()); + machineTypePb.setName(machineTypeId.type()); machineTypePb.setDescription(description); machineTypePb.setSelfLink(machineTypeId.selfLink()); machineTypePb.setGuestCpus(cpus); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java index a431d29d1e85..1d1e214a1475 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java @@ -50,19 +50,19 @@ public String apply(MachineTypeId machineTypeId) { private static final long serialVersionUID = -5819598544478859608L; private final String zone; - private final String machineType; + private final String type; - private MachineTypeId(String project, String zone, String machineType) { + private MachineTypeId(String project, String zone, String type) { super(project); this.zone = checkNotNull(zone); - this.machineType = checkNotNull(machineType); + this.type = checkNotNull(type); } /** * Returns the name of the machine type. */ - public String machineType() { - return machineType; + public String type() { + return type; } /** @@ -81,17 +81,17 @@ public ZoneId zoneId() { @Override public String selfLink() { - return super.selfLink() + "/zones/" + zone + "/machineTypes/" + machineType; + return super.selfLink() + "/zones/" + zone + "/machineTypes/" + type; } @Override MoreObjects.ToStringHelper toStringHelper() { - return super.toStringHelper().add("zone", zone).add("machineType", machineType); + return super.toStringHelper().add("zone", zone).add("type", type); } @Override public int hashCode() { - return Objects.hash(baseHashCode(), zone, machineType); + return Objects.hash(baseHashCode(), zone, type); } @Override @@ -105,7 +105,7 @@ public boolean equals(Object obj) { MachineTypeId other = (MachineTypeId) obj; return baseEquals(other) && Objects.equals(zone, other.zone) - && Objects.equals(machineType, other.machineType); + && Objects.equals(type, other.type); } @Override @@ -113,21 +113,21 @@ MachineTypeId setProjectId(String projectId) { if (project() != null) { return this; } - return MachineTypeId.of(projectId, zone, machineType); + return MachineTypeId.of(projectId, zone, type); } /** * Returns a machine type identity given the zone and type names. */ - public static MachineTypeId of(String zone, String machineType) { - return new MachineTypeId(null, zone, machineType); + public static MachineTypeId of(String zone, String type) { + return new MachineTypeId(null, zone, type); } /** * Returns a machine type identity given project, zone and type names. */ - public static MachineTypeId of(String project, String zone, String machineType) { - return new MachineTypeId(project, zone, machineType); + public static MachineTypeId of(String project, String zone, String type) { + return new MachineTypeId(project, zone, type); } /** diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java index 85ddd0e3595b..3dd28c043fd7 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java @@ -561,28 +561,28 @@ public void testGetOptions() { @Test public void testGetDiskType() { EasyMock.expect( - computeRpcMock.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.diskType(), EMPTY_RPC_OPTIONS)) + computeRpcMock.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.type(), EMPTY_RPC_OPTIONS)) .andReturn(DISK_TYPE.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - DiskType diskType = compute.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.diskType()); + DiskType diskType = compute.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.type()); assertEquals(DISK_TYPE, diskType); } @Test public void testGetDiskType_Null() { EasyMock.expect( - computeRpcMock.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.diskType(), EMPTY_RPC_OPTIONS)) + computeRpcMock.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.type(), EMPTY_RPC_OPTIONS)) .andReturn(null); EasyMock.replay(computeRpcMock); compute = options.service(); - assertNull(compute.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.diskType())); + assertNull(compute.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.type())); } @Test public void testGetDiskTypeFromDiskTypeId() { EasyMock.expect( - computeRpcMock.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.diskType(), EMPTY_RPC_OPTIONS)) + computeRpcMock.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.type(), EMPTY_RPC_OPTIONS)) .andReturn(DISK_TYPE.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); @@ -595,12 +595,12 @@ public void testGetDiskTypeWithSelectedFields() { Capture> capturedOptions = Capture.newInstance(); EasyMock.expect( computeRpcMock.getDiskType( - eq(DISK_TYPE_ID.zone()), eq(DISK_TYPE_ID.diskType()), capture(capturedOptions))) + eq(DISK_TYPE_ID.zone()), eq(DISK_TYPE_ID.type()), capture(capturedOptions))) .andReturn(DISK_TYPE.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); DiskType diskType = - compute.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.diskType(), DISK_TYPE_OPTION_FIELDS); + compute.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.type(), DISK_TYPE_OPTION_FIELDS); String selector = (String) capturedOptions.getValue().get(DISK_TYPE_OPTION_FIELDS.rpcOption()); assertTrue(selector.contains("selfLink")); assertTrue(selector.contains("id")); @@ -748,12 +748,12 @@ public void testAggregatedListDiskTypesWithOptions() { public void testGetMachineType() { EasyMock.expect( computeRpcMock.getMachineType( - MACHINE_TYPE_ID.zone(), MACHINE_TYPE_ID.machineType(), EMPTY_RPC_OPTIONS)) + MACHINE_TYPE_ID.zone(), MACHINE_TYPE_ID.type(), EMPTY_RPC_OPTIONS)) .andReturn(MACHINE_TYPE.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); MachineType machineType = - compute.getMachineType(MACHINE_TYPE_ID.zone(), MACHINE_TYPE_ID.machineType()); + compute.getMachineType(MACHINE_TYPE_ID.zone(), MACHINE_TYPE_ID.type()); assertEquals(MACHINE_TYPE, machineType); } @@ -761,17 +761,17 @@ public void testGetMachineType() { public void testGetMachineType_Null() { EasyMock.expect( computeRpcMock.getMachineType( - MACHINE_TYPE_ID.zone(), MACHINE_TYPE_ID.machineType(), EMPTY_RPC_OPTIONS)) + MACHINE_TYPE_ID.zone(), MACHINE_TYPE_ID.type(), EMPTY_RPC_OPTIONS)) .andReturn(null); EasyMock.replay(computeRpcMock); compute = options.service(); - assertNull(compute.getMachineType(MACHINE_TYPE_ID.zone(), MACHINE_TYPE_ID.machineType())); + assertNull(compute.getMachineType(MACHINE_TYPE_ID.zone(), MACHINE_TYPE_ID.type())); } @Test public void testGetMachineTypeFromMachineTypeId() { EasyMock.expect(computeRpcMock.getMachineType( - MACHINE_TYPE_ID.zone(), MACHINE_TYPE_ID.machineType(), EMPTY_RPC_OPTIONS)) + MACHINE_TYPE_ID.zone(), MACHINE_TYPE_ID.type(), EMPTY_RPC_OPTIONS)) .andReturn(MACHINE_TYPE.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); @@ -783,13 +783,13 @@ public void testGetMachineTypeFromMachineTypeId() { public void testGetMachineTypeWithSelectedFields() { Capture> capturedOptions = Capture.newInstance(); EasyMock.expect( - computeRpcMock.getMachineType(eq(MACHINE_TYPE_ID.zone()), eq(MACHINE_TYPE_ID.machineType()), + computeRpcMock.getMachineType(eq(MACHINE_TYPE_ID.zone()), eq(MACHINE_TYPE_ID.type()), capture(capturedOptions))) .andReturn(MACHINE_TYPE.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); MachineType machineType = compute.getMachineType(MACHINE_TYPE_ID.zone(), - MACHINE_TYPE_ID.machineType(), MACHINE_TYPE_OPTION_FIELDS); + MACHINE_TYPE_ID.type(), MACHINE_TYPE_OPTION_FIELDS); String selector = (String) capturedOptions.getValue().get(DISK_TYPE_OPTION_FIELDS.rpcOption()); assertTrue(selector.contains("selfLink")); assertTrue(selector.contains("id")); @@ -3169,7 +3169,7 @@ public void testCreateNetworkWithOptions() { @Test public void testRetryableException() { EasyMock.expect( - computeRpcMock.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.diskType(), EMPTY_RPC_OPTIONS)) + computeRpcMock.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.type(), EMPTY_RPC_OPTIONS)) .andThrow(new ComputeException(500, "InternalError")) .andReturn(DISK_TYPE.toPb()); EasyMock.replay(computeRpcMock); @@ -3182,7 +3182,7 @@ public void testRetryableException() { public void testNonRetryableException() { String exceptionMessage = "Not Implemented"; EasyMock.expect( - computeRpcMock.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.diskType(), EMPTY_RPC_OPTIONS)) + computeRpcMock.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.type(), EMPTY_RPC_OPTIONS)) .andThrow(new ComputeException(501, exceptionMessage)); EasyMock.replay(computeRpcMock); compute = options.toBuilder().retryParams(RetryParams.defaultInstance()).build().service(); @@ -3195,7 +3195,7 @@ public void testNonRetryableException() { public void testRuntimeException() { String exceptionMessage = "Artificial runtime exception"; EasyMock.expect( - computeRpcMock.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.diskType(), EMPTY_RPC_OPTIONS)) + computeRpcMock.getDiskType(DISK_TYPE_ID.zone(), DISK_TYPE_ID.type(), EMPTY_RPC_OPTIONS)) .andThrow(new RuntimeException(exceptionMessage)); EasyMock.replay(computeRpcMock); compute = options.toBuilder().retryParams(RetryParams.defaultInstance()).build().service(); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskInfoTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskInfoTest.java index 1138d8008452..69919a871a49 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskInfoTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskInfoTest.java @@ -224,7 +224,7 @@ public void testToAndFromPb() { @Test public void testSetProjectId() { StandardDiskConfiguration standardDiskConfiguration = DISK_CONFIGURATION.toBuilder() - .diskType(DiskTypeId.of(TYPE.zone(), TYPE.diskType())) + .diskType(DiskTypeId.of(TYPE.zone(), TYPE.type())) .build(); DiskInfo diskInfo = DISK_INFO.toBuilder() .diskId(DiskId.of(DISK_ID.zone(), DISK_ID.disk())) @@ -232,7 +232,7 @@ public void testSetProjectId() { .build(); compareDiskInfo(DISK_INFO, diskInfo.setProjectId("project")); SnapshotDiskConfiguration snapshotDiskConfiguration = SNAPSHOT_DISK_CONFIGURATION.toBuilder() - .diskType(DiskTypeId.of(TYPE.zone(), TYPE.diskType())) + .diskType(DiskTypeId.of(TYPE.zone(), TYPE.type())) .sourceSnapshot(SnapshotId.of(SNAPSHOT.snapshot())) .build(); diskInfo = SNAPSHOT_DISK_INFO.toBuilder() @@ -241,7 +241,7 @@ public void testSetProjectId() { .build(); compareDiskInfo(SNAPSHOT_DISK_INFO, diskInfo.setProjectId("project")); ImageDiskConfiguration imageDiskConfiguration = IMAGE_DISK_CONFIGURATION.toBuilder() - .diskType(DiskTypeId.of(TYPE.zone(), TYPE.diskType())) + .diskType(DiskTypeId.of(TYPE.zone(), TYPE.type())) .sourceImage(ImageId.of(IMAGE.image())) .build(); diskInfo = IMAGE_DISK_INFO.toBuilder() diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java index 5ff61d5777ba..c71099de1ecb 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java @@ -42,12 +42,12 @@ public void testOf() { DiskTypeId diskTypeId = DiskTypeId.of(PROJECT, ZONE, DISK_TYPE); assertEquals(PROJECT, diskTypeId.project()); assertEquals(ZONE, diskTypeId.zone()); - assertEquals(DISK_TYPE, diskTypeId.diskType()); + assertEquals(DISK_TYPE, diskTypeId.type()); assertEquals(URL, diskTypeId.selfLink()); diskTypeId = DiskTypeId.of(ZONE, DISK_TYPE); assertNull(diskTypeId.project()); assertEquals(ZONE, diskTypeId.zone()); - assertEquals(DISK_TYPE, diskTypeId.diskType()); + assertEquals(DISK_TYPE, diskTypeId.type()); } @Test @@ -77,7 +77,7 @@ private void compareDiskTypeId(DiskTypeId expected, DiskTypeId value) { assertEquals(expected, value); assertEquals(expected.project(), expected.project()); assertEquals(expected.zone(), expected.zone()); - assertEquals(expected.diskType(), expected.diskType()); + assertEquals(expected.type(), expected.type()); assertEquals(expected.selfLink(), expected.selfLink()); assertEquals(expected.hashCode(), expected.hashCode()); } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageDiskConfigurationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageDiskConfigurationTest.java index f388109db199..54e0e1607109 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageDiskConfigurationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageDiskConfigurationTest.java @@ -93,7 +93,7 @@ public void testOf() { @Test public void testSetProjectId() { ImageDiskConfiguration diskConfiguration = DISK_CONFIGURATION.toBuilder() - .diskType(DiskTypeId.of(DISK_TYPE.zone(), DISK_TYPE.diskType())) + .diskType(DiskTypeId.of(DISK_TYPE.zone(), DISK_TYPE.type())) .sourceImage(ImageId.of(IMAGE.image())) .build(); compareImageDiskConfiguration(DISK_CONFIGURATION, diskConfiguration.setProjectId("project")); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java index 7e3f4d7eae35..10a607235a9e 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java @@ -42,12 +42,12 @@ public void testOf() { MachineTypeId machineTypeId = MachineTypeId.of(PROJECT, ZONE, TYPE); assertEquals(PROJECT, machineTypeId.project()); assertEquals(ZONE, machineTypeId.zone()); - assertEquals(TYPE, machineTypeId.machineType()); + assertEquals(TYPE, machineTypeId.type()); assertEquals(URL, machineTypeId.selfLink()); machineTypeId = MachineTypeId.of(ZONE, TYPE); assertNull(machineTypeId.project()); assertEquals(ZONE, machineTypeId.zone()); - assertEquals(TYPE, machineTypeId.machineType()); + assertEquals(TYPE, machineTypeId.type()); } @Test @@ -76,7 +76,7 @@ private void compareMachineTypeId(MachineTypeId expected, MachineTypeId value) { assertEquals(expected, value); assertEquals(expected.project(), expected.project()); assertEquals(expected.zone(), expected.zone()); - assertEquals(expected.machineType(), expected.machineType()); + assertEquals(expected.type(), expected.type()); assertEquals(expected.selfLink(), expected.selfLink()); assertEquals(expected.hashCode(), expected.hashCode()); } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotDiskConfigurationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotDiskConfigurationTest.java index a6380dca667d..313ece829b25 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotDiskConfigurationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotDiskConfigurationTest.java @@ -93,7 +93,7 @@ public void testOf() { @Test public void testSetProjectId() { SnapshotDiskConfiguration configuration = DISK_CONFIGURATION.toBuilder() - .diskType(DiskTypeId.of(DISK_TYPE.zone(), DISK_TYPE.diskType())) + .diskType(DiskTypeId.of(DISK_TYPE.zone(), DISK_TYPE.type())) .sourceSnapshot(SnapshotId.of(SNAPSHOT.snapshot())) .build(); compareSnapshotDiskConfiguration(DISK_CONFIGURATION, configuration.setProjectId("project")); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/StandardDiskConfigurationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/StandardDiskConfigurationTest.java index 702a362b6ddc..9240a758ab58 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/StandardDiskConfigurationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/StandardDiskConfigurationTest.java @@ -87,7 +87,7 @@ public void testOf() { @Test public void testSetProjectId() { StandardDiskConfiguration configuration = DISK_CONFIGURATION.toBuilder() - .diskType(DiskTypeId.of(DISK_TYPE.zone(), DISK_TYPE.diskType())) + .diskType(DiskTypeId.of(DISK_TYPE.zone(), DISK_TYPE.type())) .build(); compareStandardDiskConfiguration(DISK_CONFIGURATION, configuration.setProjectId("project")); } diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java index aa94baf9809e..d47d0fb6082b 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java @@ -104,7 +104,7 @@ public void testGetDiskType() { DiskType diskType = compute.getDiskType(ZONE, DISK_TYPE); // assertNotNull(diskType.id()); assertEquals(ZONE, diskType.diskTypeId().zone()); - assertEquals(DISK_TYPE, diskType.diskTypeId().diskType()); + assertEquals(DISK_TYPE, diskType.diskTypeId().type()); assertNotNull(diskType.creationTimestamp()); assertNotNull(diskType.description()); assertNotNull(diskType.validDiskSize()); @@ -117,7 +117,7 @@ public void testGetDiskTypeWithSelectedFields() { Compute.DiskTypeOption.fields(Compute.DiskTypeField.CREATION_TIMESTAMP)); // assertNotNull(diskType.id()); assertEquals(ZONE, diskType.diskTypeId().zone()); - assertEquals(DISK_TYPE, diskType.diskTypeId().diskType()); + assertEquals(DISK_TYPE, diskType.diskTypeId().type()); assertNotNull(diskType.creationTimestamp()); assertNull(diskType.description()); assertNull(diskType.validDiskSize()); @@ -216,7 +216,7 @@ public void testAggregatedListDiskTypesWithFilter() { public void testGetMachineType() { MachineType machineType = compute.getMachineType(ZONE, MACHINE_TYPE); assertEquals(ZONE, machineType.machineTypeId().zone()); - assertEquals(MACHINE_TYPE, machineType.machineTypeId().machineType()); + assertEquals(MACHINE_TYPE, machineType.machineTypeId().type()); assertNotNull(machineType.id()); assertNotNull(machineType.creationTimestamp()); assertNotNull(machineType.description()); @@ -231,7 +231,7 @@ public void testGetMachineTypeWithSelectedFields() { MachineType machineType = compute.getMachineType(ZONE, MACHINE_TYPE, Compute.MachineTypeOption.fields(Compute.MachineTypeField.ID)); assertEquals(ZONE, machineType.machineTypeId().zone()); - assertEquals(MACHINE_TYPE, machineType.machineTypeId().machineType()); + assertEquals(MACHINE_TYPE, machineType.machineTypeId().type()); assertNotNull(machineType.id()); assertNull(machineType.creationTimestamp()); assertNull(machineType.description()); @@ -901,7 +901,7 @@ public void testCreateGetResizeAndDeleteStandardDisk() throws InterruptedExcepti assertTrue(remoteDisk.configuration() instanceof StandardDiskConfiguration); StandardDiskConfiguration remoteConfiguration = remoteDisk.configuration(); assertEquals(100L, (long) remoteConfiguration.sizeGb()); - assertEquals("pd-ssd", remoteConfiguration.diskType().diskType()); + assertEquals("pd-ssd", remoteConfiguration.diskType().type()); assertEquals(DiskConfiguration.Type.STANDARD, remoteConfiguration.type()); assertNull(remoteDisk.lastAttachTimestamp()); assertNull(remoteDisk.lastDetachTimestamp()); @@ -919,7 +919,7 @@ public void testCreateGetResizeAndDeleteStandardDisk() throws InterruptedExcepti assertTrue(remoteDisk.configuration() instanceof StandardDiskConfiguration); remoteConfiguration = remoteDisk.configuration(); assertEquals(200L, (long) remoteConfiguration.sizeGb()); - assertEquals("pd-ssd", remoteConfiguration.diskType().diskType()); + assertEquals("pd-ssd", remoteConfiguration.diskType().type()); assertEquals(DiskConfiguration.Type.STANDARD, remoteConfiguration.type()); assertNull(remoteDisk.lastAttachTimestamp()); assertNull(remoteDisk.lastDetachTimestamp()); @@ -953,7 +953,7 @@ public void testCreateGetAndDeleteImageDisk() throws InterruptedException { assertNotNull(remoteConfiguration.sourceImageId()); assertEquals(DiskConfiguration.Type.IMAGE, remoteConfiguration.type()); assertNotNull(remoteConfiguration.sizeGb()); - assertEquals("pd-standard", remoteConfiguration.diskType().diskType()); + assertEquals("pd-standard", remoteConfiguration.diskType().type()); assertNull(remoteDisk.lastAttachTimestamp()); assertNull(remoteDisk.lastDetachTimestamp()); // test get with selected fields @@ -969,7 +969,7 @@ public void testCreateGetAndDeleteImageDisk() throws InterruptedException { assertNull(remoteConfiguration.sourceImageId()); assertEquals(DiskConfiguration.Type.IMAGE, remoteConfiguration.type()); assertNull(remoteConfiguration.sizeGb()); - assertEquals("pd-standard", remoteConfiguration.diskType().diskType()); + assertEquals("pd-standard", remoteConfiguration.diskType().type()); assertNull(remoteDisk.lastAttachTimestamp()); assertNull(remoteDisk.lastDetachTimestamp()); operation = remoteDisk.delete(); @@ -1042,7 +1042,7 @@ public void testCreateGetAndDeleteSnapshotAndSnapshotDisk() throws InterruptedEx assertEquals(DiskConfiguration.Type.SNAPSHOT, remoteConfiguration.type()); assertEquals(snapshotName, remoteConfiguration.sourceSnapshot().snapshot()); assertEquals(100L, (long) remoteConfiguration.sizeGb()); - assertEquals("pd-standard", remoteConfiguration.diskType().diskType()); + assertEquals("pd-standard", remoteConfiguration.diskType().type()); assertNotNull(remoteConfiguration.sourceSnapshotId()); assertNull(remoteDisk.lastAttachTimestamp()); assertNull(remoteDisk.lastDetachTimestamp()); @@ -1059,7 +1059,7 @@ public void testCreateGetAndDeleteSnapshotAndSnapshotDisk() throws InterruptedEx assertEquals(DiskConfiguration.Type.SNAPSHOT, remoteConfiguration.type()); assertEquals(snapshotName, remoteConfiguration.sourceSnapshot().snapshot()); assertNull(remoteConfiguration.sizeGb()); - assertEquals("pd-standard", remoteConfiguration.diskType().diskType()); + assertEquals("pd-standard", remoteConfiguration.diskType().type()); assertNull(remoteDisk.configuration().sourceSnapshotId()); assertNull(remoteDisk.lastAttachTimestamp()); assertNull(remoteDisk.lastDetachTimestamp()); @@ -1108,7 +1108,7 @@ public void testListDisksAndSnapshots() throws InterruptedException { assertTrue(remoteDisk.configuration() instanceof StandardDiskConfiguration); StandardDiskConfiguration remoteConfiguration = remoteDisk.configuration(); assertEquals(100L, (long) remoteConfiguration.sizeGb()); - assertEquals("pd-ssd", remoteConfiguration.diskType().diskType()); + assertEquals("pd-ssd", remoteConfiguration.diskType().type()); assertEquals(DiskConfiguration.Type.STANDARD, remoteConfiguration.type()); assertNull(remoteDisk.lastAttachTimestamp()); assertNull(remoteDisk.lastDetachTimestamp()); @@ -1130,7 +1130,7 @@ public void testListDisksAndSnapshots() throws InterruptedException { assertTrue(remoteDisk.configuration() instanceof StandardDiskConfiguration); StandardDiskConfiguration remoteConfiguration = remoteDisk.configuration(); assertNull(remoteConfiguration.sizeGb()); - assertEquals("pd-ssd", remoteConfiguration.diskType().diskType()); + assertEquals("pd-ssd", remoteConfiguration.diskType().type()); assertEquals(DiskConfiguration.Type.STANDARD, remoteConfiguration.type()); assertNull(remoteDisk.lastAttachTimestamp()); assertNull(remoteDisk.lastDetachTimestamp()); @@ -1228,7 +1228,7 @@ public void testAggregatedListDisks() throws InterruptedException { assertTrue(remoteDisk.configuration() instanceof StandardDiskConfiguration); StandardDiskConfiguration remoteConfiguration = remoteDisk.configuration(); assertEquals(100L, (long) remoteConfiguration.sizeGb()); - assertEquals("pd-ssd", remoteConfiguration.diskType().diskType()); + assertEquals("pd-ssd", remoteConfiguration.diskType().type()); assertEquals(DiskConfiguration.Type.STANDARD, remoteConfiguration.type()); count++; } From 9d1d455823ffb2750129725e181781cba06912bf Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 27 Apr 2016 16:54:02 +0200 Subject: [PATCH 323/375] Add functional methods for instances, Instance class and tests (#959) --- .../com/google/gcloud/compute/Compute.java | 389 ++++++++ .../google/gcloud/compute/ComputeImpl.java | 437 ++++++++- .../com/google/gcloud/compute/Instance.java | 465 +++++++++ .../google/gcloud/compute/spi/ComputeRpc.java | 173 ++++ .../gcloud/compute/spi/DefaultComputeRpc.java | 261 +++++ .../gcloud/compute/ComputeImplTest.java | 816 ++++++++++++++++ .../google/gcloud/compute/InstanceTest.java | 895 ++++++++++++++++++ .../gcloud/compute/SerializationTest.java | 16 +- .../gcloud/compute/it/ITComputeTest.java | 320 +++++++ 9 files changed, 3769 insertions(+), 3 deletions(-) create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/Instance.java create mode 100644 gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceTest.java diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java index 907f581fcca6..0512a1554ee0 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java @@ -23,6 +23,8 @@ import com.google.common.collect.Sets; import com.google.gcloud.Page; import com.google.gcloud.Service; +import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; +import com.google.gcloud.compute.NetworkInterface.AccessConfig; import com.google.gcloud.compute.spi.ComputeRpc; import java.io.Serializable; @@ -520,6 +522,51 @@ static String selector(NetworkField... fields) { } } + /** + * Fields of a Compute Engine Instance resource. + * + * @see + * Network Resource + */ + enum InstanceField { + CAN_IP_FORWARD("canIpForward"), + CPU_PLATFORM("cpuPlatform"), + CREATION_TIMESTAMP("creationTimestamp"), + DESCRIPTION("description"), + DISKS("disks"), + ID("id"), + MACHINE_TYPE("machineType"), + METADATA("metadata"), + NAME("name"), + NETWORK_INTERFACES("networkInterfaces"), + SCHEDULING("scheduling"), + SELF_LINK("selfLink"), + SERVICE_ACCOUNTS("serviceAccounts"), + STATUS("status"), + STATUS_MESSAGE("statusMessage"), + TAGS("tags"), + ZONE("zone"); + + private final String selector; + + InstanceField(String selector) { + this.selector = selector; + } + + public String selector() { + return selector; + } + + static String selector(InstanceField... fields) { + Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); + fieldStrings.add(SELF_LINK.selector()); + for (InstanceField field : fields) { + fieldStrings.add(field.selector()); + } + return Joiner.on(',').join(fieldStrings); + } + } + /** * Base class for list filters. */ @@ -1045,6 +1092,54 @@ public static NetworkFilter notEquals(NetworkField field, boolean value) { } } + /** + * Class for filtering instance lists. + */ + class InstanceFilter extends ListFilter { + + private static final long serialVersionUID = 679008888882025686L; + + private InstanceFilter(InstanceField field, ComparisonOperator operator, Object value) { + super(field.selector(), operator, value); + } + + /** + * Returns an equals filter for the given field and string value. For string fields, + * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must + * match the entire field. + * + * @see RE2 + */ + public static InstanceFilter equals(InstanceField field, String value) { + return new InstanceFilter(checkNotNull(field), ComparisonOperator.EQ, checkNotNull(value)); + } + + /** + * Returns a not-equals filter for the given field and string value. For string fields, + * {@code value} is interpreted as a regular expression using RE2 syntax. {@code value} must + * match the entire field. + * + * @see RE2 + */ + public static InstanceFilter notEquals(InstanceField field, String value) { + return new InstanceFilter(checkNotNull(field), ComparisonOperator.NE, checkNotNull(value)); + } + + /** + * Returns a equals filter for the given field and boolean value. + */ + public static InstanceFilter equals(InstanceField field, boolean value) { + return new InstanceFilter(checkNotNull(field), ComparisonOperator.EQ, value); + } + + /** + * Returns a not-equals filter for the given field and boolean value. + */ + public static InstanceFilter notEquals(InstanceField field, boolean value) { + return new InstanceFilter(checkNotNull(field), ComparisonOperator.EQ, value); + } + } + /** * Class for specifying disk type get options. */ @@ -1989,6 +2084,108 @@ public static NetworkListOption fields(NetworkField... fields) { } } + /** + * Class for specifying instance get options. + */ + class InstanceOption extends Option { + + private static final long serialVersionUID = -5277658025892081493L; + + private InstanceOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify the instance's fields to be returned by the RPC call. If this + * option is not provided, all instance's fields are returned. {@code InstanceOption.fields} + * can be used to specify only the fields of interest. {@link Instance#instanceId()} is always + * returned, even if not specified. + */ + public static InstanceOption fields(InstanceField... fields) { + return new InstanceOption(ComputeRpc.Option.FIELDS, InstanceField.selector(fields)); + } + } + + /** + * Class for specifying instance list options. + */ + class InstanceListOption extends Option { + + private static final long serialVersionUID = -1096684312959047430L; + + private InstanceListOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify a filter on the instances being listed. + */ + public static InstanceListOption filter(InstanceFilter filter) { + return new InstanceListOption(ComputeRpc.Option.FILTER, filter.toPb()); + } + + /** + * Returns an option to specify the maximum number of instances returned per page. + * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used. + */ + public static InstanceListOption pageSize(long pageSize) { + return new InstanceListOption(ComputeRpc.Option.MAX_RESULTS, pageSize); + } + + /** + * Returns an option to specify the page token from which to start listing instances. + */ + public static InstanceListOption pageToken(String pageToken) { + return new InstanceListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); + } + + /** + * Returns an option to specify the instance's fields to be returned by the RPC call. If this + * option is not provided, all instance's fields are returned. {@code InstanceListOption.fields} + * can be used to specify only the fields of interest. {@link Instance#instanceId()} is always + * returned, even if not specified. + */ + public static InstanceListOption fields(InstanceField... fields) { + StringBuilder builder = new StringBuilder(); + builder.append("items(").append(InstanceField.selector(fields)).append("),nextPageToken"); + return new InstanceListOption(ComputeRpc.Option.FIELDS, builder.toString()); + } + } + + /** + * Class for specifying instance aggregated list options. + */ + class InstanceAggregatedListOption extends Option { + + private static final long serialVersionUID = -2020005298975967713L; + + private InstanceAggregatedListOption(ComputeRpc.Option option, Object value) { + super(option, value); + } + + /** + * Returns an option to specify a filter on the instances being listed. + */ + public static InstanceAggregatedListOption filter(InstanceFilter filter) { + return new InstanceAggregatedListOption(ComputeRpc.Option.FILTER, filter.toPb()); + } + + /** + * Returns an option to specify the maximum number of instances returned per page. + * {@code pageSize} must be between 0 and 500 (inclusive). If not specified 500 is used. + */ + public static InstanceAggregatedListOption pageSize(long pageSize) { + return new InstanceAggregatedListOption(ComputeRpc.Option.MAX_RESULTS, pageSize); + } + + /** + * Returns an option to specify the page token from which to start listing instances. + */ + public static InstanceAggregatedListOption pageToken(String pageToken) { + return new InstanceAggregatedListOption(ComputeRpc.Option.PAGE_TOKEN, pageToken); + } + } + /** * Returns the requested disk type or {@code null} if not found. * @@ -2397,4 +2594,196 @@ Operation deprecate(ImageId image, DeprecationStatus deprecationStatus, * @throws ComputeException upon failure */ Operation deleteNetwork(NetworkId network, OperationOption... options); + + /** + * Creates a new instance. + * + * @return a zone operation for instance's creation + * @throws ComputeException upon failure + */ + Operation create(InstanceInfo instance, OperationOption... options); + + /** + * Returns the requested instance or {@code null} if not found. + * + * @throws ComputeException upon failure + */ + Instance get(InstanceId instance, InstanceOption... options); + + /** + * Lists instances for the provided zone. + * + * @throws ComputeException upon failure + */ + Page listInstances(String zone, InstanceListOption... options); + + /** + * Lists instances for all zones. + * + * @throws ComputeException upon failure + */ + Page listInstances(InstanceAggregatedListOption... options); + + /** + * Deletes the requested instance. + * + * @return a zone operation if the delete request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + Operation delete(InstanceId instance, OperationOption... options); + + /** + * Adds an access configuration to an instance's network interface. + * + * @return a zone operation if the add request was issued correctly, {@code null} if the instance + * was not found + * @throws ComputeException upon failure + */ + Operation addAccessConfig(InstanceId instance, String networkInterface, AccessConfig accessConfig, + OperationOption... options); + + /** + * Attaches a persistent disk to an instance given its configuration. + * + * @return a zone operation if the attach request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + Operation attachDisk(InstanceId instance, PersistentDiskConfiguration configuration, + OperationOption... options); + + /** + * Attaches a persistent disk to an instance given the device name and its configuration. + * + * @return a zone operation if the attach request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + Operation attachDisk(InstanceId instance, String deviceName, + PersistentDiskConfiguration configuration, OperationOption... options); + + /** + * Attaches a persistent disk to an instance given the device name, its configuration and the + * device index. + * + * @return a zone operation if the attach request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + Operation attachDisk(InstanceId instance, String deviceName, + PersistentDiskConfiguration configuration, int index, OperationOption... options); + + /** + * Deletes an access configuration from an instance's network interface. + * + * @return a zone operation if the delete request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + Operation deleteAccessConfig(InstanceId instance, String networkInterface, String accessConfig, + OperationOption... options); + + /** + * Detaches a disk from an instance. + * + * @return a zone operation if the detach request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + Operation detachDisk(InstanceId instance, String deviceName, OperationOption... options); + + /** + * Returns the serial port output for the provided instance and port number. {@code port} must be + * between 1 and 4 (inclusive). + * + * @return the serial port output or {@code null} if the instance was not found + * @throws ComputeException upon failure + */ + String getSerialPortOutput(InstanceId instance, int port); + + /** + * Returns the default serial port output for the provided instance. Default serial port + * corresponds to port number 1. + * + * @return the serial port output or {@code null} if the instance was not found + * @throws ComputeException upon failure + */ + String getSerialPortOutput(InstanceId instance); + + /** + * Resets the provided instance. + * + * @return a zone operation if the reset request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + Operation reset(InstanceId instance, OperationOption... options); + + /** + * Sets the auto-delete flag for a disk attached to the provided instance. + * + * @return a zone operation if the flag setting request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + Operation setDiskAutoDelete(InstanceId instance, String deviceName, boolean autoDelete, + OperationOption... options); + + /** + * Sets the machine type for the provided instance. Instance must be in + * {@link InstanceInfo.Status#TERMINATED} state to be able to set its machine type. + * + * @return a zone operation if the set request was issued correctly, {@code null} if the instance + * was not found + * @throws ComputeException upon failure + */ + Operation setMachineType(InstanceId instance, MachineTypeId machineType, + OperationOption... options); + + /** + * Sets the metadata for the provided instance. + * + * @return a zone operation if the set request was issued correctly, {@code null} if the instance + * was not found + * @throws ComputeException upon failure + */ + Operation setMetadata(InstanceId instance, Metadata metadata, OperationOption... options); + + /** + * Sets the scheduling options for the provided instance. + * + * @return a zone operation if the set request was issued correctly, {@code null} if the instance + * was not found + * @throws ComputeException upon failure + */ + Operation setSchedulingOptions(InstanceId instance, SchedulingOptions scheduling, + OperationOption... options); + + /** + * Sets the tags for the provided instance. + * + * @return a zone operation if the set request was issued correctly, {@code null} if the instance + * was not found + * @throws ComputeException upon failure + */ + Operation setTags(InstanceId instance, Tags tags, OperationOption... options); + + /** + * Starts the provided instance. + * + * @return a zone operation if the start request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + Operation start(InstanceId instance, OperationOption... options); + + /** + * Stops the provided instance. + * + * @return a zone operation if the stop request was issued correctly, {@code null} if the instance + * was not found + * @throws ComputeException upon failure + */ + Operation stop(InstanceId instance, OperationOption... options); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java index d8ac3a840761..3a8f46a88265 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java @@ -28,6 +28,8 @@ import com.google.gcloud.PageImpl; import com.google.gcloud.PageImpl.NextPageFetcher; import com.google.gcloud.RetryHelper; +import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; +import com.google.gcloud.compute.NetworkInterface.AccessConfig; import com.google.gcloud.compute.spi.ComputeRpc; import java.util.Map; @@ -412,6 +414,46 @@ public Page nextPage() { } } + private static class InstancePageFetcher implements NextPageFetcher { + + private static final long serialVersionUID = 7563769742657453865L; + private final Map requestOptions; + private final ComputeOptions serviceOptions; + private final String zone; + + InstancePageFetcher(String zone, ComputeOptions serviceOptions, String cursor, + Map optionMap) { + this.requestOptions = + PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + this.zone = zone; + } + + @Override + public Page nextPage() { + return listInstances(zone, serviceOptions, requestOptions); + } + } + + private static class AggregatedInstancePageFetcher implements NextPageFetcher { + + private static final long serialVersionUID = 1863059389783095681L; + private final Map requestOptions; + private final ComputeOptions serviceOptions; + + AggregatedInstancePageFetcher(ComputeOptions serviceOptions, String cursor, + Map optionMap) { + this.requestOptions = + PageImpl.nextRequestOptions(ComputeRpc.Option.PAGE_TOKEN, cursor, optionMap); + this.serviceOptions = serviceOptions; + } + + @Override + public Page nextPage() { + return listInstances(serviceOptions, requestOptions); + } + } + private final ComputeRpc computeRpc; ComputeImpl(ComputeOptions options) { @@ -1431,7 +1473,7 @@ public com.google.api.services.compute.model.Subnetwork call() { } private static Function - subnetworkFromPb(final ComputeOptions serviceOptions) { + subnetworkFromPb(final ComputeOptions serviceOptions) { return new Function() { @Override public Subnetwork apply(com.google.api.services.compute.model.Subnetwork subnetwork) { @@ -1605,6 +1647,399 @@ public Operation deleteNetwork(String network, OperationOption... options) { return deleteNetwork(NetworkId.of(network)); } + @Override + public Operation create(InstanceInfo instance, OperationOption... options) { + final InstanceInfo completeInstance = instance.setProjectId(options().projectId()); + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.createInstance(completeInstance.instanceId().zone(), + completeInstance.toPb(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Instance get(final InstanceId instance, InstanceOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Instance answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Instance call() { + return computeRpc.getInstance(instance.zone(), instance.instance(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Instance.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + private static Function + instanceFromPb(final ComputeOptions serviceOptions) { + return new Function() { + @Override + public Instance apply(com.google.api.services.compute.model.Instance instance) { + return Instance.fromPb(serviceOptions.service(), instance); + } + }; + } + + @Override + public Page listInstances(String zone, InstanceListOption... options) { + return listInstances(zone, options(), optionMap(options)); + } + + private static Page listInstances(final String zone, + final ComputeOptions serviceOptions, final Map optionsMap) { + try { + ComputeRpc.Tuple> result = + runWithRetries(new Callable>>() { + @Override + public ComputeRpc.Tuple> call() { + return serviceOptions.rpc().listInstances(zone, optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.x(); + Iterable instances = Iterables.transform( + result.y() == null ? ImmutableList.of() + : result.y(), instanceFromPb(serviceOptions)); + return new PageImpl<>(new InstancePageFetcher(zone, serviceOptions, cursor, optionsMap), + cursor, instances); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Page listInstances(InstanceAggregatedListOption... options) { + return listInstances(options(), optionMap(options)); + } + + private static Page listInstances(final ComputeOptions serviceOptions, + final Map optionsMap) { + try { + ComputeRpc.Tuple> result = + runWithRetries(new Callable>>() { + @Override + public ComputeRpc.Tuple> call() { + return serviceOptions.rpc().listInstances(optionsMap); + } + }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + String cursor = result.x(); + Iterable instances = Iterables.transform( + result.y() == null ? ImmutableList.of() + : result.y(), instanceFromPb(serviceOptions)); + return new PageImpl<>(new AggregatedInstancePageFetcher(serviceOptions, cursor, optionsMap), + cursor, instances); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation delete(final InstanceId instance, OperationOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.deleteInstance(instance.zone(), instance.instance(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation addAccessConfig(final InstanceId instance, final String networkInterface, + final AccessConfig accessConfig, OperationOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.addAccessConfig(instance.zone(), instance.instance(), + networkInterface, accessConfig.toPb(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + private Operation attachDisk(final InstanceId instance, AttachedDisk diskToAttach, + OperationOption... options) { + final AttachedDisk completeDisk = diskToAttach.setProjectId(options().projectId()); + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.attachDisk(instance.zone(), instance.instance(), + completeDisk.toPb(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation attachDisk(InstanceId instance, PersistentDiskConfiguration configuration, + OperationOption... options) { + return attachDisk(instance, AttachedDisk.of(configuration), options); + } + + @Override + public Operation attachDisk(InstanceId instance, String deviceName, + PersistentDiskConfiguration configuration, OperationOption... options) { + return attachDisk(instance, AttachedDisk.of(deviceName, configuration), options); + } + + @Override + public Operation attachDisk(InstanceId instance, String deviceName, + PersistentDiskConfiguration configuration, int index, OperationOption... options) { + AttachedDisk attachedDisk = AttachedDisk.builder(configuration) + .deviceName(deviceName) + .index(index) + .build(); + return attachDisk(instance, attachedDisk, options); + } + + @Override + public Operation deleteAccessConfig(final InstanceId instance, final String networkInterface, + final String accessConfig, OperationOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.deleteAccessConfig(instance.zone(), instance.instance(), + networkInterface, accessConfig, optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation detachDisk(final InstanceId instance, final String deviceName, + OperationOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.detachDisk(instance.zone(), instance.instance(), deviceName, + optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public String getSerialPortOutput(final InstanceId instance, final int port) { + try { + return runWithRetries(new Callable() { + @Override + public String call() { + return computeRpc.getSerialPortOutput(instance.zone(), instance.instance(), port, + optionMap()); + } + }, options().retryParams(), EXCEPTION_HANDLER); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public String getSerialPortOutput(final InstanceId instance) { + try { + return runWithRetries(new Callable() { + @Override + public String call() { + return computeRpc.getSerialPortOutput(instance.zone(), instance.instance(), null, + optionMap()); + } + }, options().retryParams(), EXCEPTION_HANDLER); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation reset(final InstanceId instance, OperationOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.reset(instance.zone(), instance.instance(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation setDiskAutoDelete(final InstanceId instance, final String deviceName, + final boolean autoDelete, OperationOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.setDiskAutoDelete(instance.zone(), instance.instance(), deviceName, + autoDelete, optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation setMachineType(final InstanceId instance, final MachineTypeId machineType, + OperationOption... options) { + final String machineTypeUrl = machineType.setProjectId(options().projectId()).selfLink(); + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.setMachineType(instance.zone(), instance.instance(), machineTypeUrl, + optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation setMetadata(final InstanceId instance, final Metadata metadata, + OperationOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.setMetadata(instance.zone(), instance.instance(), metadata.toPb(), + optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation setSchedulingOptions(final InstanceId instance, + final SchedulingOptions schedulingOptions, OperationOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.setScheduling(instance.zone(), instance.instance(), + schedulingOptions.toPb(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation setTags(final InstanceId instance, final Tags tags, OperationOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.setTags(instance.zone(), instance.instance(), tags.toPb(), + optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation start(final InstanceId instance, OperationOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.start(instance.zone(), instance.instance(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + + @Override + public Operation stop(final InstanceId instance, OperationOption... options) { + final Map optionsMap = optionMap(options); + try { + com.google.api.services.compute.model.Operation answer = + runWithRetries(new Callable() { + @Override + public com.google.api.services.compute.model.Operation call() { + return computeRpc.stop(instance.zone(), instance.instance(), optionsMap); + } + }, options().retryParams(), EXCEPTION_HANDLER); + return answer == null ? null : Operation.fromPb(this, answer); + } catch (RetryHelper.RetryHelperException e) { + throw ComputeException.translateAndThrow(e); + } + } + private Map optionMap(Option... options) { Map optionMap = Maps.newEnumMap(ComputeRpc.Option.class); for (Option option : options) { diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Instance.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Instance.java new file mode 100644 index 000000000000..5f9aee0dd840 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Instance.java @@ -0,0 +1,465 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.collect.ImmutableList; +import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; +import com.google.gcloud.compute.Compute.InstanceOption; +import com.google.gcloud.compute.Compute.OperationOption; +import com.google.gcloud.compute.NetworkInterface.AccessConfig; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * A Google Compute Engine VM Instance. An instance is a virtual machine (VM) hosted on Google's + * infrastructure. Instances can run Linux and Windows Server images provided by Google, or any + * customized versions of these images. You can also build and run images of other operating + * systems. Objects of this class are immutable. To get an {@code Instance} object with the most + * recent information use {@link #reload}. {@code Instance} adds a layer of service-related + * functionality over {@link InstanceInfo}. + * + * @see Virtual Machine Instances + */ +public class Instance extends InstanceInfo { + + private static final long serialVersionUID = 3072508155558980677L; + + private final ComputeOptions options; + private transient Compute compute; + + /** + * A builder for {@code Instance} objects. + */ + public static class Builder extends InstanceInfo.Builder { + + private final Compute compute; + private final InstanceInfo.BuilderImpl infoBuilder; + + Builder(Compute compute, InstanceId instanceId, MachineTypeId machineType, + AttachedDisk attachedDisk, NetworkInterface networkInterface) { + this.compute = compute; + this.infoBuilder = new InstanceInfo.BuilderImpl(instanceId); + this.infoBuilder.machineType(machineType); + this.infoBuilder.attachedDisks(ImmutableList.of(attachedDisk)); + this.infoBuilder.networkInterfaces(ImmutableList.of(networkInterface)); + } + + Builder(Instance instance) { + this.compute = instance.compute; + this.infoBuilder = new InstanceInfo.BuilderImpl(instance); + } + + @Override + Builder id(String id) { + this.infoBuilder.id(id); + return this; + } + + @Override + public Builder instanceId(InstanceId instanceId) { + this.infoBuilder.instanceId(instanceId); + return this; + } + + @Override + Builder creationTimestamp(Long creationTimestamp) { + this.infoBuilder.creationTimestamp(creationTimestamp); + return this; + } + + @Override + public Builder description(String description) { + this.infoBuilder.description(description); + return this; + } + + @Override + Builder status(Status status) { + this.infoBuilder.status(status); + return this; + } + + @Override + Builder statusMessage(String statusMessage) { + this.infoBuilder.statusMessage(statusMessage); + return this; + } + + @Override + public Builder tags(Tags tags) { + this.infoBuilder.tags(tags); + return this; + } + + @Override + public Builder machineType(MachineTypeId machineType) { + this.infoBuilder.machineType(machineType); + return this; + } + + @Override + public Builder canIpForward(Boolean canIpForward) { + this.infoBuilder.canIpForward(canIpForward); + return this; + } + + @Override + public Builder networkInterfaces(List networkInterfaces) { + this.infoBuilder.networkInterfaces(networkInterfaces); + return this; + } + + @Override + public Builder networkInterfaces(NetworkInterface... networkInterfaces) { + this.infoBuilder.networkInterfaces(networkInterfaces); + return this; + } + + @Override + public Builder attachedDisks(List attachedDisks) { + this.infoBuilder.attachedDisks(attachedDisks); + return this; + } + + @Override + public Builder attachedDisks(AttachedDisk... attachedDisks) { + this.infoBuilder.attachedDisks(attachedDisks); + return this; + } + + @Override + public Builder metadata(Metadata metadata) { + this.infoBuilder.metadata(metadata); + return this; + } + + @Override + public Builder serviceAccounts(List serviceAccounts) { + this.infoBuilder.serviceAccounts(serviceAccounts); + return this; + } + + @Override + public Builder schedulingOptions(SchedulingOptions schedulingOptions) { + this.infoBuilder.schedulingOptions(schedulingOptions); + return this; + } + + @Override + Builder cpuPlatform(String cpuPlatform) { + this.infoBuilder.cpuPlatform(cpuPlatform); + return this; + } + + @Override + public Instance build() { + return new Instance(compute, infoBuilder); + } + } + + Instance(Compute compute, Instance.BuilderImpl infoBuilder) { + super(infoBuilder); + this.compute = checkNotNull(compute); + this.options = compute.options(); + } + + /** + * Checks if this instance exists. + * + * @return {@code true} if this instance exists, {@code false} otherwise + * @throws ComputeException upon failure + */ + public boolean exists() { + return reload(InstanceOption.fields()) != null; + } + + /** + * Fetches current instance's latest information. Returns {@code null} if the instance does not + * exist. + * + * @param options instance options + * @return a {@code Instance} object with latest information or {@code null} if not found + * @throws ComputeException upon failure + */ + public Instance reload(InstanceOption... options) { + return compute.get(instanceId(), options); + } + + /** + * Deletes this instance. + * + * @return a zone operation if delete request was successfully sent, {@code null} if the instance + * was not found + * @throws ComputeException upon failure + */ + public Operation delete(OperationOption... options) { + return compute.delete(instanceId(), options); + } + + /** + * Adds an access configuration to the provided network interface for this instance. + * + * @return a zone operation if the add request was issued correctly, {@code null} if the instance + * was not found + * @throws ComputeException upon failure + */ + public Operation addAccessConfig(String networkInterface, AccessConfig accessConfig, + OperationOption... options) { + return compute.addAccessConfig(instanceId(), networkInterface, accessConfig, options); + } + + /** + * Attaches a persistent disk to this instance given its configuration. + * + * @return a zone operation if the attach request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + public Operation attachDisk(PersistentDiskConfiguration configuration, + OperationOption... options) { + return compute.attachDisk(instanceId(), configuration, options); + } + + /** + * Attaches a persistent disk to this instance given the device name and its configuration. + * + * @return a zone operation if the attach request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + public Operation attachDisk(String deviceName, PersistentDiskConfiguration configuration, + OperationOption... options) { + return compute.attachDisk(instanceId(), deviceName, configuration, options); + } + + /** + * Attaches a persistent disk to this instance given the device name, its configuration and the + * device index. + * + * @return a zone operation if the attach request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + public Operation attachDisk(String deviceName, PersistentDiskConfiguration configuration, + int index, OperationOption... options) { + return compute.attachDisk(instanceId(), deviceName, configuration, index, options); + } + + /** + * Deletes an access configuration from the provided network interface for this instance. + * + * @return a zone operation if the delete request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + public Operation deleteAccessConfig(String networkInterface, String accessConfig, + OperationOption... options) { + return compute.deleteAccessConfig(instanceId(), networkInterface, accessConfig, options); + } + + /** + * Detaches a disk from this instance. + * + * @return a zone operation if the detach request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + public Operation detachDisk(String deviceName, OperationOption... options) { + return compute.detachDisk(instanceId(), deviceName, options); + } + + /** + * Returns the serial port output for this instance and port number. {@code port} must be between + * 1 and 4 (inclusive). + * + * @return the serial port output or {@code null} if the instance was not found + * @throws ComputeException upon failure + */ + public String getSerialPortOutput(int port) { + return compute.getSerialPortOutput(instanceId(), port); + } + + /** + * Returns the default serial port output for this instance. Default serial port corresponds to + * port number 1. + * + * @return the serial port output or {@code null} if the instance was not found + * @throws ComputeException upon failure + */ + public String getSerialPortOutput() { + return compute.getSerialPortOutput(instanceId()); + } + + /** + * Resets this instance. + * + * @return a zone operation if the reset request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + public Operation reset(OperationOption... options) { + return compute.reset(instanceId(), options); + } + + /** + * Sets the auto-delete flag for a disk attached to this instance. + * + * @return a zone operation if the flag setting request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + public Operation setDiskAutoDelete(String deviceName, boolean autoDelete, + OperationOption... options) { + return compute.setDiskAutoDelete(instanceId(), deviceName, autoDelete, options); + } + + /** + * Sets the machine type for this instance. The instance must be in + * {@link InstanceInfo.Status#TERMINATED} state to be able to set its machine type. + * + * @return a zone operation if the set request was issued correctly, {@code null} if the instance + * was not found + * @throws ComputeException upon failure + */ + public Operation setMachineType(MachineTypeId machineType, OperationOption... options) { + return compute.setMachineType(instanceId(), machineType, options); + } + + /** + * Sets the metadata for this instance. + * + * @return a zone operation if the set request was issued correctly, {@code null} if the instance + * was not found + * @throws ComputeException upon failure + */ + public Operation setMetadata(Metadata metadata, OperationOption... options) { + return compute.setMetadata(instanceId(), metadata, options); + } + + /** + * Sets the metadata for this instance, fingerprint value is taken from this instance's + * {@code tags().fingerprint()}. + * + * @return a zone operation if the set request was issued correctly, {@code null} if the instance + * was not found + * @throws ComputeException upon failure + */ + public Operation setMetadata(Map metadata, OperationOption... options) { + return setMetadata(metadata().toBuilder().values(metadata).build(), options); + } + + /** + * Sets the scheduling options for this instance. + * + * @return a zone operation if the set request was issued correctly, {@code null} if the instance + * was not found + * @throws ComputeException upon failure + */ + public Operation setSchedulingOptions(SchedulingOptions scheduling, OperationOption... options) { + return compute.setSchedulingOptions(instanceId(), scheduling, options); + } + + /** + * Sets the tags for this instance. + * + * @return a zone operation if the set request was issued correctly, {@code null} if the instance + * was not found + * @throws ComputeException upon failure + */ + public Operation setTags(Tags tags, OperationOption... options) { + return compute.setTags(instanceId(), tags, options); + } + + /** + * Sets the tags for this instance, fingerprint value is taken from this instance's + * {@code tags().fingerprint()}. + * + * @return a zone operation if the set request was issued correctly, {@code null} if the instance + * was not found + * @throws ComputeException upon failure + */ + public Operation setTags(Iterable tags, OperationOption... options) { + return setTags(tags().toBuilder().values(tags).build(), options); + } + + /** + * Starts this instance. + * + * @return a zone operation if the start request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + public Operation start(OperationOption... options) { + return compute.start(instanceId(), options); + } + + /** + * Stops this instance. + * + * @return a zone operation if the stop request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + public Operation stop(OperationOption... options) { + return compute.stop(instanceId(), options); + } + + /** + * Returns the snapshot's {@code Compute} object used to issue requests. + */ + public Compute compute() { + return compute; + } + + @Override + public Builder toBuilder() { + return new Builder(this); + } + + @Override + public final boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null || !obj.getClass().equals(Instance.class)) { + return false; + } + Instance other = (Instance) obj; + return Objects.equals(toPb(), other.toPb()) && Objects.equals(options, other.options); + } + + @Override + public final int hashCode() { + return Objects.hash(super.hashCode(), options); + } + + private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { + input.defaultReadObject(); + this.compute = options.service(); + } + + static Instance fromPb(Compute compute, + com.google.api.services.compute.model.Instance instancePb) { + return new Instance(compute, new InstanceInfo.BuilderImpl(instancePb)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/ComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/ComputeRpc.java index f3e51266aa50..4da5931d064c 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/ComputeRpc.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/ComputeRpc.java @@ -16,18 +16,24 @@ package com.google.gcloud.compute.spi; +import com.google.api.services.compute.model.AccessConfig; import com.google.api.services.compute.model.Address; +import com.google.api.services.compute.model.AttachedDisk; import com.google.api.services.compute.model.DeprecationStatus; import com.google.api.services.compute.model.Disk; import com.google.api.services.compute.model.DiskType; import com.google.api.services.compute.model.Image; +import com.google.api.services.compute.model.Instance; import com.google.api.services.compute.model.License; import com.google.api.services.compute.model.MachineType; +import com.google.api.services.compute.model.Metadata; import com.google.api.services.compute.model.Network; import com.google.api.services.compute.model.Operation; import com.google.api.services.compute.model.Region; +import com.google.api.services.compute.model.Scheduling; import com.google.api.services.compute.model.Snapshot; import com.google.api.services.compute.model.Subnetwork; +import com.google.api.services.compute.model.Tags; import com.google.api.services.compute.model.Zone; import com.google.gcloud.compute.ComputeException; @@ -496,4 +502,171 @@ Operation deprecateImage(String project, String image, DeprecationStatus depreca * @throws ComputeException upon failure */ Operation deleteNetwork(String network, Map options); + + /** + * Creates a new instance. + * + * @return a zone operation for instance's creation + * @throws ComputeException upon failure or if the zone does not exist + */ + Operation createInstance(String zone, Instance instance, Map options); + + /** + * Returns the requested instance or {@code null} if not found. + * + * @throws ComputeException upon failure or if the zone does not exist + */ + Instance getInstance(String zone, String instance, Map options); + + /** + * Lists instances for the provided zone. + * + * @throws ComputeException upon failure or if the zone does not exist + */ + Tuple> listInstances(String zone, Map options); + + /** + * Lists instances. + * + * @throws ComputeException upon failure + */ + Tuple> listInstances(Map options); + + /** + * Deletes the requested instance. + * + * @return a zone operation if the delete request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure or if the zone does not exist + */ + Operation deleteInstance(String zone, String instance, Map options); + + /** + * Adds an access configuration to an instance's network interface. + * + * @return a zone operation if the add request was issued correctly, {@code null} if the instance + * was not found + * @throws ComputeException upon failure + */ + Operation addAccessConfig(String zone, String instance, String networkInterface, + AccessConfig accessConfig, Map options); + + /** + * Attaches a disk to an instance. + * + * @return a zone operation if the attach request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + Operation attachDisk(String zone, String instance, AttachedDisk attachedDisk, + Map options); + + /** + * Deletes an access configuration from an instance's network interface. + * + * @return a zone operation if the delete request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + Operation deleteAccessConfig(String zone, String instance, String networkInterface, + String accessConfig, Map options); + + /** + * Detaches a disk from an instance. + * + * @return a zone operation if the detach request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + Operation detachDisk(String zone, String instance, String deviceName, Map options); + + /** + * Returns the serial port output for the provided instance and port number. {@code port} must be + * between 1 and 4 (inclusive). If {@code port} is {@code null} output for the default port (1) is + * returned. + * + * @return the serial port output or {@code null} if the instance was not found + * @throws ComputeException upon failure + */ + String getSerialPortOutput(String zone, String instance, Integer port, Map options); + + /** + * Resets the provided instance. + * + * @return a zone operation if the reset request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + Operation reset(String zone, String instance, Map options); + + /** + * Sets the auto-delete flag for a disk attached to the provided instance. + * + * @return a zone operation if the flag setting request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + Operation setDiskAutoDelete(String zone, String instance, String deviceName, boolean autoDelete, + Map options); + + /** + * Sets the machine type for the provided instance. Instance must be in {@code TERMINATED} state + * to be able to set its machine type. + * + * @param zone name of the zone in which the instance resides + * @param instance name of the instance + * @param machineTypeUrl full or partial URL of the machine type resource. For example + * {@code zones/us-central1-f/machineTypes/n1-standard-1}. + * @return a zone operation if the set request was issued correctly, {@code null} if the instance + * was not found + * @throws ComputeException upon failure + */ + Operation setMachineType(String zone, String instance, String machineTypeUrl, + Map options); + + /** + * Sets the metadata for the provided instance. + * + * @return a zone operation if the set request was issued correctly, {@code null} if the instance + * was not found + * @throws ComputeException upon failure + */ + Operation setMetadata(String zone, String instance, Metadata metadata, Map options); + + /** + * Sets the scheduling options for the provided instance. + * + * @return a zone operation if the set request was issued correctly, {@code null} if the instance + * was not found + * @throws ComputeException upon failure + */ + Operation setScheduling(String zone, String instance, Scheduling scheduling, + Map options); + + /** + * Sets the tags for the provided instance. + * + * @return a zone operation if the set request was issued correctly, {@code null} if the instance + * was not found + * @throws ComputeException upon failure + */ + Operation setTags(String zone, String instance, Tags tags, Map options); + + /** + * Starts the provided instance. + * + * @return a zone operation if the start request was issued correctly, {@code null} if the + * instance was not found + * @throws ComputeException upon failure + */ + Operation start(String zone, String instance, Map options); + + /** + * Stops the provided instance. + * + * @return a zone operation if the stop request was issued correctly, {@code null} if the instance + * was not found + * @throws ComputeException upon failure + */ + Operation stop(String zone, String instance, Map options); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/DefaultComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/DefaultComputeRpc.java index 9db50af5db4c..48f9f8d187d5 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/DefaultComputeRpc.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/DefaultComputeRpc.java @@ -26,10 +26,12 @@ import com.google.api.client.http.HttpTransport; import com.google.api.client.json.jackson.JacksonFactory; import com.google.api.services.compute.Compute; +import com.google.api.services.compute.model.AccessConfig; import com.google.api.services.compute.model.Address; import com.google.api.services.compute.model.AddressAggregatedList; import com.google.api.services.compute.model.AddressList; import com.google.api.services.compute.model.AddressesScopedList; +import com.google.api.services.compute.model.AttachedDisk; import com.google.api.services.compute.model.DeprecationStatus; import com.google.api.services.compute.model.Disk; import com.google.api.services.compute.model.DiskAggregatedList; @@ -42,23 +44,32 @@ import com.google.api.services.compute.model.DisksScopedList; import com.google.api.services.compute.model.Image; import com.google.api.services.compute.model.ImageList; +import com.google.api.services.compute.model.Instance; +import com.google.api.services.compute.model.InstanceAggregatedList; +import com.google.api.services.compute.model.InstanceList; +import com.google.api.services.compute.model.InstancesScopedList; +import com.google.api.services.compute.model.InstancesSetMachineTypeRequest; import com.google.api.services.compute.model.License; import com.google.api.services.compute.model.MachineType; import com.google.api.services.compute.model.MachineTypeAggregatedList; import com.google.api.services.compute.model.MachineTypeList; import com.google.api.services.compute.model.MachineTypesScopedList; +import com.google.api.services.compute.model.Metadata; import com.google.api.services.compute.model.Network; import com.google.api.services.compute.model.NetworkList; import com.google.api.services.compute.model.Operation; import com.google.api.services.compute.model.OperationList; import com.google.api.services.compute.model.Region; import com.google.api.services.compute.model.RegionList; +import com.google.api.services.compute.model.Scheduling; +import com.google.api.services.compute.model.SerialPortOutput; import com.google.api.services.compute.model.Snapshot; import com.google.api.services.compute.model.SnapshotList; import com.google.api.services.compute.model.Subnetwork; import com.google.api.services.compute.model.SubnetworkAggregatedList; import com.google.api.services.compute.model.SubnetworkList; import com.google.api.services.compute.model.SubnetworksScopedList; +import com.google.api.services.compute.model.Tags; import com.google.api.services.compute.model.Zone; import com.google.api.services.compute.model.ZoneList; import com.google.common.collect.ImmutableList; @@ -869,6 +880,256 @@ public Operation deleteNetwork(String network, Map options) { } } + @Override + public Operation createInstance(String zone, Instance instance, Map options) { + try { + return compute.instances() + .insert(this.options.projectId(), zone, instance) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Instance getInstance(String zone, String instance, Map options) { + try { + return compute.instances() + .get(this.options.projectId(), zone, instance) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Tuple> listInstances(String zone, Map options) { + try { + InstanceList instanceList = compute.instances() + .list(this.options.projectId(), zone) + .setFilter(FILTER.getString(options)) + .setMaxResults(MAX_RESULTS.getLong(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + .setFields(FIELDS.getString(options)) + .execute(); + Iterable instances = instanceList.getItems(); + return Tuple.of(instanceList.getNextPageToken(), instances); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Tuple> listInstances(Map options) { + try { + InstanceAggregatedList aggregatedList = compute.instances() + .aggregatedList(this.options.projectId()) + .setFilter(FILTER.getString(options)) + .setMaxResults(MAX_RESULTS.getLong(options)) + .setPageToken(PAGE_TOKEN.getString(options)) + // todo(mziccard): uncomment or remove once #711 is closed + // .setFields(FIELDS.getString(options)) + .execute(); + ImmutableList.Builder builder = ImmutableList.builder(); + Map scopedList = aggregatedList.getItems(); + if (scopedList != null) { + for (InstancesScopedList instancesScopedList : scopedList.values()) { + if (instancesScopedList.getInstances() != null) { + builder.addAll(instancesScopedList.getInstances()); + } + } + } + return Tuple.>of(aggregatedList.getNextPageToken(), + builder.build()); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Operation deleteInstance(String zone, String instance, Map options) { + try { + return compute.instances() + .delete(this.options.projectId(), zone, instance) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Operation addAccessConfig(String zone, String instance, String networkInterface, + AccessConfig accessConfig, Map options) { + try { + return compute.instances() + .addAccessConfig(this.options.projectId(), zone, instance, networkInterface, accessConfig) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Operation attachDisk(String zone, String instance, AttachedDisk attachedDisk, + Map options) { + try { + return compute.instances() + .attachDisk(this.options.projectId(), zone, instance, attachedDisk) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public Operation deleteAccessConfig(String zone, String instance, String networkInterface, + String accessConfig, Map options) { + try { + return compute.instances() + .deleteAccessConfig(this.options.projectId(), zone, instance, accessConfig, + networkInterface) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Operation detachDisk(String zone, String instance, String deviceName, + Map options) { + try { + return compute.instances() + .detachDisk(this.options.projectId(), zone, instance, deviceName) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public String getSerialPortOutput(String zone, String instance, Integer port, + Map options) { + try { + SerialPortOutput portOutput = compute.instances() + .getSerialPortOutput(this.options.projectId(), zone, instance) + .setPort(port) + .setFields(FIELDS.getString(options)) + .execute(); + return portOutput != null ? portOutput.getContents() : null; + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Operation reset(String zone, String instance, Map options) { + try { + return compute.instances() + .reset(this.options.projectId(), zone, instance) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Operation setDiskAutoDelete(String zone, String instance, String deviceName, + boolean autoDelete, Map options) { + try { + return compute.instances() + .setDiskAutoDelete(this.options.projectId(), zone, instance, autoDelete, deviceName) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Operation setMachineType(String zone, String instance, String machineTypeUrl, + Map options) { + try { + InstancesSetMachineTypeRequest request = + new InstancesSetMachineTypeRequest().setMachineType(machineTypeUrl); + return compute.instances() + .setMachineType(this.options.projectId(), zone, instance, request) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Operation setMetadata(String zone, String instance, Metadata metadata, + Map options) { + try { + return compute.instances() + .setMetadata(this.options.projectId(), zone, instance, metadata) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Operation setScheduling(String zone, String instance, Scheduling scheduling, + Map options) { + try { + return compute.instances() + .setScheduling(this.options.projectId(), zone, instance, scheduling) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Operation setTags(String zone, String instance, Tags tags, Map options) { + try { + return compute.instances() + .setTags(this.options.projectId(), zone, instance, tags) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Operation start(String zone, String instance, Map options) { + try { + return compute.instances() + .start(this.options.projectId(), zone, instance) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + + @Override + public Operation stop(String zone, String instance, Map options) { + try { + return compute.instances() + .stop(this.options.projectId(), zone, instance) + .setFields(FIELDS.getString(options)) + .execute(); + } catch (IOException ex) { + return nullForNotFound(ex); + } + } + /** * This method returns {@code null} if the error code of {@code exception} was 404, re-throws the * exception otherwise. diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java index 3dd28c043fd7..023bd7064a3e 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java @@ -34,6 +34,7 @@ import com.google.common.collect.Iterables; import com.google.gcloud.Page; import com.google.gcloud.RetryParams; +import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; import com.google.gcloud.compute.Compute.AddressAggregatedListOption; import com.google.gcloud.compute.Compute.AddressFilter; import com.google.gcloud.compute.Compute.AddressListOption; @@ -51,6 +52,11 @@ import com.google.gcloud.compute.Compute.ImageFilter; import com.google.gcloud.compute.Compute.ImageListOption; import com.google.gcloud.compute.Compute.ImageOption; +import com.google.gcloud.compute.Compute.InstanceAggregatedListOption; +import com.google.gcloud.compute.Compute.InstanceField; +import com.google.gcloud.compute.Compute.InstanceFilter; +import com.google.gcloud.compute.Compute.InstanceListOption; +import com.google.gcloud.compute.Compute.InstanceOption; import com.google.gcloud.compute.Compute.LicenseOption; import com.google.gcloud.compute.Compute.MachineTypeAggregatedListOption; import com.google.gcloud.compute.Compute.MachineTypeFilter; @@ -77,6 +83,7 @@ import com.google.gcloud.compute.Compute.ZoneFilter; import com.google.gcloud.compute.Compute.ZoneListOption; import com.google.gcloud.compute.Compute.ZoneOption; +import com.google.gcloud.compute.NetworkInterface.AccessConfig; import com.google.gcloud.compute.Operation.OperationError; import com.google.gcloud.compute.Operation.OperationWarning; import com.google.gcloud.compute.Operation.Status; @@ -213,6 +220,14 @@ public class ComputeImplTest { SubnetworkInfo.of(SUBNETWORK_ID, NETWORK_ID, "192.168.0.0/16"); private static final NetworkInfo NETWORK = NetworkInfo.of(NETWORK_ID, StandardNetworkConfiguration.of("192.168.0.0/16")); + private static final InstanceId INSTANCE_ID = InstanceId.of("project", "zone", "instance"); + private static final PersistentDiskConfiguration PERSISTENT_DISK_CONFIGURATION = + PersistentDiskConfiguration.of(DISK_ID); + private static final AttachedDisk ATTACHED_DISK = + AttachedDisk.of("device", PERSISTENT_DISK_CONFIGURATION); + private static final NetworkInterface NETWORK_INTERFACE = NetworkInterface.of(NETWORK_ID); + private static final InstanceInfo INSTANCE = + InstanceInfo.of(INSTANCE_ID, MACHINE_TYPE_ID, ATTACHED_DISK, NETWORK_INTERFACE); // Empty ComputeRpc options private static final Map EMPTY_RPC_OPTIONS = ImmutableMap.of(); @@ -450,6 +465,32 @@ public class ComputeImplTest { MAX_RESULTS, 42L, FILTER, "IPv4Range eq 192.168.0.0/16"); + // Instance options + private static final InstanceOption INSTANCE_OPTION_FIELDS = + InstanceOption.fields(InstanceField.ID, InstanceField.DESCRIPTION); + + // Instance list options + private static final InstanceFilter INSTANCE_FILTER = + InstanceFilter.equals(InstanceField.CAN_IP_FORWARD, true); + private static final InstanceListOption INSTANCE_LIST_PAGE_TOKEN = + InstanceListOption.pageToken("cursor"); + private static final InstanceListOption INSTANCE_LIST_PAGE_SIZE = + InstanceListOption.pageSize(42L); + private static final InstanceListOption INSTANCE_LIST_FILTER = + InstanceListOption.filter(INSTANCE_FILTER); + private static final Map INSTANCE_LIST_OPTIONS = ImmutableMap.of( + PAGE_TOKEN, "cursor", + MAX_RESULTS, 42L, + FILTER, "canIpForward eq true"); + + // Instance aggregated list options + private static final InstanceAggregatedListOption INSTANCE_AGGREGATED_LIST_PAGE_TOKEN = + InstanceAggregatedListOption.pageToken("cursor"); + private static final InstanceAggregatedListOption INSTANCE_AGGREGATED_LIST_PAGE_SIZE = + InstanceAggregatedListOption.pageSize(42L); + private static final InstanceAggregatedListOption INSTANCE_AGGREGATED_LIST_FILTER = + InstanceAggregatedListOption.filter(INSTANCE_FILTER); + private static final Function OPERATION_TO_PB_FUNCTION = new Function() { @@ -3166,6 +3207,781 @@ public void testCreateNetworkWithOptions() { assertEquals(globalOperation, operation); } + @Test + public void testGetInstance() { + EasyMock.expect(computeRpcMock.getInstance(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + EMPTY_RPC_OPTIONS)).andReturn(INSTANCE.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Instance instance = compute.get(INSTANCE_ID); + assertEquals(new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE)), instance); + } + + @Test + public void testGetInstance_Null() { + EasyMock.expect(computeRpcMock.getInstance(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.get(INSTANCE_ID)); + } + + @Test + public void testGetInstanceWithSelectedFields() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.getInstance(eq(INSTANCE_ID.zone()), eq(INSTANCE_ID.instance()), + capture(capturedOptions))).andReturn(INSTANCE.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Instance instance = compute.get(INSTANCE_ID, INSTANCE_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(INSTANCE_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE)), instance); + } + + @Test + public void testDeleteInstance_Operation() { + EasyMock.expect(computeRpcMock.deleteInstance(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + EMPTY_RPC_OPTIONS)).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(zoneOperation, compute.delete(INSTANCE_ID)); + } + + @Test + public void testDeleteInstanceWithSelectedFields_Operation() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.deleteInstance(eq(INSTANCE_ID.zone()), + eq(INSTANCE_ID.instance()), capture(capturedOptions))).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.delete(INSTANCE_ID, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(zoneOperation, operation); + } + + @Test + public void testDeleteInstance_Null() { + EasyMock.expect(computeRpcMock.deleteInstance(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.delete(INSTANCE_ID)); + } + + @Test + public void testListInstances() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList instanceList = ImmutableList.of( + new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE)), + new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(instanceList, InstanceInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listInstances(INSTANCE_ID.zone(), EMPTY_RPC_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listInstances(INSTANCE_ID.zone()); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(instanceList.toArray(), Iterables.toArray(page.values(), Instance.class)); + } + + @Test + public void testListInstancesNextPage() { + String cursor = "cursor"; + String nextCursor = "nextCursor"; + compute = options.service(); + ImmutableList instanceList = ImmutableList.of( + new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE)), + new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE))); + ImmutableList nextInstanceList = ImmutableList.of( + new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(instanceList, InstanceInfo.TO_PB_FUNCTION)); + Tuple> nextResult = + Tuple.of(nextCursor, Iterables.transform(nextInstanceList, InstanceInfo.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + EasyMock.expect(computeRpcMock.listInstances(INSTANCE_ID.zone(), EMPTY_RPC_OPTIONS)) + .andReturn(result); + EasyMock.expect(computeRpcMock.listInstances(INSTANCE_ID.zone(), nextOptions)) + .andReturn(nextResult); + EasyMock.replay(computeRpcMock); + Page page = compute.listInstances(INSTANCE_ID.zone()); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(instanceList.toArray(), Iterables.toArray(page.values(), Instance.class)); + page = page.nextPage(); + assertEquals(nextCursor, page.nextPageCursor()); + assertArrayEquals(nextInstanceList.toArray(), Iterables.toArray(page.values(), Instance.class)); + } + + @Test + public void testListEmptyInstances() { + compute = options.service(); + ImmutableList instances = ImmutableList.of(); + Tuple> result = + Tuple.>of(null, instances); + EasyMock.expect(computeRpcMock.listInstances(INSTANCE_ID.zone(), EMPTY_RPC_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listInstances(INSTANCE_ID.zone()); + assertNull(page.nextPageCursor()); + assertArrayEquals(instances.toArray(), Iterables.toArray(page.values(), Instance.class)); + } + + @Test + public void testListInstancesWithOptions() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList instanceList = ImmutableList.of( + new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE)), + new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(instanceList, InstanceInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listInstances(INSTANCE_ID.zone(), INSTANCE_LIST_OPTIONS)) + .andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listInstances(INSTANCE_ID.zone(), INSTANCE_LIST_PAGE_SIZE, + INSTANCE_LIST_PAGE_TOKEN, INSTANCE_LIST_FILTER); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(instanceList.toArray(), Iterables.toArray(page.values(), Instance.class)); + } + + @Test + public void testAggregatedListInstances() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList instanceList = ImmutableList.of( + new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE)), + new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(instanceList, InstanceInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listInstances(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listInstances(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(instanceList.toArray(), Iterables.toArray(page.values(), Instance.class)); + } + + @Test + public void testAggregatedListInstancesNextPage() { + String cursor = "cursor"; + String nextCursor = "nextCursor"; + compute = options.service(); + ImmutableList instanceList = ImmutableList.of( + new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE)), + new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE))); + ImmutableList nextInstanceList = ImmutableList.of( + new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(instanceList, InstanceInfo.TO_PB_FUNCTION)); + Tuple> nextResult = + Tuple.of(nextCursor, Iterables.transform(nextInstanceList, InstanceInfo.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + EasyMock.expect(computeRpcMock.listInstances(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.expect(computeRpcMock.listInstances(nextOptions)).andReturn(nextResult); + EasyMock.replay(computeRpcMock); + Page page = compute.listInstances(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(instanceList.toArray(), Iterables.toArray(page.values(), Instance.class)); + page = page.nextPage(); + assertEquals(nextCursor, page.nextPageCursor()); + assertArrayEquals(nextInstanceList.toArray(), Iterables.toArray(page.values(), Instance.class)); + } + + @Test + public void testAggregatedListEmptyInstances() { + compute = options.service(); + ImmutableList instanceList = ImmutableList.of(); + Tuple> result = + Tuple.>of(null, + instanceList); + EasyMock.expect(computeRpcMock.listInstances(EMPTY_RPC_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listInstances(); + assertNull(page.nextPageCursor()); + assertArrayEquals(instanceList.toArray(), Iterables.toArray(page.values(), Instance.class)); + } + + @Test + public void testAggregatedListInstancesWithOptions() { + String cursor = "cursor"; + compute = options.service(); + ImmutableList instanceList = ImmutableList.of( + new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE)), + new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE))); + Tuple> result = + Tuple.of(cursor, Iterables.transform(instanceList, InstanceInfo.TO_PB_FUNCTION)); + EasyMock.expect(computeRpcMock.listInstances(INSTANCE_LIST_OPTIONS)).andReturn(result); + EasyMock.replay(computeRpcMock); + Page page = compute.listInstances(INSTANCE_AGGREGATED_LIST_PAGE_SIZE, + INSTANCE_AGGREGATED_LIST_PAGE_TOKEN, INSTANCE_AGGREGATED_LIST_FILTER); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(instanceList.toArray(), Iterables.toArray(page.values(), Instance.class)); + } + + @Test + public void testCreateInstance() { + EasyMock.expect(computeRpcMock.createInstance(INSTANCE_ID.zone(), INSTANCE.toPb(), + EMPTY_RPC_OPTIONS)).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + InstanceInfo instance = InstanceInfo.of(InstanceId.of("zone", "instance"), + MachineTypeId.of("zone", "type"), ATTACHED_DISK, + NetworkInterface.of(NetworkId.of("network"))); + Operation operation = compute.create(instance); + assertEquals(zoneOperation, operation); + } + + @Test + public void testCreateInstanceWithOptions() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.createInstance(eq(INSTANCE_ID.zone()), eq(INSTANCE.toPb()), + capture(capturedOptions))).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.create(INSTANCE, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(zoneOperation, operation); + } + + @Test + public void testAddAccessConfig_Operation() { + AccessConfig accessConfig = AccessConfig.of("192.168.1.1"); + EasyMock.expect(computeRpcMock.addAccessConfig(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + "networkInterface", accessConfig.toPb(), EMPTY_RPC_OPTIONS)) + .andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(zoneOperation, + compute.addAccessConfig(INSTANCE_ID, "networkInterface", accessConfig)); + } + + @Test + public void testAddAccessConfigWithSelectedFields_Operation() { + Capture> capturedOptions = Capture.newInstance(); + AccessConfig accessConfig = AccessConfig.of("192.168.1.1"); + EasyMock.expect(computeRpcMock.addAccessConfig(eq(INSTANCE_ID.zone()), + eq(INSTANCE_ID.instance()), eq("networkInterface"), eq(accessConfig.toPb()), + capture(capturedOptions))).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.addAccessConfig(INSTANCE_ID, "networkInterface", accessConfig, + OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(zoneOperation, operation); + } + + @Test + public void testAddAccessConfig_Null() { + AccessConfig accessConfig = AccessConfig.of("192.168.1.1"); + EasyMock.expect(computeRpcMock.addAccessConfig(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + "networkInterface", accessConfig.toPb(), EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.addAccessConfig(INSTANCE_ID, "networkInterface", accessConfig)); + } + + @Test + public void testAttachDisk_Operation() { + AttachedDisk attachedDisk = AttachedDisk.of(PERSISTENT_DISK_CONFIGURATION); + EasyMock.expect(computeRpcMock.attachDisk(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + attachedDisk.toPb(), EMPTY_RPC_OPTIONS)).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(zoneOperation, compute.attachDisk(INSTANCE_ID, PERSISTENT_DISK_CONFIGURATION)); + } + + @Test + public void testAttachDiskWithSelectedFields_Operation() { + AttachedDisk attachedDisk = AttachedDisk.of(PERSISTENT_DISK_CONFIGURATION); + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.attachDisk(eq(INSTANCE_ID.zone()), eq(INSTANCE_ID.instance()), + eq(attachedDisk.toPb()), capture(capturedOptions))).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = + compute.attachDisk(INSTANCE_ID, PERSISTENT_DISK_CONFIGURATION, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(zoneOperation, operation); + } + + @Test + public void testAttachDisk_Null() { + AttachedDisk attachedDisk = AttachedDisk.of(PERSISTENT_DISK_CONFIGURATION); + EasyMock.expect(computeRpcMock.attachDisk(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + attachedDisk.toPb(), EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.attachDisk(INSTANCE_ID, PERSISTENT_DISK_CONFIGURATION)); + } + + @Test + public void testAttachDiskName_Operation() { + AttachedDisk attachedDisk = AttachedDisk.of("dev0", PERSISTENT_DISK_CONFIGURATION); + EasyMock.expect(computeRpcMock.attachDisk(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + attachedDisk.toPb(), EMPTY_RPC_OPTIONS)).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(zoneOperation, + compute.attachDisk(INSTANCE_ID, "dev0", PERSISTENT_DISK_CONFIGURATION)); + } + + @Test + public void testAttachDiskNameWithSelectedFields_Operation() { + AttachedDisk attachedDisk = AttachedDisk.of("dev0", PERSISTENT_DISK_CONFIGURATION); + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.attachDisk(eq(INSTANCE_ID.zone()), eq(INSTANCE_ID.instance()), + eq(attachedDisk.toPb()), capture(capturedOptions))).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.attachDisk(INSTANCE_ID, "dev0", PERSISTENT_DISK_CONFIGURATION, + OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(zoneOperation, operation); + } + + @Test + public void testAttachDiskName_Null() { + AttachedDisk attachedDisk = AttachedDisk.of("dev0", PERSISTENT_DISK_CONFIGURATION); + EasyMock.expect(computeRpcMock.attachDisk(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + attachedDisk.toPb(), EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.attachDisk(INSTANCE_ID, "dev0", PERSISTENT_DISK_CONFIGURATION)); + } + + @Test + public void testDeleteAccessConfig_Operation() { + EasyMock.expect(computeRpcMock.deleteAccessConfig(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + "networkInterface", "accessConfig", EMPTY_RPC_OPTIONS)).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(zoneOperation, + compute.deleteAccessConfig(INSTANCE_ID, "networkInterface", "accessConfig")); + } + + @Test + public void testDeleteAccessConfigWithSelectedFields_Operation() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.deleteAccessConfig(eq(INSTANCE_ID.zone()), + eq(INSTANCE_ID.instance()), eq("networkInterface"), eq("accessConfig"), + capture(capturedOptions))).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.deleteAccessConfig(INSTANCE_ID, "networkInterface", + "accessConfig", OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(zoneOperation, operation); + } + + @Test + public void testDeleteAccessConfig_Null() { + EasyMock.expect(computeRpcMock.deleteAccessConfig(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + "networkInterface", "accessConfig", EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.deleteAccessConfig(INSTANCE_ID, "networkInterface", "accessConfig")); + } + + @Test + public void testDetachDisk_Operation() { + EasyMock.expect(computeRpcMock.detachDisk(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + "device", EMPTY_RPC_OPTIONS)).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(zoneOperation, compute.detachDisk(INSTANCE_ID, "device")); + } + + @Test + public void testDetachDiskWithSelectedFields_Operation() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.detachDisk(eq(INSTANCE_ID.zone()), + eq(INSTANCE_ID.instance()), eq("device"), capture(capturedOptions))) + .andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.detachDisk(INSTANCE_ID, "device", OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(zoneOperation, operation); + } + + @Test + public void testDetachDisk_Null() { + EasyMock.expect(computeRpcMock.detachDisk(INSTANCE_ID.zone(), INSTANCE_ID.instance(), "device", + EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.detachDisk(INSTANCE_ID, "device")); + } + + @Test + public void testSerialPortOutputFromPort() { + String output = "output"; + EasyMock.expect(computeRpcMock.getSerialPortOutput(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + 2, EMPTY_RPC_OPTIONS)).andReturn(output); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(output, compute.getSerialPortOutput(INSTANCE_ID, 2)); + } + + @Test + public void testSerialPortOutputDefault() { + String output = "output"; + EasyMock.expect(computeRpcMock.getSerialPortOutput(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + null, EMPTY_RPC_OPTIONS)).andReturn(output); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(output, compute.getSerialPortOutput(INSTANCE_ID)); + } + + @Test + public void testSerialPortOutputFromPort_Null() { + EasyMock.expect(computeRpcMock.getSerialPortOutput(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + 2, EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.getSerialPortOutput(INSTANCE_ID, 2)); + } + + @Test + public void testSerialPortOutputDefault_Null() { + EasyMock.expect(computeRpcMock.getSerialPortOutput(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + null, EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.getSerialPortOutput(INSTANCE_ID)); + } + + @Test + public void testResetInstance_Operation() { + EasyMock.expect(computeRpcMock.reset(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + EMPTY_RPC_OPTIONS)).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(zoneOperation, compute.reset(INSTANCE_ID)); + } + + @Test + public void testResetInstanceWithSelectedFields_Operation() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.reset(eq(INSTANCE_ID.zone()), eq(INSTANCE_ID.instance()), + capture(capturedOptions))).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.reset(INSTANCE_ID, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(zoneOperation, operation); + } + + @Test + public void testResetInstance_Null() { + EasyMock.expect(computeRpcMock.reset(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.reset(INSTANCE_ID)); + } + + @Test + public void testSetDiskAutodelete_Operation() { + EasyMock.expect(computeRpcMock.setDiskAutoDelete(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + "device", true, EMPTY_RPC_OPTIONS)).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(zoneOperation, compute.setDiskAutoDelete(INSTANCE_ID, "device", true)); + } + + @Test + public void testSetDiskAutodeleteWithSelectedFields_Operation() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.setDiskAutoDelete(eq(INSTANCE_ID.zone()), + eq(INSTANCE_ID.instance()), eq("device"), eq(true), capture(capturedOptions))) + .andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = + compute.setDiskAutoDelete(INSTANCE_ID, "device", true, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(zoneOperation, operation); + } + + @Test + public void testSetDiskAutodelete_Null() { + EasyMock.expect(computeRpcMock.setDiskAutoDelete(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + "device", false, EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.setDiskAutoDelete(INSTANCE_ID, "device", false)); + } + + @Test + public void testSetMachineType_Operation() { + EasyMock.expect(computeRpcMock.setMachineType(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + MACHINE_TYPE_ID.selfLink(), EMPTY_RPC_OPTIONS)).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(zoneOperation, + compute.setMachineType(INSTANCE_ID, MachineTypeId.of("zone", "type"))); + } + + @Test + public void testSetMachineTypeWithOptions_Operation() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.setMachineType(eq(INSTANCE_ID.zone()), + eq(INSTANCE_ID.instance()), eq(MACHINE_TYPE_ID.selfLink()), capture(capturedOptions))) + .andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.setMachineType(INSTANCE_ID, MachineTypeId.of("zone", "type"), + OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(zoneOperation, operation); + } + + @Test + public void testSetMachineType_Null() { + EasyMock.expect(computeRpcMock.setMachineType(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + MACHINE_TYPE_ID.selfLink(), EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.setMachineType(INSTANCE_ID, MachineTypeId.of("zone", "type"))); + } + + @Test + public void testSetMetadata_Operation() { + Metadata metadata = Metadata.builder() + .add("key", "value") + .fingerprint("fingerprint") + .build(); + EasyMock.expect(computeRpcMock.setMetadata(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + metadata.toPb(), EMPTY_RPC_OPTIONS)).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(zoneOperation, compute.setMetadata(INSTANCE_ID, metadata)); + } + + @Test + public void testSetMetadataWithOptions_Operation() { + Capture> capturedOptions = Capture.newInstance(); + Metadata metadata = Metadata.builder() + .add("key", "value") + .fingerprint("fingerprint") + .build(); + EasyMock.expect(computeRpcMock.setMetadata(eq(INSTANCE_ID.zone()), eq(INSTANCE_ID.instance()), + eq(metadata.toPb()), capture(capturedOptions))).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.setMetadata(INSTANCE_ID, metadata, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(zoneOperation, operation); + } + + @Test + public void testSetMetadata_Null() { + Metadata metadata = Metadata.builder() + .add("key", "value") + .fingerprint("fingerprint") + .build(); + EasyMock.expect(computeRpcMock.setMetadata(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + metadata.toPb(), EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.setMetadata(INSTANCE_ID, metadata)); + } + + @Test + public void testSetSchedulingOptions_Operation() { + SchedulingOptions schedulingOptions = + SchedulingOptions.standard(true, SchedulingOptions.Maintenance.MIGRATE); + EasyMock.expect(computeRpcMock.setScheduling(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + schedulingOptions.toPb(), EMPTY_RPC_OPTIONS)).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(zoneOperation, compute.setSchedulingOptions(INSTANCE_ID, schedulingOptions)); + } + + @Test + public void testSetSchedulingOptionsWithOptions_Operation() { + Capture> capturedOptions = Capture.newInstance(); + SchedulingOptions schedulingOptions = + SchedulingOptions.standard(true, SchedulingOptions.Maintenance.MIGRATE); + EasyMock.expect(computeRpcMock.setScheduling(eq(INSTANCE_ID.zone()), eq(INSTANCE_ID.instance()), + eq(schedulingOptions.toPb()), capture(capturedOptions))).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = + compute.setSchedulingOptions(INSTANCE_ID, schedulingOptions, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(zoneOperation, operation); + } + + @Test + public void testSetSchedulingOptions_Null() { + SchedulingOptions schedulingOptions = + SchedulingOptions.standard(true, SchedulingOptions.Maintenance.MIGRATE); + EasyMock.expect(computeRpcMock.setScheduling(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + schedulingOptions.toPb(), EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.setSchedulingOptions(INSTANCE_ID, schedulingOptions)); + } + + @Test + public void testTags_Operation() { + Tags tags = Tags.of("tag1", "tag2"); + EasyMock.expect(computeRpcMock.setTags(INSTANCE_ID.zone(), INSTANCE_ID.instance(), tags.toPb(), + EMPTY_RPC_OPTIONS)).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(zoneOperation, compute.setTags(INSTANCE_ID, tags)); + } + + @Test + public void testSetTagsWithOptions_Operation() { + Tags tags = Tags.of("tag1", "tag2"); + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.setTags(eq(INSTANCE_ID.zone()), eq(INSTANCE_ID.instance()), + eq(tags.toPb()), capture(capturedOptions))).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.setTags(INSTANCE_ID, tags, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(zoneOperation, operation); + } + + @Test + public void testSetTags_Null() { + Tags tags = Tags.of("tag1", "tag2"); + EasyMock.expect(computeRpcMock.setTags(INSTANCE_ID.zone(), INSTANCE_ID.instance(), tags.toPb(), + EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.setTags(INSTANCE_ID, tags)); + } + + @Test + public void testStartInstance_Operation() { + EasyMock.expect(computeRpcMock.start(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + EMPTY_RPC_OPTIONS)).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(zoneOperation, compute.start(INSTANCE_ID)); + } + + @Test + public void testStartInstanceWithSelectedFields_Operation() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.start(eq(INSTANCE_ID.zone()), eq(INSTANCE_ID.instance()), + capture(capturedOptions))).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.start(INSTANCE_ID, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(zoneOperation, operation); + } + + @Test + public void testStartInstance_Null() { + EasyMock.expect(computeRpcMock.start(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.start(INSTANCE_ID)); + } + + @Test + public void testStopInstance_Operation() { + EasyMock.expect(computeRpcMock.stop(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + EMPTY_RPC_OPTIONS)).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertEquals(zoneOperation, compute.stop(INSTANCE_ID)); + } + + @Test + public void testStopInstanceWithSelectedFields_Operation() { + Capture> capturedOptions = Capture.newInstance(); + EasyMock.expect(computeRpcMock.stop(eq(INSTANCE_ID.zone()), eq(INSTANCE_ID.instance()), + capture(capturedOptions))).andReturn(zoneOperation.toPb()); + EasyMock.replay(computeRpcMock); + compute = options.service(); + Operation operation = compute.stop(INSTANCE_ID, OPERATION_OPTION_FIELDS); + String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); + assertTrue(selector.contains("selfLink")); + assertTrue(selector.contains("id")); + assertTrue(selector.contains("description")); + assertEquals(23, selector.length()); + assertEquals(zoneOperation, operation); + } + + @Test + public void testStopInstance_Null() { + EasyMock.expect(computeRpcMock.stop(INSTANCE_ID.zone(), INSTANCE_ID.instance(), + EMPTY_RPC_OPTIONS)).andReturn(null); + EasyMock.replay(computeRpcMock); + compute = options.service(); + assertNull(compute.stop(INSTANCE_ID)); + } + @Test public void testRetryableException() { EasyMock.expect( diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceTest.java new file mode 100644 index 000000000000..880ed68f63ab --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceTest.java @@ -0,0 +1,895 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.compute; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.createStrictMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; +import com.google.gcloud.compute.Compute.InstanceOption; +import com.google.gcloud.compute.Compute.OperationOption; +import com.google.gcloud.compute.NetworkInterface.AccessConfig; +import com.google.gcloud.compute.SchedulingOptions.Maintenance; + +import org.junit.Test; + +import java.util.List; +import java.util.Map; + +public class InstanceTest { + + private static final String ID = "42"; + private static final Long CREATION_TIMESTAMP = 1453293540000L; + private static final String DESCRIPTION = "description"; + private static final InstanceId INSTANCE_ID = InstanceId.of("project", "zone", "instance"); + private static final InstanceInfo.Status STATUS = InstanceInfo.Status.RUNNING; + private static final String STATUS_MESSAGE = "statusMessage"; + private static final Tags TAGS = Tags.builder() + .values("tag1", "tag2") + .fingerprint("fingerprint") + .build(); + private static final MachineTypeId MACHINE_TYPE = MachineTypeId.of("project", "zone", "type"); + private static final Boolean CAN_IP_FORWARD = true; + private static final NetworkInterface NETWORK_INTERFACE = + NetworkInterface.of(NetworkId.of("project", "network")); + private static final List NETWORK_INTERFACES = + ImmutableList.of(NETWORK_INTERFACE); + private static final DiskId DISK_ID = DiskId.of("project", "zone", "disk"); + private static final AttachedDisk ATTACHED_DISK = + AttachedDisk.of(PersistentDiskConfiguration.of(DISK_ID)); + private static final List ATTACHED_DISKS = ImmutableList.of(ATTACHED_DISK); + private static final Metadata METADATA = Metadata.builder() + .add("key1", "value1") + .add("key2", "value2") + .fingerprint("fingerprint") + .build(); + private static final ServiceAccount SERVICE_ACCOUNT = + ServiceAccount.of("email", ImmutableList.of("scope1")); + private static final List SERVICE_ACCOUNTS = + ImmutableList.of(SERVICE_ACCOUNT); + private static final SchedulingOptions SCHEDULING_OPTIONS = SchedulingOptions.preemptible(); + private static final String CPU_PLATFORM = "cpuPlatform"; + + private final Compute serviceMockReturnsOptions = createStrictMock(Compute.class); + private final ComputeOptions mockOptions = createMock(ComputeOptions.class); + private Compute compute; + private Instance instance; + private Instance expectedInstance; + + private void initializeExpectedInstance(int optionsCalls) { + expect(serviceMockReturnsOptions.options()).andReturn(mockOptions).times(optionsCalls); + replay(serviceMockReturnsOptions); + expectedInstance = new Instance.Builder(serviceMockReturnsOptions, INSTANCE_ID, MACHINE_TYPE, + ATTACHED_DISK, NETWORK_INTERFACE) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .status(STATUS) + .statusMessage(STATUS_MESSAGE) + .tags(TAGS) + .canIpForward(CAN_IP_FORWARD) + .metadata(METADATA) + .serviceAccounts(SERVICE_ACCOUNTS) + .schedulingOptions(SCHEDULING_OPTIONS) + .cpuPlatform(CPU_PLATFORM) + .build(); + compute = createStrictMock(Compute.class); + } + + private void initializeInstance() { + instance = new Instance.Builder(compute, INSTANCE_ID, MACHINE_TYPE, + ATTACHED_DISK, NETWORK_INTERFACE) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .status(STATUS) + .statusMessage(STATUS_MESSAGE) + .tags(TAGS) + .canIpForward(CAN_IP_FORWARD) + .metadata(METADATA) + .serviceAccounts(SERVICE_ACCOUNTS) + .schedulingOptions(SCHEDULING_OPTIONS) + .cpuPlatform(CPU_PLATFORM) + .build(); + } + + @Test + public void testToBuilder() { + initializeExpectedInstance(8); + compareInstance(expectedInstance, expectedInstance.toBuilder().build()); + Instance newInstance = expectedInstance.toBuilder().description("newDescription").build(); + assertEquals("newDescription", newInstance.description()); + newInstance = newInstance.toBuilder().description("description").build(); + compareInstance(expectedInstance, newInstance); + } + + @Test + public void testToBuilderIncomplete() { + initializeExpectedInstance(5); + InstanceInfo instanceInfo = + InstanceInfo.of(INSTANCE_ID, MACHINE_TYPE, ATTACHED_DISK, NETWORK_INTERFACE); + Instance instance = + new Instance(serviceMockReturnsOptions, new InstanceInfo.BuilderImpl(instanceInfo)); + compareInstance(instance, instance.toBuilder().build()); + } + + @Test + public void testBuilder() { + initializeExpectedInstance(2); + assertEquals(ID, expectedInstance.id()); + assertEquals(INSTANCE_ID, expectedInstance.instanceId()); + assertEquals(CREATION_TIMESTAMP, expectedInstance.creationTimestamp()); + assertEquals(DESCRIPTION, expectedInstance.description()); + assertEquals(STATUS, expectedInstance.status()); + assertEquals(STATUS_MESSAGE, expectedInstance.statusMessage()); + assertEquals(TAGS, expectedInstance.tags()); + assertEquals(MACHINE_TYPE, expectedInstance.machineType()); + assertEquals(CAN_IP_FORWARD, expectedInstance.canIpForward()); + assertEquals(NETWORK_INTERFACES, expectedInstance.networkInterfaces()); + assertEquals(ATTACHED_DISKS, expectedInstance.attachedDisks()); + assertEquals(METADATA, expectedInstance.metadata()); + assertEquals(SERVICE_ACCOUNTS, expectedInstance.serviceAccounts()); + assertEquals(SCHEDULING_OPTIONS, expectedInstance.schedulingOptions()); + assertEquals(CPU_PLATFORM, expectedInstance.cpuPlatform()); + assertSame(serviceMockReturnsOptions, expectedInstance.compute()); + InstanceInfo instanceInfo = + InstanceInfo.of(INSTANCE_ID, MACHINE_TYPE, ATTACHED_DISK, NETWORK_INTERFACE); + Instance instance = + new Instance(serviceMockReturnsOptions, new InstanceInfo.BuilderImpl(instanceInfo)); + assertNull(instance.id()); + assertEquals(INSTANCE_ID, instance.instanceId()); + assertNull(instance.creationTimestamp()); + assertNull(instance.description()); + assertNull(instance.status()); + assertNull(instance.statusMessage()); + assertNull(instance.tags()); + assertEquals(MACHINE_TYPE, instance.machineType()); + assertNull(instance.canIpForward()); + assertEquals(NETWORK_INTERFACES, instance.networkInterfaces()); + assertEquals(ATTACHED_DISKS, instance.attachedDisks()); + assertNull(instance.metadata()); + assertNull(instance.serviceAccounts()); + assertNull(instance.schedulingOptions()); + assertNull(instance.cpuPlatform()); + assertSame(serviceMockReturnsOptions, instance.compute()); + } + + @Test + public void testToAndFromPb() { + initializeExpectedInstance(8); + compareInstance(expectedInstance, + Instance.fromPb(serviceMockReturnsOptions, expectedInstance.toPb())); + Instance instance = new Instance.Builder(serviceMockReturnsOptions, INSTANCE_ID, MACHINE_TYPE, + ATTACHED_DISK, NETWORK_INTERFACE).build(); + compareInstance(instance, Instance.fromPb(serviceMockReturnsOptions, instance.toPb())); + } + + @Test + public void testDeleteOperation() { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + expect(compute.delete(INSTANCE_ID)).andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.delete()); + } + + @Test + public void testDeleteNull() { + initializeExpectedInstance(1); + expect(compute.options()).andReturn(mockOptions); + expect(compute.delete(INSTANCE_ID)).andReturn(null); + replay(compute); + initializeInstance(); + assertNull(instance.delete()); + } + + @Test + public void testExists_True() throws Exception { + initializeExpectedInstance(1); + InstanceOption[] expectedOptions = {InstanceOption.fields()}; + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(INSTANCE_ID, expectedOptions)).andReturn(expectedInstance); + replay(compute); + initializeInstance(); + assertTrue(instance.exists()); + verify(compute); + } + + @Test + public void testExists_False() throws Exception { + initializeExpectedInstance(1); + InstanceOption[] expectedOptions = {InstanceOption.fields()}; + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(INSTANCE_ID, expectedOptions)).andReturn(null); + replay(compute); + initializeInstance(); + assertFalse(instance.exists()); + verify(compute); + } + + @Test + public void testReload() throws Exception { + initializeExpectedInstance(3); + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(INSTANCE_ID)).andReturn(expectedInstance); + replay(compute); + initializeInstance(); + Instance updatedInstance = instance.reload(); + compareInstance(expectedInstance, updatedInstance); + verify(compute); + } + + @Test + public void testReloadNull() throws Exception { + initializeExpectedInstance(1); + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(INSTANCE_ID)).andReturn(null); + replay(compute); + initializeInstance(); + assertNull(instance.reload()); + verify(compute); + } + + @Test + public void testReloadWithOptions() throws Exception { + initializeExpectedInstance(3); + expect(compute.options()).andReturn(mockOptions); + expect(compute.get(INSTANCE_ID, InstanceOption.fields())).andReturn(expectedInstance); + replay(compute); + initializeInstance(); + Instance updateInstance = instance.reload(InstanceOption.fields()); + compareInstance(expectedInstance, updateInstance); + verify(compute); + } + + @Test + public void testAddAccessConfig() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + AccessConfig accessConfig = AccessConfig.of("192.168.1.1"); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + expect(compute.addAccessConfig(INSTANCE_ID, "nic0", accessConfig)).andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.addAccessConfig("nic0", accessConfig)); + } + + @Test + public void testAddAccessConfig_Null() throws Exception { + initializeExpectedInstance(1); + expect(compute.options()).andReturn(mockOptions); + AccessConfig accessConfig = AccessConfig.of("192.168.1.1"); + expect(compute.addAccessConfig(INSTANCE_ID, "nic0", accessConfig)).andReturn(null); + replay(compute); + initializeInstance(); + assertNull(instance.addAccessConfig("nic0", accessConfig)); + } + + @Test + public void testAddAccessConfigWithOptions() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + AccessConfig accessConfig = AccessConfig.of("192.168.1.1"); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + expect(compute.addAccessConfig(INSTANCE_ID, "nic0", accessConfig, OperationOption.fields())) + .andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.addAccessConfig("nic0", accessConfig, OperationOption.fields())); + } + + @Test + public void testAttachDisk() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + PersistentDiskConfiguration configuration = PersistentDiskConfiguration.of(DISK_ID); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + expect(compute.attachDisk(INSTANCE_ID, configuration)).andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.attachDisk(configuration)); + } + + @Test + public void testAttachDisk_Null() throws Exception { + initializeExpectedInstance(1); + expect(compute.options()).andReturn(mockOptions); + PersistentDiskConfiguration configuration = PersistentDiskConfiguration.of(DISK_ID); + expect(compute.attachDisk(INSTANCE_ID, configuration)).andReturn(null); + replay(compute); + initializeInstance(); + assertNull(instance.attachDisk(configuration)); + } + + @Test + public void testAttachDiskWithOptions() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + PersistentDiskConfiguration configuration = PersistentDiskConfiguration.of(DISK_ID); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + expect(compute.attachDisk(INSTANCE_ID, configuration, OperationOption.fields())) + .andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.attachDisk(configuration, OperationOption.fields())); + } + + @Test + public void testAttachDiskName() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + PersistentDiskConfiguration configuration = PersistentDiskConfiguration.of(DISK_ID); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + expect(compute.attachDisk(INSTANCE_ID, "dev0", configuration)).andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.attachDisk("dev0", configuration)); + } + + @Test + public void testAttachDiskName_Null() throws Exception { + initializeExpectedInstance(1); + expect(compute.options()).andReturn(mockOptions); + PersistentDiskConfiguration configuration = PersistentDiskConfiguration.of(DISK_ID); + expect(compute.attachDisk(INSTANCE_ID, "dev0", configuration)).andReturn(null); + replay(compute); + initializeInstance(); + assertNull(instance.attachDisk("dev0", configuration)); + } + + @Test + public void testAttachDiskNameWithOptions() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + PersistentDiskConfiguration configuration = PersistentDiskConfiguration.of(DISK_ID); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + expect(compute.attachDisk(INSTANCE_ID, "dev0", configuration, OperationOption.fields())) + .andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.attachDisk("dev0", configuration, OperationOption.fields())); + } + + @Test + public void testAttachDiskNameIndex() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + PersistentDiskConfiguration configuration = PersistentDiskConfiguration.of(DISK_ID); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + expect(compute.attachDisk(INSTANCE_ID, "dev0", configuration, 1)).andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.attachDisk("dev0", configuration, 1)); + } + + @Test + public void testAttachDiskNameIndex_Null() throws Exception { + initializeExpectedInstance(1); + expect(compute.options()).andReturn(mockOptions); + PersistentDiskConfiguration configuration = PersistentDiskConfiguration.of(DISK_ID); + expect(compute.attachDisk(INSTANCE_ID, "dev0", configuration, 1)).andReturn(null); + replay(compute); + initializeInstance(); + assertNull(instance.attachDisk("dev0", configuration, 1)); + } + + @Test + public void testAttachDiskNameIndexWithOptions() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + PersistentDiskConfiguration configuration = PersistentDiskConfiguration.of(DISK_ID); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + expect(compute.attachDisk(INSTANCE_ID, "dev0", configuration, 1, OperationOption.fields())) + .andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, + instance.attachDisk("dev0", configuration, 1, OperationOption.fields())); + } + + @Test + public void testDeleteAccessConfig() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + expect(compute.deleteAccessConfig(INSTANCE_ID, "nic0", "NAT")).andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.deleteAccessConfig("nic0", "NAT")); + } + + @Test + public void testDeleteAccessConfig_Null() throws Exception { + initializeExpectedInstance(1); + expect(compute.options()).andReturn(mockOptions); + expect(compute.deleteAccessConfig(INSTANCE_ID, "nic0", "NAT")).andReturn(null); + replay(compute); + initializeInstance(); + assertNull(instance.deleteAccessConfig("nic0", "NAT")); + } + + @Test + public void testDeleteAccessConfigWithOptions() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + expect(compute.deleteAccessConfig(INSTANCE_ID, "nic0", "NAT", OperationOption.fields())) + .andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.deleteAccessConfig("nic0", "NAT", OperationOption.fields())); + } + + @Test + public void testDetachDisk() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + expect(compute.detachDisk(INSTANCE_ID, "dev0")).andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.detachDisk("dev0")); + } + + @Test + public void testDetachDisk_Null() throws Exception { + initializeExpectedInstance(1); + expect(compute.options()).andReturn(mockOptions); + expect(compute.detachDisk(INSTANCE_ID, "dev0")).andReturn(null); + replay(compute); + initializeInstance(); + assertNull(instance.detachDisk("dev0")); + } + + @Test + public void testDetachDiskWithOptions() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + expect(compute.detachDisk(INSTANCE_ID, "dev0", OperationOption.fields())).andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.detachDisk("dev0", OperationOption.fields())); + } + + @Test + public void testGetSerialPortOutputWithNumber() throws Exception { + initializeExpectedInstance(1); + expect(compute.options()).andReturn(mockOptions); + expect(compute.getSerialPortOutput(INSTANCE_ID, 2)).andReturn("output"); + replay(compute); + initializeInstance(); + assertSame("output", instance.getSerialPortOutput(2)); + } + + @Test + public void testGetSerialPortOutput() throws Exception { + initializeExpectedInstance(1); + expect(compute.options()).andReturn(mockOptions); + expect(compute.getSerialPortOutput(INSTANCE_ID)).andReturn("output"); + replay(compute); + initializeInstance(); + assertSame("output", instance.getSerialPortOutput()); + } + + @Test + public void testResetOperation() { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + expect(compute.reset(INSTANCE_ID)).andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.reset()); + } + + @Test + public void testResetNull() { + initializeExpectedInstance(1); + expect(compute.options()).andReturn(mockOptions); + expect(compute.reset(INSTANCE_ID)).andReturn(null); + replay(compute); + initializeInstance(); + assertNull(instance.reset()); + } + + @Test + public void testSetDiskAutodelete() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + expect(compute.setDiskAutoDelete(INSTANCE_ID, "dev0", true)).andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.setDiskAutoDelete("dev0", true)); + } + + @Test + public void testSetDiskAutodelete_Null() throws Exception { + initializeExpectedInstance(1); + expect(compute.options()).andReturn(mockOptions); + expect(compute.setDiskAutoDelete(INSTANCE_ID, "dev0", false)).andReturn(null); + replay(compute); + initializeInstance(); + assertNull(instance.setDiskAutoDelete("dev0", false)); + } + + @Test + public void testSetDiskAutodeleteWithOptions() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + expect(compute.setDiskAutoDelete(INSTANCE_ID, "dev0", true, OperationOption.fields())) + .andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.setDiskAutoDelete("dev0", true, OperationOption.fields())); + } + + @Test + public void testSetMachineType() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + expect(compute.setMachineType(INSTANCE_ID, MACHINE_TYPE)).andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.setMachineType(MACHINE_TYPE)); + } + + @Test + public void testSetMachineType_Null() throws Exception { + initializeExpectedInstance(1); + expect(compute.options()).andReturn(mockOptions); + expect(compute.setMachineType(INSTANCE_ID, MACHINE_TYPE)).andReturn(null); + replay(compute); + initializeInstance(); + assertNull(instance.setMachineType(MACHINE_TYPE)); + } + + @Test + public void testSetMachineTypeWithOptions() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + expect(compute.setMachineType(INSTANCE_ID, MACHINE_TYPE, OperationOption.fields())) + .andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.setMachineType(MACHINE_TYPE, OperationOption.fields())); + } + + @Test + public void testSetMetadata() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + Metadata metadata = Metadata.builder().add("k", "v").fingerprint("fingerprint").build(); + expect(compute.setMetadata(INSTANCE_ID, metadata)).andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.setMetadata(metadata)); + } + + @Test + public void testSetMetadata_Null() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Metadata metadata = Metadata.builder().add("k", "v").fingerprint("fingerprint").build(); + expect(compute.setMetadata(INSTANCE_ID, metadata)).andReturn(null); + replay(compute); + initializeInstance(); + assertNull(instance.setMetadata(metadata)); + } + + @Test + public void testSetMetadataWithOptions() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + Metadata metadata = Metadata.builder().add("k", "v").fingerprint("fingerprint").build(); + expect(compute.setMetadata(INSTANCE_ID, metadata, OperationOption.fields())) + .andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.setMetadata(metadata, OperationOption.fields())); + } + + @Test + public void testSetMetadataFromMap() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + Map metadataMap = ImmutableMap.of("k", "v"); + Metadata metadata = Metadata.builder().values(metadataMap).fingerprint("fingerprint").build(); + expect(compute.setMetadata(INSTANCE_ID, metadata)).andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.setMetadata(metadataMap)); + } + + @Test + public void testSetMetadataFromMap_Null() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Map metadataMap = ImmutableMap.of("k", "v"); + Metadata metadata = Metadata.builder().values(metadataMap).fingerprint("fingerprint").build(); + expect(compute.setMetadata(INSTANCE_ID, metadata)).andReturn(null); + replay(compute); + initializeInstance(); + assertNull(instance.setMetadata(metadataMap)); + } + + @Test + public void testSetMetadataFromMapWithOptions() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + Map metadataMap = ImmutableMap.of("k", "v"); + Metadata metadata = Metadata.builder().values(metadataMap).fingerprint("fingerprint").build(); + expect(compute.setMetadata(INSTANCE_ID, metadata, OperationOption.fields())) + .andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.setMetadata(metadataMap, OperationOption.fields())); + } + + @Test + public void testSetSchedulingOptions() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + SchedulingOptions schedulingOptions = SchedulingOptions.standard(true, Maintenance.MIGRATE); + expect(compute.setSchedulingOptions(INSTANCE_ID, schedulingOptions)).andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.setSchedulingOptions(schedulingOptions)); + } + + @Test + public void testSetSchedulingOptions_Null() throws Exception { + initializeExpectedInstance(1); + expect(compute.options()).andReturn(mockOptions); + SchedulingOptions schedulingOptions = SchedulingOptions.standard(true, Maintenance.MIGRATE); + expect(compute.setSchedulingOptions(INSTANCE_ID, schedulingOptions)).andReturn(null); + replay(compute); + initializeInstance(); + assertNull(instance.setSchedulingOptions(schedulingOptions)); + } + + @Test + public void testSetSchedulingOptionsWithOptions() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + SchedulingOptions schedulingOptions = SchedulingOptions.standard(true, Maintenance.MIGRATE); + expect(compute.setSchedulingOptions(INSTANCE_ID, schedulingOptions, OperationOption.fields())) + .andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, + instance.setSchedulingOptions(schedulingOptions, OperationOption.fields())); + } + + @Test + public void testSetTags() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + Tags tags = Tags.builder().values("v1", "v2").fingerprint("fingerprint").build(); + expect(compute.setTags(INSTANCE_ID, tags)).andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.setTags(tags)); + } + + @Test + public void testSetTags_Null() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Tags tags = Tags.builder().values("v1", "v2").fingerprint("fingerprint").build(); + expect(compute.setTags(INSTANCE_ID, tags)).andReturn(null); + replay(compute); + initializeInstance(); + assertNull(instance.setTags(tags)); + } + + @Test + public void testSetTagsWithOptions() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + Tags tags = Tags.builder().values("v1", "v2").fingerprint("fingerprint").build(); + expect(compute.setTags(INSTANCE_ID, tags, OperationOption.fields())).andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.setTags(tags, OperationOption.fields())); + } + + @Test + public void testSetTagsFromList() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + List tagList = ImmutableList.of("v1", "v2"); + Tags tags = Tags.builder().values(tagList).fingerprint("fingerprint").build(); + expect(compute.setTags(INSTANCE_ID, tags)).andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.setTags(tagList)); + } + + @Test + public void testSetTagsFromList_Null() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + List tagList = ImmutableList.of("v1", "v2"); + Tags tags = Tags.builder().values(tagList).fingerprint("fingerprint").build(); + expect(compute.setTags(INSTANCE_ID, tags)).andReturn(null); + replay(compute); + initializeInstance(); + assertNull(instance.setTags(tagList)); + } + + @Test + public void testSetTagsFromListWithOptions() throws Exception { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + List tagList = ImmutableList.of("v1", "v2"); + Tags tags = Tags.builder().values(tagList).fingerprint("fingerprint").build(); + expect(compute.setTags(INSTANCE_ID, tags, OperationOption.fields())).andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.setTags(tagList, OperationOption.fields())); + } + + @Test + public void testStartOperation() { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + expect(compute.start(INSTANCE_ID)).andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.start()); + } + + @Test + public void testStartNull() { + initializeExpectedInstance(1); + expect(compute.options()).andReturn(mockOptions); + expect(compute.start(INSTANCE_ID)).andReturn(null); + replay(compute); + initializeInstance(); + assertNull(instance.start()); + } + + @Test + public void testStopOperation() { + initializeExpectedInstance(2); + expect(compute.options()).andReturn(mockOptions); + Operation operation = new Operation.Builder(serviceMockReturnsOptions) + .operationId(ZoneOperationId.of("project", "op")) + .build(); + expect(compute.stop(INSTANCE_ID)).andReturn(operation); + replay(compute); + initializeInstance(); + assertSame(operation, instance.stop()); + } + + @Test + public void testStopNull() { + initializeExpectedInstance(1); + expect(compute.options()).andReturn(mockOptions); + expect(compute.stop(INSTANCE_ID)).andReturn(null); + replay(compute); + initializeInstance(); + assertNull(instance.stop()); + } + + public void compareInstance(Instance expected, Instance value) { + assertEquals(expected, value); + assertEquals(expected.compute().options(), value.compute().options()); + assertEquals(expected.id(), value.id()); + assertEquals(expected.instanceId(), value.instanceId()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.status(), value.status()); + assertEquals(expected.statusMessage(), value.statusMessage()); + assertEquals(expected.tags(), value.tags()); + assertEquals(expected.machineType(), value.machineType()); + assertEquals(expected.canIpForward(), value.canIpForward()); + assertEquals(expected.networkInterfaces(), value.networkInterfaces()); + assertEquals(expected.attachedDisks(), value.attachedDisks()); + assertEquals(expected.metadata(), value.metadata()); + assertEquals(expected.serviceAccounts(), value.serviceAccounts()); + assertEquals(expected.schedulingOptions(), value.schedulingOptions()); + assertEquals(expected.cpuPlatform(), value.cpuPlatform()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java index 92b1128ac6c4..5b5b97142a3d 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java @@ -193,6 +193,9 @@ public class SerializationTest { private static final SchedulingOptions SCHEDULING_OPTIONS = SchedulingOptions.preemptible(); private static final InstanceInfo INSTANCE_INFO = InstanceInfo.of(INSTANCE_ID, MACHINE_TYPE_ID, ATTACHED_DISK, NETWORK_INTERFACE); + private static final Instance INSTANCE = + new Instance.Builder(COMPUTE, INSTANCE_ID, MACHINE_TYPE_ID, ATTACHED_DISK, NETWORK_INTERFACE) + .build(); private static final Compute.DiskTypeOption DISK_TYPE_OPTION = Compute.DiskTypeOption.fields(); private static final Compute.DiskTypeFilter DISK_TYPE_FILTER = @@ -263,6 +266,14 @@ public class SerializationTest { Compute.NetworkFilter.equals(Compute.NetworkField.SELF_LINK, "selfLink"); private static final Compute.NetworkListOption NETWORK_LIST_OPTION = Compute.NetworkListOption.filter(NETWORK_FILTER); + private static final Compute.InstanceOption INSTANCE_OPTION = + Compute.InstanceOption.fields(); + private static final Compute.InstanceFilter INSTANCE_FILTER = + Compute.InstanceFilter.equals(Compute.InstanceField.SELF_LINK, "selfLink"); + private static final Compute.InstanceListOption INSTANCE_LIST_OPTION = + Compute.InstanceListOption.filter(INSTANCE_FILTER); + private static final Compute.InstanceAggregatedListOption INSTANCE_AGGREGATED_LIST_OPTION = + Compute.InstanceAggregatedListOption.filter(INSTANCE_FILTER); @Test public void testServiceOptions() throws Exception { @@ -296,7 +307,7 @@ public void testModelAndRequests() throws Exception { STANDARD_NETWORK_CONFIGURATION, SUBNET_NETWORK_CONFIGURATION, NETWORK_INFO, NETWORK, ACCESS_CONFIG, NETWORK_INTERFACE, CREATE_DISK_CONFIGURATION, PERSISTENT_DISK_CONFIGURATION, SCRATCH_DISK_CONFIGURATION, ATTACHED_DISK, TAGS, METADATA, SERVICE_ACCOUNT, - SCHEDULING_OPTIONS, INSTANCE_INFO, DISK_TYPE_OPTION, DISK_TYPE_FILTER, + SCHEDULING_OPTIONS, INSTANCE_INFO, INSTANCE, DISK_TYPE_OPTION, DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, DISK_TYPE_AGGREGATED_LIST_OPTION, MACHINE_TYPE_OPTION, MACHINE_TYPE_FILTER, MACHINE_TYPE_LIST_OPTION, MACHINE_TYPE_AGGREGATED_LIST_OPTION, REGION_OPTION, REGION_FILTER, REGION_LIST_OPTION, ZONE_OPTION, ZONE_FILTER, @@ -305,7 +316,8 @@ public void testModelAndRequests() throws Exception { SNAPSHOT_OPTION, SNAPSHOT_FILTER, SNAPSHOT_LIST_OPTION, IMAGE_OPTION, IMAGE_FILTER, IMAGE_LIST_OPTION, DISK_OPTION, DISK_FILTER, DISK_LIST_OPTION, DISK_AGGREGATED_LIST_OPTION, SUBNETWORK_OPTION, SUBNETWORK_FILTER, SUBNETWORK_LIST_OPTION, - SUBNETWORK_AGGREGATED_LIST_OPTION, NETWORK_OPTION, NETWORK_FILTER, NETWORK_LIST_OPTION}; + SUBNETWORK_AGGREGATED_LIST_OPTION, NETWORK_OPTION, NETWORK_FILTER, NETWORK_LIST_OPTION, + INSTANCE_OPTION, INSTANCE_FILTER, INSTANCE_LIST_OPTION, INSTANCE_AGGREGATED_LIST_OPTION}; for (Serializable obj : objects) { Object copy = serializeAndDeserialize(obj); assertEquals(obj, obj); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java index d47d0fb6082b..00a26cf82602 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java @@ -23,11 +23,18 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.gcloud.Page; import com.google.gcloud.compute.Address; import com.google.gcloud.compute.AddressId; import com.google.gcloud.compute.AddressInfo; +import com.google.gcloud.compute.AttachedDisk; +import com.google.gcloud.compute.AttachedDisk.AttachedDiskConfiguration; +import com.google.gcloud.compute.AttachedDisk.CreateDiskConfiguration; +import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; +import com.google.gcloud.compute.AttachedDisk.ScratchDiskConfiguration; import com.google.gcloud.compute.Compute; import com.google.gcloud.compute.DeprecationStatus; import com.google.gcloud.compute.Disk; @@ -43,17 +50,25 @@ import com.google.gcloud.compute.ImageDiskConfiguration; import com.google.gcloud.compute.ImageId; import com.google.gcloud.compute.ImageInfo; +import com.google.gcloud.compute.Instance; +import com.google.gcloud.compute.InstanceId; +import com.google.gcloud.compute.InstanceInfo; import com.google.gcloud.compute.License; import com.google.gcloud.compute.LicenseId; import com.google.gcloud.compute.MachineType; +import com.google.gcloud.compute.MachineTypeId; import com.google.gcloud.compute.Network; import com.google.gcloud.compute.NetworkConfiguration; import com.google.gcloud.compute.NetworkId; import com.google.gcloud.compute.NetworkInfo; +import com.google.gcloud.compute.NetworkInterface; +import com.google.gcloud.compute.NetworkInterface.AccessConfig; import com.google.gcloud.compute.Operation; import com.google.gcloud.compute.Region; import com.google.gcloud.compute.RegionAddressId; import com.google.gcloud.compute.RegionOperationId; +import com.google.gcloud.compute.SchedulingOptions; +import com.google.gcloud.compute.SchedulingOptions.Maintenance; import com.google.gcloud.compute.Snapshot; import com.google.gcloud.compute.SnapshotDiskConfiguration; import com.google.gcloud.compute.SnapshotId; @@ -75,6 +90,8 @@ import org.junit.rules.Timeout; import java.util.Iterator; +import java.util.List; +import java.util.Map; import java.util.Set; public class ITComputeTest { @@ -1599,4 +1616,307 @@ public void testAggregatedListSubnetworks() throws InterruptedException { } assertNull(compute.getNetwork(networkName)); } + + @Test + public void testCreateGetAndDeleteInstance() throws InterruptedException { + String instanceName = BASE_RESOURCE_NAME + "create-and-get-instance"; + String addressName = BASE_RESOURCE_NAME + "create-and-get-instance-address"; + // Create an address to assign to the instance + AddressId addressId = RegionAddressId.of(REGION, addressName); + AddressInfo addressInfo = AddressInfo.of(addressId); + Operation operation = compute.create(addressInfo); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + Address address = compute.get(addressId); + // Create an instance + InstanceId instanceId = InstanceId.of(ZONE, instanceName); + NetworkId networkId = NetworkId.of("default"); + NetworkInterface networkInterface = NetworkInterface.builder(networkId) + .accessConfigurations(AccessConfig.builder().name("NAT").natIp(address.address()).build()) + .build(); + AttachedDisk disk1 = AttachedDisk.of("dev0", + CreateDiskConfiguration.builder(IMAGE_ID).autoDelete(true).build()); + AttachedDisk disk2 = + AttachedDisk.of("dev1", ScratchDiskConfiguration.of(DiskTypeId.of(ZONE, DISK_TYPE))); + InstanceInfo instanceInfo = + InstanceInfo.builder(instanceId, MachineTypeId.of(ZONE, "n1-standard-1")) + .attachedDisks(disk1, disk2) + .networkInterfaces(networkInterface) + .build(); + operation = compute.create(instanceInfo); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + // test get + Instance remoteInstance = compute.get(instanceId); + assertEquals(instanceName, remoteInstance.instanceId().instance()); + assertEquals(ZONE, remoteInstance.instanceId().zone()); + assertEquals(InstanceInfo.Status.RUNNING, remoteInstance.status()); + assertEquals("n1-standard-1", remoteInstance.machineType().type()); + assertEquals(ZONE, remoteInstance.machineType().zone()); + assertNotNull(remoteInstance.creationTimestamp()); + Set deviceSet = ImmutableSet.of("dev0", "dev1"); + assertEquals(2, remoteInstance.attachedDisks().size()); + for (AttachedDisk remoteAttachedDisk : remoteInstance.attachedDisks()) { + assertTrue(deviceSet.contains(remoteAttachedDisk.deviceName())); + } + assertEquals(AttachedDiskConfiguration.Type.PERSISTENT, + remoteInstance.attachedDisks().get(0).configuration().type()); + PersistentDiskConfiguration remoteConfiguration = + remoteInstance.attachedDisks().get(0).configuration(); + assertEquals(instanceName, remoteConfiguration.sourceDisk().disk()); + assertEquals(ZONE, remoteConfiguration.sourceDisk().zone()); + assertTrue(remoteConfiguration.boot()); + assertTrue(remoteConfiguration.autoDelete()); + assertEquals(1, remoteInstance.networkInterfaces().size()); + NetworkInterface remoteNetworkInterface = remoteInstance.networkInterfaces().get(0); + assertNotNull(remoteNetworkInterface.name()); + assertEquals("default", remoteNetworkInterface.network().network()); + List remoteAccessConfigurations = remoteNetworkInterface.accessConfigurations(); + assertNotNull(remoteAccessConfigurations); + assertEquals(1, remoteAccessConfigurations.size()); + AccessConfig remoteAccessConfig = remoteAccessConfigurations.get(0); + assertEquals(address.address(), remoteAccessConfig.natIp()); + assertEquals("NAT", remoteAccessConfig.name()); + assertNotNull(remoteInstance.metadata()); + assertNotNull(remoteInstance.tags()); + // test get with selected fields + remoteInstance = compute.get(instanceId, + Compute.InstanceOption.fields(Compute.InstanceField.CREATION_TIMESTAMP)); + assertEquals(instanceName, remoteInstance.instanceId().instance()); + assertEquals(ZONE, remoteInstance.instanceId().zone()); + assertNull(remoteInstance.machineType()); + assertNotNull(remoteInstance.creationTimestamp()); + assertNull(remoteInstance.attachedDisks()); + assertNull(remoteInstance.networkInterfaces()); + assertNull(remoteInstance.metadata()); + assertNull(remoteInstance.tags()); + // test get default serial port output + String serialPortOutput = remoteInstance.getSerialPortOutput(); + assertNotNull(serialPortOutput); + // test get serial port output by number + String newSerialPortOutput = remoteInstance.getSerialPortOutput(1); + assertTrue(newSerialPortOutput.contains(serialPortOutput)); + operation = remoteInstance.delete(); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + assertNull(compute.get(instanceId)); + address.delete(); + } + + @Test + public void testStartStopAndResetInstance() throws InterruptedException { + String instanceName = BASE_RESOURCE_NAME + "start-stop-reset-instance"; + InstanceId instanceId = InstanceId.of(ZONE, instanceName); + NetworkId networkId = NetworkId.of("default"); + NetworkInterface networkInterface = NetworkInterface.builder(networkId).build(); + AttachedDisk disk = AttachedDisk.of("dev0", + CreateDiskConfiguration.builder(IMAGE_ID).autoDelete(true).build()); + InstanceInfo instanceInfo = + InstanceInfo.builder(instanceId, MachineTypeId.of(ZONE, MACHINE_TYPE)) + .attachedDisks(disk) + .networkInterfaces(networkInterface) + .build(); + Operation operation = compute.create(instanceInfo); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + Instance remoteInstance = + compute.get(instanceId, Compute.InstanceOption.fields(Compute.InstanceField.STATUS)); + assertEquals(InstanceInfo.Status.RUNNING, remoteInstance.status()); + operation = remoteInstance.stop(); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + remoteInstance = + compute.get(instanceId, Compute.InstanceOption.fields(Compute.InstanceField.STATUS)); + assertEquals(InstanceInfo.Status.TERMINATED, remoteInstance.status()); + operation = remoteInstance.start(); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + remoteInstance = + compute.get(instanceId, Compute.InstanceOption.fields(Compute.InstanceField.STATUS)); + assertEquals(InstanceInfo.Status.RUNNING, remoteInstance.status()); + operation = remoteInstance.reset(); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + remoteInstance = + compute.get(instanceId, Compute.InstanceOption.fields(Compute.InstanceField.STATUS)); + assertEquals(InstanceInfo.Status.RUNNING, remoteInstance.status()); + remoteInstance.delete(); + } + + @Test + public void testSetInstanceProperties() throws InterruptedException { + String instanceName = BASE_RESOURCE_NAME + "set-properties-instance"; + InstanceId instanceId = InstanceId.of(ZONE, instanceName); + NetworkId networkId = NetworkId.of("default"); + NetworkInterface networkInterface = NetworkInterface.builder(networkId).build(); + AttachedDisk disk = AttachedDisk.of("dev0", + CreateDiskConfiguration.builder(IMAGE_ID).autoDelete(true).build()); + InstanceInfo instanceInfo = + InstanceInfo.builder(instanceId, MachineTypeId.of(ZONE, MACHINE_TYPE)) + .attachedDisks(disk) + .networkInterfaces(networkInterface) + .build(); + Operation operation = compute.create(instanceInfo); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + Instance remoteInstance = compute.get(instanceId); + // test set tags + List tags = ImmutableList.of("tag1", "tag2"); + operation = remoteInstance.setTags(tags); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + remoteInstance = compute.get(instanceId); + assertEquals(tags, remoteInstance.tags().values()); + // test set metadata + Map metadata = ImmutableMap.of("key", "value"); + operation = remoteInstance.setMetadata(metadata); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + remoteInstance = compute.get(instanceId); + assertEquals(metadata, remoteInstance.metadata().values()); + // test set machine type + operation = remoteInstance.stop(); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + operation = remoteInstance.setMachineType(MachineTypeId.of(ZONE, "n1-standard-1")); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + remoteInstance = compute.get(instanceId); + assertEquals("n1-standard-1", remoteInstance.machineType().type()); + assertEquals(ZONE, remoteInstance.machineType().zone()); + // test set scheduling options + SchedulingOptions options = SchedulingOptions.standard(false, Maintenance.TERMINATE); + operation = remoteInstance.setSchedulingOptions(options); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + remoteInstance = compute.get(instanceId); + assertEquals(options, remoteInstance.schedulingOptions()); + remoteInstance.delete(); + } + + @Test + public void testAttachAndDetachDisk() throws InterruptedException { + String instanceName = BASE_RESOURCE_NAME + "attach-and-detach-disk-instance"; + String diskName = BASE_RESOURCE_NAME + "attach-and-detach-disk"; + InstanceId instanceId = InstanceId.of(ZONE, instanceName); + NetworkId networkId = NetworkId.of("default"); + NetworkInterface networkInterface = NetworkInterface.builder(networkId).build(); + AttachedDisk disk = AttachedDisk.of("dev0", + CreateDiskConfiguration.builder(IMAGE_ID).autoDelete(true).build()); + InstanceInfo instanceInfo = + InstanceInfo.builder(instanceId, MachineTypeId.of(ZONE, MACHINE_TYPE)) + .attachedDisks(disk) + .networkInterfaces(networkInterface) + .build(); + Operation instanceOperation = compute.create(instanceInfo); + DiskId diskId = DiskId.of(ZONE, diskName); + Operation diskOperation = compute.create(DiskInfo.of(diskId, + StandardDiskConfiguration.of(DiskTypeId.of(ZONE, "pd-ssd")))); + while (!instanceOperation.isDone()) { + Thread.sleep(1000L); + } + while (!diskOperation.isDone()) { + Thread.sleep(1000L); + } + Instance remoteInstance = compute.get(instanceId); + // test attach disk + instanceOperation = remoteInstance.attachDisk("dev1", + PersistentDiskConfiguration.builder(diskId).build()); + while (!instanceOperation.isDone()) { + Thread.sleep(1000L); + } + remoteInstance = compute.get(instanceId); + Set deviceSet = ImmutableSet.of("dev0", "dev1"); + assertEquals(2, remoteInstance.attachedDisks().size()); + for (AttachedDisk remoteAttachedDisk : remoteInstance.attachedDisks()) { + assertTrue(deviceSet.contains(remoteAttachedDisk.deviceName())); + } + // test set disk auto-delete + instanceOperation = remoteInstance.setDiskAutoDelete("dev1", true); + while (!instanceOperation.isDone()) { + Thread.sleep(1000L); + } + remoteInstance = compute.get(instanceId); + for (AttachedDisk remoteAttachedDisk : remoteInstance.attachedDisks()) { + assertTrue(deviceSet.contains(remoteAttachedDisk.deviceName())); + assertTrue(remoteAttachedDisk.configuration().autoDelete()); + } + // test detach disk + instanceOperation = remoteInstance.detachDisk("dev1"); + while (!instanceOperation.isDone()) { + Thread.sleep(1000L); + } + remoteInstance = compute.get(instanceId); + assertEquals(1, remoteInstance.attachedDisks().size()); + assertEquals("dev0", remoteInstance.attachedDisks().get(0).deviceName()); + remoteInstance.delete(); + } + + @Test + public void testAddAndRemoveAccessConfig() throws InterruptedException { + String instanceName = BASE_RESOURCE_NAME + "add-and-remove-access-instance"; + String addressName = BASE_RESOURCE_NAME + "add-and-remove-access-address"; + InstanceId instanceId = InstanceId.of(ZONE, instanceName); + NetworkId networkId = NetworkId.of("default"); + NetworkInterface networkInterface = NetworkInterface.builder(networkId).build(); + AttachedDisk disk = AttachedDisk.of("dev0", + CreateDiskConfiguration.builder(IMAGE_ID).autoDelete(true).build()); + InstanceInfo instanceInfo = + InstanceInfo.builder(instanceId, MachineTypeId.of(ZONE, MACHINE_TYPE)) + .attachedDisks(disk) + .networkInterfaces(networkInterface) + .build(); + Operation instanceOperation = compute.create(instanceInfo); + AddressId addressId = RegionAddressId.of(REGION, addressName); + AddressInfo addressInfo = AddressInfo.of(addressId); + Operation addressOperation = compute.create(addressInfo); + while (!addressOperation.isDone()) { + Thread.sleep(1000L); + } + while (!instanceOperation.isDone()) { + Thread.sleep(1000L); + } + while (!addressOperation.isDone()) { + Thread.sleep(1000L); + } + Address remoteAddress = compute.get(addressId); + Instance remoteInstance = compute.get(instanceId); + String networkInterfaceName = remoteInstance.networkInterfaces().get(0).name(); + // test add access config + AccessConfig accessConfig = AccessConfig.builder() + .natIp(remoteAddress.address()) + .name("NAT") + .build(); + instanceOperation = remoteInstance.addAccessConfig(networkInterfaceName, accessConfig); + while (!instanceOperation.isDone()) { + Thread.sleep(1000L); + } + remoteInstance = compute.get(instanceId); + List accessConfigurations = + remoteInstance.networkInterfaces().get(0).accessConfigurations(); + assertEquals(1, accessConfigurations.size()); + assertEquals("NAT", accessConfigurations.get(0).name()); + // test delete access config + instanceOperation = remoteInstance.deleteAccessConfig(networkInterfaceName, "NAT"); + while (!instanceOperation.isDone()) { + Thread.sleep(1000L); + } + remoteInstance = compute.get(instanceId); + assertTrue(remoteInstance.networkInterfaces().get(0).accessConfigurations().isEmpty()); + remoteInstance.delete(); + remoteAddress.delete(); + } } From b8989f3ec82634e19f2c3de17f56804245427e15 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 27 Apr 2016 19:44:36 +0200 Subject: [PATCH 324/375] Add travis_wait directive before verify script (#965) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c023116917a3..1e4b639b0e0d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ before_install: - cp target/travis/settings.xml ~/.m2/settings.xml install: mvn install -DskipTests=true -Dgpg.skip=true script: -- utilities/verify.sh +- travis_wait 30 utilities/verify.sh after_success: - utilities/after_success.sh env: From 4888e129da3c92ce7bf1e922cc4e790bb8bcc2c0 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 27 Apr 2016 21:40:38 +0200 Subject: [PATCH 325/375] Rename id to generatedId for Compute resources (#966) --- .../com/google/gcloud/compute/Address.java | 4 +- .../google/gcloud/compute/AddressInfo.java | 31 ++-- .../java/com/google/gcloud/compute/Disk.java | 4 +- .../compute/DiskImageConfiguration.java | 5 +- .../com/google/gcloud/compute/DiskInfo.java | 28 ++-- .../com/google/gcloud/compute/DiskType.java | 24 ++-- .../java/com/google/gcloud/compute/Image.java | 4 +- .../compute/ImageDiskConfiguration.java | 9 +- .../com/google/gcloud/compute/ImageInfo.java | 30 ++-- .../com/google/gcloud/compute/Instance.java | 4 +- .../google/gcloud/compute/InstanceInfo.java | 34 ++--- .../google/gcloud/compute/MachineType.java | 24 ++-- .../com/google/gcloud/compute/Network.java | 4 +- .../google/gcloud/compute/NetworkInfo.java | 30 ++-- .../com/google/gcloud/compute/Operation.java | 26 ++-- .../com/google/gcloud/compute/Region.java | 24 ++-- .../com/google/gcloud/compute/Snapshot.java | 4 +- .../compute/SnapshotDiskConfiguration.java | 8 +- .../google/gcloud/compute/SnapshotInfo.java | 36 ++--- .../com/google/gcloud/compute/Subnetwork.java | 4 +- .../google/gcloud/compute/SubnetworkInfo.java | 32 ++--- .../java/com/google/gcloud/compute/Zone.java | 24 ++-- .../gcloud/compute/AddressInfoTest.java | 24 ++-- .../google/gcloud/compute/AddressTest.java | 24 ++-- .../gcloud/compute/ComputeImplTest.java | 16 +-- .../google/gcloud/compute/DiskInfoTest.java | 22 +-- .../com/google/gcloud/compute/DiskTest.java | 20 +-- .../google/gcloud/compute/DiskTypeTest.java | 8 +- .../google/gcloud/compute/ImageInfoTest.java | 16 +-- .../com/google/gcloud/compute/ImageTest.java | 16 +-- .../gcloud/compute/InstanceInfoTest.java | 12 +- .../google/gcloud/compute/InstanceTest.java | 12 +- .../gcloud/compute/MachineTypeTest.java | 8 +- .../gcloud/compute/NetworkInfoTest.java | 14 +- .../google/gcloud/compute/NetworkTest.java | 14 +- .../google/gcloud/compute/OperationTest.java | 15 +- .../com/google/gcloud/compute/RegionTest.java | 8 +- .../gcloud/compute/SerializationTest.java | 6 - .../gcloud/compute/SnapshotInfoTest.java | 10 +- .../google/gcloud/compute/SnapshotTest.java | 12 +- .../gcloud/compute/SubnetworkInfoTest.java | 10 +- .../google/gcloud/compute/SubnetworkTest.java | 10 +- .../com/google/gcloud/compute/ZoneTest.java | 8 +- .../gcloud/compute/it/ITComputeTest.java | 136 +++++++++--------- 44 files changed, 405 insertions(+), 409 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java index e1e70def80d5..c76e75f13da3 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java @@ -80,8 +80,8 @@ public Builder description(String description) { } @Override - Builder id(String id) { - infoBuilder.id(id); + Builder generatedId(String generatedId) { + infoBuilder.generatedId(generatedId); return this; } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressInfo.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressInfo.java index 249f8462d401..a18123027989 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressInfo.java @@ -68,7 +68,7 @@ public Address apply(AddressInfo addressInfo) { private final String address; private final Long creationTimestamp; private final String description; - private final String id; + private final String generatedId; private final AddressId addressId; private final Status status; private final Usage usage; @@ -296,7 +296,7 @@ public abstract static class Builder { */ public abstract Builder description(String description); - abstract Builder id(String id); + abstract Builder generatedId(String generatedId); public abstract Builder addressId(AddressId addressId); @@ -315,7 +315,7 @@ static final class BuilderImpl extends Builder { private String address; private Long creationTimestamp; private String description; - private String id; + private String generatedId; private AddressId addressId; private Status status; private Usage usage; @@ -326,7 +326,7 @@ static final class BuilderImpl extends Builder { this.address = addressInfo.address; this.creationTimestamp = addressInfo.creationTimestamp; this.description = addressInfo.description; - this.id = addressInfo.id; + this.generatedId = addressInfo.generatedId; this.addressId = addressInfo.addressId; this.status = addressInfo.status; this.usage = addressInfo.usage; @@ -344,7 +344,7 @@ static final class BuilderImpl extends Builder { } description = addressPb.getDescription(); if (addressPb.getId() != null) { - id = addressPb.getId().toString(); + generatedId = addressPb.getId().toString(); } if (addressPb.getStatus() != null) { status = Status.valueOf(addressPb.getStatus()); @@ -373,8 +373,8 @@ public BuilderImpl description(String description) { } @Override - BuilderImpl id(String id) { - this.id = id; + BuilderImpl generatedId(String generatedId) { + this.generatedId = generatedId; return this; } @@ -406,7 +406,7 @@ public AddressInfo build() { address = builder.address; creationTimestamp = builder.creationTimestamp; description = builder.description; - id = builder.id; + generatedId = builder.generatedId; addressId = checkNotNull(builder.addressId); status = builder.status; usage = builder.usage; @@ -434,10 +434,10 @@ public String description() { } /** - * Returns the unique identifier for the address; defined by the service. + * Returns the service-generated unique identifier for the address. */ - public String id() { - return id; + public String generatedId() { + return generatedId; } /** @@ -481,7 +481,7 @@ public String toString() { .add("address", address) .add("creationTimestamp", creationTimestamp) .add("description", description) - .add("id", id) + .add("generatedId", generatedId) .add("addressId", addressId) .add("status", status) .add("usage", usage) @@ -490,7 +490,8 @@ public String toString() { @Override public int hashCode() { - return Objects.hash(address, creationTimestamp, description, id, addressId, status, usage); + return Objects.hash(address, creationTimestamp, description, generatedId, addressId, status, + usage); } @Override @@ -514,8 +515,8 @@ Address toPb() { addressPb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); } addressPb.setDescription(description); - if (id != null) { - addressPb.setId(new BigInteger(id)); + if (generatedId != null) { + addressPb.setId(new BigInteger(generatedId)); } addressPb.setName(addressId.address()); if (addressId.type() == AddressId.Type.REGION) { diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Disk.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Disk.java index 265996a56af6..9904f49b819e 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Disk.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Disk.java @@ -60,8 +60,8 @@ public static class Builder extends DiskInfo.Builder { } @Override - Builder id(String id) { - infoBuilder.id(id); + Builder generatedId(String generatedId) { + infoBuilder.generatedId(generatedId); return this; } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskImageConfiguration.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskImageConfiguration.java index 51b6cb912272..259ff0ef9fc3 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskImageConfiguration.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskImageConfiguration.java @@ -95,8 +95,9 @@ public DiskId sourceDisk() { } /** - * Returns the id of the disk used to create this image. This value may be used to determine - * whether the image was taken from the current or a previous instance of a given disk name. + * Returns the service-generated unique id of the disk used to create this image. This value may + * be used to determine whether the image was taken from the current or a previous instance of a + * given disk name. */ public String sourceDiskId() { return sourceDiskId; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskInfo.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskInfo.java index 1f55b4256a30..bfe7d21911e6 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskInfo.java @@ -58,7 +58,7 @@ public Disk apply(DiskInfo diskType) { private static final long serialVersionUID = -7173418340679279619L; private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); - private final String id; + private final String generatedId; private final DiskId diskId; private final DiskConfiguration configuration; private final Long creationTimestamp; @@ -99,7 +99,7 @@ public enum CreationStatus { */ public abstract static class Builder { - abstract Builder id(String id); + abstract Builder generatedId(String generatedId); /** * Sets the disk configuration. @@ -136,7 +136,7 @@ public abstract static class Builder { static final class BuilderImpl extends Builder { - private String id; + private String generatedId; private DiskId diskId; private DiskConfiguration configuration; private Long creationTimestamp; @@ -153,7 +153,7 @@ static final class BuilderImpl extends Builder { } BuilderImpl(DiskInfo diskInfo) { - this.id = diskInfo.id; + this.generatedId = diskInfo.generatedId; this.configuration = diskInfo.configuration; this.creationTimestamp = diskInfo.creationTimestamp; this.creationStatus = diskInfo.creationStatus; @@ -167,7 +167,7 @@ static final class BuilderImpl extends Builder { BuilderImpl(Disk diskPb) { if (diskPb.getId() != null) { - this.id = diskPb.getId().toString(); + this.generatedId = diskPb.getId().toString(); } this.configuration = DiskConfiguration.fromPb(diskPb); if (diskPb.getCreationTimestamp() != null) { @@ -193,8 +193,8 @@ static final class BuilderImpl extends Builder { } @Override - BuilderImpl id(String id) { - this.id = id; + BuilderImpl generatedId(String generatedId) { + this.generatedId = generatedId; return this; } @@ -260,7 +260,7 @@ public DiskInfo build() { } DiskInfo(BuilderImpl builder) { - this.id = builder.id; + this.generatedId = builder.generatedId; this.configuration = builder.configuration; this.creationTimestamp = builder.creationTimestamp; this.creationStatus = builder.creationStatus; @@ -280,10 +280,10 @@ public Long creationTimestamp() { } /** - * Returns the unique identifier for the disk; defined by the service. + * Returns the service-generated unique identifier for the disk. */ - public String id() { - return id; + public String generatedId() { + return generatedId; } /** @@ -353,7 +353,7 @@ public Builder toBuilder() { @Override public String toString() { return MoreObjects.toStringHelper(this) - .add("id", id) + .add("generatedId", generatedId) .add("diskId", diskId) .add("configuration", configuration) .add("creationTimestamp", creationTimestamp) @@ -408,8 +408,8 @@ DiskInfo setProjectId(String projectId) { Disk toPb() { Disk diskPb = configuration.toPb(); - if (id != null) { - diskPb.setId(new BigInteger(id)); + if (generatedId != null) { + diskPb.setId(new BigInteger(generatedId)); } if (creationTimestamp != null) { diskPb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java index f6c8342a0f1c..2e245f438508 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java @@ -52,7 +52,7 @@ public com.google.api.services.compute.model.DiskType apply(DiskType diskType) { private static final long serialVersionUID = -944042261695072026L; private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); - private final String id; + private final String generatedId; private final DiskTypeId diskTypeId; private final Long creationTimestamp; private final String description; @@ -62,7 +62,7 @@ public com.google.api.services.compute.model.DiskType apply(DiskType diskType) { static final class Builder { - private String id; + private String generatedId; private DiskTypeId diskTypeId; private Long creationTimestamp; private String description; @@ -72,8 +72,8 @@ static final class Builder { private Builder() {} - Builder id(String id) { - this.id = id; + Builder generatedId(String generatedId) { + this.generatedId = generatedId; return this; } @@ -113,7 +113,7 @@ DiskType build() { } private DiskType(Builder builder) { - this.id = builder.id; + this.generatedId = builder.generatedId; this.creationTimestamp = builder.creationTimestamp; this.diskTypeId = builder.diskTypeId; this.description = builder.description; @@ -137,10 +137,10 @@ public DiskTypeId diskTypeId() { } /** - * Returns the unique identifier for the disk type; defined by the service. + * Returns the service-generated unique identifier for the disk type. */ - public String id() { - return id; + public String generatedId() { + return generatedId; } /** @@ -176,7 +176,7 @@ public DeprecationStatus deprecationStatus() { @Override public String toString() { return MoreObjects.toStringHelper(this) - .add("id", id) + .add("generatedId", generatedId) .add("creationTimestamp", creationTimestamp) .add("description", description) .add("validDiskSize", validDiskSize) @@ -198,8 +198,8 @@ public final boolean equals(Object obj) { com.google.api.services.compute.model.DiskType toPb() { com.google.api.services.compute.model.DiskType diskTypePb = new com.google.api.services.compute.model.DiskType(); - if (id != null) { - diskTypePb.setId(new BigInteger(id)); + if (generatedId != null) { + diskTypePb.setId(new BigInteger(generatedId)); } if (creationTimestamp != null) { diskTypePb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); @@ -222,7 +222,7 @@ static Builder builder() { static DiskType fromPb(com.google.api.services.compute.model.DiskType diskTypePb) { Builder builder = builder(); if (diskTypePb.getId() != null) { - builder.id(diskTypePb.getId().toString()); + builder.generatedId(diskTypePb.getId().toString()); } if (diskTypePb.getCreationTimestamp() != null) { builder.creationTimestamp(TIMESTAMP_FORMATTER.parseMillis(diskTypePb.getCreationTimestamp())); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Image.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Image.java index 7815929f3bf3..a68febb01c7e 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Image.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Image.java @@ -65,8 +65,8 @@ public static class Builder extends ImageInfo.Builder { } @Override - Builder id(String id) { - infoBuilder.id(id); + Builder generatedId(String generatedId) { + infoBuilder.generatedId(generatedId); return this; } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageDiskConfiguration.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageDiskConfiguration.java index c738251bf7ac..5961f94c80d4 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageDiskConfiguration.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageDiskConfiguration.java @@ -108,10 +108,11 @@ public ImageId sourceImage() { } /** - * Returns the ID value of the image used to create this disk. This value identifies the exact - * image that was used to create this persistent disk. For example, if you created the persistent - * disk from an image that was later deleted and recreated under the same name, the source image - * ID would identify the exact version of the image that was used. + * Returns the service-generated unique id of the image used to create this disk. This value + * identifies the exact image that was used to create this persistent disk. For example, if you + * created the persistent disk from an image that was later deleted and recreated under the same + * name, the source image service-generated id would identify the exact version of the image that + * was used. */ public String sourceImageId() { return sourceImageId; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageInfo.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageInfo.java index c243154cec4e..6de9c52b455b 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageInfo.java @@ -63,7 +63,7 @@ public Image apply(ImageInfo image) { private static final long serialVersionUID = -1061916352807358977L; private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); - private final String id; + private final String generatedId; private final ImageId imageId; private final Long creationTimestamp; private final String description; @@ -99,7 +99,7 @@ public enum Status { */ public abstract static class Builder { - abstract Builder id(String id); + abstract Builder generatedId(String generatedId); abstract Builder creationTimestamp(Long creationTimestamp); @@ -136,7 +136,7 @@ public abstract static class Builder { static final class BuilderImpl extends Builder { - private String id; + private String generatedId; private Long creationTimestamp; private ImageId imageId; private String description; @@ -149,7 +149,7 @@ static final class BuilderImpl extends Builder { BuilderImpl() {} BuilderImpl(ImageInfo imageInfo) { - this.id = imageInfo.id; + this.generatedId = imageInfo.generatedId; this.creationTimestamp = imageInfo.creationTimestamp; this.imageId = imageInfo.imageId; this.description = imageInfo.description; @@ -162,7 +162,7 @@ static final class BuilderImpl extends Builder { BuilderImpl(Image imagePb) { if (imagePb.getId() != null) { - this.id = imagePb.getId().toString(); + this.generatedId = imagePb.getId().toString(); } if (imagePb.getCreationTimestamp() != null) { this.creationTimestamp = TIMESTAMP_FORMATTER.parseMillis(imagePb.getCreationTimestamp()); @@ -184,8 +184,8 @@ static final class BuilderImpl extends Builder { } @Override - BuilderImpl id(String id) { - this.id = id; + BuilderImpl generatedId(String generatedId) { + this.generatedId = generatedId; return this; } @@ -244,7 +244,7 @@ public ImageInfo build() { } ImageInfo(BuilderImpl builder) { - this.id = builder.id; + this.generatedId = builder.generatedId; this.creationTimestamp = builder.creationTimestamp; this.imageId = checkNotNull(builder.imageId); this.description = builder.description; @@ -256,10 +256,10 @@ public ImageInfo build() { } /** - * Returns the unique identifier for the image; defined by the service. + * Returns the service-generated unique identifier for the image. */ - public String id() { - return id; + public String generatedId() { + return generatedId; } /** @@ -335,7 +335,7 @@ public Builder toBuilder() { @Override public String toString() { return MoreObjects.toStringHelper(this) - .add("id", id) + .add("generatedId", generatedId) .add("creationTimestamp", creationTimestamp) .add("imageId", imageId) .add("description", description) @@ -348,7 +348,7 @@ public String toString() { @Override public int hashCode() { - return Objects.hash(id, creationTimestamp, imageId, description, configuration, status, + return Objects.hash(generatedId, creationTimestamp, imageId, description, configuration, status, diskSizeGb, licenses); } @@ -368,8 +368,8 @@ ImageInfo setProjectId(String projectId) { Image toPb() { Image imagePb = configuration.toPb(); - if (id != null) { - imagePb.setId(new BigInteger(id)); + if (generatedId != null) { + imagePb.setId(new BigInteger(generatedId)); } if (creationTimestamp != null) { imagePb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Instance.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Instance.java index 5f9aee0dd840..7c84d11d71d7 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Instance.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Instance.java @@ -70,8 +70,8 @@ public static class Builder extends InstanceInfo.Builder { } @Override - Builder id(String id) { - this.infoBuilder.id(id); + Builder generatedId(String generatedId) { + this.infoBuilder.generatedId(generatedId); return this; } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceInfo.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceInfo.java index 0ce3e8f1bb76..67b0568e2ebc 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceInfo.java @@ -71,7 +71,7 @@ public Instance apply(InstanceInfo instance) { private static final long serialVersionUID = -6601223112628977168L; private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); - private final String id; + private final String generatedId; private final InstanceId instanceId; private final Long creationTimestamp; private final String description; @@ -125,7 +125,7 @@ public enum Status { */ public abstract static class Builder { - abstract Builder id(String id); + abstract Builder generatedId(String generatedId); /** * Sets the identity of the virtual machine instance. @@ -219,7 +219,7 @@ public abstract static class Builder { public static final class BuilderImpl extends Builder { - private String id; + private String generatedId; private InstanceId instanceId; private Long creationTimestamp; private String description; @@ -240,7 +240,7 @@ public static final class BuilderImpl extends Builder { } BuilderImpl(InstanceInfo instance) { - this.id = instance.id; + this.generatedId = instance.generatedId; this.instanceId = instance.instanceId; this.creationTimestamp = instance.creationTimestamp; this.description = instance.description; @@ -259,7 +259,7 @@ public static final class BuilderImpl extends Builder { BuilderImpl(Instance instancePb) { if (instancePb.getId() != null) { - this.id = instancePb.getId().toString(); + this.generatedId = instancePb.getId().toString(); } this.instanceId = InstanceId.fromUrl(instancePb.getSelfLink()); if (instancePb.getCreationTimestamp() != null) { @@ -298,8 +298,8 @@ public static final class BuilderImpl extends Builder { } @Override - Builder id(String id) { - this.id = id; + Builder generatedId(String generatedId) { + this.generatedId = generatedId; return this; } @@ -408,7 +408,7 @@ public InstanceInfo build() { } InstanceInfo(BuilderImpl builder) { - this.id = builder.id; + this.generatedId = builder.generatedId; this.instanceId = builder.instanceId; this.creationTimestamp = builder.creationTimestamp; this.description = builder.description; @@ -426,10 +426,10 @@ public InstanceInfo build() { } /** - * Returns the unique identifier for the instance; defined by the service. + * Returns the service-generated unique identifier for the instance. */ - public String id() { - return id; + public String generatedId() { + return generatedId; } /** @@ -551,7 +551,7 @@ public Builder toBuilder() { @Override public String toString() { return MoreObjects.toStringHelper(this) - .add("id", id) + .add("generatedId", generatedId) .add("instanceId", instanceId) .add("creationTimestamp", creationTimestamp) .add("description", description) @@ -571,9 +571,9 @@ public String toString() { @Override public int hashCode() { - return Objects.hash(id, instanceId, creationTimestamp, description, status, statusMessage, tags, - machineType, canIpForward, networkInterfaces, attachedDisks, metadata, serviceAccounts, - schedulingOptions, cpuPlatform); + return Objects.hash(generatedId, instanceId, creationTimestamp, description, status, + statusMessage, tags, machineType, canIpForward, networkInterfaces, attachedDisks, metadata, + serviceAccounts, schedulingOptions, cpuPlatform); } @Override @@ -605,8 +605,8 @@ public AttachedDisk apply(AttachedDisk attachedDisk) { Instance toPb() { Instance instancePb = new Instance(); - if (id != null) { - instancePb.setId(new BigInteger(id)); + if (generatedId != null) { + instancePb.setId(new BigInteger(generatedId)); } if (creationTimestamp != null) { instancePb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java index a381ec1de6b4..cab5ecb1bded 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java @@ -59,7 +59,7 @@ public com.google.api.services.compute.model.MachineType apply(MachineType type) private static final long serialVersionUID = -4210962597502860450L; private final MachineTypeId machineTypeId; - private final String id; + private final String generatedId; private final Long creationTimestamp; private final String description; private final Integer cpus; @@ -72,7 +72,7 @@ public com.google.api.services.compute.model.MachineType apply(MachineType type) static final class Builder { private MachineTypeId machineTypeId; - private String id; + private String generatedId; private Long creationTimestamp; private String description; private Integer cpus; @@ -89,8 +89,8 @@ Builder machineTypeId(MachineTypeId machineTypeId) { return this; } - Builder id(String id) { - this.id = id; + Builder generatedId(String generatedId) { + this.generatedId = generatedId; return this; } @@ -141,7 +141,7 @@ MachineType build() { private MachineType(Builder builder) { this.machineTypeId = builder.machineTypeId; - this.id = builder.id; + this.generatedId = builder.generatedId; this.creationTimestamp = builder.creationTimestamp; this.description = builder.description; this.cpus = builder.cpus; @@ -160,10 +160,10 @@ public MachineTypeId machineTypeId() { } /** - * Returns the unique identifier for the machine type; defined by the service. + * Returns the service-generated unique identifier for the machine type. */ - public String id() { - return id; + public String generatedId() { + return generatedId; } /** @@ -229,7 +229,7 @@ public DeprecationStatus deprecationStatus() { public String toString() { return MoreObjects.toStringHelper(this) .add("machineTypeId", machineTypeId) - .add("id", id) + .add("generatedId", generatedId) .add("creationTimestamp", creationTimestamp) .add("description", description) .add("cpus", cpus) @@ -254,8 +254,8 @@ public final boolean equals(Object obj) { com.google.api.services.compute.model.MachineType toPb() { com.google.api.services.compute.model.MachineType machineTypePb = new com.google.api.services.compute.model.MachineType(); - if (id != null) { - machineTypePb.setId(new BigInteger(id)); + if (generatedId != null) { + machineTypePb.setId(new BigInteger(generatedId)); } if (creationTimestamp != null) { machineTypePb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); @@ -291,7 +291,7 @@ static MachineType fromPb(com.google.api.services.compute.model.MachineType mach Builder builder = builder(); builder.machineTypeId(MachineTypeId.fromUrl(machineTypePb.getSelfLink())); if (machineTypePb.getId() != null) { - builder.id(machineTypePb.getId().toString()); + builder.generatedId(machineTypePb.getId().toString()); } if (machineTypePb.getCreationTimestamp() != null) { builder.creationTimestamp( diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Network.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Network.java index f438f2b8d3df..854cb72ce7d1 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Network.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Network.java @@ -63,8 +63,8 @@ public static class Builder extends NetworkInfo.Builder { } @Override - Builder id(String id) { - infoBuilder.id(id); + Builder generatedId(String generatedId) { + infoBuilder.generatedId(generatedId); return this; } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInfo.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInfo.java index d3e1cddcd6be..fc5d0464d534 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInfo.java @@ -60,7 +60,7 @@ public Network apply(NetworkInfo network) { private static final long serialVersionUID = 4336912581538114026L; private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); - private final String id; + private final String generatedId; private final NetworkId networkId; private final Long creationTimestamp; private final String description; @@ -71,7 +71,7 @@ public Network apply(NetworkInfo network) { */ public abstract static class Builder { - abstract Builder id(String id); + abstract Builder generatedId(String generatedId); abstract Builder creationTimestamp(Long creationTimestamp); @@ -101,7 +101,7 @@ public abstract static class Builder { static final class BuilderImpl extends Builder { - private String id; + private String generatedId; private NetworkId networkId; private Long creationTimestamp; private String description; @@ -113,7 +113,7 @@ static final class BuilderImpl extends Builder { } BuilderImpl(NetworkInfo networkInfo) { - this.id = networkInfo.id; + this.generatedId = networkInfo.generatedId; this.creationTimestamp = networkInfo.creationTimestamp; this.networkId = networkInfo.networkId; this.description = networkInfo.description; @@ -122,7 +122,7 @@ static final class BuilderImpl extends Builder { BuilderImpl(Network networkPb) { if (networkPb.getId() != null) { - this.id = networkPb.getId().toString(); + this.generatedId = networkPb.getId().toString(); } if (networkPb.getCreationTimestamp() != null) { this.creationTimestamp = TIMESTAMP_FORMATTER.parseMillis(networkPb.getCreationTimestamp()); @@ -133,8 +133,8 @@ static final class BuilderImpl extends Builder { } @Override - BuilderImpl id(String id) { - this.id = id; + BuilderImpl generatedId(String generatedId) { + this.generatedId = generatedId; return this; } @@ -169,7 +169,7 @@ public NetworkInfo build() { } NetworkInfo(BuilderImpl builder) { - this.id = builder.id; + this.generatedId = builder.generatedId; this.creationTimestamp = builder.creationTimestamp; this.networkId = builder.networkId; this.description = builder.description; @@ -177,10 +177,10 @@ public NetworkInfo build() { } /** - * Returns the unique identifier for the subnetwork; defined by the service. + * Returns the service-generated unique identifier for the network. */ - public String id() { - return id; + public String generatedId() { + return generatedId; } /** @@ -224,7 +224,7 @@ public Builder toBuilder() { @Override public String toString() { return MoreObjects.toStringHelper(this) - .add("id", id) + .add("generatedId", generatedId) .add("creationTimestamp", creationTimestamp) .add("networkId", networkId) .add("description", description) @@ -234,7 +234,7 @@ public String toString() { @Override public int hashCode() { - return Objects.hash(id, networkId, creationTimestamp, description, configuration); + return Objects.hash(generatedId, networkId, creationTimestamp, description, configuration); } @Override @@ -253,8 +253,8 @@ NetworkInfo setProjectId(String projectId) { Network toPb() { Network networkPb = configuration.toPb(); - if (id != null) { - networkPb.setId(new BigInteger(id)); + if (generatedId != null) { + networkPb.setId(new BigInteger(generatedId)); } if (creationTimestamp != null) { networkPb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java index 2b35dac3fd2b..3e4935dbb859 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java @@ -50,7 +50,7 @@ public class Operation implements Serializable { private transient Compute compute; private final ComputeOptions options; - private final String id; + private final String generatedId; private final OperationId operationId; private final String clientOperationId; private final String operationType; @@ -294,7 +294,7 @@ public int hashCode() { static final class Builder { private Compute compute; - private String id; + private String generatedId; private OperationId operationId; private String clientOperationId; private String operationType; @@ -320,7 +320,7 @@ static final class Builder { Builder(Compute compute, com.google.api.services.compute.model.Operation operationPb) { this.compute = compute; if (operationPb.getId() != null) { - id = operationPb.getId().toString(); + generatedId = operationPb.getId().toString(); } if (RegionOperationId.matchesUrl(operationPb.getSelfLink())) { operationId = RegionOperationId.fromUrl(operationPb.getSelfLink()); @@ -362,8 +362,8 @@ static final class Builder { description = operationPb.getDescription(); } - Builder id(String id) { - this.id = id; + Builder generatedId(String generatedId) { + this.generatedId = generatedId; return this; } @@ -460,7 +460,7 @@ Operation build() { private Operation(Builder builder) { this.compute = checkNotNull(builder.compute); this.options = compute.options(); - this.id = builder.id; + this.generatedId = builder.generatedId; this.operationId = checkNotNull(builder.operationId); this.clientOperationId = builder.clientOperationId; this.operationType = builder.operationType; @@ -488,10 +488,10 @@ public Compute compute() { } /** - * Returns the service-defined unique identifier for the operation. + * Returns the service-generated unique identifier for the operation. */ - public String id() { - return id; + public String generatedId() { + return generatedId; } /** @@ -683,7 +683,7 @@ public boolean delete() throws ComputeException { @Override public String toString() { return MoreObjects.toStringHelper(this) - .add("id", id) + .add("generatedId", generatedId) .add("operationsId", operationId) .add("clientOperationId", clientOperationId) .add("operationType", operationType) @@ -706,7 +706,7 @@ public String toString() { @Override public final int hashCode() { - return Objects.hash(id); + return Objects.hash(operationId); } @Override @@ -719,8 +719,8 @@ public final boolean equals(Object obj) { com.google.api.services.compute.model.Operation toPb() { com.google.api.services.compute.model.Operation operationPb = new com.google.api.services.compute.model.Operation(); - if (id != null) { - operationPb.setId(new BigInteger(id)); + if (generatedId != null) { + operationPb.setId(new BigInteger(generatedId)); } operationPb.setName(operationId.operation()); operationPb.setClientOperationId(clientOperationId); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java index fb7890187a14..afc761df2e0d 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java @@ -55,7 +55,7 @@ public com.google.api.services.compute.model.Region apply(Region region) { private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); private final RegionId regionId; - private final String id; + private final String generatedId; private final Long creationTimestamp; private final String description; private final Status status; @@ -166,7 +166,7 @@ static Quota fromPb(com.google.api.services.compute.model.Quota quotaPb) { static final class Builder { private RegionId regionId; - private String id; + private String generatedId; private Long creationTimestamp; private String description; @@ -182,8 +182,8 @@ Builder regionId(RegionId regionId) { return this; } - Builder id(String id) { - this.id = id; + Builder generatedId(String generatedId) { + this.generatedId = generatedId; return this; } @@ -224,7 +224,7 @@ Region build() { private Region(Builder builder) { this.regionId = builder.regionId; - this.id = builder.id; + this.generatedId = builder.generatedId; this.creationTimestamp = builder.creationTimestamp; this.description = builder.description; this.status = builder.status; @@ -241,10 +241,10 @@ public RegionId regionId() { } /** - * Returns the unique identifier for the region; defined by the service. + * Returns the service-generated unique identifier for the region. */ - public String id() { - return id; + public String generatedId() { + return generatedId; } /** @@ -295,7 +295,7 @@ public DeprecationStatus deprecationStatus() { public String toString() { return MoreObjects.toStringHelper(this) .add("regionId", regionId) - .add("id", id) + .add("generatedId", generatedId) .add("creationTimestamp", creationTimestamp) .add("description", description) .add("status", status) @@ -318,8 +318,8 @@ public final boolean equals(Object obj) { com.google.api.services.compute.model.Region toPb() { com.google.api.services.compute.model.Region regionPb = new com.google.api.services.compute.model.Region(); - if (id != null) { - regionPb.setId(new BigInteger(id)); + if (generatedId != null) { + regionPb.setId(new BigInteger(generatedId)); } if (creationTimestamp != null) { regionPb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); @@ -350,7 +350,7 @@ static Region fromPb(com.google.api.services.compute.model.Region regionPb) { Builder builder = builder(); builder.regionId(RegionId.fromUrl(regionPb.getSelfLink())); if (regionPb.getId() != null) { - builder.id(regionPb.getId().toString()); + builder.generatedId(regionPb.getId().toString()); } if (regionPb.getCreationTimestamp() != null) { builder.creationTimestamp(TIMESTAMP_FORMATTER.parseMillis(regionPb.getCreationTimestamp())); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Snapshot.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Snapshot.java index e93a419d5b4a..a12404a9fd4f 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Snapshot.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Snapshot.java @@ -65,8 +65,8 @@ public static class Builder extends SnapshotInfo.Builder { } @Override - Builder id(String id) { - infoBuilder.id(id); + Builder generatedId(String generatedId) { + infoBuilder.generatedId(generatedId); return this; } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotDiskConfiguration.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotDiskConfiguration.java index 1bdc319e30c5..178c54f0038e 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotDiskConfiguration.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotDiskConfiguration.java @@ -113,10 +113,10 @@ public SnapshotId sourceSnapshot() { } /** - * Returns the unique ID of the snapshot used to create this disk. This value identifies the exact - * snapshot that was used to create the persistent disk. For example, if you created the - * persistent disk from a snapshot that was later deleted and recreated under the same name, the - * source snapshot ID would identify the exact version of the snapshot that was used. + * Returns the service-generated unique id of the snapshot used to create this disk. This value + * identifies the exact snapshot that was used to create the persistent disk. For example, if you + * created the persistent disk from a snapshot that was later deleted and recreated under the same + * name, the source snapshot ID would identify the exact version of the snapshot that was used. */ public String sourceSnapshotId() { return sourceSnapshotId; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotInfo.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotInfo.java index fe567988d82c..34f6c53884bf 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotInfo.java @@ -61,7 +61,7 @@ public Snapshot apply(SnapshotInfo snapshot) { private static final long serialVersionUID = 1065513502131159769L; private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); - private final String id; + private final String generatedId; private final SnapshotId snapshotId; private final Long creationTimestamp; private final String description; @@ -125,7 +125,7 @@ public enum StorageBytesStatus { */ public abstract static class Builder { - abstract Builder id(String id); + abstract Builder generatedId(String generatedId); abstract Builder creationTimestamp(Long creationTimestamp); @@ -164,7 +164,7 @@ public abstract static class Builder { static final class BuilderImpl extends Builder { - private String id; + private String generatedId; private Long creationTimestamp; private SnapshotId snapshotId; private String description; @@ -179,7 +179,7 @@ static final class BuilderImpl extends Builder { BuilderImpl() {} BuilderImpl(SnapshotInfo snapshotInfo) { - this.id = snapshotInfo.id; + this.generatedId = snapshotInfo.generatedId; this.creationTimestamp = snapshotInfo.creationTimestamp; this.snapshotId = snapshotInfo.snapshotId; this.description = snapshotInfo.description; @@ -194,7 +194,7 @@ static final class BuilderImpl extends Builder { BuilderImpl(Snapshot snapshotPb) { if (snapshotPb.getId() != null) { - this.id = snapshotPb.getId().toString(); + this.generatedId = snapshotPb.getId().toString(); } if (snapshotPb.getCreationTimestamp() != null) { this.creationTimestamp = TIMESTAMP_FORMATTER.parseMillis(snapshotPb.getCreationTimestamp()); @@ -219,8 +219,8 @@ static final class BuilderImpl extends Builder { } @Override - BuilderImpl id(String id) { - this.id = id; + BuilderImpl generatedId(String generatedId) { + this.generatedId = generatedId; return this; } @@ -291,7 +291,7 @@ public SnapshotInfo build() { } SnapshotInfo(BuilderImpl builder) { - this.id = builder.id; + this.generatedId = builder.generatedId; this.creationTimestamp = builder.creationTimestamp; this.snapshotId = checkNotNull(builder.snapshotId); this.description = builder.description; @@ -305,10 +305,10 @@ public SnapshotInfo build() { } /** - * Returns the unique identifier for the snapshot; defined by the service. + * Returns the service-generated unique identifier for the snapshot. */ - public String id() { - return id; + public String generatedId() { + return generatedId; } /** @@ -363,9 +363,9 @@ public DiskId sourceDisk() { } /** - * Returns the id value of the disk used to create this snapshot. This value may be used to - * determine whether the snapshot was taken from the current or a previous instance of a given - * disk name. + * Returns the service-generated unique id of the disk used to create this snapshot. This value + * may be used to determine whether the snapshot was taken from the current or a previous instance + * of a given disk name. */ public String sourceDiskId() { return sourceDiskId; @@ -399,7 +399,7 @@ public Builder toBuilder() { @Override public String toString() { return MoreObjects.toStringHelper(this) - .add("id", id) + .add("generatedId", generatedId) .add("creationTimestamp", creationTimestamp) .add("snapshotId", snapshotId) .add("description", description) @@ -415,7 +415,7 @@ public String toString() { @Override public int hashCode() { - return Objects.hash(id, creationTimestamp, snapshotId, description, status, diskSizeGb, + return Objects.hash(generatedId, creationTimestamp, snapshotId, description, status, diskSizeGb, licenses, sourceDisk, sourceDiskId, storageBytes, storageBytesStatus); } @@ -435,8 +435,8 @@ SnapshotInfo setProjectId(String projectId) { Snapshot toPb() { Snapshot snapshotPb = new Snapshot(); - if (id != null) { - snapshotPb.setId(new BigInteger(id)); + if (generatedId != null) { + snapshotPb.setId(new BigInteger(generatedId)); } if (creationTimestamp != null) { snapshotPb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Subnetwork.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Subnetwork.java index 6a42d8663ea3..035af9f829c2 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Subnetwork.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Subnetwork.java @@ -63,8 +63,8 @@ public static class Builder extends SubnetworkInfo.Builder { } @Override - Builder id(String id) { - infoBuilder.id(id); + Builder generatedId(String generatedId) { + infoBuilder.generatedId(generatedId); return this; } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkInfo.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkInfo.java index d6988ee7eea8..e61a2c82b5de 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkInfo.java @@ -56,7 +56,7 @@ public Subnetwork apply(SubnetworkInfo subnetwork) { private static final long serialVersionUID = 7491176262675441579L; private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); - private final String id; + private final String generatedId; private final SubnetworkId subnetworkId; private final Long creationTimestamp; private final String description; @@ -69,7 +69,7 @@ public Subnetwork apply(SubnetworkInfo subnetwork) { */ public abstract static class Builder { - abstract Builder id(String id); + abstract Builder generatedId(String generatedId); abstract Builder creationTimestamp(Long creationTimestamp); @@ -108,7 +108,7 @@ public abstract static class Builder { static final class BuilderImpl extends Builder { - private String id; + private String generatedId; private SubnetworkId subnetworkId; private Long creationTimestamp; private String description; @@ -123,7 +123,7 @@ static final class BuilderImpl extends Builder { } BuilderImpl(SubnetworkInfo subnetworkInfo) { - this.id = subnetworkInfo.id; + this.generatedId = subnetworkInfo.generatedId; this.creationTimestamp = subnetworkInfo.creationTimestamp; this.subnetworkId = subnetworkInfo.subnetworkId; this.description = subnetworkInfo.description; @@ -134,7 +134,7 @@ static final class BuilderImpl extends Builder { BuilderImpl(Subnetwork subnetworkPb) { if (subnetworkPb.getId() != null) { - this.id = subnetworkPb.getId().toString(); + this.generatedId = subnetworkPb.getId().toString(); } if (subnetworkPb.getCreationTimestamp() != null) { this.creationTimestamp = @@ -150,8 +150,8 @@ static final class BuilderImpl extends Builder { } @Override - BuilderImpl id(String id) { - this.id = id; + BuilderImpl generatedId(String generatedId) { + this.generatedId = generatedId; return this; } @@ -198,7 +198,7 @@ public SubnetworkInfo build() { } SubnetworkInfo(BuilderImpl builder) { - this.id = builder.id; + this.generatedId = builder.generatedId; this.creationTimestamp = builder.creationTimestamp; this.subnetworkId = checkNotNull(builder.subnetworkId); this.description = builder.description; @@ -208,10 +208,10 @@ public SubnetworkInfo build() { } /** - * Returns the unique identifier for the subnetwork; defined by the service. + * Returns the service-generated unique identifier for the subnetwork. */ - public String id() { - return id; + public String generatedId() { + return generatedId; } /** @@ -271,7 +271,7 @@ public Builder toBuilder() { @Override public String toString() { return MoreObjects.toStringHelper(this) - .add("id", id) + .add("generatedId", generatedId) .add("creationTimestamp", creationTimestamp) .add("subnetworkId", subnetworkId) .add("description", description) @@ -283,8 +283,8 @@ public String toString() { @Override public int hashCode() { - return Objects.hash(id, creationTimestamp, subnetworkId, description, gatewayAddress, network, - ipRange); + return Objects.hash(generatedId, creationTimestamp, subnetworkId, description, gatewayAddress, + network, ipRange); } @Override @@ -304,8 +304,8 @@ SubnetworkInfo setProjectId(String projectId) { Subnetwork toPb() { Subnetwork subnetworkPb = new Subnetwork(); - if (id != null) { - subnetworkPb.setId(new BigInteger(id)); + if (generatedId != null) { + subnetworkPb.setId(new BigInteger(generatedId)); } if (creationTimestamp != null) { subnetworkPb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java index 80a6c08f4db1..ff5ed877408c 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java @@ -52,7 +52,7 @@ public com.google.api.services.compute.model.Zone apply(Zone region) { private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); private final ZoneId zoneId; - private final String id; + private final String generatedId; private final Long creationTimestamp; private final String description; private final Status status; @@ -70,7 +70,7 @@ public enum Status { static final class Builder { private ZoneId zoneId; - private String id; + private String generatedId; private Long creationTimestamp; private String description; @@ -85,8 +85,8 @@ Builder zoneId(ZoneId zoneId) { return this; } - Builder id(String id) { - this.id = id; + Builder generatedId(String generatedId) { + this.generatedId = generatedId; return this; } @@ -122,7 +122,7 @@ Zone build() { private Zone(Builder builder) { this.zoneId = builder.zoneId; - this.id = builder.id; + this.generatedId = builder.generatedId; this.creationTimestamp = builder.creationTimestamp; this.description = builder.description; this.status = builder.status; @@ -152,10 +152,10 @@ public String description() { } /** - * Returns the unique identifier for the zone; defined by the service. + * Returns the service-generated unique identifier for the zone. */ - public String id() { - return id; + public String generatedId() { + return generatedId; } /** @@ -185,7 +185,7 @@ public DeprecationStatus deprecationStatus() { public String toString() { return MoreObjects.toStringHelper(this) .add("zoneId", zoneId) - .add("id", id) + .add("generatedId", generatedId) .add("creationTimestamp", creationTimestamp) .add("description", description) .add("status", status) @@ -207,8 +207,8 @@ public final boolean equals(Object obj) { com.google.api.services.compute.model.Zone toPb() { com.google.api.services.compute.model.Zone zonePb = new com.google.api.services.compute.model.Zone(); - if (id != null) { - zonePb.setId(new BigInteger(id)); + if (generatedId != null) { + zonePb.setId(new BigInteger(generatedId)); } if (creationTimestamp != null) { zonePb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); @@ -236,7 +236,7 @@ static Zone fromPb(com.google.api.services.compute.model.Zone zonePb) { Builder builder = builder(); builder.zoneId(ZoneId.fromUrl(zonePb.getSelfLink())); if (zonePb.getId() != null) { - builder.id(zonePb.getId().toString()); + builder.generatedId(zonePb.getId().toString()); } if (zonePb.getCreationTimestamp() != null) { builder.creationTimestamp(TIMESTAMP_FORMATTER.parseMillis(zonePb.getCreationTimestamp())); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressInfoTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressInfoTest.java index cb4ba3678c30..d476cf275268 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressInfoTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressInfoTest.java @@ -33,7 +33,7 @@ public class AddressInfoTest { private static final String ADDRESS = "192.168.1.1"; private static final Long CREATION_TIMESTAMP = 1452602400000L; private static final String DESCRIPTION = "description"; - private static final String ID = "42"; + private static final String GENERATED_ID = "42"; private static final GlobalAddressId GLOBAL_ADDRESS_ID = GlobalAddressId.of("project", "address"); private static final RegionAddressId REGION_ADDRESS_ID = RegionAddressId.of("project", "region", "address"); @@ -54,7 +54,7 @@ public class AddressInfoTest { .address(ADDRESS) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) - .id(ID) + .generatedId(GENERATED_ID) .status(STATUS) .usage(INSTANCE_USAGE) .build(); @@ -63,7 +63,7 @@ public class AddressInfoTest { .address(ADDRESS) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) - .id(ID) + .generatedId(GENERATED_ID) .status(STATUS) .usage(GLOBAL_FORWARDING_USAGE) .build(); @@ -72,7 +72,7 @@ public class AddressInfoTest { .address(ADDRESS) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) - .id(ID) + .generatedId(GENERATED_ID) .status(STATUS) .usage(REGION_FORWARDING_USAGE) .build(); @@ -106,7 +106,7 @@ public void testBuilder() { assertEquals(ADDRESS, INSTANCE_ADDRESS_INFO.address()); assertEquals(CREATION_TIMESTAMP, INSTANCE_ADDRESS_INFO.creationTimestamp()); assertEquals(DESCRIPTION, INSTANCE_ADDRESS_INFO.description()); - assertEquals(ID, INSTANCE_ADDRESS_INFO.id()); + assertEquals(GENERATED_ID, INSTANCE_ADDRESS_INFO.generatedId()); assertEquals(REGION_ADDRESS_ID, INSTANCE_ADDRESS_INFO.addressId()); assertEquals(STATUS, INSTANCE_ADDRESS_INFO.status()); assertEquals(INSTANCE_USAGE, INSTANCE_ADDRESS_INFO.usage()); @@ -115,7 +115,7 @@ public void testBuilder() { assertEquals(ADDRESS, REGION_FORWARDING_ADDRESS_INFO.address()); assertEquals(CREATION_TIMESTAMP, REGION_FORWARDING_ADDRESS_INFO.creationTimestamp()); assertEquals(DESCRIPTION, REGION_FORWARDING_ADDRESS_INFO.description()); - assertEquals(ID, REGION_FORWARDING_ADDRESS_INFO.id()); + assertEquals(GENERATED_ID, REGION_FORWARDING_ADDRESS_INFO.generatedId()); assertEquals(REGION_ADDRESS_ID, REGION_FORWARDING_ADDRESS_INFO.addressId()); assertEquals(STATUS, REGION_FORWARDING_ADDRESS_INFO.status()); assertEquals(REGION_FORWARDING_USAGE, REGION_FORWARDING_ADDRESS_INFO.usage()); @@ -124,7 +124,7 @@ public void testBuilder() { assertEquals(ADDRESS, GLOBAL_FORWARDING_ADDRESS_INFO.address()); assertEquals(CREATION_TIMESTAMP, GLOBAL_FORWARDING_ADDRESS_INFO.creationTimestamp()); assertEquals(DESCRIPTION, GLOBAL_FORWARDING_ADDRESS_INFO.description()); - assertEquals(ID, GLOBAL_FORWARDING_ADDRESS_INFO.id()); + assertEquals(GENERATED_ID, GLOBAL_FORWARDING_ADDRESS_INFO.generatedId()); assertEquals(GLOBAL_ADDRESS_ID, GLOBAL_FORWARDING_ADDRESS_INFO.addressId()); assertEquals(STATUS, GLOBAL_FORWARDING_ADDRESS_INFO.status()); assertEquals(GLOBAL_FORWARDING_USAGE, GLOBAL_FORWARDING_ADDRESS_INFO.usage()); @@ -139,7 +139,7 @@ public void testOf() { assertNull(addressInfo.address()); assertNull(addressInfo.creationTimestamp()); assertNull(addressInfo.description()); - assertNull(addressInfo.id()); + assertNull(addressInfo.generatedId()); assertNull(addressInfo.status()); assertNull(addressInfo.usage()); addressInfo = AddressInfo.of(GLOBAL_ADDRESS_ID); @@ -147,7 +147,7 @@ public void testOf() { assertNull(addressInfo.address()); assertNull(addressInfo.creationTimestamp()); assertNull(addressInfo.description()); - assertNull(addressInfo.id()); + assertNull(addressInfo.generatedId()); assertNull(addressInfo.status()); assertNull(addressInfo.usage()); addressInfo = AddressInfo.of("region", "address"); @@ -155,7 +155,7 @@ public void testOf() { assertNull(addressInfo.address()); assertNull(addressInfo.creationTimestamp()); assertNull(addressInfo.description()); - assertNull(addressInfo.id()); + assertNull(addressInfo.generatedId()); assertNull(addressInfo.status()); assertNull(addressInfo.usage()); addressInfo = AddressInfo.of(RegionId.of("region"), "address"); @@ -163,7 +163,7 @@ public void testOf() { assertNull(addressInfo.address()); assertNull(addressInfo.creationTimestamp()); assertNull(addressInfo.description()); - assertNull(addressInfo.id()); + assertNull(addressInfo.generatedId()); assertNull(addressInfo.status()); assertNull(addressInfo.usage()); } @@ -192,7 +192,7 @@ private void compareAddressInfo(AddressInfo expected, AddressInfo value) { assertEquals(expected.address(), value.address()); assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.description(), value.description()); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.addressId(), value.addressId()); assertEquals(expected.usage(), value.usage()); assertEquals(expected.status(), value.status()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressTest.java index a9404a90f755..2fe9e516f486 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressTest.java @@ -39,7 +39,7 @@ public class AddressTest { private static final String ADDRESS = "192.168.1.1"; private static final Long CREATION_TIMESTAMP = 1452602400000L; private static final String DESCRIPTION = "description"; - private static final String ID = "42"; + private static final String GENERATED_ID = "42"; private static final GlobalAddressId GLOBAL_ADDRESS_ID = GlobalAddressId.of("project", "address"); private static final RegionAddressId REGION_ADDRESS_ID = RegionAddressId.of("project", "region", "address"); @@ -72,7 +72,7 @@ private void initializeExpectedAddress(int optionsCalls) { .address(ADDRESS) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) - .id(ID) + .generatedId(GENERATED_ID) .status(STATUS) .usage(INSTANCE_USAGE) .build(); @@ -80,7 +80,7 @@ private void initializeExpectedAddress(int optionsCalls) { .address(ADDRESS) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) - .id(ID) + .generatedId(GENERATED_ID) .status(STATUS) .usage(GLOBAL_FORWARDING_USAGE) .build(); @@ -88,7 +88,7 @@ private void initializeExpectedAddress(int optionsCalls) { .address(ADDRESS) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) - .id(ID) + .generatedId(GENERATED_ID) .status(STATUS) .usage(REGION_FORWARDING_USAGE) .build(); @@ -100,7 +100,7 @@ private void initializeAddress() { .address(ADDRESS) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) - .id(ID) + .generatedId(GENERATED_ID) .status(STATUS) .usage(REGION_FORWARDING_USAGE) .build(); @@ -117,7 +117,7 @@ public void testBuilder() { assertEquals(ADDRESS, instanceAddress.address()); assertEquals(CREATION_TIMESTAMP, instanceAddress.creationTimestamp()); assertEquals(DESCRIPTION, instanceAddress.description()); - assertEquals(ID, instanceAddress.id()); + assertEquals(GENERATED_ID, instanceAddress.generatedId()); assertEquals(REGION_ADDRESS_ID, instanceAddress.addressId()); assertEquals(STATUS, instanceAddress.status()); assertEquals(INSTANCE_USAGE, instanceAddress.usage()); @@ -125,7 +125,7 @@ public void testBuilder() { assertEquals(ADDRESS, regionForwardingAddress.address()); assertEquals(CREATION_TIMESTAMP, regionForwardingAddress.creationTimestamp()); assertEquals(DESCRIPTION, regionForwardingAddress.description()); - assertEquals(ID, regionForwardingAddress.id()); + assertEquals(GENERATED_ID, regionForwardingAddress.generatedId()); assertEquals(REGION_ADDRESS_ID, regionForwardingAddress.addressId()); assertEquals(STATUS, regionForwardingAddress.status()); assertEquals(REGION_FORWARDING_USAGE, regionForwardingAddress.usage()); @@ -133,7 +133,7 @@ public void testBuilder() { assertEquals(ADDRESS, globalForwardingAddress.address()); assertEquals(CREATION_TIMESTAMP, globalForwardingAddress.creationTimestamp()); assertEquals(DESCRIPTION, globalForwardingAddress.description()); - assertEquals(ID, globalForwardingAddress.id()); + assertEquals(GENERATED_ID, globalForwardingAddress.generatedId()); assertEquals(GLOBAL_ADDRESS_ID, globalForwardingAddress.addressId()); assertEquals(STATUS, globalForwardingAddress.status()); assertEquals(GLOBAL_FORWARDING_USAGE, globalForwardingAddress.usage()); @@ -144,7 +144,7 @@ public void testBuilder() { assertNull(address.address()); assertNull(address.creationTimestamp()); assertNull(address.description()); - assertNull(address.id()); + assertNull(address.generatedId()); assertNull(address.status()); assertNull(address.usage()); address = new Address.Builder(serviceMockReturnsOptions, REGION_ADDRESS_ID).build(); @@ -153,7 +153,7 @@ public void testBuilder() { assertNull(address.address()); assertNull(address.creationTimestamp()); assertNull(address.description()); - assertNull(address.id()); + assertNull(address.generatedId()); assertNull(address.status()); assertNull(address.usage()); address = new Address.Builder(serviceMockReturnsOptions, REGION_ADDRESS_ID) @@ -164,7 +164,7 @@ public void testBuilder() { assertNull(address.address()); assertNull(address.creationTimestamp()); assertNull(address.description()); - assertNull(address.id()); + assertNull(address.generatedId()); assertNull(address.status()); assertNull(address.usage()); } @@ -285,7 +285,7 @@ private void compareAddress(Address expected, Address value) { assertEquals(expected.address(), value.address()); assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.description(), value.description()); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.addressId(), value.addressId()); assertEquals(expected.usage(), value.usage()); assertEquals(expected.status(), value.status()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java index 023bd7064a3e..32cf4bba12d3 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java @@ -105,14 +105,14 @@ public class ComputeImplTest { private static final String PROJECT = "project"; - private static final String ID = "42"; + private static final String GENERATED_ID = "42"; private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final String DESCRIPTION = "description"; private static final String VALID_DISK_SIZE = "10GB-10TB"; private static final Long DEFAULT_DISK_SIZE_GB = 10L; private static final DiskTypeId DISK_TYPE_ID = DiskTypeId.of("project", "zone", "diskType"); private static final DiskType DISK_TYPE = DiskType.builder() - .id(ID) + .generatedId(GENERATED_ID) .diskTypeId(DISK_TYPE_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) @@ -126,7 +126,7 @@ public class ComputeImplTest { private static final Integer MAXIMUM_PERSISTENT_DISKS = 4; private static final Long MAXIMUM_PERSISTENT_DISKS_SIZE_GB = 5L; private static final MachineType MACHINE_TYPE = MachineType.builder() - .id(ID) + .generatedId(GENERATED_ID) .machineTypeId(MACHINE_TYPE_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) @@ -148,7 +148,7 @@ public class ComputeImplTest { private static final List QUOTAS = ImmutableList.of(QUOTA1, QUOTA2); private static final Region REGION = Region.builder() .regionId(REGION_ID) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .status(REGION_STATUS) @@ -159,7 +159,7 @@ public class ComputeImplTest { private static final Zone.Status ZONE_STATUS = Zone.Status.DOWN; private static final Zone ZONE = Zone.builder() .zoneId(ZONE_ID) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .status(ZONE_STATUS) @@ -526,7 +526,7 @@ public void setUp() { .build(); Compute otherService = options.toBuilder().build().service(); globalOperation = new Operation.Builder(otherService) - .id(ID) + .generatedId(GENERATED_ID) .operationId(GLOBAL_OPERATION_ID) .clientOperationId(CLIENT_OPERATION_ID) .operationType(OPERATION_TYPE) @@ -546,7 +546,7 @@ public void setUp() { .description(DESCRIPTION) .build(); zoneOperation = new Operation.Builder(otherService) - .id(ID) + .generatedId(GENERATED_ID) .operationId(ZONE_OPERATION_ID) .clientOperationId(CLIENT_OPERATION_ID) .operationType(OPERATION_TYPE) @@ -566,7 +566,7 @@ public void setUp() { .description(DESCRIPTION) .build(); regionOperation = new Operation.Builder(otherService) - .id(ID) + .generatedId(GENERATED_ID) .operationId(REGION_OPERATION_ID) .clientOperationId(CLIENT_OPERATION_ID) .operationType(OPERATION_TYPE) diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskInfoTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskInfoTest.java index 69919a871a49..4011af7eb04f 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskInfoTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskInfoTest.java @@ -29,7 +29,7 @@ public class DiskInfoTest { - private static final String ID = "42"; + private static final String GENERATED_ID = "42"; private static final DiskId DISK_ID = DiskId.of("project", "zone", "disk"); private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final CreationStatus CREATION_STATUS = CreationStatus.READY; @@ -65,7 +65,7 @@ public class DiskInfoTest { .sourceImageId(IMAGE_ID) .build(); private static final DiskInfo DISK_INFO = DiskInfo.builder(DISK_ID, DISK_CONFIGURATION) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .creationStatus(CREATION_STATUS) .description(DESCRIPTION) @@ -76,7 +76,7 @@ public class DiskInfoTest { .build(); private static final DiskInfo SNAPSHOT_DISK_INFO = DiskInfo.builder(DISK_ID, SNAPSHOT_DISK_CONFIGURATION) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .creationStatus(CREATION_STATUS) .description(DESCRIPTION) @@ -87,7 +87,7 @@ public class DiskInfoTest { .build(); private static final DiskInfo IMAGE_DISK_INFO = DiskInfo.builder(DISK_ID, IMAGE_DISK_CONFIGURATION) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .creationStatus(CREATION_STATUS) .description(DESCRIPTION) @@ -120,7 +120,7 @@ public void testToBuilderIncomplete() { @Test public void testBuilder() { - assertEquals(ID, DISK_INFO.id()); + assertEquals(GENERATED_ID, DISK_INFO.generatedId()); assertEquals(DISK_ID, DISK_INFO.diskId()); assertEquals(DISK_CONFIGURATION, DISK_INFO.configuration()); assertEquals(CREATION_TIMESTAMP, DISK_INFO.creationTimestamp()); @@ -130,7 +130,7 @@ public void testBuilder() { assertEquals(ATTACHED_INSTANCES, DISK_INFO.attachedInstances()); assertEquals(LAST_ATTACH_TIMESTAMP, DISK_INFO.lastAttachTimestamp()); assertEquals(LAST_DETACH_TIMESTAMP, DISK_INFO.lastDetachTimestamp()); - assertEquals(ID, IMAGE_DISK_INFO.id()); + assertEquals(GENERATED_ID, IMAGE_DISK_INFO.generatedId()); assertEquals(DISK_ID, IMAGE_DISK_INFO.diskId()); assertEquals(IMAGE_DISK_CONFIGURATION, IMAGE_DISK_INFO.configuration()); assertEquals(CREATION_TIMESTAMP, IMAGE_DISK_INFO.creationTimestamp()); @@ -140,7 +140,7 @@ public void testBuilder() { assertEquals(ATTACHED_INSTANCES, IMAGE_DISK_INFO.attachedInstances()); assertEquals(LAST_ATTACH_TIMESTAMP, IMAGE_DISK_INFO.lastAttachTimestamp()); assertEquals(LAST_DETACH_TIMESTAMP, IMAGE_DISK_INFO.lastDetachTimestamp()); - assertEquals(ID, SNAPSHOT_DISK_INFO.id()); + assertEquals(GENERATED_ID, SNAPSHOT_DISK_INFO.generatedId()); assertEquals(DISK_ID, SNAPSHOT_DISK_INFO.diskId()); assertEquals(SNAPSHOT_DISK_CONFIGURATION, SNAPSHOT_DISK_INFO.configuration()); assertEquals(CREATION_TIMESTAMP, SNAPSHOT_DISK_INFO.creationTimestamp()); @@ -155,7 +155,7 @@ public void testBuilder() { @Test public void testOf() { DiskInfo diskInfo = DiskInfo.of(DISK_ID, DISK_CONFIGURATION); - assertNull(diskInfo.id()); + assertNull(diskInfo.generatedId()); assertEquals(DISK_ID, diskInfo.diskId()); assertEquals(DISK_CONFIGURATION, diskInfo.configuration()); assertNull(diskInfo.creationTimestamp()); @@ -166,7 +166,7 @@ public void testOf() { assertNull(diskInfo.lastAttachTimestamp()); assertNull(diskInfo.lastDetachTimestamp()); diskInfo = DiskInfo.of(DISK_ID, IMAGE_DISK_CONFIGURATION); - assertNull(diskInfo.id()); + assertNull(diskInfo.generatedId()); assertEquals(DISK_ID, diskInfo.diskId()); assertEquals(IMAGE_DISK_CONFIGURATION, diskInfo.configuration()); assertNull(diskInfo.creationTimestamp()); @@ -177,7 +177,7 @@ public void testOf() { assertNull(diskInfo.lastAttachTimestamp()); assertNull(diskInfo.lastDetachTimestamp()); diskInfo = DiskInfo.of(DISK_ID, SNAPSHOT_DISK_CONFIGURATION); - assertNull(diskInfo.id()); + assertNull(diskInfo.generatedId()); assertEquals(DISK_ID, diskInfo.diskId()); assertEquals(SNAPSHOT_DISK_CONFIGURATION, diskInfo.configuration()); assertNull(diskInfo.creationTimestamp()); @@ -254,7 +254,7 @@ public void testSetProjectId() { public void compareDiskInfo(DiskInfo expected, DiskInfo value) { assertEquals(expected, value); assertEquals(expected.configuration(), value.configuration()); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.diskId(), value.diskId()); assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.creationStatus(), value.creationStatus()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTest.java index 8915a7894147..8b54a1ea2715 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTest.java @@ -36,7 +36,7 @@ public class DiskTest { - private static final String ID = "42"; + private static final String GENERATED_ID = "42"; private static final DiskId DISK_ID = DiskId.of("project", "zone", "disk"); private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final CreationStatus CREATION_STATUS = CreationStatus.READY; @@ -84,7 +84,7 @@ private void initializeExpectedDisk(int optionsCalls) { expect(serviceMockReturnsOptions.options()).andReturn(mockOptions).times(optionsCalls); replay(serviceMockReturnsOptions); standardDisk = new Disk.Builder(serviceMockReturnsOptions, DISK_ID, DISK_CONFIGURATION) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .creationStatus(CREATION_STATUS) .description(DESCRIPTION) @@ -94,7 +94,7 @@ private void initializeExpectedDisk(int optionsCalls) { .lastDetachTimestamp(LAST_DETACH_TIMESTAMP) .build(); snapshotDisk = new Disk.Builder(serviceMockReturnsOptions, DISK_ID, SNAPSHOT_DISK_CONFIGURATION) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .creationStatus(CREATION_STATUS) .description(DESCRIPTION) @@ -104,7 +104,7 @@ private void initializeExpectedDisk(int optionsCalls) { .lastDetachTimestamp(LAST_DETACH_TIMESTAMP) .build(); imageDisk = new Disk.Builder(serviceMockReturnsOptions, DISK_ID, IMAGE_DISK_CONFIGURATION) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .creationStatus(CREATION_STATUS) .description(DESCRIPTION) @@ -118,7 +118,7 @@ private void initializeExpectedDisk(int optionsCalls) { private void initializeDisk() { disk = new Disk.Builder(compute, DISK_ID, DISK_CONFIGURATION) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .creationStatus(CREATION_STATUS) .description(DESCRIPTION) @@ -157,7 +157,7 @@ public void testToBuilderIncomplete() { public void testBuilder() { initializeExpectedDisk(4); assertEquals(DISK_ID, standardDisk.diskId()); - assertEquals(ID, standardDisk.id()); + assertEquals(GENERATED_ID, standardDisk.generatedId()); assertEquals(DISK_CONFIGURATION, standardDisk.configuration()); assertEquals(CREATION_TIMESTAMP, standardDisk.creationTimestamp()); assertEquals(CREATION_STATUS, standardDisk.creationStatus()); @@ -168,7 +168,7 @@ public void testBuilder() { assertEquals(LAST_DETACH_TIMESTAMP, standardDisk.lastDetachTimestamp()); assertSame(serviceMockReturnsOptions, standardDisk.compute()); assertEquals(DISK_ID, imageDisk.diskId()); - assertEquals(ID, imageDisk.id()); + assertEquals(GENERATED_ID, imageDisk.generatedId()); assertEquals(IMAGE_DISK_CONFIGURATION, imageDisk.configuration()); assertEquals(CREATION_TIMESTAMP, imageDisk.creationTimestamp()); assertEquals(CREATION_STATUS, imageDisk.creationStatus()); @@ -179,7 +179,7 @@ public void testBuilder() { assertEquals(LAST_DETACH_TIMESTAMP, imageDisk.lastDetachTimestamp()); assertSame(serviceMockReturnsOptions, imageDisk.compute()); assertEquals(DISK_ID, snapshotDisk.diskId()); - assertEquals(ID, snapshotDisk.id()); + assertEquals(GENERATED_ID, snapshotDisk.generatedId()); assertEquals(SNAPSHOT_DISK_CONFIGURATION, snapshotDisk.configuration()); assertEquals(CREATION_TIMESTAMP, snapshotDisk.creationTimestamp()); assertEquals(CREATION_STATUS, snapshotDisk.creationStatus()); @@ -194,7 +194,7 @@ public void testBuilder() { .configuration(SNAPSHOT_DISK_CONFIGURATION) .build(); assertEquals(DiskId.of("newProject", "newZone"), disk.diskId()); - assertNull(disk.id()); + assertNull(disk.generatedId()); assertEquals(SNAPSHOT_DISK_CONFIGURATION, disk.configuration()); assertNull(disk.creationTimestamp()); assertNull(disk.creationStatus()); @@ -462,7 +462,7 @@ public void compareDisk(Disk expected, Disk value) { assertEquals(expected.compute().options(), value.compute().options()); assertEquals(expected.diskId(), value.diskId()); assertEquals(expected.configuration(), value.configuration()); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.creationStatus(), value.creationStatus()); assertEquals(expected.description(), value.description()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java index 4cbb8351270c..f322a4b05ed0 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java @@ -22,7 +22,7 @@ public class DiskTypeTest { - private static final String ID = "42"; + private static final String GENERATED_ID = "42"; private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final String DESCRIPTION = "description"; private static final String VALID_DISK_SIZE = "10GB-10TB"; @@ -31,7 +31,7 @@ public class DiskTypeTest { private static final DeprecationStatus DEPRECATION_STATUS = DeprecationStatus.of(DeprecationStatus.Status.DELETED, DISK_TYPE_ID); private static final DiskType DISK_TYPE = DiskType.builder() - .id(ID) + .generatedId(GENERATED_ID) .diskTypeId(DISK_TYPE_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) @@ -42,7 +42,7 @@ public class DiskTypeTest { @Test public void testBuilder() { - assertEquals(ID, DISK_TYPE.id()); + assertEquals(GENERATED_ID, DISK_TYPE.generatedId()); assertEquals(DISK_TYPE_ID, DISK_TYPE.diskTypeId()); assertEquals(CREATION_TIMESTAMP, DISK_TYPE.creationTimestamp()); assertEquals(DESCRIPTION, DISK_TYPE.description()); @@ -60,7 +60,7 @@ public void testToPbAndFromPb() { private void compareDiskTypes(DiskType expected, DiskType value) { assertEquals(expected, value); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.diskTypeId(), value.diskTypeId()); assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.description(), value.description()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageInfoTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageInfoTest.java index db6e092b5587..a0c9ca6bc134 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageInfoTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageInfoTest.java @@ -29,7 +29,7 @@ public class ImageInfoTest { private static final ImageId IMAGE_ID = ImageId.of("project", "image"); - private static final String ID = "42"; + private static final String GENERATED_ID = "42"; private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final String DESCRIPTION = "description"; private static final ImageInfo.Status STATUS = ImageInfo.Status.READY; @@ -58,7 +58,7 @@ public class ImageInfoTest { private static final DeprecationStatus DEPRECATION_STATUS = DeprecationStatus.of(DeprecationStatus.Status.DELETED, IMAGE_ID); private static final ImageInfo STORAGE_IMAGE = ImageInfo.builder(IMAGE_ID, STORAGE_CONFIGURATION) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .status(STATUS) @@ -67,7 +67,7 @@ public class ImageInfoTest { .deprecationStatus(DEPRECATION_STATUS) .build(); private static final ImageInfo DISK_IMAGE = ImageInfo.builder(IMAGE_ID, DISK_CONFIGURATION) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .status(STATUS) @@ -96,7 +96,7 @@ public void testToBuilderIncomplete() { @Test public void testBuilder() { - assertEquals(ID, STORAGE_IMAGE.id()); + assertEquals(GENERATED_ID, STORAGE_IMAGE.generatedId()); assertEquals(IMAGE_ID, STORAGE_IMAGE.imageId()); assertEquals(CREATION_TIMESTAMP, STORAGE_IMAGE.creationTimestamp()); assertEquals(DESCRIPTION, STORAGE_IMAGE.description()); @@ -105,7 +105,7 @@ public void testBuilder() { assertEquals(DISK_SIZE_GB, STORAGE_IMAGE.diskSizeGb()); assertEquals(LICENSES, STORAGE_IMAGE.licenses()); assertEquals(DEPRECATION_STATUS, STORAGE_IMAGE.deprecationStatus()); - assertEquals(ID, DISK_IMAGE.id()); + assertEquals(GENERATED_ID, DISK_IMAGE.generatedId()); assertEquals(IMAGE_ID, DISK_IMAGE.imageId()); assertEquals(CREATION_TIMESTAMP, DISK_IMAGE.creationTimestamp()); assertEquals(DESCRIPTION, DISK_IMAGE.description()); @@ -121,7 +121,7 @@ public void testOf() { ImageInfo imageInfo = ImageInfo.of(IMAGE_ID, STORAGE_CONFIGURATION); assertEquals(IMAGE_ID, imageInfo.imageId()); assertEquals(STORAGE_CONFIGURATION, imageInfo.configuration()); - assertNull(imageInfo.id()); + assertNull(imageInfo.generatedId()); assertNull(imageInfo.creationTimestamp()); assertNull(imageInfo.description()); assertNull(imageInfo.status()); @@ -131,7 +131,7 @@ public void testOf() { imageInfo = ImageInfo.of(IMAGE_ID, DISK_CONFIGURATION); assertEquals(IMAGE_ID, imageInfo.imageId()); assertEquals(DISK_CONFIGURATION, imageInfo.configuration()); - assertNull(imageInfo.id()); + assertNull(imageInfo.generatedId()); assertNull(imageInfo.creationTimestamp()); assertNull(imageInfo.description()); assertNull(imageInfo.status()); @@ -161,7 +161,7 @@ public void testSetProjectId() { public void compareImageInfo(ImageInfo expected, ImageInfo value) { assertEquals(expected, value); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.imageId(), value.imageId()); assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.description(), value.description()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageTest.java index dcf7e2513e07..43e27d011974 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageTest.java @@ -38,7 +38,7 @@ public class ImageTest { private static final ImageId IMAGE_ID = ImageId.of("project", "image"); - private static final String ID = "42"; + private static final String GENERATED_ID = "42"; private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final String DESCRIPTION = "description"; private static final ImageInfo.Status STATUS = ImageInfo.Status.READY; @@ -78,7 +78,7 @@ private void initializeExpectedImage(int optionsCalls) { expect(serviceMockReturnsOptions.options()).andReturn(mockOptions).times(optionsCalls); replay(serviceMockReturnsOptions); diskImage = new Image.Builder(serviceMockReturnsOptions, IMAGE_ID, DISK_CONFIGURATION) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .status(STATUS) @@ -87,7 +87,7 @@ private void initializeExpectedImage(int optionsCalls) { .deprecationStatus(DEPRECATION_STATUS) .build(); storageImage = new Image.Builder(serviceMockReturnsOptions, IMAGE_ID, STORAGE_CONFIGURATION) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .status(STATUS) @@ -100,7 +100,7 @@ private void initializeExpectedImage(int optionsCalls) { private void initializeImage() { image = new Image.Builder(compute, IMAGE_ID, DISK_CONFIGURATION) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .status(STATUS) @@ -133,7 +133,7 @@ public void testToBuilderIncomplete() { @Test public void testBuilder() { initializeExpectedImage(3); - assertEquals(ID, diskImage.id()); + assertEquals(GENERATED_ID, diskImage.generatedId()); assertEquals(IMAGE_ID, diskImage.imageId()); assertEquals(CREATION_TIMESTAMP, diskImage.creationTimestamp()); assertEquals(DESCRIPTION, diskImage.description()); @@ -143,7 +143,7 @@ public void testBuilder() { assertEquals(LICENSES, diskImage.licenses()); assertEquals(DEPRECATION_STATUS, diskImage.deprecationStatus()); assertSame(serviceMockReturnsOptions, diskImage.compute()); - assertEquals(ID, storageImage.id()); + assertEquals(GENERATED_ID, storageImage.generatedId()); assertEquals(IMAGE_ID, storageImage.imageId()); assertEquals(CREATION_TIMESTAMP, storageImage.creationTimestamp()); assertEquals(DESCRIPTION, storageImage.description()); @@ -158,7 +158,7 @@ public void testBuilder() { .imageId(imageId) .configuration(DISK_CONFIGURATION) .build(); - assertNull(image.id()); + assertNull(image.generatedId()); assertEquals(imageId, image.imageId()); assertNull(image.creationTimestamp()); assertNull(image.description()); @@ -292,7 +292,7 @@ public void testDeprecateNull() { public void compareImage(Image expected, Image value) { assertEquals(expected, value); assertEquals(expected.compute().options(), value.compute().options()); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.imageId(), value.imageId()); assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.description(), value.description()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceInfoTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceInfoTest.java index 51b2dcb91c72..be0a866e0df7 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceInfoTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceInfoTest.java @@ -28,7 +28,7 @@ public class InstanceInfoTest { - private static final String ID = "42"; + private static final String GENERATED_ID = "42"; private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final String DESCRIPTION = "description"; private static final InstanceId INSTANCE_ID = InstanceId.of("project", "zone", "instance"); @@ -55,7 +55,7 @@ public class InstanceInfoTest { private static final SchedulingOptions SCHEDULING_OPTIONS = SchedulingOptions.preemptible(); private static final String CPU_PLATFORM = "cpuPlatform"; private static final InstanceInfo INSTANCE_INFO = InstanceInfo.builder(INSTANCE_ID, MACHINE_TYPE) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .status(STATUS) @@ -88,7 +88,7 @@ public void testToBuilderIncomplete() { @Test public void testBuilder() { - assertEquals(ID, INSTANCE_INFO.id()); + assertEquals(GENERATED_ID, INSTANCE_INFO.generatedId()); assertEquals(INSTANCE_ID, INSTANCE_INFO.instanceId()); assertEquals(CREATION_TIMESTAMP, INSTANCE_INFO.creationTimestamp()); assertEquals(DESCRIPTION, INSTANCE_INFO.description()); @@ -104,7 +104,7 @@ public void testBuilder() { assertEquals(SCHEDULING_OPTIONS, INSTANCE_INFO.schedulingOptions()); assertEquals(CPU_PLATFORM, INSTANCE_INFO.cpuPlatform()); InstanceInfo instanceInfo = InstanceInfo.builder(INSTANCE_ID, MACHINE_TYPE) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .status(STATUS) @@ -125,7 +125,7 @@ public void testBuilder() { public void testOf() { InstanceInfo instance = InstanceInfo.of(INSTANCE_ID, MACHINE_TYPE, ATTACHED_DISK, NETWORK_INTERFACE); - assertNull(instance.id()); + assertNull(instance.generatedId()); assertEquals(INSTANCE_ID, instance.instanceId()); assertNull(instance.creationTimestamp()); assertNull(instance.description()); @@ -164,7 +164,7 @@ public void testSetProjectId() { public void compareInstanceInfo(InstanceInfo expected, InstanceInfo value) { assertEquals(expected, value); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.instanceId(), value.instanceId()); assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.description(), value.description()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceTest.java index 880ed68f63ab..85e2ff5311c0 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceTest.java @@ -42,7 +42,7 @@ public class InstanceTest { - private static final String ID = "42"; + private static final String GENERATED_ID = "42"; private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final String DESCRIPTION = "description"; private static final InstanceId INSTANCE_ID = InstanceId.of("project", "zone", "instance"); @@ -85,7 +85,7 @@ private void initializeExpectedInstance(int optionsCalls) { replay(serviceMockReturnsOptions); expectedInstance = new Instance.Builder(serviceMockReturnsOptions, INSTANCE_ID, MACHINE_TYPE, ATTACHED_DISK, NETWORK_INTERFACE) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .status(STATUS) @@ -103,7 +103,7 @@ private void initializeExpectedInstance(int optionsCalls) { private void initializeInstance() { instance = new Instance.Builder(compute, INSTANCE_ID, MACHINE_TYPE, ATTACHED_DISK, NETWORK_INTERFACE) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .status(STATUS) @@ -140,7 +140,7 @@ public void testToBuilderIncomplete() { @Test public void testBuilder() { initializeExpectedInstance(2); - assertEquals(ID, expectedInstance.id()); + assertEquals(GENERATED_ID, expectedInstance.generatedId()); assertEquals(INSTANCE_ID, expectedInstance.instanceId()); assertEquals(CREATION_TIMESTAMP, expectedInstance.creationTimestamp()); assertEquals(DESCRIPTION, expectedInstance.description()); @@ -160,7 +160,7 @@ public void testBuilder() { InstanceInfo.of(INSTANCE_ID, MACHINE_TYPE, ATTACHED_DISK, NETWORK_INTERFACE); Instance instance = new Instance(serviceMockReturnsOptions, new InstanceInfo.BuilderImpl(instanceInfo)); - assertNull(instance.id()); + assertNull(instance.generatedId()); assertEquals(INSTANCE_ID, instance.instanceId()); assertNull(instance.creationTimestamp()); assertNull(instance.description()); @@ -875,7 +875,7 @@ public void testStopNull() { public void compareInstance(Instance expected, Instance value) { assertEquals(expected, value); assertEquals(expected.compute().options(), value.compute().options()); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.instanceId(), value.instanceId()); assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.description(), value.description()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java index 6b0f78dff00a..f57f35a8ec3b 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java @@ -26,7 +26,7 @@ public class MachineTypeTest { - private static final String ID = "42"; + private static final String GENERATED_ID = "42"; private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final String DESCRIPTION = "description"; private static final MachineTypeId MACHINE_TYPE_ID = MachineTypeId.of("project", "zone", "type"); @@ -38,7 +38,7 @@ public class MachineTypeTest { private static final DeprecationStatus DEPRECATION_STATUS = DeprecationStatus.of(DeprecationStatus.Status.DELETED, MACHINE_TYPE_ID); private static final MachineType MACHINE_TYPE = MachineType.builder() - .id(ID) + .generatedId(GENERATED_ID) .machineTypeId(MACHINE_TYPE_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) @@ -52,7 +52,7 @@ public class MachineTypeTest { @Test public void testBuilder() { - assertEquals(ID, MACHINE_TYPE.id()); + assertEquals(GENERATED_ID, MACHINE_TYPE.generatedId()); assertEquals(MACHINE_TYPE_ID, MACHINE_TYPE.machineTypeId()); assertEquals(CREATION_TIMESTAMP, MACHINE_TYPE.creationTimestamp()); assertEquals(DESCRIPTION, MACHINE_TYPE.description()); @@ -74,7 +74,7 @@ public void testToPbAndFromPb() { private void compareMachineTypes(MachineType expected, MachineType value) { assertEquals(expected, value); assertEquals(expected.machineTypeId(), value.machineTypeId()); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.description(), value.description()); assertEquals(expected.cpus(), value.cpus()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkInfoTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkInfoTest.java index 3886e13816fe..a57ee91901b8 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkInfoTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkInfoTest.java @@ -27,7 +27,7 @@ public class NetworkInfoTest { - private static final String ID = "42"; + private static final String GENERATED_ID = "42"; private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final String DESCRIPTION = "description"; private static final SubnetworkId SUBNETWORK1 = SubnetworkId.of("project", "region1", "network1"); @@ -43,13 +43,13 @@ public class NetworkInfoTest { new SubnetNetworkConfiguration(AUTO_CREATE_SUBNETWORKS, SUBNETWORKS); private static final NetworkInfo NETWORK_INFO = NetworkInfo.builder(NETWORK_ID, NETWORK_CONFIGURATION) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .build(); private static final NetworkInfo SUBNET_NETWORK_INFO = NetworkInfo.builder(NETWORK_ID, SUBNET_NETWORK_CONFIGURATION) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .build(); @@ -76,12 +76,12 @@ public void testToBuilderIncomplete() { @Test public void testBuilder() { - assertEquals(ID, NETWORK_INFO.id()); + assertEquals(GENERATED_ID, NETWORK_INFO.generatedId()); assertEquals(NETWORK_ID, NETWORK_INFO.networkId()); assertEquals(CREATION_TIMESTAMP, NETWORK_INFO.creationTimestamp()); assertEquals(DESCRIPTION, NETWORK_INFO.description()); assertEquals(NETWORK_CONFIGURATION, NETWORK_INFO.configuration()); - assertEquals(ID, SUBNET_NETWORK_INFO.id()); + assertEquals(GENERATED_ID, SUBNET_NETWORK_INFO.generatedId()); assertEquals(NETWORK_ID, SUBNET_NETWORK_INFO.networkId()); assertEquals(CREATION_TIMESTAMP, SUBNET_NETWORK_INFO.creationTimestamp()); assertEquals(DESCRIPTION, SUBNET_NETWORK_INFO.description()); @@ -91,7 +91,7 @@ public void testBuilder() { @Test public void testOf() { NetworkInfo networkInfo = NetworkInfo.of(NETWORK_ID, NETWORK_CONFIGURATION); - assertNull(networkInfo.id()); + assertNull(networkInfo.generatedId()); assertEquals(NETWORK_ID, NETWORK_INFO.networkId()); assertEquals(NETWORK_CONFIGURATION, NETWORK_INFO.configuration()); assertNull(networkInfo.creationTimestamp()); @@ -116,7 +116,7 @@ public void testSetProjectId() { public void compareNetworkInfo(NetworkInfo expected, NetworkInfo value) { assertEquals(expected, value); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.networkId(), value.networkId()); assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.description(), value.description()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkTest.java index 3d303702ecc4..21978180f3b6 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkTest.java @@ -35,7 +35,7 @@ public class NetworkTest { - private static final String ID = "42"; + private static final String GENERATED_ID = "42"; private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final String DESCRIPTION = "description"; private static final SubnetworkId SUBNETWORK1 = SubnetworkId.of("project", "region1", "network1"); @@ -62,13 +62,13 @@ private void initializeExpectedNetwork(int optionsCalls) { replay(serviceMockReturnsOptions); standardNetwork = new Network.Builder(serviceMockReturnsOptions, NETWORK_ID, NETWORK_CONFIGURATION) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .build(); subnetNetwork = new Network.Builder(serviceMockReturnsOptions, NETWORK_ID, SUBNET_NETWORK_CONFIGURATION) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .build(); @@ -77,7 +77,7 @@ private void initializeExpectedNetwork(int optionsCalls) { private void initializeNetwork() { network = new Network.Builder(compute, NETWORK_ID, NETWORK_CONFIGURATION) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .build(); @@ -105,13 +105,13 @@ public void testToBuilderIncomplete() { @Test public void testBuilder() { initializeExpectedNetwork(2); - assertEquals(ID, standardNetwork.id()); + assertEquals(GENERATED_ID, standardNetwork.generatedId()); assertEquals(NETWORK_ID, standardNetwork.networkId()); assertEquals(CREATION_TIMESTAMP, standardNetwork.creationTimestamp()); assertEquals(DESCRIPTION, standardNetwork.description()); assertEquals(NETWORK_CONFIGURATION, standardNetwork.configuration()); assertSame(serviceMockReturnsOptions, standardNetwork.compute()); - assertEquals(ID, subnetNetwork.id()); + assertEquals(GENERATED_ID, subnetNetwork.generatedId()); assertEquals(NETWORK_ID, subnetNetwork.networkId()); assertEquals(CREATION_TIMESTAMP, subnetNetwork.creationTimestamp()); assertEquals(DESCRIPTION, subnetNetwork.description()); @@ -249,7 +249,7 @@ public void testCreateSubnetworkWithOptions() throws Exception { public void compareNetwork(Network expected, Network value) { assertEquals(expected, value); assertEquals(expected.compute().options(), value.compute().options()); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.networkId(), value.networkId()); assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.description(), value.description()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java index 450097c4ef30..e13f77c551ad 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java @@ -49,8 +49,7 @@ public class OperationTest { new OperationWarning("code1", "message1", ImmutableMap.of("k1", "v1")); private static final OperationWarning OPERATION_WARNING2 = new OperationWarning("code2", "location2", ImmutableMap.of("k2", "v2")); - private static final String ID = "1"; - private static final Long CREATION_TIMESTAMP = 1453293540000L; + private static final String GENERATED_ID = "1"; private static final String CLIENT_OPERATION_ID = "clientOperationId"; private static final String OPERATION_TYPE = "delete"; private static final String TARGET_LINK = "targetLink"; @@ -88,7 +87,7 @@ private void initializeExpectedOperation(int optionsCalls) { expect(serviceMockReturnsOptions.options()).andReturn(mockOptions).times(optionsCalls); replay(serviceMockReturnsOptions); globalOperation = new Operation.Builder(serviceMockReturnsOptions) - .id(ID) + .generatedId(GENERATED_ID) .operationId(GLOBAL_OPERATION_ID) .clientOperationId(CLIENT_OPERATION_ID) .operationType(OPERATION_TYPE) @@ -108,7 +107,7 @@ private void initializeExpectedOperation(int optionsCalls) { .description(DESCRIPTION) .build(); zoneOperation = new Operation.Builder(serviceMockReturnsOptions) - .id(ID) + .generatedId(GENERATED_ID) .operationId(ZONE_OPERATION_ID) .clientOperationId(CLIENT_OPERATION_ID) .operationType(OPERATION_TYPE) @@ -128,7 +127,7 @@ private void initializeExpectedOperation(int optionsCalls) { .description(DESCRIPTION) .build(); regionOperation = new Operation.Builder(serviceMockReturnsOptions) - .id(ID) + .generatedId(GENERATED_ID) .operationId(REGION_OPERATION_ID) .clientOperationId(CLIENT_OPERATION_ID) .operationType(OPERATION_TYPE) @@ -152,7 +151,7 @@ private void initializeExpectedOperation(int optionsCalls) { private void initializeOperation() { operation = new Operation.Builder(compute) - .id(ID) + .generatedId(GENERATED_ID) .operationId(GLOBAL_OPERATION_ID) .clientOperationId(CLIENT_OPERATION_ID) .operationType(OPERATION_TYPE) @@ -179,7 +178,7 @@ public void tearDown() throws Exception { } private void assertEqualsCommonFields(Operation operation) { - assertEquals(ID, operation.id()); + assertEquals(GENERATED_ID, operation.generatedId()); assertEquals(CLIENT_OPERATION_ID, operation.clientOperationId()); assertEquals(OPERATION_TYPE, operation.operationType()); assertEquals(TARGET_LINK, operation.targetLink()); @@ -200,7 +199,7 @@ private void assertEqualsCommonFields(Operation operation) { } private void assertNullCommonFields(Operation operation) { - assertNull(operation.id()); + assertNull(operation.generatedId()); assertNull(operation.clientOperationId()); assertNull(operation.operationType()); assertNull(operation.targetLink()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java index 07701b1d2248..5b1947a585ab 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java @@ -27,7 +27,7 @@ public class RegionTest { private static final RegionId REGION_ID = RegionId.of("project", "region"); - private static final String ID = "42"; + private static final String GENERATED_ID = "42"; private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final String DESCRIPTION = "description"; private static final Region.Status STATUS = Region.Status.DOWN; @@ -43,7 +43,7 @@ public class RegionTest { DeprecationStatus.of(DeprecationStatus.Status.DELETED, REGION_ID); private static final Region REGION = Region.builder() .regionId(REGION_ID) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .status(STATUS) @@ -55,7 +55,7 @@ public class RegionTest { @Test public void testBuilder() { assertEquals(REGION_ID, REGION.regionId()); - assertEquals(ID, REGION.id()); + assertEquals(GENERATED_ID, REGION.generatedId()); assertEquals(CREATION_TIMESTAMP, REGION.creationTimestamp()); assertEquals(DESCRIPTION, REGION.description()); assertEquals(STATUS, REGION.status()); @@ -77,7 +77,7 @@ public void testToAndFromPb() { private void compareRegions(Region expected, Region value) { assertEquals(expected, value); assertEquals(expected.regionId(), value.regionId()); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.description(), value.description()); assertEquals(expected.status(), value.status()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java index 5b5b97142a3d..4761ccc80f5c 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java @@ -41,14 +41,12 @@ public class SerializationTest { private static final Compute COMPUTE = ComputeOptions.builder().projectId("p").build().service(); - private static final String ID = "42"; private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final String DESCRIPTION = "description"; private static final String VALID_DISK_SIZE = "10GB-10TB"; private static final Long DEFAULT_DISK_SIZE_GB = 10L; private static final DiskTypeId DISK_TYPE_ID = DiskTypeId.of("project", "zone", "diskType"); private static final DiskType DISK_TYPE = DiskType.builder() - .id(ID) .diskTypeId(DISK_TYPE_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) @@ -62,7 +60,6 @@ public class SerializationTest { private static final Integer MAXIMUM_PERSISTENT_DISKS = 4; private static final Long MAXIMUM_PERSISTENT_DISKS_SIZE_GB = 5L; private static final MachineType MACHINE_TYPE = MachineType.builder() - .id(ID) .machineTypeId(MACHINE_TYPE_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) @@ -84,7 +81,6 @@ public class SerializationTest { private static final List QUOTAS = ImmutableList.of(QUOTA1, QUOTA2); private static final Region REGION = Region.builder() .regionId(REGION_ID) - .id(ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .status(REGION_STATUS) @@ -95,7 +91,6 @@ public class SerializationTest { private static final Zone.Status ZONE_STATUS = Zone.Status.DOWN; private static final Zone ZONE = Zone.builder() .zoneId(ZONE_ID) - .id(ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .status(ZONE_STATUS) @@ -135,7 +130,6 @@ public class SerializationTest { private static final AddressInfo ADDRESS_INFO = AddressInfo.builder(REGION_ADDRESS_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) - .id(ID) .usage(INSTANCE_USAGE) .build(); private static final Address ADDRESS = new Address.Builder(COMPUTE, REGION_ADDRESS_ID).build(); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotInfoTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotInfoTest.java index 15789b414574..b9febeb9f011 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotInfoTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotInfoTest.java @@ -29,7 +29,7 @@ public class SnapshotInfoTest { - private static final String ID = "42"; + private static final String GENERATED_ID = "42"; private static final DiskId SOURCE_DISK = DiskId.of("project", "zone", "disk"); private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final String DESCRIPTION = "description"; @@ -42,7 +42,7 @@ public class SnapshotInfoTest { private static final Long STORAGE_BYTES = 24L; private static final StorageBytesStatus STORAGE_BYTES_STATUS = StorageBytesStatus.UP_TO_DATE; private static final SnapshotInfo SNAPSHOT_INFO = SnapshotInfo.builder(SNAPSHOT_ID, SOURCE_DISK) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .status(STATUS) @@ -70,7 +70,7 @@ public void testToBuilderIncomplete() { @Test public void testBuilder() { - assertEquals(ID, SNAPSHOT_INFO.id()); + assertEquals(GENERATED_ID, SNAPSHOT_INFO.generatedId()); assertEquals(SNAPSHOT_ID, SNAPSHOT_INFO.snapshotId()); assertEquals(CREATION_TIMESTAMP, SNAPSHOT_INFO.creationTimestamp()); assertEquals(DESCRIPTION, SNAPSHOT_INFO.description()); @@ -86,7 +86,7 @@ public void testBuilder() { @Test public void testOf() { SnapshotInfo snapshotInfo = SnapshotInfo.of(SNAPSHOT_ID, SOURCE_DISK); - assertNull(snapshotInfo.id()); + assertNull(snapshotInfo.generatedId()); assertEquals(SNAPSHOT_ID, snapshotInfo.snapshotId()); assertNull(snapshotInfo.creationTimestamp()); assertNull(snapshotInfo.description()); @@ -119,7 +119,7 @@ public void testSetProjectId() { public void compareSnapshotInfo(SnapshotInfo expected, SnapshotInfo value) { assertEquals(expected, value); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.snapshotId(), value.snapshotId()); assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.description(), value.description()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotTest.java index ac02669d7d5c..9959b875b92a 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotTest.java @@ -35,7 +35,7 @@ public class SnapshotTest { - private static final String ID = "42"; + private static final String GENERATED_ID = "42"; private static final DiskId SOURCE_DISK = DiskId.of("project", "zone", "disk"); private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final String DESCRIPTION = "description"; @@ -59,7 +59,7 @@ private void initializeExpectedSnapshot(int optionsCalls) { expect(serviceMockReturnsOptions.options()).andReturn(mockOptions).times(optionsCalls); replay(serviceMockReturnsOptions); expectedSnapshot = new Snapshot.Builder(serviceMockReturnsOptions, SNAPSHOT_ID, SOURCE_DISK) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .status(STATUS) @@ -74,7 +74,7 @@ private void initializeExpectedSnapshot(int optionsCalls) { private void initializeSnapshot() { snapshot = new Snapshot.Builder(compute, SNAPSHOT_ID, SOURCE_DISK) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .status(STATUS) @@ -108,7 +108,7 @@ public void testToBuilderIncomplete() { @Test public void testBuilder() { initializeExpectedSnapshot(2); - assertEquals(ID, expectedSnapshot.id()); + assertEquals(GENERATED_ID, expectedSnapshot.generatedId()); assertEquals(SNAPSHOT_ID, expectedSnapshot.snapshotId()); assertEquals(CREATION_TIMESTAMP, expectedSnapshot.creationTimestamp()); assertEquals(DESCRIPTION, expectedSnapshot.description()); @@ -126,7 +126,7 @@ public void testBuilder() { .snapshotId(otherSnapshotId) .sourceDisk(otherSourceDisk) .build(); - assertNull(snapshot.id()); + assertNull(snapshot.generatedId()); assertEquals(otherSnapshotId, snapshot.snapshotId()); assertNull(snapshot.creationTimestamp()); assertNull(snapshot.description()); @@ -237,7 +237,7 @@ public void testReloadWithOptions() throws Exception { public void compareSnapshot(Snapshot expected, Snapshot value) { assertEquals(expected, value); assertEquals(expected.compute().options(), value.compute().options()); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.snapshotId(), value.snapshotId()); assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.description(), value.description()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkInfoTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkInfoTest.java index 83ba0bf9baab..721072ef9065 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkInfoTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkInfoTest.java @@ -23,7 +23,7 @@ public class SubnetworkInfoTest { - private static final String ID = "42"; + private static final String GENERATED_ID = "42"; private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final String DESCRIPTION = "description"; private static final SubnetworkId SUBNETWORK_ID = @@ -33,7 +33,7 @@ public class SubnetworkInfoTest { private static final String IP_RANGE = "192.168.0.0/16"; private static final SubnetworkInfo SUBNETWORK_INFO = SubnetworkInfo.builder(SUBNETWORK_ID, NETWORK_ID, IP_RANGE) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .gatewayAddress(GATEWAY_ADDRESS) @@ -57,7 +57,7 @@ public void testToBuilderIncomplete() { @Test public void testBuilder() { - assertEquals(ID, SUBNETWORK_INFO.id()); + assertEquals(GENERATED_ID, SUBNETWORK_INFO.generatedId()); assertEquals(SUBNETWORK_ID, SUBNETWORK_INFO.subnetworkId()); assertEquals(CREATION_TIMESTAMP, SUBNETWORK_INFO.creationTimestamp()); assertEquals(DESCRIPTION, SUBNETWORK_INFO.description()); @@ -69,7 +69,7 @@ public void testBuilder() { @Test public void testOf() { SubnetworkInfo subnetworkInfo = SubnetworkInfo.of(SUBNETWORK_ID, NETWORK_ID, IP_RANGE); - assertNull(subnetworkInfo.id()); + assertNull(subnetworkInfo.generatedId()); assertEquals(SUBNETWORK_ID, subnetworkInfo.subnetworkId()); assertNull(subnetworkInfo.creationTimestamp()); assertNull(subnetworkInfo.description()); @@ -96,7 +96,7 @@ public void testSetProjectId() { public void compareSubnetworkInfo(SubnetworkInfo expected, SubnetworkInfo value) { assertEquals(expected, value); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.subnetworkId(), value.subnetworkId()); assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.description(), value.description()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkTest.java index 4e47c9aa1198..8fc841383f1e 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkTest.java @@ -31,7 +31,7 @@ public class SubnetworkTest { - private static final String ID = "42"; + private static final String GENERATED_ID = "42"; private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final String DESCRIPTION = "description"; private static final SubnetworkId SUBNETWORK_ID = SubnetworkId.of("project", "region", "network"); @@ -50,7 +50,7 @@ private void initializeExpectedSubnetwork(int optionsCalls) { replay(serviceMockReturnsOptions); expectedSubnetwork = new Subnetwork.Builder(serviceMockReturnsOptions, SUBNETWORK_ID, NETWORK_ID, IP_RANGE) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .gatewayAddress(GATEWAY_ADDRESS) @@ -61,7 +61,7 @@ private void initializeExpectedSubnetwork(int optionsCalls) { private void initializeSubnetwork() { subnetwork = new Subnetwork.Builder(compute, SUBNETWORK_ID, NETWORK_ID, IP_RANGE) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .gatewayAddress(GATEWAY_ADDRESS) @@ -90,7 +90,7 @@ public void testToBuilderIncomplete() { @Test public void testBuilder() { initializeExpectedSubnetwork(1); - assertEquals(ID, expectedSubnetwork.id()); + assertEquals(GENERATED_ID, expectedSubnetwork.generatedId()); assertEquals(SUBNETWORK_ID, expectedSubnetwork.subnetworkId()); assertEquals(CREATION_TIMESTAMP, expectedSubnetwork.creationTimestamp()); assertEquals(DESCRIPTION, expectedSubnetwork.description()); @@ -198,7 +198,7 @@ public void testReloadWithOptions() throws Exception { public void compareSubnetwork(Subnetwork expected, Subnetwork value) { assertEquals(expected, value); assertEquals(expected.compute().options(), value.compute().options()); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.subnetworkId(), value.subnetworkId()); assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.description(), value.description()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java index 97a80a4de05b..624fd4d2d62b 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java @@ -24,7 +24,7 @@ public class ZoneTest { private static final ZoneId ZONE_ID = ZoneId.of("project", "zone"); private static final RegionId REGION_ID = RegionId.of("project", "region"); - private static final String ID = "42"; + private static final String GENERATED_ID = "42"; private static final Long CREATION_TIMESTAMP = 1453293540000L; private static final String DESCRIPTION = "description"; private static final Zone.Status STATUS = Zone.Status.DOWN; @@ -32,7 +32,7 @@ public class ZoneTest { DeprecationStatus.of(DeprecationStatus.Status.DELETED, ZONE_ID); private static final Zone ZONE = Zone.builder() .zoneId(ZONE_ID) - .id(ID) + .generatedId(GENERATED_ID) .creationTimestamp(CREATION_TIMESTAMP) .description(DESCRIPTION) .status(STATUS) @@ -43,7 +43,7 @@ public class ZoneTest { @Test public void testBuilder() { assertEquals(REGION_ID, ZONE.region()); - assertEquals(ID, ZONE.id()); + assertEquals(GENERATED_ID, ZONE.generatedId()); assertEquals(CREATION_TIMESTAMP, ZONE.creationTimestamp()); assertEquals(DESCRIPTION, ZONE.description()); assertEquals(STATUS, ZONE.status()); @@ -66,7 +66,7 @@ public void testToAndFromPb() { private void compareZones(Zone expected, Zone value) { assertEquals(expected, value); assertEquals(expected.zoneId(), value.zoneId()); - assertEquals(expected.id(), value.id()); + assertEquals(expected.generatedId(), value.generatedId()); assertEquals(expected.creationTimestamp(), value.creationTimestamp()); assertEquals(expected.description(), value.description()); assertEquals(expected.status(), value.status()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java index 00a26cf82602..a46d47d2040d 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java @@ -119,7 +119,7 @@ public static void beforeClass() { @Test public void testGetDiskType() { DiskType diskType = compute.getDiskType(ZONE, DISK_TYPE); - // assertNotNull(diskType.id()); + // assertNotNull(diskType.generatedId()); assertEquals(ZONE, diskType.diskTypeId().zone()); assertEquals(DISK_TYPE, diskType.diskTypeId().type()); assertNotNull(diskType.creationTimestamp()); @@ -132,7 +132,7 @@ public void testGetDiskType() { public void testGetDiskTypeWithSelectedFields() { DiskType diskType = compute.getDiskType(ZONE, DISK_TYPE, Compute.DiskTypeOption.fields(Compute.DiskTypeField.CREATION_TIMESTAMP)); - // assertNotNull(diskType.id()); + // assertNotNull(diskType.generatedId()); assertEquals(ZONE, diskType.diskTypeId().zone()); assertEquals(DISK_TYPE, diskType.diskTypeId().type()); assertNotNull(diskType.creationTimestamp()); @@ -148,7 +148,7 @@ public void testListDiskTypes() { assertTrue(diskTypeIterator.hasNext()); while (diskTypeIterator.hasNext()) { DiskType diskType = diskTypeIterator.next(); - // assertNotNull(diskType.id()); + // assertNotNull(diskType.generatedId()); assertNotNull(diskType.diskTypeId()); assertEquals(ZONE, diskType.diskTypeId().zone()); assertNotNull(diskType.creationTimestamp()); @@ -166,7 +166,7 @@ public void testListDiskTypesWithSelectedFields() { assertTrue(diskTypeIterator.hasNext()); while (diskTypeIterator.hasNext()) { DiskType diskType = diskTypeIterator.next(); - assertNull(diskType.id()); + assertNull(diskType.generatedId()); assertNotNull(diskType.diskTypeId()); assertEquals(ZONE, diskType.diskTypeId().zone()); assertNotNull(diskType.creationTimestamp()); @@ -185,7 +185,7 @@ public void testListDiskTypesWithFilter() { while (diskTypeIterator.hasNext()) { DiskType diskType = diskTypeIterator.next(); // todo(mziccard): uncomment or remove once #695 is closed - // assertNotNull(diskType.id()); + // assertNotNull(diskType.generatedId()); assertNotNull(diskType.diskTypeId()); assertEquals(ZONE, diskType.diskTypeId().zone()); assertNotNull(diskType.creationTimestamp()); @@ -202,7 +202,7 @@ public void testAggregatedListDiskTypes() { assertTrue(diskTypeIterator.hasNext()); while (diskTypeIterator.hasNext()) { DiskType diskType = diskTypeIterator.next(); - // assertNotNull(diskType.id()); + // assertNotNull(diskType.generatedId()); assertNotNull(diskType.diskTypeId()); assertNotNull(diskType.creationTimestamp()); assertNotNull(diskType.description()); @@ -220,7 +220,7 @@ public void testAggregatedListDiskTypesWithFilter() { while (diskTypeIterator.hasNext()) { DiskType diskType = diskTypeIterator.next(); // todo(mziccard): uncomment or remove once #695 is closed - // assertNotNull(diskType.id()); + // assertNotNull(diskType.generatedId()); assertNotNull(diskType.diskTypeId()); assertNotNull(diskType.creationTimestamp()); assertNotNull(diskType.description()); @@ -234,7 +234,7 @@ public void testGetMachineType() { MachineType machineType = compute.getMachineType(ZONE, MACHINE_TYPE); assertEquals(ZONE, machineType.machineTypeId().zone()); assertEquals(MACHINE_TYPE, machineType.machineTypeId().type()); - assertNotNull(machineType.id()); + assertNotNull(machineType.generatedId()); assertNotNull(machineType.creationTimestamp()); assertNotNull(machineType.description()); assertNotNull(machineType.cpus()); @@ -249,7 +249,7 @@ public void testGetMachineTypeWithSelectedFields() { Compute.MachineTypeOption.fields(Compute.MachineTypeField.ID)); assertEquals(ZONE, machineType.machineTypeId().zone()); assertEquals(MACHINE_TYPE, machineType.machineTypeId().type()); - assertNotNull(machineType.id()); + assertNotNull(machineType.generatedId()); assertNull(machineType.creationTimestamp()); assertNull(machineType.description()); assertNull(machineType.cpus()); @@ -267,7 +267,7 @@ public void testListMachineTypes() { MachineType machineType = machineTypeIterator.next(); assertNotNull(machineType.machineTypeId()); assertEquals(ZONE, machineType.machineTypeId().zone()); - assertNotNull(machineType.id()); + assertNotNull(machineType.generatedId()); assertNotNull(machineType.creationTimestamp()); assertNotNull(machineType.description()); assertNotNull(machineType.cpus()); @@ -287,7 +287,7 @@ public void testListMachineTypesWithSelectedFields() { MachineType machineType = machineTypeIterator.next(); assertNotNull(machineType.machineTypeId()); assertEquals(ZONE, machineType.machineTypeId().zone()); - assertNull(machineType.id()); + assertNull(machineType.generatedId()); assertNotNull(machineType.creationTimestamp()); assertNull(machineType.description()); assertNull(machineType.cpus()); @@ -308,7 +308,7 @@ public void testListMachineTypesWithFilter() { MachineType machineType = machineTypeIterator.next(); assertNotNull(machineType.machineTypeId()); assertEquals(ZONE, machineType.machineTypeId().zone()); - assertNotNull(machineType.id()); + assertNotNull(machineType.generatedId()); assertNotNull(machineType.creationTimestamp()); assertNotNull(machineType.description()); assertNotNull(machineType.cpus()); @@ -327,7 +327,7 @@ public void testAggregatedListMachineTypes() { while (machineTypeIterator.hasNext()) { MachineType machineType = machineTypeIterator.next(); assertNotNull(machineType.machineTypeId()); - assertNotNull(machineType.id()); + assertNotNull(machineType.generatedId()); assertNotNull(machineType.creationTimestamp()); assertNotNull(machineType.description()); assertNotNull(machineType.cpus()); @@ -347,7 +347,7 @@ public void testAggregatedListMachineTypesWithFilter() { while (machineTypeIterator.hasNext()) { MachineType machineType = machineTypeIterator.next(); assertNotNull(machineType.machineTypeId()); - assertNotNull(machineType.id()); + assertNotNull(machineType.generatedId()); assertNotNull(machineType.creationTimestamp()); assertNotNull(machineType.description()); assertNotNull(machineType.cpus()); @@ -378,7 +378,7 @@ public void testGetRegion() { assertEquals(REGION, region.regionId().region()); assertNotNull(region.description()); assertNotNull(region.creationTimestamp()); - assertNotNull(region.id()); + assertNotNull(region.generatedId()); assertNotNull(region.quotas()); assertNotNull(region.status()); assertNotNull(region.zones()); @@ -388,7 +388,7 @@ public void testGetRegion() { public void testGetRegionWithSelectedFields() { Region region = compute.getRegion(REGION, Compute.RegionOption.fields(Compute.RegionField.ID)); assertEquals(REGION, region.regionId().region()); - assertNotNull(region.id()); + assertNotNull(region.generatedId()); assertNull(region.description()); assertNull(region.creationTimestamp()); assertNull(region.quotas()); @@ -405,7 +405,7 @@ public void testListRegions() { assertNotNull(region.regionId()); assertNotNull(region.description()); assertNotNull(region.creationTimestamp()); - assertNotNull(region.id()); + assertNotNull(region.generatedId()); assertNotNull(region.quotas()); assertNotNull(region.status()); assertNotNull(region.zones()); @@ -422,7 +422,7 @@ public void testListRegionsWithSelectedFields() { assertNotNull(region.regionId()); assertNull(region.description()); assertNull(region.creationTimestamp()); - assertNotNull(region.id()); + assertNotNull(region.generatedId()); assertNull(region.quotas()); assertNull(region.status()); assertNull(region.zones()); @@ -442,7 +442,7 @@ public void testListRegionsWithFilter() { public void testGetZone() { Zone zone = compute.getZone(ZONE); assertEquals(ZONE, zone.zoneId().zone()); - assertNotNull(zone.id()); + assertNotNull(zone.generatedId()); assertNotNull(zone.creationTimestamp()); assertNotNull(zone.description()); assertNotNull(zone.status()); @@ -453,7 +453,7 @@ public void testGetZone() { public void testGetZoneWithSelectedFields() { Zone zone = compute.getZone(ZONE, Compute.ZoneOption.fields(Compute.ZoneField.ID)); assertEquals(ZONE, zone.zoneId().zone()); - assertNotNull(zone.id()); + assertNotNull(zone.generatedId()); assertNull(zone.creationTimestamp()); assertNull(zone.description()); assertNull(zone.status()); @@ -467,7 +467,7 @@ public void testListZones() { while (zoneIterator.hasNext()) { Zone zone = zoneIterator.next(); assertNotNull(zone.zoneId()); - assertNotNull(zone.id()); + assertNotNull(zone.generatedId()); assertNotNull(zone.creationTimestamp()); assertNotNull(zone.description()); assertNotNull(zone.status()); @@ -483,7 +483,7 @@ public void testListZonesWithSelectedFields() { while (zoneIterator.hasNext()) { Zone zone = zoneIterator.next(); assertNotNull(zone.zoneId()); - assertNull(zone.id()); + assertNull(zone.generatedId()); assertNotNull(zone.creationTimestamp()); assertNull(zone.description()); assertNull(zone.status()); @@ -506,7 +506,7 @@ public void testListGlobalOperations() { Iterator operationIterator = operationPage.iterateAll(); while (operationIterator.hasNext()) { Operation operation = operationIterator.next(); - assertNotNull(operation.id()); + assertNotNull(operation.generatedId()); assertNotNull(operation.operationId()); // todo(mziccard): uncomment or remove once #727 is closed // assertNotNull(operation.creationTimestamp()); @@ -523,7 +523,7 @@ public void testListGlobalOperationsWithSelectedFields() { Iterator operationIterator = operationPage.iterateAll(); while (operationIterator.hasNext()) { Operation operation = operationIterator.next(); - assertNotNull(operation.id()); + assertNotNull(operation.generatedId()); assertNotNull(operation.operationId()); assertNull(operation.operationType()); assertNull(operation.targetLink()); @@ -549,7 +549,7 @@ public void testListGlobalOperationsWithFilter() { Iterator operationIterator = operationPage.iterateAll(); while (operationIterator.hasNext()) { Operation operation = operationIterator.next(); - assertNotNull(operation.id()); + assertNotNull(operation.generatedId()); assertNotNull(operation.operationId()); // todo(mziccard): uncomment or remove once #727 is closed // assertNotNull(operation.creationTimestamp()); @@ -565,7 +565,7 @@ public void testListRegionOperations() { Iterator operationIterator = operationPage.iterateAll(); while (operationIterator.hasNext()) { Operation operation = operationIterator.next(); - assertNotNull(operation.id()); + assertNotNull(operation.generatedId()); assertNotNull(operation.operationId()); assertEquals(REGION, operation.operationId().region()); // todo(mziccard): uncomment or remove once #727 is closed @@ -583,7 +583,7 @@ public void testListRegionOperationsWithSelectedFields() { Iterator operationIterator = operationPage.iterateAll(); while (operationIterator.hasNext()) { Operation operation = operationIterator.next(); - assertNotNull(operation.id()); + assertNotNull(operation.generatedId()); assertNotNull(operation.operationId()); assertEquals(REGION, operation.operationId().region()); assertNull(operation.operationType()); @@ -611,7 +611,7 @@ public void testListRegionOperationsWithFilter() { Iterator operationIterator = operationPage.iterateAll(); while (operationIterator.hasNext()) { Operation operation = operationIterator.next(); - assertNotNull(operation.id()); + assertNotNull(operation.generatedId()); assertNotNull(operation.operationId()); assertEquals(REGION, operation.operationId().region()); // todo(mziccard): uncomment or remove once #727 is closed @@ -628,7 +628,7 @@ public void testListZoneOperations() { Iterator operationIterator = operationPage.iterateAll(); while (operationIterator.hasNext()) { Operation operation = operationIterator.next(); - assertNotNull(operation.id()); + assertNotNull(operation.generatedId()); assertNotNull(operation.operationId()); assertEquals(ZONE, operation.operationId().zone()); // todo(mziccard): uncomment or remove once #727 is closed @@ -646,7 +646,7 @@ public void testListZoneOperationsWithSelectedFields() { Iterator operationIterator = operationPage.iterateAll(); while (operationIterator.hasNext()) { Operation operation = operationIterator.next(); - assertNotNull(operation.id()); + assertNotNull(operation.generatedId()); assertNotNull(operation.operationId()); assertEquals(ZONE, operation.operationId().zone()); assertNull(operation.operationType()); @@ -674,7 +674,7 @@ public void testListZoneOperationsWithFilter() { Iterator operationIterator = operationPage.iterateAll(); while (operationIterator.hasNext()) { Operation operation = operationIterator.next(); - assertNotNull(operation.id()); + assertNotNull(operation.generatedId()); assertNotNull(operation.operationId()); assertEquals(ZONE, operation.operationId().zone()); // todo(mziccard): uncomment or remove once #727 is closed @@ -702,7 +702,7 @@ public void testCreateGetAndDeleteRegionAddress() throws InterruptedException { assertEquals(addressId.address(), remoteAddress.addressId().address()); assertNotNull(remoteAddress.address()); assertNotNull(remoteAddress.creationTimestamp()); - assertNotNull(remoteAddress.id()); + assertNotNull(remoteAddress.generatedId()); assertNotNull(remoteAddress.status()); // test get with selected fields remoteAddress = compute.get(addressId, Compute.AddressOption.fields()); @@ -712,7 +712,7 @@ public void testCreateGetAndDeleteRegionAddress() throws InterruptedException { assertEquals(addressId.address(), remoteAddress.addressId().address()); assertNull(remoteAddress.address()); assertNull(remoteAddress.creationTimestamp()); - assertNull(remoteAddress.id()); + assertNull(remoteAddress.generatedId()); operation = remoteAddress.delete(); while (!operation.isDone()) { Thread.sleep(1000L); @@ -750,7 +750,7 @@ public void testListRegionAddresses() throws InterruptedException { assertTrue(addressSet.contains(address.addressId().address())); assertNotNull(address.address()); assertNotNull(address.creationTimestamp()); - assertNotNull(address.id()); + assertNotNull(address.generatedId()); count++; } assertEquals(2, count); @@ -766,7 +766,7 @@ public void testListRegionAddresses() throws InterruptedException { assertTrue(addressSet.contains(address.addressId().address())); assertNotNull(address.address()); assertNull(address.creationTimestamp()); - assertNull(address.id()); + assertNull(address.generatedId()); assertNull(address.status()); assertNull(address.usage()); count++; @@ -803,7 +803,7 @@ public void testAggregatedListAddresses() throws InterruptedException { assertTrue(addressSet.contains(address.addressId().address())); assertNotNull(address.address()); assertNotNull(address.creationTimestamp()); - assertNotNull(address.id()); + assertNotNull(address.generatedId()); count++; } assertEquals(2, count); @@ -827,7 +827,7 @@ public void testCreateGetAndDeleteGlobalAddress() throws InterruptedException { assertEquals(addressId.address(), remoteAddress.addressId().address()); assertNotNull(remoteAddress.address()); assertNotNull(remoteAddress.creationTimestamp()); - assertNotNull(remoteAddress.id()); + assertNotNull(remoteAddress.generatedId()); assertNotNull(remoteAddress.status()); // test get with selected fields remoteAddress = compute.get(addressId, Compute.AddressOption.fields()); @@ -836,7 +836,7 @@ public void testCreateGetAndDeleteGlobalAddress() throws InterruptedException { assertEquals(addressId.address(), remoteAddress.addressId().address()); assertNull(remoteAddress.address()); assertNull(remoteAddress.creationTimestamp()); - assertNull(remoteAddress.id()); + assertNull(remoteAddress.generatedId()); operation = remoteAddress.delete(); while (!operation.isDone()) { Thread.sleep(1000L); @@ -873,7 +873,7 @@ public void testListGlobalAddresses() throws InterruptedException { assertTrue(addressSet.contains(address.addressId().address())); assertNotNull(address.address()); assertNotNull(address.creationTimestamp()); - assertNotNull(address.id()); + assertNotNull(address.generatedId()); count++; } assertEquals(2, count); @@ -888,7 +888,7 @@ public void testListGlobalAddresses() throws InterruptedException { assertTrue(addressSet.contains(address.addressId().address())); assertNotNull(address.address()); assertNull(address.creationTimestamp()); - assertNull(address.id()); + assertNull(address.generatedId()); assertNull(address.status()); assertNull(address.usage()); count++; @@ -914,7 +914,7 @@ public void testCreateGetResizeAndDeleteStandardDisk() throws InterruptedExcepti assertEquals(ZONE, remoteDisk.diskId().zone()); assertEquals(diskId.disk(), remoteDisk.diskId().disk()); assertNotNull(remoteDisk.creationTimestamp()); - assertNotNull(remoteDisk.id()); + assertNotNull(remoteDisk.generatedId()); assertTrue(remoteDisk.configuration() instanceof StandardDiskConfiguration); StandardDiskConfiguration remoteConfiguration = remoteDisk.configuration(); assertEquals(100L, (long) remoteConfiguration.sizeGb()); @@ -932,7 +932,7 @@ public void testCreateGetResizeAndDeleteStandardDisk() throws InterruptedExcepti assertEquals(ZONE, remoteDisk.diskId().zone()); assertEquals(diskId.disk(), remoteDisk.diskId().disk()); assertNull(remoteDisk.creationTimestamp()); - assertNull(remoteDisk.id()); + assertNull(remoteDisk.generatedId()); assertTrue(remoteDisk.configuration() instanceof StandardDiskConfiguration); remoteConfiguration = remoteDisk.configuration(); assertEquals(200L, (long) remoteConfiguration.sizeGb()); @@ -963,7 +963,7 @@ public void testCreateGetAndDeleteImageDisk() throws InterruptedException { assertEquals(diskId.disk(), remoteDisk.diskId().disk()); assertEquals(DiskInfo.CreationStatus.READY, remoteDisk.creationStatus()); assertNotNull(remoteDisk.creationTimestamp()); - assertNotNull(remoteDisk.id()); + assertNotNull(remoteDisk.generatedId()); assertTrue(remoteDisk.configuration() instanceof ImageDiskConfiguration); ImageDiskConfiguration remoteConfiguration = remoteDisk.configuration(); assertEquals(IMAGE_ID, remoteConfiguration.sourceImage()); @@ -979,7 +979,7 @@ public void testCreateGetAndDeleteImageDisk() throws InterruptedException { assertEquals(ZONE, remoteDisk.diskId().zone()); assertEquals(diskId.disk(), remoteDisk.diskId().disk()); assertNull(remoteDisk.creationTimestamp()); - assertNull(remoteDisk.id()); + assertNull(remoteDisk.generatedId()); assertTrue(remoteDisk.configuration() instanceof ImageDiskConfiguration); remoteConfiguration = remoteDisk.configuration(); assertEquals(IMAGE_ID, remoteConfiguration.sourceImage()); @@ -1017,7 +1017,7 @@ public void testCreateGetAndDeleteSnapshotAndSnapshotDisk() throws InterruptedEx // test get snapshot with selected fields Snapshot snapshot = compute.getSnapshot(snapshotName, Compute.SnapshotOption.fields(Compute.SnapshotField.CREATION_TIMESTAMP)); - assertNull(snapshot.id()); + assertNull(snapshot.generatedId()); assertNotNull(snapshot.snapshotId()); assertNotNull(snapshot.creationTimestamp()); assertNull(snapshot.description()); @@ -1030,7 +1030,7 @@ public void testCreateGetAndDeleteSnapshotAndSnapshotDisk() throws InterruptedEx assertNull(snapshot.storageBytesStatus()); // test get snapshot snapshot = compute.getSnapshot(snapshotName); - assertNotNull(snapshot.id()); + assertNotNull(snapshot.generatedId()); assertNotNull(snapshot.snapshotId()); assertNotNull(snapshot.creationTimestamp()); assertNotNull(snapshot.status()); @@ -1053,7 +1053,7 @@ public void testCreateGetAndDeleteSnapshotAndSnapshotDisk() throws InterruptedEx assertEquals(snapshotDiskId.disk(), remoteDisk.diskId().disk()); assertEquals(DiskInfo.CreationStatus.READY, remoteDisk.creationStatus()); assertNotNull(remoteDisk.creationTimestamp()); - assertNotNull(remoteDisk.id()); + assertNotNull(remoteDisk.generatedId()); assertTrue(remoteDisk.configuration() instanceof SnapshotDiskConfiguration); SnapshotDiskConfiguration remoteConfiguration = remoteDisk.configuration(); assertEquals(DiskConfiguration.Type.SNAPSHOT, remoteConfiguration.type()); @@ -1070,7 +1070,7 @@ public void testCreateGetAndDeleteSnapshotAndSnapshotDisk() throws InterruptedEx assertEquals(snapshotDiskId.disk(), remoteDisk.diskId().disk()); assertNull(remoteDisk.creationStatus()); assertNull(remoteDisk.creationTimestamp()); - assertNull(remoteDisk.id()); + assertNull(remoteDisk.generatedId()); assertTrue(remoteDisk.configuration() instanceof SnapshotDiskConfiguration); remoteConfiguration = remoteDisk.configuration(); assertEquals(DiskConfiguration.Type.SNAPSHOT, remoteConfiguration.type()); @@ -1121,7 +1121,7 @@ public void testListDisksAndSnapshots() throws InterruptedException { assertTrue(diskSet.contains(remoteDisk.diskId().disk())); assertEquals(DiskInfo.CreationStatus.READY, remoteDisk.creationStatus()); assertNotNull(remoteDisk.creationTimestamp()); - assertNotNull(remoteDisk.id()); + assertNotNull(remoteDisk.generatedId()); assertTrue(remoteDisk.configuration() instanceof StandardDiskConfiguration); StandardDiskConfiguration remoteConfiguration = remoteDisk.configuration(); assertEquals(100L, (long) remoteConfiguration.sizeGb()); @@ -1143,7 +1143,7 @@ public void testListDisksAndSnapshots() throws InterruptedException { assertTrue(diskSet.contains(remoteDisk.diskId().disk())); assertEquals(DiskInfo.CreationStatus.READY, remoteDisk.creationStatus()); assertNull(remoteDisk.creationTimestamp()); - assertNull(remoteDisk.id()); + assertNull(remoteDisk.generatedId()); assertTrue(remoteDisk.configuration() instanceof StandardDiskConfiguration); StandardDiskConfiguration remoteConfiguration = remoteDisk.configuration(); assertNull(remoteConfiguration.sizeGb()); @@ -1174,7 +1174,7 @@ public void testListDisksAndSnapshots() throws InterruptedException { count = 0; while (snapshotIterator.hasNext()) { Snapshot remoteSnapshot = snapshotIterator.next(); - assertNotNull(remoteSnapshot.id()); + assertNotNull(remoteSnapshot.generatedId()); assertTrue(diskSet.contains(remoteSnapshot.snapshotId().snapshot())); assertNotNull(remoteSnapshot.creationTimestamp()); assertNotNull(remoteSnapshot.status()); @@ -1193,7 +1193,7 @@ public void testListDisksAndSnapshots() throws InterruptedException { count = 0; while (snapshotIterator.hasNext()) { Snapshot remoteSnapshot = snapshotIterator.next(); - assertNull(remoteSnapshot.id()); + assertNull(remoteSnapshot.generatedId()); assertTrue(diskSet.contains(remoteSnapshot.snapshotId().snapshot())); assertNotNull(remoteSnapshot.creationTimestamp()); assertNull(remoteSnapshot.status()); @@ -1241,7 +1241,7 @@ public void testAggregatedListDisks() throws InterruptedException { assertTrue(diskSet.contains(remoteDisk.diskId().disk())); assertEquals(DiskInfo.CreationStatus.READY, remoteDisk.creationStatus()); assertNotNull(remoteDisk.creationTimestamp()); - assertNotNull(remoteDisk.id()); + assertNotNull(remoteDisk.generatedId()); assertTrue(remoteDisk.configuration() instanceof StandardDiskConfiguration); StandardDiskConfiguration remoteConfiguration = remoteDisk.configuration(); assertEquals(100L, (long) remoteConfiguration.sizeGb()); @@ -1275,7 +1275,7 @@ public void testCreateGetAndDeprecateImage() throws InterruptedException { // test get image with selected fields Image image = compute.get(imageId, Compute.ImageOption.fields(Compute.ImageField.CREATION_TIMESTAMP)); - assertNull(image.id()); + assertNull(image.generatedId()); assertNotNull(image.imageId()); assertNotNull(image.creationTimestamp()); assertNull(image.description()); @@ -1290,7 +1290,7 @@ public void testCreateGetAndDeprecateImage() throws InterruptedException { assertNull(image.deprecationStatus()); // test get image image = compute.get(imageId); - assertNotNull(image.id()); + assertNotNull(image.generatedId()); assertNotNull(image.imageId()); assertNotNull(image.creationTimestamp()); assertNotNull(image.configuration()); @@ -1328,7 +1328,7 @@ public void testListImages() { while (imageIterator.hasNext()) { count++; Image image = imageIterator.next(); - assertNotNull(image.id()); + assertNotNull(image.generatedId()); assertNotNull(image.imageId()); assertNotNull(image.creationTimestamp()); assertNotNull(image.configuration()); @@ -1347,7 +1347,7 @@ public void testListImagesWithSelectedFields() { while (imageIterator.hasNext()) { count++; Image image = imageIterator.next(); - assertNotNull(image.id()); + assertNotNull(image.generatedId()); assertNotNull(image.imageId()); assertNull(image.creationTimestamp()); assertNotNull(image.configuration()); @@ -1368,7 +1368,7 @@ public void testListImagesWithFilter() { while (imageIterator.hasNext()) { count++; Image image = imageIterator.next(); - assertNotNull(image.id()); + assertNotNull(image.generatedId()); assertNotNull(image.imageId()); assertNotNull(image.creationTimestamp()); assertNotNull(image.configuration()); @@ -1394,7 +1394,7 @@ public void testCreateAndGetNetwork() throws InterruptedException { Network network = compute.getNetwork(networkId.network(), Compute.NetworkOption.fields(Compute.NetworkField.CREATION_TIMESTAMP)); assertEquals(networkId.network(), network.networkId().network()); - assertNull(network.id()); + assertNull(network.generatedId()); assertNotNull(network.creationTimestamp()); assertNull(network.description()); assertEquals(NetworkConfiguration.Type.STANDARD, network.configuration().type()); @@ -1403,7 +1403,7 @@ public void testCreateAndGetNetwork() throws InterruptedException { // test get network network = compute.getNetwork(networkId.network()); assertEquals(networkId.network(), network.networkId().network()); - assertNotNull(network.id()); + assertNotNull(network.generatedId()); assertNotNull(network.creationTimestamp()); assertEquals(NetworkConfiguration.Type.STANDARD, network.configuration().type()); remoteConfiguration = network.configuration(); @@ -1433,7 +1433,7 @@ public void testListNetworks() throws InterruptedException { while (networkIterator.hasNext()) { Network network = networkIterator.next(); assertEquals(networkId.network(), network.networkId().network()); - assertNotNull(network.id()); + assertNotNull(network.generatedId()); assertNotNull(network.creationTimestamp()); assertEquals(NetworkConfiguration.Type.STANDARD, network.configuration().type()); StandardNetworkConfiguration remoteConfiguration = network.configuration(); @@ -1449,7 +1449,7 @@ public void testListNetworks() throws InterruptedException { while (networkIterator.hasNext()) { Network network = networkIterator.next(); assertEquals(networkId.network(), network.networkId().network()); - assertNull(network.id()); + assertNull(network.generatedId()); assertNotNull(network.creationTimestamp()); assertNull(network.description()); assertEquals(NetworkConfiguration.Type.STANDARD, network.configuration().type()); @@ -1477,7 +1477,7 @@ public void testCreateNetworkAndSubnetwork() throws InterruptedException { // test get network Network network = compute.getNetwork(networkId.network()); assertEquals(networkId.network(), network.networkId().network()); - assertNotNull(network.id()); + assertNotNull(network.generatedId()); assertNotNull(network.creationTimestamp()); assertEquals(NetworkConfiguration.Type.SUBNET, network.configuration().type()); assertTrue(network.configuration() instanceof SubnetNetworkConfiguration); @@ -1492,7 +1492,7 @@ public void testCreateNetworkAndSubnetwork() throws InterruptedException { // test get subnetwork with selected fields Subnetwork subnetwork = compute.get(subnetworkId, Compute.SubnetworkOption.fields(Compute.SubnetworkField.CREATION_TIMESTAMP)); - assertNull(subnetwork.id()); + assertNull(subnetwork.generatedId()); assertEquals(subnetworkId.subnetwork(), subnetwork.subnetworkId().subnetwork()); assertNotNull(subnetwork.creationTimestamp()); assertNull(subnetwork.description()); @@ -1501,7 +1501,7 @@ public void testCreateNetworkAndSubnetwork() throws InterruptedException { assertNull(subnetwork.ipRange()); // test get subnetwork subnetwork = compute.get(subnetworkId); - assertNotNull(subnetwork.id()); + assertNotNull(subnetwork.generatedId()); assertEquals(subnetworkId.subnetwork(), subnetwork.subnetworkId().subnetwork()); assertNotNull(subnetwork.creationTimestamp()); assertNotNull(subnetwork.gatewayAddress()); @@ -1516,7 +1516,7 @@ public void testCreateNetworkAndSubnetwork() throws InterruptedException { int count = 0; while (subnetworkIterator.hasNext()) { Subnetwork remoteSubnetwork = subnetworkIterator.next(); - assertNotNull(remoteSubnetwork.id()); + assertNotNull(remoteSubnetwork.generatedId()); assertEquals(subnetworkId.subnetwork(), remoteSubnetwork.subnetworkId().subnetwork()); assertNotNull(remoteSubnetwork.creationTimestamp()); assertNotNull(remoteSubnetwork.gatewayAddress()); @@ -1532,7 +1532,7 @@ public void testCreateNetworkAndSubnetwork() throws InterruptedException { count = 0; while (subnetworkIterator.hasNext()) { Subnetwork remoteSubnetwork = subnetworkIterator.next(); - assertNull(remoteSubnetwork.id()); + assertNull(remoteSubnetwork.generatedId()); assertEquals(subnetworkId.subnetwork(), remoteSubnetwork.subnetworkId().subnetwork()); assertNotNull(remoteSubnetwork.creationTimestamp()); assertNull(remoteSubnetwork.description()); @@ -1592,7 +1592,7 @@ public void testAggregatedListSubnetworks() throws InterruptedException { int count = 0; while (subnetworkIterator.hasNext()) { Subnetwork remoteSubnetwork = subnetworkIterator.next(); - assertNotNull(remoteSubnetwork.id()); + assertNotNull(remoteSubnetwork.generatedId()); assertTrue(regionSet.contains(remoteSubnetwork.subnetworkId().region())); assertTrue(subnetworkSet.contains(remoteSubnetwork.subnetworkId().subnetwork())); assertNotNull(remoteSubnetwork.creationTimestamp()); From 77821f5e7d8216d88fce32bd3de5c12515ec1151 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 28 Apr 2016 17:58:35 +0200 Subject: [PATCH 326/375] Compute: rename get/delete methods to getXxx/deleteXxx (#968) --- .../com/google/gcloud/compute/Address.java | 4 +- .../com/google/gcloud/compute/Compute.java | 24 ++-- .../google/gcloud/compute/ComputeImpl.java | 24 ++-- .../java/com/google/gcloud/compute/Disk.java | 4 +- .../java/com/google/gcloud/compute/Image.java | 4 +- .../com/google/gcloud/compute/Instance.java | 4 +- .../com/google/gcloud/compute/Operation.java | 8 +- .../com/google/gcloud/compute/Subnetwork.java | 4 +- .../google/gcloud/compute/AddressTest.java | 14 +- .../gcloud/compute/ComputeImplTest.java | 102 +++++++------- .../com/google/gcloud/compute/DiskTest.java | 14 +- .../com/google/gcloud/compute/ImageTest.java | 14 +- .../google/gcloud/compute/InstanceTest.java | 14 +- .../google/gcloud/compute/OperationTest.java | 20 +-- .../google/gcloud/compute/SubnetworkTest.java | 14 +- .../gcloud/compute/it/ITComputeTest.java | 124 +++++++++--------- 16 files changed, 197 insertions(+), 195 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java index c76e75f13da3..9eb343cd5e74 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java @@ -134,7 +134,7 @@ public boolean exists() { * @throws ComputeException upon failure */ public Address reload(Compute.AddressOption... options) { - return compute.get(addressId(), options); + return compute.getAddress(addressId(), options); } /** @@ -145,7 +145,7 @@ public Address reload(Compute.AddressOption... options) { * @throws ComputeException upon failure */ public Operation delete(Compute.OperationOption... options) { - return compute.delete(addressId(), options); + return compute.deleteAddress(addressId(), options); } /** diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java index 0512a1554ee0..da25d63a5c2c 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java @@ -2289,7 +2289,7 @@ public static InstanceAggregatedListOption pageToken(String pageToken) { * * @throws ComputeException upon failure */ - Operation get(OperationId operationId, OperationOption... options); + Operation getOperation(OperationId operationId, OperationOption... options); /** * Lists the global operations. @@ -2321,14 +2321,14 @@ public static InstanceAggregatedListOption pageToken(String pageToken) { * @return {@code true} if operation was deleted, {@code false} if it was not found * @throws ComputeException upon failure */ - boolean delete(OperationId operation); + boolean deleteOperation(OperationId operation); /** * Returns the requested address or {@code null} if not found. * * @throws ComputeException upon failure */ - Address get(AddressId addressId, AddressOption... options); + Address getAddress(AddressId addressId, AddressOption... options); /** * Creates a new address. @@ -2366,7 +2366,7 @@ public static InstanceAggregatedListOption pageToken(String pageToken) { * found * @throws ComputeException upon failure */ - Operation delete(AddressId addressId, OperationOption... options); + Operation deleteAddress(AddressId addressId, OperationOption... options); /** * Creates a new snapshot. @@ -2429,7 +2429,7 @@ public static InstanceAggregatedListOption pageToken(String pageToken) { * * @throws ComputeException upon failure */ - Image get(ImageId imageId, ImageOption... options); + Image getImage(ImageId imageId, ImageOption... options); /** * Lists images in the provided project that are available to the current user. This method can be @@ -2457,7 +2457,7 @@ public static InstanceAggregatedListOption pageToken(String pageToken) { * image was not found * @throws ComputeException upon failure or if {@code image} is a publicly-available image */ - Operation delete(ImageId image, OperationOption... options); + Operation deleteImage(ImageId image, OperationOption... options); /** * Deprecates the requested image. @@ -2474,7 +2474,7 @@ Operation deprecate(ImageId image, DeprecationStatus deprecationStatus, * * @throws ComputeException upon failure */ - Disk get(DiskId diskId, DiskOption... options); + Disk getDisk(DiskId diskId, DiskOption... options); /** * Creates a new disk. @@ -2505,7 +2505,7 @@ Operation deprecate(ImageId image, DeprecationStatus deprecationStatus, * found * @throws ComputeException upon failure */ - Operation delete(DiskId disk, OperationOption... options); + Operation deleteDisk(DiskId disk, OperationOption... options); /** * Resizes the disk to the requested size. The new size must be larger than the previous one. @@ -2529,7 +2529,7 @@ Operation deprecate(ImageId image, DeprecationStatus deprecationStatus, * * @throws ComputeException upon failure */ - Subnetwork get(SubnetworkId subnetworkId, SubnetworkOption... options); + Subnetwork getSubnetwork(SubnetworkId subnetworkId, SubnetworkOption... options); /** * Lists subnetworks for the provided region. @@ -2553,7 +2553,7 @@ Operation deprecate(ImageId image, DeprecationStatus deprecationStatus, * subnetwork was not found * @throws ComputeException upon failure */ - Operation delete(SubnetworkId subnetwork, OperationOption... options); + Operation deleteSubnetwork(SubnetworkId subnetwork, OperationOption... options); /** * Creates a new network. @@ -2608,7 +2608,7 @@ Operation deprecate(ImageId image, DeprecationStatus deprecationStatus, * * @throws ComputeException upon failure */ - Instance get(InstanceId instance, InstanceOption... options); + Instance getInstance(InstanceId instance, InstanceOption... options); /** * Lists instances for the provided zone. @@ -2631,7 +2631,7 @@ Operation deprecate(ImageId image, DeprecationStatus deprecationStatus, * instance was not found * @throws ComputeException upon failure */ - Operation delete(InstanceId instance, OperationOption... options); + Operation deleteInstance(InstanceId instance, OperationOption... options); /** * Adds an access configuration to an instance's network interface. diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java index 3a8f46a88265..f70477fea0d7 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java @@ -765,7 +765,7 @@ public com.google.api.services.compute.model.License call() { } @Override - public Operation get(final OperationId operationId, OperationOption... options) { + public Operation getOperation(final OperationId operationId, OperationOption... options) { final Map optionsMap = optionMap(options); try { com.google.api.services.compute.model.Operation answer = @@ -889,7 +889,7 @@ Iterable> call() { } @Override - public boolean delete(final OperationId operation) { + public boolean deleteOperation(final OperationId operation) { try { return runWithRetries(new Callable() { @Override @@ -916,7 +916,7 @@ public Boolean call() { } @Override - public Address get(final AddressId addressId, AddressOption... options) { + public Address getAddress(final AddressId addressId, AddressOption... options) { final Map optionsMap = optionMap(options); try { com.google.api.services.compute.model.Address answer = @@ -1069,7 +1069,7 @@ public Address apply(com.google.api.services.compute.model.Address address) { } @Override - public Operation delete(final AddressId addressId, OperationOption... options) { + public Operation deleteAddress(final AddressId addressId, OperationOption... options) { final Map optionsMap = optionMap(options); try { com.google.api.services.compute.model.Operation answer = @@ -1206,7 +1206,7 @@ public com.google.api.services.compute.model.Operation call() { } @Override - public Image get(ImageId imageId, ImageOption... options) { + public Image getImage(ImageId imageId, ImageOption... options) { final ImageId completeImageId = imageId.setProjectId(options().projectId()); final Map optionsMap = optionMap(options); try { @@ -1264,7 +1264,7 @@ public Image apply(com.google.api.services.compute.model.Image image) { } @Override - public Operation delete(ImageId image, OperationOption... options) { + public Operation deleteImage(ImageId image, OperationOption... options) { final ImageId completeId = image.setProjectId(options().projectId()); final Map optionsMap = optionMap(options); try { @@ -1302,7 +1302,7 @@ public com.google.api.services.compute.model.Operation call() { } @Override - public Disk get(final DiskId diskId, DiskOption... options) { + public Disk getDisk(final DiskId diskId, DiskOption... options) { final Map optionsMap = optionMap(options); try { com.google.api.services.compute.model.Disk answer = @@ -1403,7 +1403,7 @@ Iterable> call() { } @Override - public Operation delete(final DiskId disk, OperationOption... options) { + public Operation deleteDisk(final DiskId disk, OperationOption... options) { final Map optionsMap = optionMap(options); try { com.google.api.services.compute.model.Operation answer = @@ -1455,7 +1455,7 @@ public com.google.api.services.compute.model.Operation call() { } @Override - public Subnetwork get(final SubnetworkId subnetworkId, SubnetworkOption... options) { + public Subnetwork getSubnetwork(final SubnetworkId subnetworkId, SubnetworkOption... options) { final Map optionsMap = optionMap(options); try { com.google.api.services.compute.model.Subnetwork answer = @@ -1539,7 +1539,7 @@ Iterable> call() { } @Override - public Operation delete(final SubnetworkId subnetwork, OperationOption... options) { + public Operation deleteSubnetwork(final SubnetworkId subnetwork, OperationOption... options) { final Map optionsMap = optionMap(options); try { com.google.api.services.compute.model.Operation answer = @@ -1667,7 +1667,7 @@ public com.google.api.services.compute.model.Operation call() { } @Override - public Instance get(final InstanceId instance, InstanceOption... options) { + public Instance getInstance(final InstanceId instance, InstanceOption... options) { final Map optionsMap = optionMap(options); try { com.google.api.services.compute.model.Instance answer = @@ -1750,7 +1750,7 @@ Iterable> call() { } @Override - public Operation delete(final InstanceId instance, OperationOption... options) { + public Operation deleteInstance(final InstanceId instance, OperationOption... options) { final Map optionsMap = optionMap(options); try { com.google.api.services.compute.model.Operation answer = diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Disk.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Disk.java index 9904f49b819e..5b0507afafd7 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Disk.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Disk.java @@ -149,7 +149,7 @@ public boolean exists() { * @throws ComputeException upon failure */ public Disk reload(DiskOption... options) { - return compute.get(diskId(), options); + return compute.getDisk(diskId(), options); } /** @@ -160,7 +160,7 @@ public Disk reload(DiskOption... options) { * @throws ComputeException upon failure */ public Operation delete(OperationOption... options) { - return compute.delete(diskId(), options); + return compute.deleteDisk(diskId(), options); } /** diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Image.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Image.java index a68febb01c7e..66e71fb1c196 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Image.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Image.java @@ -148,7 +148,7 @@ public boolean exists() { * @throws ComputeException upon failure */ public Image reload(ImageOption... options) { - return compute.get(imageId(), options); + return compute.getImage(imageId(), options); } /** @@ -159,7 +159,7 @@ public Image reload(ImageOption... options) { * @throws ComputeException upon failure or if this image is a publicly-available image */ public Operation delete(OperationOption... options) { - return compute.delete(imageId(), options); + return compute.deleteImage(imageId(), options); } /** diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Instance.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Instance.java index 7c84d11d71d7..415b4d1cfa4e 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Instance.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Instance.java @@ -202,7 +202,7 @@ public boolean exists() { * @throws ComputeException upon failure */ public Instance reload(InstanceOption... options) { - return compute.get(instanceId(), options); + return compute.getInstance(instanceId(), options); } /** @@ -213,7 +213,7 @@ public Instance reload(InstanceOption... options) { * @throws ComputeException upon failure */ public Operation delete(OperationOption... options) { - return compute.delete(instanceId(), options); + return compute.deleteInstance(instanceId(), options); } /** diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java index 3e4935dbb859..10f1d968608b 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java @@ -652,8 +652,8 @@ public boolean exists() throws ComputeException { * @throws ComputeException upon failure */ public boolean isDone() throws ComputeException { - Operation operation = - compute.get(operationId, Compute.OperationOption.fields(Compute.OperationField.STATUS)); + Operation operation = compute.getOperation(operationId, + Compute.OperationOption.fields(Compute.OperationField.STATUS)); return operation == null || operation.status() == Status.DONE; } @@ -666,7 +666,7 @@ public boolean isDone() throws ComputeException { * @throws ComputeException upon failure */ public Operation reload(Compute.OperationOption... options) throws ComputeException { - return compute.get(operationId, options); + return compute.getOperation(operationId, options); } /** @@ -677,7 +677,7 @@ public Operation reload(Compute.OperationOption... options) throws ComputeExcept * @throws ComputeException upon failure */ public boolean delete() throws ComputeException { - return compute.delete(operationId); + return compute.deleteOperation(operationId); } @Override diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Subnetwork.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Subnetwork.java index 035af9f829c2..31fc72a0f3de 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Subnetwork.java +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Subnetwork.java @@ -135,7 +135,7 @@ public boolean exists() { * @throws ComputeException upon failure */ public Subnetwork reload(SubnetworkOption... options) { - return compute.get(subnetworkId(), options); + return compute.getSubnetwork(subnetworkId(), options); } /** @@ -146,7 +146,7 @@ public Subnetwork reload(SubnetworkOption... options) { * @throws ComputeException upon failure */ public Operation delete(OperationOption... options) { - return compute.delete(subnetworkId(), options); + return compute.deleteSubnetwork(subnetworkId(), options); } /** diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressTest.java index 2fe9e516f486..e6b7cbee888d 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressTest.java @@ -203,7 +203,7 @@ public void testDeleteOperation() { Operation operation = new Operation.Builder(serviceMockReturnsOptions) .operationId(GlobalOperationId.of("project", "op")) .build(); - expect(compute.delete(REGION_ADDRESS_ID)).andReturn(operation); + expect(compute.deleteAddress(REGION_ADDRESS_ID)).andReturn(operation); replay(compute); initializeAddress(); assertSame(operation, address.delete()); @@ -213,7 +213,7 @@ public void testDeleteOperation() { public void testDeleteNull() { initializeExpectedAddress(3); expect(compute.options()).andReturn(mockOptions); - expect(compute.delete(REGION_ADDRESS_ID)).andReturn(null); + expect(compute.deleteAddress(REGION_ADDRESS_ID)).andReturn(null); replay(compute); initializeAddress(); assertNull(address.delete()); @@ -224,7 +224,7 @@ public void testExists_True() throws Exception { initializeExpectedAddress(3); Compute.AddressOption[] expectedOptions = {Compute.AddressOption.fields()}; expect(compute.options()).andReturn(mockOptions); - expect(compute.get(REGION_ADDRESS_ID, expectedOptions)).andReturn(regionForwardingAddress); + expect(compute.getAddress(REGION_ADDRESS_ID, expectedOptions)).andReturn(regionForwardingAddress); replay(compute); initializeAddress(); assertTrue(address.exists()); @@ -236,7 +236,7 @@ public void testExists_False() throws Exception { initializeExpectedAddress(3); Compute.AddressOption[] expectedOptions = {Compute.AddressOption.fields()}; expect(compute.options()).andReturn(mockOptions); - expect(compute.get(REGION_ADDRESS_ID, expectedOptions)).andReturn(null); + expect(compute.getAddress(REGION_ADDRESS_ID, expectedOptions)).andReturn(null); replay(compute); initializeAddress(); assertFalse(address.exists()); @@ -247,7 +247,7 @@ public void testExists_False() throws Exception { public void testReload() throws Exception { initializeExpectedAddress(5); expect(compute.options()).andReturn(mockOptions); - expect(compute.get(REGION_ADDRESS_ID)).andReturn(regionForwardingAddress); + expect(compute.getAddress(REGION_ADDRESS_ID)).andReturn(regionForwardingAddress); replay(compute); initializeAddress(); Address updatedAddress = address.reload(); @@ -259,7 +259,7 @@ public void testReload() throws Exception { public void testReloadNull() throws Exception { initializeExpectedAddress(3); expect(compute.options()).andReturn(mockOptions); - expect(compute.get(REGION_ADDRESS_ID)).andReturn(null); + expect(compute.getAddress(REGION_ADDRESS_ID)).andReturn(null); replay(compute); initializeAddress(); assertNull(address.reload()); @@ -270,7 +270,7 @@ public void testReloadNull() throws Exception { public void testReloadWithOptions() throws Exception { initializeExpectedAddress(5); expect(compute.options()).andReturn(mockOptions); - expect(compute.get(REGION_ADDRESS_ID, Compute.AddressOption.fields())) + expect(compute.getAddress(REGION_ADDRESS_ID, Compute.AddressOption.fields())) .andReturn(regionForwardingAddress); replay(compute); initializeAddress(); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java index 32cf4bba12d3..07c7b851e0bf 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java @@ -1272,7 +1272,7 @@ public void testGetGlobalOperation() { .andReturn(globalOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - assertEquals(globalOperation, compute.get(GLOBAL_OPERATION_ID)); + assertEquals(globalOperation, compute.getOperation(GLOBAL_OPERATION_ID)); } @Test @@ -1282,7 +1282,7 @@ public void testGetGlobalOperation_Null() { .andReturn(null); EasyMock.replay(computeRpcMock); compute = options.service(); - assertNull(compute.get(GLOBAL_OPERATION_ID)); + assertNull(compute.getOperation(GLOBAL_OPERATION_ID)); } @Test @@ -1293,7 +1293,7 @@ public void testGetGlobalOperationWithSelectedFields() { .andReturn(globalOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Operation operation = compute.get(GLOBAL_OPERATION_ID, OPERATION_OPTION_FIELDS); + Operation operation = compute.getOperation(GLOBAL_OPERATION_ID, OPERATION_OPTION_FIELDS); String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); assertTrue(selector.contains("selfLink")); assertTrue(selector.contains("id")); @@ -1375,7 +1375,7 @@ public void testDeleteGlobalOperation_True() { .andReturn(true); EasyMock.replay(computeRpcMock); compute = options.service(); - assertTrue(compute.delete(GLOBAL_OPERATION_ID)); + assertTrue(compute.deleteOperation(GLOBAL_OPERATION_ID)); } @Test @@ -1384,7 +1384,7 @@ public void testDeleteGlobalOperation_False() { .andReturn(false); EasyMock.replay(computeRpcMock); compute = options.service(); - assertFalse(compute.delete(GLOBAL_OPERATION_ID)); + assertFalse(compute.deleteOperation(GLOBAL_OPERATION_ID)); } @Test @@ -1394,7 +1394,7 @@ public void testGetRegionOperation() { .andReturn(regionOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Operation operation = compute.get(REGION_OPERATION_ID); + Operation operation = compute.getOperation(REGION_OPERATION_ID); assertEquals(regionOperation, operation); } @@ -1405,7 +1405,7 @@ public void testGetRegionOperation_Null() { .andReturn(regionOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Operation operation = compute.get(REGION_OPERATION_ID); + Operation operation = compute.getOperation(REGION_OPERATION_ID); assertEquals(regionOperation, operation); } @@ -1417,7 +1417,7 @@ public void testGetRegionOperationWithSelectedFields() { .andReturn(regionOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Operation operation = compute.get(REGION_OPERATION_ID, OPERATION_OPTION_FIELDS); + Operation operation = compute.getOperation(REGION_OPERATION_ID, OPERATION_OPTION_FIELDS); String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); assertTrue(selector.contains("selfLink")); assertTrue(selector.contains("id")); @@ -1507,7 +1507,7 @@ public void testDeleteRegionOperation_True() { REGION_OPERATION_ID.operation())).andReturn(true); EasyMock.replay(computeRpcMock); compute = options.service(); - assertTrue(compute.delete(REGION_OPERATION_ID)); + assertTrue(compute.deleteOperation(REGION_OPERATION_ID)); } @Test @@ -1516,7 +1516,7 @@ public void testDeleteRegionOperation_False() { REGION_OPERATION_ID.operation())).andReturn(false); EasyMock.replay(computeRpcMock); compute = options.service(); - assertFalse(compute.delete(REGION_OPERATION_ID)); + assertFalse(compute.deleteOperation(REGION_OPERATION_ID)); } @Test @@ -1525,7 +1525,7 @@ public void testGetZoneOperation() { ZONE_OPERATION_ID.operation(), EMPTY_RPC_OPTIONS)).andReturn(zoneOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Operation operation = compute.get(ZONE_OPERATION_ID); + Operation operation = compute.getOperation(ZONE_OPERATION_ID); assertEquals(zoneOperation, operation); } @@ -1535,7 +1535,7 @@ public void testGetZoneOperation_Null() { ZONE_OPERATION_ID.operation(), EMPTY_RPC_OPTIONS)).andReturn(null); EasyMock.replay(computeRpcMock); compute = options.service(); - assertNull(compute.get(ZONE_OPERATION_ID)); + assertNull(compute.getOperation(ZONE_OPERATION_ID)); } @Test @@ -1546,7 +1546,7 @@ public void testGetZoneOperationWithSelectedFields() { .andReturn(zoneOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Operation operation = compute.get(ZONE_OPERATION_ID, OPERATION_OPTION_FIELDS); + Operation operation = compute.getOperation(ZONE_OPERATION_ID, OPERATION_OPTION_FIELDS); String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); assertTrue(selector.contains("selfLink")); assertTrue(selector.contains("id")); @@ -1636,7 +1636,7 @@ public void testDeleteZoneOperation_True() { ZONE_OPERATION_ID.operation())).andReturn(true); EasyMock.replay(computeRpcMock); compute = options.service(); - assertTrue(compute.delete(ZONE_OPERATION_ID)); + assertTrue(compute.deleteOperation(ZONE_OPERATION_ID)); } @Test @@ -1645,7 +1645,7 @@ public void testDeleteZoneOperation_False() { ZONE_OPERATION_ID.operation())).andReturn(false); EasyMock.replay(computeRpcMock); compute = options.service(); - assertFalse(compute.delete(ZONE_OPERATION_ID)); + assertFalse(compute.deleteOperation(ZONE_OPERATION_ID)); } @Test @@ -1654,7 +1654,7 @@ public void testGetGlobalAddress() { .andReturn(GLOBAL_ADDRESS.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Address address = compute.get(GLOBAL_ADDRESS_ID); + Address address = compute.getAddress(GLOBAL_ADDRESS_ID); assertEquals(new Address(compute, new AddressInfo.BuilderImpl(GLOBAL_ADDRESS)), address); } @@ -1664,7 +1664,7 @@ public void testGetGlobalAddress_Null() { .andReturn(null); EasyMock.replay(computeRpcMock); compute = options.service(); - assertNull(compute.get(GLOBAL_ADDRESS_ID)); + assertNull(compute.getAddress(GLOBAL_ADDRESS_ID)); } @Test @@ -1675,7 +1675,7 @@ public void testGetGlobalAddressWithSelectedFields() { .andReturn(GLOBAL_ADDRESS.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Address address = compute.get(GLOBAL_ADDRESS_ID, ADDRESS_OPTION_FIELDS); + Address address = compute.getAddress(GLOBAL_ADDRESS_ID, ADDRESS_OPTION_FIELDS); String selector = (String) capturedOptions.getValue().get(ADDRESS_OPTION_FIELDS.rpcOption()); assertTrue(selector.contains("selfLink")); assertTrue(selector.contains("id")); @@ -1690,7 +1690,7 @@ public void testGetRegionAddress() { REGION_ADDRESS_ID.address(), EMPTY_RPC_OPTIONS)).andReturn(REGION_ADDRESS.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Address address = compute.get(REGION_ADDRESS_ID); + Address address = compute.getAddress(REGION_ADDRESS_ID); assertEquals(new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS)), address); } @@ -1700,7 +1700,7 @@ public void testGetRegionAddress_Null() { REGION_ADDRESS_ID.address(), EMPTY_RPC_OPTIONS)).andReturn(REGION_ADDRESS.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Address address = compute.get(REGION_ADDRESS_ID); + Address address = compute.getAddress(REGION_ADDRESS_ID); assertEquals(new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS)), address); } @@ -1712,7 +1712,7 @@ public void testGetRegionAddressWithSelectedFields() { .andReturn(REGION_ADDRESS.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Address address = compute.get(REGION_ADDRESS_ID, ADDRESS_OPTION_FIELDS); + Address address = compute.getAddress(REGION_ADDRESS_ID, ADDRESS_OPTION_FIELDS); String selector = (String) capturedOptions.getValue().get(ADDRESS_OPTION_FIELDS.rpcOption()); assertTrue(selector.contains("selfLink")); assertTrue(selector.contains("id")); @@ -1728,7 +1728,7 @@ public void testDeleteGlobalAddress_Operation() { .andReturn(globalOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - assertEquals(globalOperation, compute.delete(GLOBAL_ADDRESS_ID)); + assertEquals(globalOperation, compute.deleteAddress(GLOBAL_ADDRESS_ID)); } @Test @@ -1738,7 +1738,7 @@ public void testDeleteGlobalAddressWithSelectedFields_Operation() { capture(capturedOptions))).andReturn(globalOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Operation operation = compute.delete(GLOBAL_ADDRESS_ID, OPERATION_OPTION_FIELDS); + Operation operation = compute.deleteAddress(GLOBAL_ADDRESS_ID, OPERATION_OPTION_FIELDS); String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); assertTrue(selector.contains("selfLink")); assertTrue(selector.contains("id")); @@ -1754,7 +1754,7 @@ public void testDeleteGlobalAddress_Null() { .andReturn(null); EasyMock.replay(computeRpcMock); compute = options.service(); - assertNull(compute.delete(GLOBAL_ADDRESS_ID)); + assertNull(compute.deleteAddress(GLOBAL_ADDRESS_ID)); } @Test @@ -1763,7 +1763,7 @@ public void testDeleteRegionAddress_Operation() { REGION_ADDRESS_ID.address(), EMPTY_RPC_OPTIONS)).andReturn(regionOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - assertEquals(regionOperation, compute.delete(REGION_ADDRESS_ID)); + assertEquals(regionOperation, compute.deleteAddress(REGION_ADDRESS_ID)); } @Test @@ -1774,7 +1774,7 @@ public void testDeleteRegionAddressWithSelectedFields_Operation() { .andReturn(globalOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Operation operation = compute.delete(REGION_ADDRESS_ID, OPERATION_OPTION_FIELDS); + Operation operation = compute.deleteAddress(REGION_ADDRESS_ID, OPERATION_OPTION_FIELDS); String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); assertTrue(selector.contains("selfLink")); assertTrue(selector.contains("id")); @@ -1789,7 +1789,7 @@ public void testDeleteRegionAddress_Null() { REGION_ADDRESS_ID.address(), EMPTY_RPC_OPTIONS)).andReturn(null); EasyMock.replay(computeRpcMock); compute = options.service(); - assertNull(compute.delete(REGION_ADDRESS_ID)); + assertNull(compute.deleteAddress(REGION_ADDRESS_ID)); } @Test @@ -2276,7 +2276,7 @@ public void testGetImage() { .andReturn(IMAGE.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Image image = compute.get(IMAGE_ID); + Image image = compute.getImage(IMAGE_ID); assertEquals(new Image(compute, new ImageInfo.BuilderImpl(IMAGE)), image); } @@ -2287,7 +2287,7 @@ public void testGetImage_Null() { .andReturn(null); EasyMock.replay(computeRpcMock); compute = options.service(); - assertNull(compute.get(IMAGE_ID)); + assertNull(compute.getImage(IMAGE_ID)); } @Test @@ -2297,7 +2297,7 @@ public void testGetImageWithSelectedFields() { capture(capturedOptions))).andReturn(IMAGE.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Image image = compute.get(IMAGE_ID, IMAGE_OPTION_FIELDS); + Image image = compute.getImage(IMAGE_ID, IMAGE_OPTION_FIELDS); String selector = (String) capturedOptions.getValue().get(IMAGE_OPTION_FIELDS.rpcOption()); assertTrue(selector.contains("selfLink")); assertTrue(selector.contains("id")); @@ -2314,7 +2314,7 @@ public void testDeleteImage_Operation() { EMPTY_RPC_OPTIONS)).andReturn(globalOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - assertEquals(globalOperation, compute.delete(IMAGE_ID)); + assertEquals(globalOperation, compute.deleteImage(IMAGE_ID)); } @Test @@ -2324,7 +2324,7 @@ public void testDeleteImageWithSelectedFields_Operation() { capture(capturedOptions))).andReturn(globalOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Operation operation = compute.delete(ImageId.of("image"), OPERATION_OPTION_FIELDS); + Operation operation = compute.deleteImage(ImageId.of("image"), OPERATION_OPTION_FIELDS); String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); assertTrue(selector.contains("selfLink")); assertTrue(selector.contains("id")); @@ -2339,7 +2339,7 @@ public void testDeleteImage_Null() { EMPTY_RPC_OPTIONS)).andReturn(null); EasyMock.replay(computeRpcMock); compute = options.service(); - assertNull(compute.delete(IMAGE_ID)); + assertNull(compute.deleteImage(IMAGE_ID)); } @Test @@ -2501,7 +2501,7 @@ public void testGetDisk() { .andReturn(DISK.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Disk disk = compute.get(DISK_ID); + Disk disk = compute.getDisk(DISK_ID); assertEquals(new Disk(compute, new DiskInfo.BuilderImpl(DISK)), disk); } @@ -2511,7 +2511,7 @@ public void testGetDisk_Null() { .andReturn(null); EasyMock.replay(computeRpcMock); compute = options.service(); - assertNull(compute.get(DISK_ID)); + assertNull(compute.getDisk(DISK_ID)); } @Test @@ -2521,7 +2521,7 @@ public void testGetDiskWithSelectedFields() { capture(capturedOptions))).andReturn(DISK.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Disk disk = compute.get(DISK_ID, DISK_OPTION_FIELDS); + Disk disk = compute.getDisk(DISK_ID, DISK_OPTION_FIELDS); String selector = (String) capturedOptions.getValue().get(DISK_OPTION_FIELDS.rpcOption()); assertTrue(selector.contains("selfLink")); assertTrue(selector.contains("type")); @@ -2539,7 +2539,7 @@ public void testDeleteDisk_Operation() { .andReturn(zoneOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - assertEquals(zoneOperation, compute.delete(DISK_ID)); + assertEquals(zoneOperation, compute.deleteDisk(DISK_ID)); } @Test @@ -2549,7 +2549,7 @@ public void testDeleteDiskWithSelectedFields_Operation() { capture(capturedOptions))).andReturn(zoneOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Operation operation = compute.delete(DISK_ID, OPERATION_OPTION_FIELDS); + Operation operation = compute.deleteDisk(DISK_ID, OPERATION_OPTION_FIELDS); String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); assertTrue(selector.contains("selfLink")); assertTrue(selector.contains("id")); @@ -2564,7 +2564,7 @@ public void testDeleteDisk_Null() { .andReturn(null); EasyMock.replay(computeRpcMock); compute = options.service(); - assertNull(compute.delete(DISK_ID)); + assertNull(compute.deleteDisk(DISK_ID)); } @Test @@ -2786,7 +2786,7 @@ public void testGetSubnetwork() { EMPTY_RPC_OPTIONS)).andReturn(SUBNETWORK.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Subnetwork subnetwork = compute.get(SUBNETWORK_ID); + Subnetwork subnetwork = compute.getSubnetwork(SUBNETWORK_ID); assertEquals(new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK)), subnetwork); } @@ -2796,7 +2796,7 @@ public void testGetSubnetwork_Null() { EMPTY_RPC_OPTIONS)).andReturn(null); EasyMock.replay(computeRpcMock); compute = options.service(); - assertNull(compute.get(SUBNETWORK_ID)); + assertNull(compute.getSubnetwork(SUBNETWORK_ID)); } @Test @@ -2806,7 +2806,7 @@ public void testGetSubnetworkWithSelectedFields() { eq(SUBNETWORK_ID.subnetwork()), capture(capturedOptions))).andReturn(SUBNETWORK.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Subnetwork subnetwork = compute.get(SUBNETWORK_ID, SUBNETWORK_OPTION_FIELDS); + Subnetwork subnetwork = compute.getSubnetwork(SUBNETWORK_ID, SUBNETWORK_OPTION_FIELDS); String selector = (String) capturedOptions.getValue().get(SUBNETWORK_OPTION_FIELDS.rpcOption()); assertTrue(selector.contains("selfLink")); assertTrue(selector.contains("id")); @@ -2821,7 +2821,7 @@ public void testDeleteSubnetwork_Operation() { SUBNETWORK_ID.subnetwork(), EMPTY_RPC_OPTIONS)).andReturn(regionOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - assertEquals(regionOperation, compute.delete(SUBNETWORK_ID)); + assertEquals(regionOperation, compute.deleteSubnetwork(SUBNETWORK_ID)); } @Test @@ -2832,7 +2832,7 @@ public void testDeleteSubnetworkWithSelectedFields_Operation() { .andReturn(regionOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Operation operation = compute.delete(SUBNETWORK_ID, OPERATION_OPTION_FIELDS); + Operation operation = compute.deleteSubnetwork(SUBNETWORK_ID, OPERATION_OPTION_FIELDS); String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); assertTrue(selector.contains("selfLink")); assertTrue(selector.contains("id")); @@ -2847,7 +2847,7 @@ public void testDeleteSubnetwork_Null() { SUBNETWORK_ID.subnetwork(), EMPTY_RPC_OPTIONS)).andReturn(null); EasyMock.replay(computeRpcMock); compute = options.service(); - assertNull(compute.delete(SUBNETWORK_ID)); + assertNull(compute.deleteSubnetwork(SUBNETWORK_ID)); } @Test @@ -3213,7 +3213,7 @@ public void testGetInstance() { EMPTY_RPC_OPTIONS)).andReturn(INSTANCE.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Instance instance = compute.get(INSTANCE_ID); + Instance instance = compute.getInstance(INSTANCE_ID); assertEquals(new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE)), instance); } @@ -3223,7 +3223,7 @@ public void testGetInstance_Null() { EMPTY_RPC_OPTIONS)).andReturn(null); EasyMock.replay(computeRpcMock); compute = options.service(); - assertNull(compute.get(INSTANCE_ID)); + assertNull(compute.getInstance(INSTANCE_ID)); } @Test @@ -3233,7 +3233,7 @@ public void testGetInstanceWithSelectedFields() { capture(capturedOptions))).andReturn(INSTANCE.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Instance instance = compute.get(INSTANCE_ID, INSTANCE_OPTION_FIELDS); + Instance instance = compute.getInstance(INSTANCE_ID, INSTANCE_OPTION_FIELDS); String selector = (String) capturedOptions.getValue().get(INSTANCE_OPTION_FIELDS.rpcOption()); assertTrue(selector.contains("selfLink")); assertTrue(selector.contains("id")); @@ -3248,7 +3248,7 @@ public void testDeleteInstance_Operation() { EMPTY_RPC_OPTIONS)).andReturn(zoneOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - assertEquals(zoneOperation, compute.delete(INSTANCE_ID)); + assertEquals(zoneOperation, compute.deleteInstance(INSTANCE_ID)); } @Test @@ -3258,7 +3258,7 @@ public void testDeleteInstanceWithSelectedFields_Operation() { eq(INSTANCE_ID.instance()), capture(capturedOptions))).andReturn(zoneOperation.toPb()); EasyMock.replay(computeRpcMock); compute = options.service(); - Operation operation = compute.delete(INSTANCE_ID, OPERATION_OPTION_FIELDS); + Operation operation = compute.deleteInstance(INSTANCE_ID, OPERATION_OPTION_FIELDS); String selector = (String) capturedOptions.getValue().get(OPERATION_OPTION_FIELDS.rpcOption()); assertTrue(selector.contains("selfLink")); assertTrue(selector.contains("id")); @@ -3273,7 +3273,7 @@ public void testDeleteInstance_Null() { EMPTY_RPC_OPTIONS)).andReturn(null); EasyMock.replay(computeRpcMock); compute = options.service(); - assertNull(compute.delete(INSTANCE_ID)); + assertNull(compute.deleteInstance(INSTANCE_ID)); } @Test diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTest.java index 8b54a1ea2715..db50d8a22cd6 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTest.java @@ -228,7 +228,7 @@ public void testDeleteOperation() { Operation operation = new Operation.Builder(serviceMockReturnsOptions) .operationId(ZoneOperationId.of("project", "zone", "op")) .build(); - expect(compute.delete(DISK_ID)).andReturn(operation); + expect(compute.deleteDisk(DISK_ID)).andReturn(operation); replay(compute); initializeDisk(); assertSame(operation, disk.delete()); @@ -238,7 +238,7 @@ public void testDeleteOperation() { public void testDeleteNull() { initializeExpectedDisk(3); expect(compute.options()).andReturn(mockOptions); - expect(compute.delete(DISK_ID)).andReturn(null); + expect(compute.deleteDisk(DISK_ID)).andReturn(null); replay(compute); initializeDisk(); assertNull(disk.delete()); @@ -249,7 +249,7 @@ public void testExists_True() throws Exception { initializeExpectedDisk(3); Compute.DiskOption[] expectedOptions = {Compute.DiskOption.fields()}; expect(compute.options()).andReturn(mockOptions); - expect(compute.get(DISK_ID, expectedOptions)).andReturn(imageDisk); + expect(compute.getDisk(DISK_ID, expectedOptions)).andReturn(imageDisk); replay(compute); initializeDisk(); assertTrue(disk.exists()); @@ -261,7 +261,7 @@ public void testExists_False() throws Exception { initializeExpectedDisk(3); Compute.DiskOption[] expectedOptions = {Compute.DiskOption.fields()}; expect(compute.options()).andReturn(mockOptions); - expect(compute.get(DISK_ID, expectedOptions)).andReturn(null); + expect(compute.getDisk(DISK_ID, expectedOptions)).andReturn(null); replay(compute); initializeDisk(); assertFalse(disk.exists()); @@ -272,7 +272,7 @@ public void testExists_False() throws Exception { public void testReload() throws Exception { initializeExpectedDisk(5); expect(compute.options()).andReturn(mockOptions); - expect(compute.get(DISK_ID)).andReturn(imageDisk); + expect(compute.getDisk(DISK_ID)).andReturn(imageDisk); replay(compute); initializeDisk(); Disk updatedDisk = disk.reload(); @@ -284,7 +284,7 @@ public void testReload() throws Exception { public void testReloadNull() throws Exception { initializeExpectedDisk(3); expect(compute.options()).andReturn(mockOptions); - expect(compute.get(DISK_ID)).andReturn(null); + expect(compute.getDisk(DISK_ID)).andReturn(null); replay(compute); initializeDisk(); assertNull(disk.reload()); @@ -295,7 +295,7 @@ public void testReloadNull() throws Exception { public void testReloadWithOptions() throws Exception { initializeExpectedDisk(5); expect(compute.options()).andReturn(mockOptions); - expect(compute.get(DISK_ID, Compute.DiskOption.fields())).andReturn(imageDisk); + expect(compute.getDisk(DISK_ID, Compute.DiskOption.fields())).andReturn(imageDisk); replay(compute); initializeDisk(); Disk updatedDisk = disk.reload(Compute.DiskOption.fields()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageTest.java index 43e27d011974..1512bdcb30b1 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageTest.java @@ -189,7 +189,7 @@ public void testDeleteOperation() { Operation operation = new Operation.Builder(serviceMockReturnsOptions) .operationId(GlobalOperationId.of("project", "op")) .build(); - expect(compute.delete(IMAGE_ID)).andReturn(operation); + expect(compute.deleteImage(IMAGE_ID)).andReturn(operation); replay(compute); initializeImage(); assertSame(operation, image.delete()); @@ -199,7 +199,7 @@ public void testDeleteOperation() { public void testDeleteNull() { initializeExpectedImage(2); expect(compute.options()).andReturn(mockOptions); - expect(compute.delete(IMAGE_ID)).andReturn(null); + expect(compute.deleteImage(IMAGE_ID)).andReturn(null); replay(compute); initializeImage(); assertNull(image.delete()); @@ -210,7 +210,7 @@ public void testExists_True() throws Exception { initializeExpectedImage(2); Compute.ImageOption[] expectedOptions = {Compute.ImageOption.fields()}; expect(compute.options()).andReturn(mockOptions); - expect(compute.get(IMAGE_ID, expectedOptions)).andReturn(diskImage); + expect(compute.getImage(IMAGE_ID, expectedOptions)).andReturn(diskImage); replay(compute); initializeImage(); assertTrue(image.exists()); @@ -222,7 +222,7 @@ public void testExists_False() throws Exception { initializeExpectedImage(2); Compute.ImageOption[] expectedOptions = {Compute.ImageOption.fields()}; expect(compute.options()).andReturn(mockOptions); - expect(compute.get(IMAGE_ID, expectedOptions)).andReturn(null); + expect(compute.getImage(IMAGE_ID, expectedOptions)).andReturn(null); replay(compute); initializeImage(); assertFalse(image.exists()); @@ -233,7 +233,7 @@ public void testExists_False() throws Exception { public void testReload() throws Exception { initializeExpectedImage(5); expect(compute.options()).andReturn(mockOptions); - expect(compute.get(IMAGE_ID)).andReturn(storageImage); + expect(compute.getImage(IMAGE_ID)).andReturn(storageImage); replay(compute); initializeImage(); Image updateImage = image.reload(); @@ -245,7 +245,7 @@ public void testReload() throws Exception { public void testReloadNull() throws Exception { initializeExpectedImage(2); expect(compute.options()).andReturn(mockOptions); - expect(compute.get(IMAGE_ID)).andReturn(null); + expect(compute.getImage(IMAGE_ID)).andReturn(null); replay(compute); initializeImage(); assertNull(image.reload()); @@ -256,7 +256,7 @@ public void testReloadNull() throws Exception { public void testReloadWithOptions() throws Exception { initializeExpectedImage(5); expect(compute.options()).andReturn(mockOptions); - expect(compute.get(IMAGE_ID, Compute.ImageOption.fields())).andReturn(storageImage); + expect(compute.getImage(IMAGE_ID, Compute.ImageOption.fields())).andReturn(storageImage); replay(compute); initializeImage(); Image updateImage = image.reload(Compute.ImageOption.fields()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceTest.java index 85e2ff5311c0..44f726f4165b 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceTest.java @@ -195,7 +195,7 @@ public void testDeleteOperation() { Operation operation = new Operation.Builder(serviceMockReturnsOptions) .operationId(ZoneOperationId.of("project", "op")) .build(); - expect(compute.delete(INSTANCE_ID)).andReturn(operation); + expect(compute.deleteInstance(INSTANCE_ID)).andReturn(operation); replay(compute); initializeInstance(); assertSame(operation, instance.delete()); @@ -205,7 +205,7 @@ public void testDeleteOperation() { public void testDeleteNull() { initializeExpectedInstance(1); expect(compute.options()).andReturn(mockOptions); - expect(compute.delete(INSTANCE_ID)).andReturn(null); + expect(compute.deleteInstance(INSTANCE_ID)).andReturn(null); replay(compute); initializeInstance(); assertNull(instance.delete()); @@ -216,7 +216,7 @@ public void testExists_True() throws Exception { initializeExpectedInstance(1); InstanceOption[] expectedOptions = {InstanceOption.fields()}; expect(compute.options()).andReturn(mockOptions); - expect(compute.get(INSTANCE_ID, expectedOptions)).andReturn(expectedInstance); + expect(compute.getInstance(INSTANCE_ID, expectedOptions)).andReturn(expectedInstance); replay(compute); initializeInstance(); assertTrue(instance.exists()); @@ -228,7 +228,7 @@ public void testExists_False() throws Exception { initializeExpectedInstance(1); InstanceOption[] expectedOptions = {InstanceOption.fields()}; expect(compute.options()).andReturn(mockOptions); - expect(compute.get(INSTANCE_ID, expectedOptions)).andReturn(null); + expect(compute.getInstance(INSTANCE_ID, expectedOptions)).andReturn(null); replay(compute); initializeInstance(); assertFalse(instance.exists()); @@ -239,7 +239,7 @@ public void testExists_False() throws Exception { public void testReload() throws Exception { initializeExpectedInstance(3); expect(compute.options()).andReturn(mockOptions); - expect(compute.get(INSTANCE_ID)).andReturn(expectedInstance); + expect(compute.getInstance(INSTANCE_ID)).andReturn(expectedInstance); replay(compute); initializeInstance(); Instance updatedInstance = instance.reload(); @@ -251,7 +251,7 @@ public void testReload() throws Exception { public void testReloadNull() throws Exception { initializeExpectedInstance(1); expect(compute.options()).andReturn(mockOptions); - expect(compute.get(INSTANCE_ID)).andReturn(null); + expect(compute.getInstance(INSTANCE_ID)).andReturn(null); replay(compute); initializeInstance(); assertNull(instance.reload()); @@ -262,7 +262,7 @@ public void testReloadNull() throws Exception { public void testReloadWithOptions() throws Exception { initializeExpectedInstance(3); expect(compute.options()).andReturn(mockOptions); - expect(compute.get(INSTANCE_ID, InstanceOption.fields())).andReturn(expectedInstance); + expect(compute.getInstance(INSTANCE_ID, InstanceOption.fields())).andReturn(expectedInstance); replay(compute); initializeInstance(); Instance updateInstance = instance.reload(InstanceOption.fields()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java index e13f77c551ad..05cba345d171 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java @@ -274,7 +274,7 @@ public void testToAndFromPb() { public void testDeleteTrue() { initializeExpectedOperation(3); expect(compute.options()).andReturn(mockOptions); - expect(compute.delete(GLOBAL_OPERATION_ID)).andReturn(true); + expect(compute.deleteOperation(GLOBAL_OPERATION_ID)).andReturn(true); replay(compute); initializeOperation(); assertTrue(operation.delete()); @@ -285,7 +285,7 @@ public void testDeleteTrue() { public void testDeleteFalse() { initializeExpectedOperation(3); expect(compute.options()).andReturn(mockOptions); - expect(compute.delete(GLOBAL_OPERATION_ID)).andReturn(false); + expect(compute.deleteOperation(GLOBAL_OPERATION_ID)).andReturn(false); replay(compute); initializeOperation(); assertFalse(operation.delete()); @@ -297,7 +297,7 @@ public void testExists_True() throws Exception { initializeExpectedOperation(3); Compute.OperationOption[] expectedOptions = {Compute.OperationOption.fields()}; expect(compute.options()).andReturn(mockOptions); - expect(compute.get(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(globalOperation); + expect(compute.getOperation(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(globalOperation); replay(compute); initializeOperation(); assertTrue(operation.exists()); @@ -309,7 +309,7 @@ public void testExists_False() throws Exception { initializeExpectedOperation(3); Compute.OperationOption[] expectedOptions = {Compute.OperationOption.fields()}; expect(compute.options()).andReturn(mockOptions); - expect(compute.get(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(null); + expect(compute.getOperation(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(null); replay(compute); initializeOperation(); assertFalse(operation.exists()); @@ -322,7 +322,7 @@ public void testIsDone_True() throws Exception { Compute.OperationOption[] expectedOptions = {Compute.OperationOption.fields(Compute.OperationField.STATUS)}; expect(compute.options()).andReturn(mockOptions); - expect(compute.get(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(globalOperation); + expect(compute.getOperation(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(globalOperation); replay(compute); initializeOperation(); assertTrue(operation.isDone()); @@ -335,7 +335,7 @@ public void testIsDone_False() throws Exception { Compute.OperationOption[] expectedOptions = {Compute.OperationOption.fields(Compute.OperationField.STATUS)}; expect(compute.options()).andReturn(mockOptions); - expect(compute.get(GLOBAL_OPERATION_ID, expectedOptions)).andReturn( + expect(compute.getOperation(GLOBAL_OPERATION_ID, expectedOptions)).andReturn( Operation.fromPb(serviceMockReturnsOptions, globalOperation.toPb().setStatus("PENDING"))); replay(compute); initializeOperation(); @@ -348,7 +348,7 @@ public void testIsDone_NotExists() throws Exception { Compute.OperationOption[] expectedOptions = {Compute.OperationOption.fields(Compute.OperationField.STATUS)}; expect(compute.options()).andReturn(mockOptions); - expect(compute.get(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(null); + expect(compute.getOperation(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(null); replay(compute); initializeOperation(); assertTrue(operation.isDone()); @@ -359,7 +359,7 @@ public void testIsDone_NotExists() throws Exception { public void testReload() throws Exception { initializeExpectedOperation(5); expect(compute.options()).andReturn(mockOptions); - expect(compute.get(GLOBAL_OPERATION_ID)).andReturn(globalOperation); + expect(compute.getOperation(GLOBAL_OPERATION_ID)).andReturn(globalOperation); replay(compute); initializeOperation(); Operation updatedOperation = operation.reload(); @@ -371,7 +371,7 @@ public void testReload() throws Exception { public void testReloadNull() throws Exception { initializeExpectedOperation(3); expect(compute.options()).andReturn(mockOptions); - expect(compute.get(GLOBAL_OPERATION_ID)).andReturn(null); + expect(compute.getOperation(GLOBAL_OPERATION_ID)).andReturn(null); replay(compute); initializeOperation(); assertNull(operation.reload()); @@ -382,7 +382,7 @@ public void testReloadNull() throws Exception { public void testReloadWithOptions() throws Exception { initializeExpectedOperation(5); expect(compute.options()).andReturn(mockOptions); - expect(compute.get(GLOBAL_OPERATION_ID, Compute.OperationOption.fields())) + expect(compute.getOperation(GLOBAL_OPERATION_ID, Compute.OperationOption.fields())) .andReturn(globalOperation); replay(compute); initializeOperation(); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkTest.java index 8fc841383f1e..e394e0daf737 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkTest.java @@ -118,7 +118,7 @@ public void testDeleteOperation() { Operation operation = new Operation.Builder(serviceMockReturnsOptions) .operationId(GlobalOperationId.of("project", "op")) .build(); - expect(compute.delete(SUBNETWORK_ID)).andReturn(operation); + expect(compute.deleteSubnetwork(SUBNETWORK_ID)).andReturn(operation); replay(compute); initializeSubnetwork(); assertSame(operation, subnetwork.delete()); @@ -128,7 +128,7 @@ public void testDeleteOperation() { public void testDeleteNull() { initializeExpectedSubnetwork(1); expect(compute.options()).andReturn(mockOptions); - expect(compute.delete(SUBNETWORK_ID)).andReturn(null); + expect(compute.deleteSubnetwork(SUBNETWORK_ID)).andReturn(null); replay(compute); initializeSubnetwork(); assertNull(subnetwork.delete()); @@ -139,7 +139,7 @@ public void testExists_True() throws Exception { initializeExpectedSubnetwork(1); Compute.SubnetworkOption[] expectedOptions = {Compute.SubnetworkOption.fields()}; expect(compute.options()).andReturn(mockOptions); - expect(compute.get(SUBNETWORK_ID, expectedOptions)) + expect(compute.getSubnetwork(SUBNETWORK_ID, expectedOptions)) .andReturn(expectedSubnetwork); replay(compute); initializeSubnetwork(); @@ -152,7 +152,7 @@ public void testExists_False() throws Exception { initializeExpectedSubnetwork(1); Compute.SubnetworkOption[] expectedOptions = {Compute.SubnetworkOption.fields()}; expect(compute.options()).andReturn(mockOptions); - expect(compute.get(SUBNETWORK_ID, expectedOptions)).andReturn(null); + expect(compute.getSubnetwork(SUBNETWORK_ID, expectedOptions)).andReturn(null); replay(compute); initializeSubnetwork(); assertFalse(subnetwork.exists()); @@ -163,7 +163,7 @@ public void testExists_False() throws Exception { public void testReload() throws Exception { initializeExpectedSubnetwork(3); expect(compute.options()).andReturn(mockOptions); - expect(compute.get(SUBNETWORK_ID)).andReturn(expectedSubnetwork); + expect(compute.getSubnetwork(SUBNETWORK_ID)).andReturn(expectedSubnetwork); replay(compute); initializeSubnetwork(); Subnetwork updatedSubnetwork = subnetwork.reload(); @@ -175,7 +175,7 @@ public void testReload() throws Exception { public void testReloadNull() throws Exception { initializeExpectedSubnetwork(1); expect(compute.options()).andReturn(mockOptions); - expect(compute.get(SUBNETWORK_ID)).andReturn(null); + expect(compute.getSubnetwork(SUBNETWORK_ID)).andReturn(null); replay(compute); initializeSubnetwork(); assertNull(subnetwork.reload()); @@ -186,7 +186,7 @@ public void testReloadNull() throws Exception { public void testReloadWithOptions() throws Exception { initializeExpectedSubnetwork(3); expect(compute.options()).andReturn(mockOptions); - expect(compute.get(SUBNETWORK_ID, Compute.SubnetworkOption.fields())) + expect(compute.getSubnetwork(SUBNETWORK_ID, Compute.SubnetworkOption.fields())) .andReturn(expectedSubnetwork); replay(compute); initializeSubnetwork(); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java index a46d47d2040d..edd469b8969a 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java @@ -695,7 +695,7 @@ public void testCreateGetAndDeleteRegionAddress() throws InterruptedException { Thread.sleep(1000L); } // test get - Address remoteAddress = compute.get(addressId); + Address remoteAddress = compute.getAddress(addressId); assertNotNull(remoteAddress); assertTrue(remoteAddress.addressId() instanceof RegionAddressId); assertEquals(REGION, remoteAddress.addressId().region()); @@ -705,7 +705,7 @@ public void testCreateGetAndDeleteRegionAddress() throws InterruptedException { assertNotNull(remoteAddress.generatedId()); assertNotNull(remoteAddress.status()); // test get with selected fields - remoteAddress = compute.get(addressId, Compute.AddressOption.fields()); + remoteAddress = compute.getAddress(addressId, Compute.AddressOption.fields()); assertNotNull(remoteAddress); assertTrue(remoteAddress.addressId() instanceof RegionAddressId); assertEquals(REGION, remoteAddress.addressId().region()); @@ -717,7 +717,7 @@ public void testCreateGetAndDeleteRegionAddress() throws InterruptedException { while (!operation.isDone()) { Thread.sleep(1000L); } - assertNull(compute.get(addressId)); + assertNull(compute.getAddress(addressId)); } @Test @@ -772,8 +772,8 @@ public void testListRegionAddresses() throws InterruptedException { count++; } assertEquals(2, count); - compute.delete(firstAddressId); - compute.delete(secondAddressId); + compute.deleteAddress(firstAddressId); + compute.deleteAddress(secondAddressId); } @Test @@ -807,8 +807,8 @@ public void testAggregatedListAddresses() throws InterruptedException { count++; } assertEquals(2, count); - compute.delete(firstAddressId); - compute.delete(secondAddressId); + compute.deleteAddress(firstAddressId); + compute.deleteAddress(secondAddressId); } @Test @@ -821,7 +821,7 @@ public void testCreateGetAndDeleteGlobalAddress() throws InterruptedException { Thread.sleep(1000L); } // test get - Address remoteAddress = compute.get(addressId); + Address remoteAddress = compute.getAddress(addressId); assertNotNull(remoteAddress); assertTrue(remoteAddress.addressId() instanceof GlobalAddressId); assertEquals(addressId.address(), remoteAddress.addressId().address()); @@ -830,7 +830,7 @@ public void testCreateGetAndDeleteGlobalAddress() throws InterruptedException { assertNotNull(remoteAddress.generatedId()); assertNotNull(remoteAddress.status()); // test get with selected fields - remoteAddress = compute.get(addressId, Compute.AddressOption.fields()); + remoteAddress = compute.getAddress(addressId, Compute.AddressOption.fields()); assertNotNull(remoteAddress); assertTrue(remoteAddress.addressId() instanceof GlobalAddressId); assertEquals(addressId.address(), remoteAddress.addressId().address()); @@ -841,7 +841,7 @@ public void testCreateGetAndDeleteGlobalAddress() throws InterruptedException { while (!operation.isDone()) { Thread.sleep(1000L); } - assertNull(compute.get(addressId)); + assertNull(compute.getAddress(addressId)); } @Test @@ -894,8 +894,8 @@ public void testListGlobalAddresses() throws InterruptedException { count++; } assertEquals(2, count); - compute.delete(firstAddressId); - compute.delete(secondAddressId); + compute.deleteAddress(firstAddressId); + compute.deleteAddress(secondAddressId); } @Test @@ -909,7 +909,7 @@ public void testCreateGetResizeAndDeleteStandardDisk() throws InterruptedExcepti Thread.sleep(1000L); } // test get - Disk remoteDisk = compute.get(diskId); + Disk remoteDisk = compute.getDisk(diskId); assertNotNull(remoteDisk); assertEquals(ZONE, remoteDisk.diskId().zone()); assertEquals(diskId.disk(), remoteDisk.diskId().disk()); @@ -927,7 +927,7 @@ public void testCreateGetResizeAndDeleteStandardDisk() throws InterruptedExcepti Thread.sleep(1000L); } // test resize and get with selected fields - remoteDisk = compute.get(diskId, Compute.DiskOption.fields(Compute.DiskField.SIZE_GB)); + remoteDisk = compute.getDisk(diskId, Compute.DiskOption.fields(Compute.DiskField.SIZE_GB)); assertNotNull(remoteDisk); assertEquals(ZONE, remoteDisk.diskId().zone()); assertEquals(diskId.disk(), remoteDisk.diskId().disk()); @@ -944,7 +944,7 @@ public void testCreateGetResizeAndDeleteStandardDisk() throws InterruptedExcepti while (!operation.isDone()) { Thread.sleep(1000L); } - assertNull(compute.get(diskId)); + assertNull(compute.getDisk(diskId)); } @Test @@ -957,7 +957,7 @@ public void testCreateGetAndDeleteImageDisk() throws InterruptedException { Thread.sleep(1000L); } // test get - Disk remoteDisk = compute.get(diskId); + Disk remoteDisk = compute.getDisk(diskId); assertNotNull(remoteDisk); assertEquals(ZONE, remoteDisk.diskId().zone()); assertEquals(diskId.disk(), remoteDisk.diskId().disk()); @@ -974,7 +974,7 @@ public void testCreateGetAndDeleteImageDisk() throws InterruptedException { assertNull(remoteDisk.lastAttachTimestamp()); assertNull(remoteDisk.lastDetachTimestamp()); // test get with selected fields - remoteDisk = compute.get(diskId, Compute.DiskOption.fields()); + remoteDisk = compute.getDisk(diskId, Compute.DiskOption.fields()); assertNotNull(remoteDisk); assertEquals(ZONE, remoteDisk.diskId().zone()); assertEquals(diskId.disk(), remoteDisk.diskId().disk()); @@ -993,7 +993,7 @@ public void testCreateGetAndDeleteImageDisk() throws InterruptedException { while (!operation.isDone()) { Thread.sleep(1000L); } - assertNull(compute.get(diskId)); + assertNull(compute.getDisk(diskId)); } @Test @@ -1009,7 +1009,7 @@ public void testCreateGetAndDeleteSnapshotAndSnapshotDisk() throws InterruptedEx while (!operation.isDone()) { Thread.sleep(1000L); } - Disk remoteDisk = compute.get(diskId); + Disk remoteDisk = compute.getDisk(diskId); operation = remoteDisk.createSnapshot(snapshotName); while (!operation.isDone()) { Thread.sleep(1000L); @@ -1047,7 +1047,7 @@ public void testCreateGetAndDeleteSnapshotAndSnapshotDisk() throws InterruptedEx Thread.sleep(1000L); } // test get disk - remoteDisk = compute.get(snapshotDiskId); + remoteDisk = compute.getDisk(snapshotDiskId); assertNotNull(remoteDisk); assertEquals(ZONE, remoteDisk.diskId().zone()); assertEquals(snapshotDiskId.disk(), remoteDisk.diskId().disk()); @@ -1064,7 +1064,7 @@ public void testCreateGetAndDeleteSnapshotAndSnapshotDisk() throws InterruptedEx assertNull(remoteDisk.lastAttachTimestamp()); assertNull(remoteDisk.lastDetachTimestamp()); // test get disk with selected fields - remoteDisk = compute.get(snapshotDiskId, Compute.DiskOption.fields()); + remoteDisk = compute.getDisk(snapshotDiskId, Compute.DiskOption.fields()); assertNotNull(remoteDisk); assertEquals(ZONE, remoteDisk.diskId().zone()); assertEquals(snapshotDiskId.disk(), remoteDisk.diskId().disk()); @@ -1084,7 +1084,7 @@ public void testCreateGetAndDeleteSnapshotAndSnapshotDisk() throws InterruptedEx while (!operation.isDone()) { Thread.sleep(1000L); } - assertNull(compute.get(snapshotDiskId)); + assertNull(compute.getDisk(snapshotDiskId)); operation = snapshot.delete(); while (!operation.isDone()) { Thread.sleep(1000L); @@ -1205,8 +1205,8 @@ public void testListDisksAndSnapshots() throws InterruptedException { count++; } assertEquals(2, count); - compute.delete(firstDiskId); - compute.delete(secondDiskId); + compute.deleteDisk(firstDiskId); + compute.deleteDisk(secondDiskId); compute.deleteSnapshot(firstSnapshotId); compute.deleteSnapshot(secondSnapshotId); } @@ -1250,8 +1250,8 @@ public void testAggregatedListDisks() throws InterruptedException { count++; } assertEquals(2, count); - compute.delete(firstDiskId); - compute.delete(secondDiskId); + compute.deleteDisk(firstDiskId); + compute.deleteDisk(secondDiskId); } @Test @@ -1266,14 +1266,14 @@ public void testCreateGetAndDeprecateImage() throws InterruptedException { while (!operation.isDone()) { Thread.sleep(1000L); } - Disk remoteDisk = compute.get(diskId); + Disk remoteDisk = compute.getDisk(diskId); ImageInfo imageInfo = ImageInfo.of(imageId, DiskImageConfiguration.of(diskId)); operation = compute.create(imageInfo); while (!operation.isDone()) { Thread.sleep(1000L); } // test get image with selected fields - Image image = compute.get(imageId, + Image image = compute.getImage(imageId, Compute.ImageOption.fields(Compute.ImageField.CREATION_TIMESTAMP)); assertNull(image.generatedId()); assertNotNull(image.imageId()); @@ -1289,7 +1289,7 @@ public void testCreateGetAndDeprecateImage() throws InterruptedException { assertNull(image.licenses()); assertNull(image.deprecationStatus()); // test get image - image = compute.get(imageId); + image = compute.getImage(imageId); assertNotNull(image.generatedId()); assertNotNull(image.imageId()); assertNotNull(image.creationTimestamp()); @@ -1310,14 +1310,14 @@ public void testCreateGetAndDeprecateImage() throws InterruptedException { while (!operation.isDone()) { Thread.sleep(1000L); } - image = compute.get(imageId); + image = compute.getImage(imageId); assertEquals(deprecationStatus, image.deprecationStatus()); remoteDisk.delete(); operation = image.delete(); while (!operation.isDone()) { Thread.sleep(1000L); } - assertNull(compute.get(imageId)); + assertNull(compute.getImage(imageId)); } @Test @@ -1490,7 +1490,7 @@ public void testCreateNetworkAndSubnetwork() throws InterruptedException { Thread.sleep(1000L); } // test get subnetwork with selected fields - Subnetwork subnetwork = compute.get(subnetworkId, + Subnetwork subnetwork = compute.getSubnetwork(subnetworkId, Compute.SubnetworkOption.fields(Compute.SubnetworkField.CREATION_TIMESTAMP)); assertNull(subnetwork.generatedId()); assertEquals(subnetworkId.subnetwork(), subnetwork.subnetworkId().subnetwork()); @@ -1500,7 +1500,7 @@ public void testCreateNetworkAndSubnetwork() throws InterruptedException { assertNull(subnetwork.network()); assertNull(subnetwork.ipRange()); // test get subnetwork - subnetwork = compute.get(subnetworkId); + subnetwork = compute.getSubnetwork(subnetworkId); assertNotNull(subnetwork.generatedId()); assertEquals(subnetworkId.subnetwork(), subnetwork.subnetworkId().subnetwork()); assertNotNull(subnetwork.creationTimestamp()); @@ -1550,7 +1550,7 @@ public void testCreateNetworkAndSubnetwork() throws InterruptedException { while (!operation.isDone()) { Thread.sleep(1000L); } - assertNull(compute.get(subnetworkId)); + assertNull(compute.getSubnetwork(subnetworkId)); assertNull(compute.getNetwork(networkName)); } @@ -1602,8 +1602,8 @@ public void testAggregatedListSubnetworks() throws InterruptedException { count++; } assertEquals(2, count); - firstOperation = compute.delete(firstSubnetworkId); - secondOperation = compute.delete(secondSubnetworkId); + firstOperation = compute.deleteSubnetwork(firstSubnetworkId); + secondOperation = compute.deleteSubnetwork(secondSubnetworkId); while (!firstOperation.isDone()) { Thread.sleep(1000L); } @@ -1628,7 +1628,7 @@ public void testCreateGetAndDeleteInstance() throws InterruptedException { while (!operation.isDone()) { Thread.sleep(1000L); } - Address address = compute.get(addressId); + Address address = compute.getAddress(addressId); // Create an instance InstanceId instanceId = InstanceId.of(ZONE, instanceName); NetworkId networkId = NetworkId.of("default"); @@ -1649,7 +1649,7 @@ public void testCreateGetAndDeleteInstance() throws InterruptedException { Thread.sleep(1000L); } // test get - Instance remoteInstance = compute.get(instanceId); + Instance remoteInstance = compute.getInstance(instanceId); assertEquals(instanceName, remoteInstance.instanceId().instance()); assertEquals(ZONE, remoteInstance.instanceId().zone()); assertEquals(InstanceInfo.Status.RUNNING, remoteInstance.status()); @@ -1682,7 +1682,7 @@ public void testCreateGetAndDeleteInstance() throws InterruptedException { assertNotNull(remoteInstance.metadata()); assertNotNull(remoteInstance.tags()); // test get with selected fields - remoteInstance = compute.get(instanceId, + remoteInstance = compute.getInstance(instanceId, Compute.InstanceOption.fields(Compute.InstanceField.CREATION_TIMESTAMP)); assertEquals(instanceName, remoteInstance.instanceId().instance()); assertEquals(ZONE, remoteInstance.instanceId().zone()); @@ -1702,7 +1702,7 @@ public void testCreateGetAndDeleteInstance() throws InterruptedException { while (!operation.isDone()) { Thread.sleep(1000L); } - assertNull(compute.get(instanceId)); + assertNull(compute.getInstance(instanceId)); address.delete(); } @@ -1723,29 +1723,29 @@ public void testStartStopAndResetInstance() throws InterruptedException { while (!operation.isDone()) { Thread.sleep(1000L); } - Instance remoteInstance = - compute.get(instanceId, Compute.InstanceOption.fields(Compute.InstanceField.STATUS)); + Instance remoteInstance = compute.getInstance(instanceId, + Compute.InstanceOption.fields(Compute.InstanceField.STATUS)); assertEquals(InstanceInfo.Status.RUNNING, remoteInstance.status()); operation = remoteInstance.stop(); while (!operation.isDone()) { Thread.sleep(1000L); } - remoteInstance = - compute.get(instanceId, Compute.InstanceOption.fields(Compute.InstanceField.STATUS)); + remoteInstance = compute.getInstance(instanceId, + Compute.InstanceOption.fields(Compute.InstanceField.STATUS)); assertEquals(InstanceInfo.Status.TERMINATED, remoteInstance.status()); operation = remoteInstance.start(); while (!operation.isDone()) { Thread.sleep(1000L); } - remoteInstance = - compute.get(instanceId, Compute.InstanceOption.fields(Compute.InstanceField.STATUS)); + remoteInstance = compute.getInstance(instanceId, + Compute.InstanceOption.fields(Compute.InstanceField.STATUS)); assertEquals(InstanceInfo.Status.RUNNING, remoteInstance.status()); operation = remoteInstance.reset(); while (!operation.isDone()) { Thread.sleep(1000L); } - remoteInstance = - compute.get(instanceId, Compute.InstanceOption.fields(Compute.InstanceField.STATUS)); + remoteInstance = compute.getInstance(instanceId, + Compute.InstanceOption.fields(Compute.InstanceField.STATUS)); assertEquals(InstanceInfo.Status.RUNNING, remoteInstance.status()); remoteInstance.delete(); } @@ -1767,14 +1767,14 @@ public void testSetInstanceProperties() throws InterruptedException { while (!operation.isDone()) { Thread.sleep(1000L); } - Instance remoteInstance = compute.get(instanceId); + Instance remoteInstance = compute.getInstance(instanceId); // test set tags List tags = ImmutableList.of("tag1", "tag2"); operation = remoteInstance.setTags(tags); while (!operation.isDone()) { Thread.sleep(1000L); } - remoteInstance = compute.get(instanceId); + remoteInstance = compute.getInstance(instanceId); assertEquals(tags, remoteInstance.tags().values()); // test set metadata Map metadata = ImmutableMap.of("key", "value"); @@ -1782,7 +1782,7 @@ public void testSetInstanceProperties() throws InterruptedException { while (!operation.isDone()) { Thread.sleep(1000L); } - remoteInstance = compute.get(instanceId); + remoteInstance = compute.getInstance(instanceId); assertEquals(metadata, remoteInstance.metadata().values()); // test set machine type operation = remoteInstance.stop(); @@ -1793,7 +1793,7 @@ public void testSetInstanceProperties() throws InterruptedException { while (!operation.isDone()) { Thread.sleep(1000L); } - remoteInstance = compute.get(instanceId); + remoteInstance = compute.getInstance(instanceId); assertEquals("n1-standard-1", remoteInstance.machineType().type()); assertEquals(ZONE, remoteInstance.machineType().zone()); // test set scheduling options @@ -1802,7 +1802,7 @@ public void testSetInstanceProperties() throws InterruptedException { while (!operation.isDone()) { Thread.sleep(1000L); } - remoteInstance = compute.get(instanceId); + remoteInstance = compute.getInstance(instanceId); assertEquals(options, remoteInstance.schedulingOptions()); remoteInstance.delete(); } @@ -1831,14 +1831,14 @@ public void testAttachAndDetachDisk() throws InterruptedException { while (!diskOperation.isDone()) { Thread.sleep(1000L); } - Instance remoteInstance = compute.get(instanceId); + Instance remoteInstance = compute.getInstance(instanceId); // test attach disk instanceOperation = remoteInstance.attachDisk("dev1", PersistentDiskConfiguration.builder(diskId).build()); while (!instanceOperation.isDone()) { Thread.sleep(1000L); } - remoteInstance = compute.get(instanceId); + remoteInstance = compute.getInstance(instanceId); Set deviceSet = ImmutableSet.of("dev0", "dev1"); assertEquals(2, remoteInstance.attachedDisks().size()); for (AttachedDisk remoteAttachedDisk : remoteInstance.attachedDisks()) { @@ -1849,7 +1849,8 @@ public void testAttachAndDetachDisk() throws InterruptedException { while (!instanceOperation.isDone()) { Thread.sleep(1000L); } - remoteInstance = compute.get(instanceId); + remoteInstance = compute.getInstance(instanceId); + assertEquals(2, remoteInstance.attachedDisks().size()); for (AttachedDisk remoteAttachedDisk : remoteInstance.attachedDisks()) { assertTrue(deviceSet.contains(remoteAttachedDisk.deviceName())); assertTrue(remoteAttachedDisk.configuration().autoDelete()); @@ -1859,10 +1860,11 @@ public void testAttachAndDetachDisk() throws InterruptedException { while (!instanceOperation.isDone()) { Thread.sleep(1000L); } - remoteInstance = compute.get(instanceId); + remoteInstance = compute.getInstance(instanceId); assertEquals(1, remoteInstance.attachedDisks().size()); assertEquals("dev0", remoteInstance.attachedDisks().get(0).deviceName()); remoteInstance.delete(); + compute.deleteDisk(diskId); } @Test @@ -1892,8 +1894,8 @@ public void testAddAndRemoveAccessConfig() throws InterruptedException { while (!addressOperation.isDone()) { Thread.sleep(1000L); } - Address remoteAddress = compute.get(addressId); - Instance remoteInstance = compute.get(instanceId); + Address remoteAddress = compute.getAddress(addressId); + Instance remoteInstance = compute.getInstance(instanceId); String networkInterfaceName = remoteInstance.networkInterfaces().get(0).name(); // test add access config AccessConfig accessConfig = AccessConfig.builder() @@ -1904,7 +1906,7 @@ public void testAddAndRemoveAccessConfig() throws InterruptedException { while (!instanceOperation.isDone()) { Thread.sleep(1000L); } - remoteInstance = compute.get(instanceId); + remoteInstance = compute.getInstance(instanceId); List accessConfigurations = remoteInstance.networkInterfaces().get(0).accessConfigurations(); assertEquals(1, accessConfigurations.size()); @@ -1914,7 +1916,7 @@ public void testAddAndRemoveAccessConfig() throws InterruptedException { while (!instanceOperation.isDone()) { Thread.sleep(1000L); } - remoteInstance = compute.get(instanceId); + remoteInstance = compute.getInstance(instanceId); assertTrue(remoteInstance.networkInterfaces().get(0).accessConfigurations().isEmpty()); remoteInstance.delete(); remoteAddress.delete(); From d77974a0e04967dffd31dba95ee88fcdcf2aec97 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 29 Apr 2016 09:22:27 +0200 Subject: [PATCH 327/375] Add Compute examples and snippets. Add them to READMEs. (#967) --- README.md | 79 + gcloud-java-compute/README.md | 172 +- .../google/gcloud/compute/package-info.java | 63 + gcloud-java-examples/README.md | 12 + .../examples/compute/ComputeExample.java | 2539 +++++++++++++++++ .../CreateAddressDiskAndInstance.java | 111 + .../compute/snippets/CreateInstance.java | 54 + .../compute/snippets/CreateSnapshot.java | 48 + 8 files changed, 3070 insertions(+), 8 deletions(-) create mode 100644 gcloud-java-compute/src/main/java/com/google/gcloud/compute/package-info.java create mode 100644 gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/ComputeExample.java create mode 100644 gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateAddressDiskAndInstance.java create mode 100644 gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateInstance.java create mode 100644 gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateSnapshot.java diff --git a/README.md b/README.md index 6bc56bad250a..daa3813b1fb7 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Java idiomatic client for [Google Cloud Platform][cloud-platform] services. This client supports the following Google Cloud Platform services: - [Google Cloud BigQuery] (#google-cloud-bigquery-alpha) (Alpha) +- [Google Cloud Compute] (#google-cloud-compute-alpha) (Alpha) - [Google Cloud Datastore] (#google-cloud-datastore) - [Google Cloud DNS] (#google-cloud-dns-alpha) (Alpha) - [Google Cloud Resource Manager] (#google-cloud-resource-manager-alpha) (Alpha) @@ -50,6 +51,8 @@ Example Applications - [`BigQueryExample`](./gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java) - A simple command line interface providing some of Cloud BigQuery's functionality - Read more about using this application on the [`BigQueryExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/cloud/examples/bigquery/BigQueryExample.html). +- [`ComputeExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/ComputeExample.java) - A simple command line interface providing some of Cloud Compute's functionality + - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/compute/ComputeExample.html). - [`Bookshelf`](https://github.com/GoogleCloudPlatform/getting-started-java/tree/master/bookshelf) - An App Engine app that manages a virtual bookshelf. - This app uses `gcloud-java` to interface with Cloud Datastore and Cloud Storage. It also uses Cloud SQL, another Google Cloud Platform service. - [`DatastoreExample`](./gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/DatastoreExample.java) - A simple command line interface for Cloud Datastore @@ -173,6 +176,78 @@ if (loadJob.status().error() != null) { } ``` +Google Cloud Compute (Alpha) +---------------------- + +- [API Documentation][compute-api] +- [Official Documentation][cloud-compute-docs] + +#### Preview + +Here are two code snippets showing simple usage examples from within Compute/App Engine. Note that +you must [supply credentials](#authentication) and a project ID if running this snippet elsewhere. + +The first snippet shows how to create a snapshot from an existing disk. Complete source code can be +found at +[CreateSnapshot.java](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateSnapshot.java). + +```java +import com.google.gcloud.compute.Compute; +import com.google.gcloud.compute.ComputeOptions; +import com.google.gcloud.compute.Disk; +import com.google.gcloud.compute.DiskId; +import com.google.gcloud.compute.Operation; +import com.google.gcloud.compute.Snapshot; + +Compute compute = ComputeOptions.defaultInstance().service(); +DiskId diskId = DiskId.of("us-central1-a", "disk-name"); +Disk disk = compute.getDisk(diskId, Compute.DiskOption.fields()); +if (disk != null) { + String snapshotName = "disk-name-snapshot"; + Operation operation = disk.createSnapshot(snapshotName); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + if (operation.errors() == null) { + // use snapshot + Snapshot snapshot = compute.getSnapshot("disk-name-snapshot"); + } +} +``` +The second snippet shows how to create a virtual machine instance. Complete source code can be found +at +[CreateInstance.java](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateInstance.java). +```java +import com.google.gcloud.compute.AttachedDisk; +import com.google.gcloud.compute.Compute; +import com.google.gcloud.compute.ComputeOptions; +import com.google.gcloud.compute.ImageId; +import com.google.gcloud.compute.Instance; +import com.google.gcloud.compute.InstanceId; +import com.google.gcloud.compute.InstanceInfo; +import com.google.gcloud.compute.MachineTypeId; +import com.google.gcloud.compute.NetworkId; +import com.google.gcloud.compute.NetworkInterface; +import com.google.gcloud.compute.Operation; + +Compute compute = ComputeOptions.defaultInstance().service(); +ImageId imageId = ImageId.of("debian-cloud", "debian-8-jessie-v20160329"); +NetworkId networkId = NetworkId.of("default"); +AttachedDisk attachedDisk = AttachedDisk.of(AttachedDisk.CreateDiskConfiguration.of(imageId)); +NetworkInterface networkInterface = NetworkInterface.of(networkId); +InstanceId instanceId = InstanceId.of("us-central1-a", "instance-name"); +MachineTypeId machineTypeId = MachineTypeId.of("us-central1-a", "n1-standard-1"); +Operation operation = + compute.create(InstanceInfo.of(instanceId, machineTypeId, attachedDisk, networkInterface)); +while (!operation.isDone()) { + Thread.sleep(1000L); +} +if (operation.errors() == null) { + // use instance + Instance instance = compute.getInstance(instanceId); +} +``` + Google Cloud Datastore ---------------------- @@ -455,3 +530,7 @@ Apache 2.0 - See [LICENSE] for more information. [cloud-bigquery]: https://cloud.google.com/bigquery/ [cloud-bigquery-docs]: https://cloud.google.com/bigquery/docs/overview [bigquery-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/bigquery/package-summary.html + +[cloud-compute]: https://cloud.google.com/compute/ +[cloud-compute-docs]: https://cloud.google.com/compute/docs/overview +[compute-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/compute/package-summary.html diff --git a/gcloud-java-compute/README.md b/gcloud-java-compute/README.md index d1909f904095..2b9dbd63cc3d 100644 --- a/gcloud-java-compute/README.md +++ b/gcloud-java-compute/README.md @@ -1,17 +1,16 @@ Google Cloud Java Client for Compute (Alpha) ==================================== -Java idiomatic client for [Google Cloud Compute] (https://cloud.google.com/compute). +Java idiomatic client for [Google Cloud Compute](https://cloud.google.com/compute). [![Build Status](https://travis-ci.org/GoogleCloudPlatform/gcloud-java.svg?branch=master)](https://travis-ci.org/GoogleCloudPlatform/gcloud-java) [![Coverage Status](https://coveralls.io/repos/GoogleCloudPlatform/gcloud-java/badge.svg?branch=master)](https://coveralls.io/r/GoogleCloudPlatform/gcloud-java?branch=master) - +[![Maven](https://img.shields.io/maven-central/v/com.google.cloud/gcloud-java-compute.svg)]( https://img.shields.io/maven-central/v/com.google.cloud/gcloud-java-compute.svg) [![Codacy Badge](https://api.codacy.com/project/badge/grade/9da006ad7c3a4fe1abd142e77c003917)](https://www.codacy.com/app/mziccard/gcloud-java) [![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969) -- [Homepage] (https://googlecloudplatform.github.io/gcloud-java/) - - +- [Homepage](https://googlecloudplatform.github.io/gcloud-java/) +- [API Documentation](http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/compute/package-summary.html) > Note: This client is a work-in-progress, and may occasionally > make backwards-incompatible changes. @@ -27,7 +26,11 @@ If you are using SBT, add this to your dependencies Example Application ------------------- - + +[`ComputeExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/ComputeExample.java) +is a simple command line interface that provides some of Google Cloud Compute Engine's +functionality. Read more about using the application on the +[`ComputeExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/compute/ComputeExample.html). Authentication -------------- @@ -51,7 +54,160 @@ with Google Cloud Compute using this Client Library. Getting Started --------------- - + +#### Prerequisites +For this tutorial, you will need a [Google Developers Console](https://console.developers.google.com/) +project with the Compute Engine API enabled. You will need to [enable billing](https://support.google.com/cloud/answer/6158867?hl=en) +to use Google Cloud DNS. [Follow these instructions](https://cloud.google.com/docs/authentication#preparation) +to get your project set up. You will also need to set up the local development environment by +[installing the Google Cloud SDK](https://cloud.google.com/sdk/) and running the following commands +in command line: `gcloud auth login` and `gcloud config set project [YOUR PROJECT ID]`. + +#### Installation and setup +You'll need to obtain the `gcloud-java-compute` library. See the [Quickstart](#quickstart) section +to add `gcloud-java-compute` as a dependency in your code. + +#### Creating an authorized service object +To make authenticated requests to Google Cloud Compute Engine, you must create a service object with +credentials. You can then make API calls by calling methods on the Compute service object. The +simplest way to authenticate is to use [Application Default Credentials](https://developers.google.com/identity/protocols/application-default-credentials). +These credentials are automatically inferred from your environment, so you only need the following +code to create your service object: + +```java +import com.google.gcloud.compute.Compute; +import com.google.gcloud.compute.ComputeOptions; + +Compute compute = ComputeOptions.defaultInstance().service(); +``` + +For other authentication options, see the [Authentication](https://github.com/GoogleCloudPlatform/gcloud-java#authentication) +page. + +#### Creating a region IP address +An external region IP address can be associated to a Google Compute Engine instance to communicate +with instances in different regions or to communicate with the instance from ouside of Compute +Engine. In this code snippet, we will create a new external region address. + +Add the following imports at the top of your file: + +```java +import com.google.gcloud.compute.AddressInfo; +import com.google.gcloud.compute.Operation; +import com.google.gcloud.compute.RegionAddressId; +``` + +Then add the following code to create an address. Most Compute Engine calls return an `Operation` +object that can be used to wait for operation completion and to check whether operation failed or +succeeded: + +```java +RegionAddressId addressId = RegionAddressId.of("us-central1", "test-address"); +Operation operation = compute.create(AddressInfo.of(addressId)); +while (!operation.isDone()) { + Thread.sleep(1000L); +} +operation = operation.reload(); +if (operation.errors() == null) { + System.out.println("Address " + addressId + " was successfully created"); +} else { + // inspect operation.errors() + throw new RuntimeException("Address creation failed"); +} +``` + +#### Creating a persistent disk +A persistent disk can be used as primary storage for your virtual machine instances. Persistent +disks can be created empty, from a disk image or from a disk snapshot. Compute Engine offers +[publicly-available images](https://cloud.google.com/compute/docs/operating-systems/) of certain +operating systems that you can use. In this code snippet, we will create a new persistent disk from +a publicly-available image. + +Add the following imports at the top of your file: + +```java +import com.google.gcloud.compute.DiskInfo; +import com.google.gcloud.compute.DiskId; +import com.google.gcloud.compute.ImageDiskConfiguration; +import com.google.gcloud.compute.ImageId; +``` + +Then add the following code to create a disk and wait for disk creation to terminate. + +```java +ImageId imageId = ImageId.of("debian-cloud", "debian-8-jessie-v20160329"); +DiskId diskId = DiskId.of("us-central1-a", "test-disk"); +ImageDiskConfiguration diskConfiguration = ImageDiskConfiguration.of(imageId); +DiskInfo disk = DiskInfo.of(diskId, diskConfiguration); +Operation operation = compute.create(disk); +while (!operation.isDone()) { + Thread.sleep(1000L); +} +operation = operation.reload(); +if (operation.errors() == null) { + System.out.println("Disk " + diskId + " was successfully created"); +} else { + // inspect operation.errors() + throw new RuntimeException("Disk creation failed"); +} +``` + +#### Creating a virtual machine instance +An Google Compute Engine instance is a virtual machine (VM) hosted on Google's infrastructure. An +instance can be created given it's identity, a machine type, one boot disk and a network interface. +In this code snippet, we will create a virtual machine instance in the default network using as a +boot disk the disk we have just created and assigning to it the just created IP address. + +Add the following imports at the top of your file: + +```java +import com.google.gcloud.compute.AttachedDisk; +import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; +import com.google.gcloud.compute.InstanceId; +import com.google.gcloud.compute.InstanceInfo; +import com.google.gcloud.compute.MachineTypeId; +import com.google.gcloud.compute.NetworkConfiguration; +import com.google.gcloud.compute.NetworkConfiguration.AccessConfig; +import com.google.gcloud.compute.NetworkId; +import com.google.gcloud.compute.NetworkInterface; +``` + +Then add the following code to create an instance and wait for instance creation to terminate. + +```java +Address externalIp = compute.getAddress(addressId); +InstanceId instanceId = InstanceId.of("us-central1-a", "test-instance"); +NetworkId networkId = NetworkId.of("default"); +PersistentDiskConfiguration attachConfiguration = + PersistentDiskConfiguration.builder(diskId).boot(true).build(); +AttachedDisk attachedDisk = AttachedDisk.of("dev0", attachConfiguration); +NetworkInterface networkInterface = NetworkInterface.builder(networkId) + .accessConfigurations(AccessConfig.of(externalIp.address())) + .build(); +MachineTypeId machineTypeId = MachineTypeId.of("us-central1-a", "n1-standard-1"); +InstanceInfo instance = + InstanceInfo.of(instanceId, machineTypeId, attachedDisk, networkInterface); +Operation operation = compute.create(instance); +while (!operation.isDone()) { + Thread.sleep(1000L); +} +operation = operation.reload(); +if (operation.errors() == null) { + System.out.println("Instance " + instanceId + " was successfully created"); +} else { + // inspect operation.errors() + throw new RuntimeException("Instance creation failed"); +} +``` + +#### Complete source code + +In +[CreateAddressDiskAndInstance.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateAddressDiskAndInstance.java) +we put together all the code shown above into one program. The program assumes that you are +running on Compute Engine or from your own desktop. To run the example on App Engine, simply move +the code from the main method to your application's servlet class and change the print statements to +display on your webpage. Troubleshooting --------------- @@ -73,7 +229,7 @@ See [TESTING] to read more about testing. Versioning ---------- -This library follows [Semantic Versioning] (http://semver.org/). +This library follows [Semantic Versioning](http://semver.org/). It is currently in major version zero (``0.y.z``), which means that anything may change at any time and the public API should not be considered diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/package-info.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/package-info.java new file mode 100644 index 000000000000..88dab612c599 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/package-info.java @@ -0,0 +1,63 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +/** + * A client to Google Cloud Compute. + * + *

    Here's a simple usage example for using gcloud-java from App/Compute Engine. This example + * shows how to create a snapshot from an existing disk. For the complete source code see + * + * CreateSnapshot.java. + *

     {@code
    + * Compute compute = ComputeOptions.defaultInstance().service();
    + * DiskId diskId = DiskId.of("us-central1-a", "disk-name");
    + * Disk disk = compute.getDisk(diskId, Compute.DiskOption.fields());
    + * if (disk != null) {
    + *   String snapshotName = "disk-name-snapshot";
    + *   Operation operation = disk.createSnapshot(snapshotName);
    + *   while (!operation.isDone()) {
    + *     Thread.sleep(1000L);
    + *   }
    + *   if (operation.errors() == null) {
    + *     // use snapshot
    + *     Snapshot snapshot = compute.getSnapshot("disk-name-snapshot");
    + *   }
    + * }}
    + *

    This second example shows how to create a virtual machine instance. Complete source code can + * be found at + * + * CreateInstance.java. + *

     {@code
    + * Compute compute = ComputeOptions.defaultInstance().service();
    + * ImageId imageId = ImageId.of("debian-cloud", "debian-8-jessie-v20160329");
    + * NetworkId networkId = NetworkId.of("default");
    + * AttachedDisk attachedDisk = AttachedDisk.of(AttachedDisk.CreateDiskConfiguration.of(imageId));
    + * NetworkInterface networkInterface = NetworkInterface.of(networkId);
    + * InstanceId instanceId = InstanceId.of("us-central1-a", "instance-name");
    + * MachineTypeId machineTypeId = MachineTypeId.of("us-central1-a", "n1-standard-1");
    + * Operation operation =
    + * compute.create(InstanceInfo.of(instanceId, machineTypeId, attachedDisk, networkInterface));
    + * while (!operation.isDone()) {
    + *   Thread.sleep(1000L);
    + * }
    + * if (operation.errors() == null) {
    + *   // use instance
    + *   Instance instance = compute.getInstance(instanceId);
    + * }}
    + * + * @see Google Cloud Compute + */ +package com.google.gcloud.compute; diff --git a/gcloud-java-examples/README.md b/gcloud-java-examples/README.md index 2aab551da6f6..10c2d0ce3650 100644 --- a/gcloud-java-examples/README.md +++ b/gcloud-java-examples/README.md @@ -62,6 +62,18 @@ To run examples from your command line: mvn exec:java -Dexec.mainClass="com.google.cloud.examples.bigquery.BigQueryExample" -Dexec.args="query 'select * from new_dataset_id.new_table_id'" ``` + * Here's an example run of `ComputeExample`. + + Before running the example, go to the [Google Developers Console][developers-console] to ensure + that Compute API is enabled. + ``` + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.compute.ComputeExample" -Dexec.args="create image-disk us-central1-a test-disk debian-cloud debian-8-jessie-v20160329" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.compute.ComputeExample" -Dexec.args="create instance us-central1-a test-instance n1-standard-1 test-disk default" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.compute.ComputeExample" -Dexec.args="add-access-config us-central1-a test-instance nic0 NAT" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.compute.ComputeExample" -Dexec.args="delete instance us-central1-a test-instance" + mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.compute.ComputeExample" -Dexec.args="delete disk us-central1-a test-disk" + ``` + * Here's an example run of `DatastoreExample`. Be sure to change the placeholder project ID "your-project-id" with your own project ID. Also note that you have to enable the Google Cloud Datastore API on the [Google Developers Console][developers-console] before running the following commands. diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/ComputeExample.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/ComputeExample.java new file mode 100644 index 000000000000..afc2d6c049c2 --- /dev/null +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/ComputeExample.java @@ -0,0 +1,2539 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.examples.compute; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.gcloud.compute.Address; +import com.google.gcloud.compute.AddressId; +import com.google.gcloud.compute.AddressInfo; +import com.google.gcloud.compute.AttachedDisk; +import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; +import com.google.gcloud.compute.Compute; +import com.google.gcloud.compute.ComputeOptions; +import com.google.gcloud.compute.Disk; +import com.google.gcloud.compute.DiskConfiguration; +import com.google.gcloud.compute.DiskId; +import com.google.gcloud.compute.DiskImageConfiguration; +import com.google.gcloud.compute.DiskInfo; +import com.google.gcloud.compute.DiskType; +import com.google.gcloud.compute.DiskTypeId; +import com.google.gcloud.compute.GlobalAddressId; +import com.google.gcloud.compute.GlobalOperationId; +import com.google.gcloud.compute.Image; +import com.google.gcloud.compute.ImageDiskConfiguration; +import com.google.gcloud.compute.ImageId; +import com.google.gcloud.compute.ImageInfo; +import com.google.gcloud.compute.Instance; +import com.google.gcloud.compute.InstanceId; +import com.google.gcloud.compute.InstanceInfo; +import com.google.gcloud.compute.LicenseId; +import com.google.gcloud.compute.MachineType; +import com.google.gcloud.compute.MachineTypeId; +import com.google.gcloud.compute.Network; +import com.google.gcloud.compute.NetworkId; +import com.google.gcloud.compute.NetworkInfo; +import com.google.gcloud.compute.NetworkInterface; +import com.google.gcloud.compute.NetworkInterface.AccessConfig; +import com.google.gcloud.compute.Operation; +import com.google.gcloud.compute.Region; +import com.google.gcloud.compute.RegionAddressId; +import com.google.gcloud.compute.RegionId; +import com.google.gcloud.compute.RegionOperationId; +import com.google.gcloud.compute.SchedulingOptions; +import com.google.gcloud.compute.SchedulingOptions.Maintenance; +import com.google.gcloud.compute.Snapshot; +import com.google.gcloud.compute.SnapshotDiskConfiguration; +import com.google.gcloud.compute.SnapshotId; +import com.google.gcloud.compute.SnapshotInfo; +import com.google.gcloud.compute.StandardDiskConfiguration; +import com.google.gcloud.compute.StandardNetworkConfiguration; +import com.google.gcloud.compute.SubnetNetworkConfiguration; +import com.google.gcloud.compute.Subnetwork; +import com.google.gcloud.compute.SubnetworkId; +import com.google.gcloud.compute.SubnetworkInfo; +import com.google.gcloud.compute.Zone; +import com.google.gcloud.compute.ZoneId; +import com.google.gcloud.compute.ZoneOperationId; +import com.google.gcloud.compute.spi.ComputeRpc.Tuple; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * An example of using Google Compute. + * + *

    This example demonstrates a simple/typical Compute usage. + * + *

    Steps needed for running the example: + *

      + *
    1. login using gcloud SDK - {@code gcloud auth login}.
    2. + *
    3. compile using maven - {@code mvn compile}
    4. + *
    5. run using maven - + *
      {@code mvn exec:java -Dexec.mainClass="com.google.cloud.examples.compute.ComputeExample"
      + *  -Dexec.args="[]
      + * list networks |
      + * list region-operations  |
      + * list instances ? |
      + * list regions |
      + * list zones |
      + * list zone-operations  |
      + * list disks ? |
      + * list subnetworks ? |
      + * list machineTypes ? |
      + * list global-operations |
      + * list images |
      + * list diskTypes ? |
      + * list snapshots |
      + * list addresses ? |
      + * create subnet-network  true|false |
      + * create image-disk   ?  |
      + * create subnetwork     |
      + * create address ? 
      | + * create snapshot | + * create snapshot-disk | + * create image | + * create standard-network | + * create instance | + * create standard-disk ? | + * info region | + * info region-operation | + * info machineType | + * info snapshot | + * info disk | + * info image | + * info diskType | + * info network | + * info zone-operation | + * info subnetwork | + * info address ?
      | + * info instance | + * info license | + * info global-operation | + * info zone | + * delete region-operation | + * delete zone-operation | + * delete subnetwork | + * delete address ?
      | + * delete snapshot | + * delete disk | + * delete image | + * delete instance | + * delete global-operation | + * delete network | + * get-serial-port | + * set-machine-type | + * set-disk-auto-delete true|false | + * set-scheduling-options preemptible|(standard true|false MIGRATE|TERMINATE) | + * add-access-config ? | + * delete-access-config | + * attach-disk | + * detach-disk | + * start | + * stop | + * reset | + * set-tags * | + * set-metadata *"}
      + *
    6. + *
    + * + *

    The first parameter is an optional {@code project_id} (logged-in project will be used if not + * supplied). Second parameter is a Compute operation and can be used to demonstrate its usage. For + * operations that apply to more than one entity (`list`, `create`, `info` and `delete`) the third + * parameter specifies the entity. + */ +public class ComputeExample { + + private static final Map CREATE_ACTIONS = new HashMap<>(); + private static final Map INFO_ACTIONS = new HashMap<>(); + private static final Map LIST_ACTIONS = new HashMap<>(); + private static final Map DELETE_ACTIONS = new HashMap<>(); + private static final Map ACTIONS = new HashMap<>(); + + static class Triple { + + private final X x; + private final Y y; + private final Z z; + + private Triple(X x, Y y, Z z) { + this.x = x; + this.y = y; + this.z = z; + } + + public static Triple of(X x, Y y, Z z) { + return new Triple<>(x, y, z); + } + + X x() { + return x; + } + + Y y() { + return y; + } + + Z z() { + return z; + } + } + + private abstract static class ComputeAction { + + abstract void run(Compute compute, T request) throws Exception; + + abstract T parse(String... args) throws Exception; + + protected String params() { + return ""; + } + } + + private static class ParentAction extends ComputeAction> { + + private final Map subActions; + + ParentAction(Map subActions) { + this.subActions = ImmutableMap.copyOf(subActions); + } + + @Override + @SuppressWarnings("unchecked") + void run(Compute compute, Tuple subaction) throws Exception { + subaction.x().run(compute, subaction.y()); + } + + @Override + Tuple parse(String... args) throws Exception { + if (args.length >= 1) { + ComputeAction action = subActions.get(args[0]); + if (action != null) { + Object actionArguments = action.parse(Arrays.copyOfRange(args, 1, args.length)); + return Tuple.of(action, actionArguments); + } else { + throw new IllegalArgumentException("Unrecognized entity '" + args[0] + "'."); + } + } + throw new IllegalArgumentException("Missing required entity."); + } + + @Override + public String params() { + StringBuilder builder = new StringBuilder(); + for (Map.Entry entry : subActions.entrySet()) { + builder.append('\n').append(entry.getKey()); + String param = entry.getValue().params(); + if (param != null && !param.isEmpty()) { + builder.append(' ').append(param); + } + } + return builder.toString(); + } + } + + private abstract static class OptionalZoneAction extends ComputeAction { + @Override + ZoneId parse(String... args) throws Exception { + String message; + if (args.length == 1) { + return ZoneId.of(args[0]); + } else if (args.length > 1) { + message = "Too many arguments."; + } else { + return null; + } + throw new IllegalArgumentException(message); + } + + @Override + public String params() { + return "?"; + } + } + + private abstract static class OptionalRegionAction extends ComputeAction { + @Override + RegionId parse(String... args) throws Exception { + String message; + if (args.length == 1) { + return RegionId.of(args[0]); + } else if (args.length > 1) { + message = "Too many arguments."; + } else { + return null; + } + throw new IllegalArgumentException(message); + } + + @Override + public String params() { + return "?"; + } + } + + private abstract static class NoArgsAction extends ComputeAction { + @Override + Void parse(String... args) throws Exception { + if (args.length == 0) { + return null; + } + throw new IllegalArgumentException("This action takes no arguments."); + } + } + + /** + * This class demonstrates how to list Compute disk types. + * + * @see DiskTypes: + * list + * @see + * DiskTypes: aggregated list + */ + private static class ListDiskTypesAction extends OptionalZoneAction { + @Override + public void run(Compute compute, ZoneId zone) { + Iterator diskTypeIterator; + if (zone != null) { + diskTypeIterator = compute.listDiskTypes(zone.zone()).iterateAll(); + } else { + diskTypeIterator = compute.listDiskTypes().iterateAll(); + } + while (diskTypeIterator.hasNext()) { + System.out.println(diskTypeIterator.next()); + } + } + } + + /** + * This class demonstrates how to retrieve information on a Compute disk type. + * + * @see DiskTypes: + * get + */ + private static class DiskTypeInfoAction extends ComputeAction { + @Override + public void run(Compute compute, DiskTypeId diskType) { + System.out.println("Disk type info: " + compute.getDiskType(diskType)); + } + + @Override + DiskTypeId parse(String... args) throws Exception { + String message; + if (args.length == 2) { + return DiskTypeId.of(args[0], args[1]); + } else if (args.length < 2) { + message = "Missing required zone and disk type id."; + } else { + message = "Too many arguments."; + } + throw new IllegalArgumentException(message); + } + + @Override + public String params() { + return " "; + } + } + + /** + * This class demonstrates how to list Compute machine types. + * + * @see + * MachineTypes: list + * @see + * MachineTypes: aggregated list + */ + private static class ListMachineTypesAction extends OptionalZoneAction { + @Override + public void run(Compute compute, ZoneId zone) { + Iterator machineTypeIterator; + if (zone != null) { + machineTypeIterator = compute.listMachineTypes(zone.zone()).iterateAll(); + } else { + machineTypeIterator = compute.listMachineTypes().iterateAll(); + } + while (machineTypeIterator.hasNext()) { + System.out.println(machineTypeIterator.next()); + } + } + } + + /** + * This class demonstrates how to retrieve information on a Compute machine type. + * + * @see + * MachineTypes: get + */ + private static class MachineTypeInfoAction extends ComputeAction { + @Override + public void run(Compute compute, MachineTypeId machineType) { + System.out.println("Machine type info: " + compute.getMachineType(machineType)); + } + + @Override + MachineTypeId parse(String... args) throws Exception { + String message; + if (args.length == 2) { + return MachineTypeId.of(args[0], args[1]); + } else if (args.length < 2) { + message = "Missing required zone and machine type id."; + } else { + message = "Too many arguments."; + } + throw new IllegalArgumentException(message); + } + + @Override + public String params() { + return " "; + } + } + + /** + * This class demonstrates how to list Compute regions. + * + * @see Regions: + * list + */ + private static class ListRegionsAction extends NoArgsAction { + @Override + public void run(Compute compute, Void arg) { + Iterator regionIterator = compute.listRegions().iterateAll(); + while (regionIterator.hasNext()) { + System.out.println(regionIterator.next()); + } + } + } + + /** + * This class demonstrates how to retrieve information on a Compute region. + * + * @see + * Regions: get + */ + private static class RegionInfoAction extends ComputeAction { + @Override + public void run(Compute compute, RegionId region) { + System.out.println("Region info: " + compute.getRegion(region.region())); + } + + @Override + RegionId parse(String... args) throws Exception { + String message; + if (args.length == 1) { + return RegionId.of(args[0]); + } else if (args.length > 1) { + message = "Too many arguments."; + } else { + message = "Missing required region id."; + } + throw new IllegalArgumentException(message); + } + + @Override + public String params() { + return ""; + } + } + + /** + * This class demonstrates how to list Compute zones. + * + * @see Zones: list + * + */ + private static class ListZonesAction extends NoArgsAction { + @Override + public void run(Compute compute, Void arg) { + Iterator zoneIterator = compute.listZones().iterateAll(); + while (zoneIterator.hasNext()) { + System.out.println(zoneIterator.next()); + } + } + } + + /** + * This class demonstrates how to retrieve information on a Compute zone. + * + * @see Zones: get + */ + private static class ZoneInfoAction extends ComputeAction { + @Override + public void run(Compute compute, ZoneId zone) { + System.out.println("Zone info: " + compute.getZone(zone.zone())); + } + + @Override + ZoneId parse(String... args) throws Exception { + String message; + if (args.length == 1) { + return ZoneId.of(args[0]); + } else if (args.length > 1) { + message = "Too many arguments."; + } else { + message = "Missing required zone id."; + } + throw new IllegalArgumentException(message); + } + + @Override + public String params() { + return ""; + } + } + + /** + * This class demonstrates how to retrieve information on a Compute license. + * + * @see License: + * get + */ + private static class LicenseInfoAction extends ComputeAction { + @Override + public void run(Compute compute, LicenseId license) { + System.out.println("License info: " + compute.getLicense(license.license())); + } + + @Override + LicenseId parse(String... args) throws Exception { + String message; + if (args.length == 1) { + return LicenseId.of(args[0]); + } else if (args.length > 1) { + message = "Too many arguments."; + } else { + message = "Missing required license id."; + } + throw new IllegalArgumentException(message); + } + + @Override + public String params() { + return ""; + } + } + + /** + * This class demonstrates how to list Compute global operations. + * + * @see + * GLobalOperations: list + */ + private static class ListGlobalOperationsAction extends NoArgsAction { + @Override + public void run(Compute compute, Void arg) { + Iterator operationIterator = compute.listGlobalOperations().iterateAll(); + while (operationIterator.hasNext()) { + System.out.println(operationIterator.next()); + } + } + } + + /** + * This class demonstrates how to list Compute zone operations. + * + * @see + * ZoneOperations: list + */ + private static class ListZoneOperationsAction extends ComputeAction { + @Override + public void run(Compute compute, ZoneId zone) { + Iterator operationIterator = compute.listZoneOperations(zone.zone()).iterateAll(); + while (operationIterator.hasNext()) { + System.out.println(operationIterator.next()); + } + } + + @Override + ZoneId parse(String... args) throws Exception { + String message; + if (args.length == 1) { + return ZoneId.of(args[0]); + } else if (args.length > 1) { + message = "Too many arguments."; + } else { + message = "Missing required zone id."; + } + throw new IllegalArgumentException(message); + } + + @Override + public String params() { + return ""; + } + } + + /** + * This class demonstrates how to list Compute region operations. + * + * @see + * RegionOperations: list + */ + private static class ListRegionOperationsAction extends ComputeAction { + @Override + public void run(Compute compute, RegionId region) { + Iterator operationIterator = + compute.listRegionOperations(region.region()).iterateAll(); + while (operationIterator.hasNext()) { + System.out.println(operationIterator.next()); + } + } + + @Override + RegionId parse(String... args) throws Exception { + String message; + if (args.length == 1) { + return RegionId.of(args[0]); + } else if (args.length > 1) { + message = "Too many arguments."; + } else { + message = "Missing required region id."; + } + throw new IllegalArgumentException(message); + } + + @Override + public String params() { + return ""; + } + } + + private abstract static class GlobalOperationAction extends ComputeAction { + @Override + GlobalOperationId parse(String... args) throws Exception { + String message; + if (args.length == 1) { + return GlobalOperationId.of(args[0]); + } else if (args.length > 1) { + message = "Too many arguments."; + } else { + message = "Missing required operation id."; + } + throw new IllegalArgumentException(message); + } + + @Override + public String params() { + return ""; + } + } + + private abstract static class ZoneOperationAction extends ComputeAction { + @Override + ZoneOperationId parse(String... args) throws Exception { + String message; + if (args.length == 2) { + return ZoneOperationId.of(args[0], (args[1])); + } else if (args.length > 2) { + message = "Too many arguments."; + } else { + message = "Missing required zone and operation id."; + } + throw new IllegalArgumentException(message); + } + + @Override + public String params() { + return " "; + } + } + + private abstract static class RegionOperationAction extends ComputeAction { + @Override + RegionOperationId parse(String... args) throws Exception { + String message; + if (args.length == 2) { + return RegionOperationId.of(args[0], (args[1])); + } else if (args.length > 2) { + message = "Too many arguments."; + } else { + message = "Missing required region and operation id."; + } + throw new IllegalArgumentException(message); + } + + @Override + public String params() { + return " "; + } + } + + /** + * This class demonstrates how to retrieve information on a Compute global operation. + * + * @see + * GlobalOperations: get + */ + private static class GlobalOperationInfoAction extends GlobalOperationAction { + @Override + public void run(Compute compute, GlobalOperationId operation) { + System.out.println("Operation info: " + compute.getOperation(operation)); + } + } + + /** + * This class demonstrates how to retrieve information on a Compute zone operation. + * + * @see + * ZoneOperations: get + */ + private static class ZoneOperationInfoAction extends ZoneOperationAction { + @Override + public void run(Compute compute, ZoneOperationId operation) { + System.out.println("Operation info: " + compute.getOperation(operation)); + } + } + + /** + * This class demonstrates how to retrieve information on a Compute region operation. + * + * @see + * RegionOperations: get + */ + private static class RegionOperationInfoAction extends RegionOperationAction { + @Override + public void run(Compute compute, RegionOperationId operation) { + System.out.println("Operation info: " + compute.getOperation(operation)); + } + } + + /** + * This class demonstrates how to delete a Compute global operation. + * + * @see + * GlobalOperations: delete + */ + private static class DeleteGlobalOperationAction extends GlobalOperationAction { + @Override + public void run(Compute compute, GlobalOperationId operation) { + if (compute.deleteOperation(operation)) { + System.out.println("Operation " + operation + " was deleted"); + } else { + System.out.println("Operation " + operation + " not found"); + } + } + } + + /** + * This class demonstrates how to delete a Compute zone operation. + * + * @see + * ZoneOperations: delete + */ + private static class DeleteZoneOperationAction extends ZoneOperationAction { + @Override + public void run(Compute compute, ZoneOperationId operation) { + if (compute.deleteOperation(operation)) { + System.out.println("Operation " + operation + " was deleted"); + } else { + System.out.println("Operation " + operation + " not found"); + } + } + } + + /** + * This class demonstrates how to delete a Compute region operation. + * + * @see + * RegionOperations: delete + */ + private static class DeleteRegionOperationAction extends RegionOperationAction { + @Override + public void run(Compute compute, RegionOperationId operation) { + if (compute.deleteOperation(operation)) { + System.out.println("Operation " + operation + " was deleted"); + } else { + System.out.println("Operation " + operation + " not found"); + } + } + } + + /** + * This class demonstrates how to list Compute addresses. + * + * @see + * Addresses: list + * @see + * Addresses: aggerated list + */ + private static class ListAddressesAction extends OptionalRegionAction { + @Override + public void run(Compute compute, RegionId region) { + Iterator

    addressIterator; + if (region != null) { + addressIterator = compute.listRegionAddresses(region.region()).iterateAll(); + } else { + addressIterator = compute.listAddresses().iterateAll(); + } + while (addressIterator.hasNext()) { + System.out.println(addressIterator.next()); + } + } + } + + private abstract static class AddressAction extends ComputeAction { + @Override + AddressId parse(String... args) throws Exception { + String message; + if (args.length == 2) { + return RegionAddressId.of(args[0], (args[1])); + } else if (args.length == 1) { + return GlobalAddressId.of(args[0]); + } else if (args.length > 2) { + message = "Too many arguments."; + } else { + message = "Missing required address id."; + } + throw new IllegalArgumentException(message); + } + + @Override + public String params() { + return "?
    "; + } + } + + /** + * This class demonstrates how to retrieve information on a Compute address. + * + * @see + * Addresses: get + * @see + * Global Addresses: get + */ + private static class AddressInfoAction extends AddressAction { + @Override + public void run(Compute compute, AddressId address) { + System.out.println("Address info: " + compute.getAddress(address)); + } + } + + /** + * This class demonstrates how to delete a Compute address. + * + * @see + * Addresses: delete + * @see + * Global Addresses: delete + */ + private static class DeleteAddressAction extends AddressAction { + @Override + public void run(Compute compute, AddressId address) throws InterruptedException { + Operation operation = compute.deleteAddress(address); + if (operation == null) { + System.out.println("Address " + address + " does not exist"); + return; + } + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Address " + address + " was deleted"); + } else { + System.out.println("Deletion of address " + address + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + } + + /** + * This class demonstrates how to create a Compute address. + * + * @see + * Addresses: insert + * @see + * Global Addresses: insert + */ + private static class CreateAddressAction extends AddressAction { + @Override + public void run(Compute compute, AddressId address) throws InterruptedException { + Operation operation = compute.create(AddressInfo.of(address)); + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Address " + address + " was created"); + } else { + System.out.println("Creation of address " + address + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + } + + /** + * This class demonstrates how to list Compute snapshots. + * + * @see + * Snapshots: list + */ + private static class ListSnapshotsAction extends NoArgsAction { + @Override + public void run(Compute compute, Void arg) { + Iterator snapshotIterator = compute.listSnapshots().iterateAll(); + while (snapshotIterator.hasNext()) { + System.out.println(snapshotIterator.next()); + } + } + } + + private abstract static class SnapshotAction extends ComputeAction { + @Override + SnapshotId parse(String... args) throws Exception { + String message; + if (args.length == 1) { + return SnapshotId.of(args[0]); + } else if (args.length > 1) { + message = "Too many arguments."; + } else { + message = "Missing required shapshot id."; + } + throw new IllegalArgumentException(message); + } + + @Override + public String params() { + return ""; + } + } + + /** + * This class demonstrates how to retrieve information on a Compute snapshot. + * + * @see + * Snapshots: get + */ + private static class SnapshotInfoAction extends SnapshotAction { + @Override + public void run(Compute compute, SnapshotId snapshot) { + System.out.println("Snapshot info: " + compute.getSnapshot(snapshot.snapshot())); + } + } + + /** + * This class demonstrates how to delete a Compute snapshot. + * + * @see + * Snapshots: delete + */ + private static class DeleteSnapshotAction extends SnapshotAction { + @Override + public void run(Compute compute, SnapshotId snapshot) throws InterruptedException { + Operation operation = compute.deleteSnapshot(snapshot.snapshot()); + if (operation == null) { + System.out.println("Snapshot " + snapshot + " does not exist"); + return; + } + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Snapshot " + snapshot + " was deleted"); + } else { + System.out.println("Deletion of snapshot " + snapshot + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + } + + /** + * This class demonstrates how to create a Compute snapshot. + * + * @see + * Snapshots: insert + */ + private static class CreateSnapshotAction extends ComputeAction { + @Override + public void run(Compute compute, SnapshotInfo snapshot) throws InterruptedException { + Operation operation = compute.create(snapshot); + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Snapshot " + snapshot.snapshotId() + " was created"); + } else { + System.out.println("Creation of snapshot " + snapshot.snapshotId() + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + + @Override + SnapshotInfo parse(String... args) throws Exception { + String message; + if (args.length == 3) { + String snapshot = args[0]; + String zone = args[1]; + String disk = args[2]; + return SnapshotInfo.of(SnapshotId.of(snapshot), DiskId.of(zone, disk)); + } else if (args.length > 3) { + message = "Too many arguments."; + } else { + message = "Missing required arguments."; + } + throw new IllegalArgumentException(message); + } + + @Override + protected String params() { + return " "; + } + } + + /** + * This class demonstrates how to list Compute images. + * + * @see Images: list + * + */ + private static class ListImagesAction extends NoArgsAction { + @Override + public void run(Compute compute, Void arg) { + Iterator imageIterator = compute.listImages().iterateAll(); + while (imageIterator.hasNext()) { + System.out.println(imageIterator.next()); + } + } + } + + private abstract static class ImageAction extends ComputeAction { + @Override + ImageId parse(String... args) throws Exception { + String message; + if (args.length == 1) { + return ImageId.of(args[0]); + } else if (args.length > 1) { + message = "Too many arguments."; + } else { + message = "Missing required image id."; + } + throw new IllegalArgumentException(message); + } + + @Override + public String params() { + return ""; + } + } + + /** + * This class demonstrates how to retrieve information on a Compute image. + * + * @see Images: get + * + */ + private static class ImageInfoAction extends ImageAction { + @Override + public void run(Compute compute, ImageId image) { + System.out.println("Image info: " + compute.getImage(image)); + } + } + + /** + * This class demonstrates how to delete a Compute image. + * + * @see Images: + * delete + */ + private static class DeleteImageAction extends ImageAction { + @Override + public void run(Compute compute, ImageId image) throws InterruptedException { + Operation operation = compute.deleteImage(image); + if (operation == null) { + System.out.println("Image " + image + " does not exist"); + return; + } + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Image " + image + " was deleted"); + } else { + System.out.println("Deletion of image " + image + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + } + + /** + * This class demonstrates how to create a Compute image. + * + * @see Images: + * insert + */ + private static class CreateImageAction extends ComputeAction { + @Override + public void run(Compute compute, ImageInfo image) throws InterruptedException { + Operation operation = compute.create(image); + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Image " + image.imageId() + " was created"); + } else { + System.out.println("Creation of image " + image.imageId() + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + + @Override + ImageInfo parse(String... args) throws Exception { + String message; + if (args.length == 3) { + String image = args[0]; + String zone = args[1]; + String disk = args[2]; + return ImageInfo.of(ImageId.of(image), DiskImageConfiguration.of(DiskId.of(zone, disk))); + } else if (args.length > 3) { + message = "Too many arguments."; + } else { + message = "Missing required arguments."; + } + throw new IllegalArgumentException(message); + } + + @Override + protected String params() { + return " "; + } + } + + private abstract static class DiskAction extends ComputeAction { + @Override + DiskId parse(String... args) throws Exception { + String message; + if (args.length == 2) { + return DiskId.of(args[0], args[1]); + } else if (args.length > 2) { + message = "Too many arguments."; + } else { + message = "Missing required zone and disk id."; + } + throw new IllegalArgumentException(message); + } + + @Override + public String params() { + return " "; + } + } + + /** + * This class demonstrates how to retrieve information on a Compute disk. + * + * @see + * Snapshots: get + */ + private static class DiskInfoAction extends DiskAction { + @Override + public void run(Compute compute, DiskId disk) { + System.out.println("Disk info: " + compute.getDisk(disk)); + } + } + + /** + * This class demonstrates how to delete a Compute disk. + * + * @see Disks: + * delete + */ + private static class DeleteDiskAction extends DiskAction { + @Override + public void run(Compute compute, DiskId disk) throws InterruptedException { + Operation operation = compute.deleteDisk(disk); + if (operation == null) { + System.out.println("Disk " + disk + " does not exist"); + return; + } + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Disk " + disk + " was deleted"); + } else { + System.out.println("Deletion of disk " + disk + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + } + + /** + * This class demonstrates how to list Compute disks. + * + * @see Disks: list + * + */ + private static class ListDisksAction extends OptionalZoneAction { + @Override + public void run(Compute compute, ZoneId zone) { + Iterator diskIterator = compute.listDisks().iterateAll(); + while (diskIterator.hasNext()) { + System.out.println(diskIterator.next()); + } + } + } + + private abstract static class CreateDiskAction extends ComputeAction { + @Override + public void run(Compute compute, DiskInfo disk) throws InterruptedException { + Operation operation = compute.create(disk); + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Disk " + disk.diskId() + " was created"); + } else { + System.out.println("Creation of disk " + disk.diskId() + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + + static DiskId parseDiskId(String[] args) { + return DiskId.of(args[0], args[1]); + } + } + + /** + * This class demonstrates how to create a Compute disk given its type and size. + * + * @see Disks: + * insert + */ + private static class CreateStandardDiskAction extends CreateDiskAction { + @Override + DiskInfo parse(String... args) throws Exception { + if (args.length >= 3) { + DiskId diskId = parseDiskId(args); + String diskType = args[2]; + DiskConfiguration configuration; + if (args.length == 4) { + try { + configuration = StandardDiskConfiguration.of(DiskTypeId.of(diskId.zone(), diskType), + Integer.parseInt(args[3])); + } catch (NumberFormatException ex) { + throw new IllegalArgumentException("Error parsing disk size parameter."); + } + } else if (args.length == 3) { + configuration = StandardDiskConfiguration.of(DiskTypeId.of(diskId.zone(), diskType)); + } else { + throw new IllegalArgumentException("Too many arguments."); + } + return DiskInfo.of(diskId, configuration); + } else { + throw new IllegalArgumentException("Missing required arguments."); + } + } + + @Override + protected String params() { + return " ?"; + } + } + + /** + * This class demonstrates how to create a Compute disk given a source snapshot. + * + * @see Disks: + * insert + */ + private static class CreateSnapshotDiskAction extends CreateDiskAction { + @Override + DiskInfo parse(String... args) throws Exception { + if (args.length == 3) { + DiskId diskId = parseDiskId(args); + return DiskInfo.of(diskId, SnapshotDiskConfiguration.of(SnapshotId.of(args[2]))); + } else if (args.length > 3) { + throw new IllegalArgumentException("Too many arguments."); + } else { + throw new IllegalArgumentException("Missing required arguments."); + } + } + + @Override + protected String params() { + return " "; + } + } + + /** + * This class demonstrates how to create a Compute disk given a source image. + * + * @see Disks: + * insert + */ + private static class CreateImageDiskAction extends CreateDiskAction { + @Override + DiskInfo parse(String... args) throws Exception { + if (args.length == 3) { + DiskId diskId = parseDiskId(args); + return DiskInfo.of(diskId, ImageDiskConfiguration.of(ImageId.of(args[2]))); + } else if (args.length == 4) { + DiskId diskId = parseDiskId(args); + return DiskInfo.of(diskId, ImageDiskConfiguration.of(ImageId.of(args[2], args[3]))); + } else if (args.length > 4) { + throw new IllegalArgumentException("Too many arguments."); + } else { + throw new IllegalArgumentException("Missing required arguments."); + } + } + + @Override + protected String params() { + return " ? "; + } + } + + /** + * This class demonstrates how to list Compute networks. + * + * @see Networks: + * list + */ + private static class ListNetworksAction extends NoArgsAction { + @Override + public void run(Compute compute, Void arg) { + Iterator networkIterator = compute.listNetworks().iterateAll(); + while (networkIterator.hasNext()) { + System.out.println(networkIterator.next()); + } + } + } + + private abstract static class NetworkAction extends ComputeAction { + @Override + NetworkId parse(String... args) throws Exception { + String message; + if (args.length == 1) { + return NetworkId.of(args[0]); + } else if (args.length > 1) { + message = "Too many arguments."; + } else { + message = "Missing required network id."; + } + throw new IllegalArgumentException(message); + } + + @Override + public String params() { + return ""; + } + } + + /** + * This class demonstrates how to retrieve information on a Compute network. + * + * @see Networks: + * get + */ + private static class NetworkInfoAction extends NetworkAction { + @Override + public void run(Compute compute, NetworkId network) { + System.out.println("Network info: " + compute.getNetwork(network.network())); + } + } + + /** + * This class demonstrates how to delete a Compute network. + * + * @see Networks: + * delete + */ + private static class DeleteNetworkAction extends NetworkAction { + @Override + public void run(Compute compute, NetworkId network) throws InterruptedException { + Operation operation = compute.deleteNetwork(network.network()); + if (operation == null) { + System.out.println("Network " + network + " does not exist"); + return; + } + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Network " + network + " was deleted"); + } else { + System.out.println("Deletion of network " + network + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + } + + private abstract static class CreateNetworkAction extends ComputeAction { + @Override + public void run(Compute compute, NetworkInfo network) throws InterruptedException { + Operation operation = compute.create(network); + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Network " + network.networkId() + " was created"); + } else { + System.out.println("Creation of network " + network.networkId() + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + } + + /** + * This class demonstrates how to create a Compute network with no subnetworks. + * + * @see Networks: + * insert + */ + private static class CreateStandardNetworkAction extends CreateNetworkAction { + @Override + NetworkInfo parse(String... args) throws Exception { + if (args.length == 2) { + return NetworkInfo.of(NetworkId.of(args[0]), StandardNetworkConfiguration.of(args[1])); + } else if (args.length > 2) { + throw new IllegalArgumentException("Too many arguments."); + } else { + throw new IllegalArgumentException("Missing required arguments."); + } + } + + @Override + protected String params() { + return " "; + } + } + + /** + * This class demonstrates how to create a Compute network that supports the creation of + * subnetworks (either manual or automatic). + * + * @see Networks: + * insert + */ + private static class CreateSubnetNetworkAction extends CreateNetworkAction { + @Override + NetworkInfo parse(String... args) throws Exception { + if (args.length == 2) { + boolean autoCreateSubnetworks; + switch (args[1]) { + case "true": + autoCreateSubnetworks = true; + break; + case "false": + autoCreateSubnetworks = false; + break; + default: + throw new IllegalArgumentException( + "Couldn't parse autoCreateSubnetworks argument (must be either true or false)."); + } + return NetworkInfo.of(NetworkId.of(args[0]), + SubnetNetworkConfiguration.of(autoCreateSubnetworks)); + } else if (args.length > 2) { + throw new IllegalArgumentException("Too many arguments."); + } else { + throw new IllegalArgumentException("Missing required arguments."); + } + } + + @Override + protected String params() { + return " true|false"; + } + } + + /** + * This class demonstrates how to list Compute subnetworks. + * + * @see + * Subnetworks: list + */ + private static class ListSubnetworksAction extends OptionalRegionAction { + + @Override + public void run(Compute compute, RegionId region) { + Iterator subnetworkIterator; + if (region != null) { + subnetworkIterator = compute.listSubnetworks(region.region()).iterateAll(); + } else { + subnetworkIterator = compute.listSubnetworks().iterateAll(); + } + while (subnetworkIterator.hasNext()) { + System.out.println(subnetworkIterator.next()); + } + } + } + + private abstract static class SubnetworkAction extends ComputeAction { + @Override + SubnetworkId parse(String... args) throws Exception { + String message; + if (args.length == 2) { + return SubnetworkId.of(args[0], args[1]); + } else if (args.length > 2) { + message = "Too many arguments."; + } else { + message = "Missing required region and subnetwork."; + } + throw new IllegalArgumentException(message); + } + + @Override + public String params() { + return " "; + } + } + + /** + * This class demonstrates how to retrieve information on a Compute subnetwork. + * + * @see + * Subnetworks: get + */ + private static class SubnetworkInfoAction extends SubnetworkAction { + @Override + public void run(Compute compute, SubnetworkId subnetwork) { + System.out.println("Subnetwork info: " + compute.getSubnetwork(subnetwork)); + } + } + + /** + * This class demonstrates how to delete a Compute subnetwork. + * + * @see + * Subnetworks: delete + */ + private static class DeleteSubnetworkAction extends SubnetworkAction { + @Override + public void run(Compute compute, SubnetworkId subnetwork) throws InterruptedException { + Operation operation = compute.deleteSubnetwork(subnetwork); + if (operation == null) { + System.out.println("Subnetwork " + subnetwork + " does not exist"); + return; + } + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Subnetwork " + subnetwork + " was deleted"); + } else { + System.out.println("Deletion of subnetwork " + subnetwork + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + } + + /** + * This class demonstrates how to create a Compute subnetwork. + * + * @see + * Subnetworks: insert + */ + private static class CreateSubnetworkAction extends ComputeAction { + @Override + public void run(Compute compute, SubnetworkInfo subnetwork) throws InterruptedException { + Operation operation = compute.create(subnetwork); + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Subnetwork " + subnetwork.subnetworkId() + " was created"); + } else { + System.out.println("Creation of subnetwork " + subnetwork.subnetworkId() + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + + @Override + SubnetworkInfo parse(String... args) throws Exception { + String message; + if (args.length == 4) { + SubnetworkId subnetwork = SubnetworkId.of(args[0], args[1]); + return SubnetworkInfo.of(subnetwork, NetworkId.of(args[2]), args[3]); + } else if (args.length > 4) { + message = "Too many arguments."; + } else { + message = "Missing required arguments."; + } + throw new IllegalArgumentException(message); + } + + @Override + protected String params() { + return " "; + } + } + + /** + * This class demonstrates how to list Compute instances. + * + * @see Instances: + * list + */ + private static class ListInstancesAction extends OptionalZoneAction { + @Override + public void run(Compute compute, ZoneId zone) { + Iterator instanceIterator; + if (zone != null) { + instanceIterator = compute.listInstances(zone.zone()).iterateAll(); + } else { + instanceIterator = compute.listInstances().iterateAll(); + } + while (instanceIterator.hasNext()) { + System.out.println(instanceIterator.next()); + } + } + } + + private abstract static class InstanceAction extends ComputeAction { + @Override + InstanceId parse(String... args) throws Exception { + String message; + if (args.length == 2) { + return InstanceId.of(args[0], args[1]); + } else if (args.length > 2) { + message = "Too many arguments."; + } else { + message = "Missing required zone and instance."; + } + throw new IllegalArgumentException(message); + } + + @Override + public String params() { + return " "; + } + } + + /** + * This class demonstrates how to retrieve information on a Compute instance. + * + * @see Instances: + * get + */ + private static class InstanceInfoAction extends InstanceAction { + @Override + public void run(Compute compute, InstanceId instance) { + System.out.println("Instance info: " + compute.getInstance(instance)); + } + } + + /** + * This class demonstrates how to delete a Compute instance. + * + * @see + * Instances: delete + */ + private static class DeleteInstanceAction extends InstanceAction { + @Override + public void run(Compute compute, InstanceId instance) throws InterruptedException { + Operation operation = compute.deleteInstance(instance); + if (operation == null) { + System.out.println("Instance " + instance + " does not exist"); + return; + } + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Instance " + instance + " was deleted"); + } else { + System.out.println("Deletion of instance " + instance + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + } + + /** + * This class demonstrates how to create a Compute instance. + * + * @see + * Instances: insert + */ + private static class CreateInstanceAction extends ComputeAction { + @Override + public void run(Compute compute, InstanceInfo instance) throws InterruptedException { + Operation operation = compute.create(instance); + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Instance " + instance.instanceId() + " was created"); + } else { + System.out.println("Creation of instance " + instance.instanceId() + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + + @Override + InstanceInfo parse(String... args) throws Exception { + String message; + if (args.length == 5) { + String zone = args[0]; + String instance = args[1]; + InstanceId instanceId = InstanceId.of(zone, instance); + MachineTypeId machineTypeId = MachineTypeId.of(zone, args[2]); + DiskId diskId = DiskId.of(zone, args[3]); + AttachedDisk disk = + AttachedDisk.of(PersistentDiskConfiguration.builder(diskId).boot(true).build()); + NetworkInterface networkInterface = NetworkInterface.of(args[4]); + return InstanceInfo.of(instanceId, machineTypeId, disk, networkInterface); + } else if (args.length > 5) { + message = "Too many arguments."; + } else { + message = "Missing required arguments."; + } + throw new IllegalArgumentException(message); + } + + @Override + protected String params() { + return " "; + } + } + + /** + * This class demonstrates how to get the serial port output for a Compute instance. + * + * @see + * Instances: getSerialPortOutput + */ + private static class GetSerialPortAction extends ComputeAction> { + @Override + public void run(Compute compute, Tuple instanceAndPort) + throws InterruptedException { + InstanceId instance = instanceAndPort.x(); + Integer port = instanceAndPort.y(); + String serialPortOutput; + if (port != null) { + System.out.println("Getting serial port " + port + " output for instance " + instance); + serialPortOutput = compute.getSerialPortOutput(instance, port); + } else { + System.out.println("Getting serial port output for instance " + instance); + serialPortOutput = compute.getSerialPortOutput(instance); + } + System.out.println(serialPortOutput); + } + + @Override + Tuple parse(String... args) throws Exception { + if (args.length >= 2) { + InstanceId instanceId = InstanceId.of(args[0], args[1]); + Integer port = null; + if (args.length == 3) { + try { + port = Integer.parseInt(args[2]); + } catch (NumberFormatException ex) { + throw new IllegalArgumentException( + "Error parsing portNumber parameter (must be a number)"); + } + } else if (args.length > 3) { + throw new IllegalArgumentException("Too many arguments."); + } + return Tuple.of(instanceId, port); + } else { + throw new IllegalArgumentException("Missing required arguments."); + } + } + + @Override + protected String params() { + return " "; + } + } + + /** + * This class demonstrates how to add an access configuration to a Compute instance network + * interface. + * + * @see + * Instances: addAccessConfig + */ + private static class AddAccessConfigAction + extends ComputeAction> { + @Override + public void run(Compute compute, Triple interfaceAndConfig) + throws InterruptedException { + InstanceId instance = interfaceAndConfig.x(); + String networkInterface = interfaceAndConfig.y(); + AccessConfig accessConfig = interfaceAndConfig.z(); + Operation operation = compute.addAccessConfig(instance, networkInterface, accessConfig); + if (operation == null) { + System.out.println("Instance " + instance + " does not exist"); + return; + } + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Access config added to network interface " + networkInterface + + " of instance " + instance); + } else { + System.out.println("Attempt to add access config to network interface " + networkInterface + + " of instance " + instance + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + + @Override + Triple parse(String... args) throws Exception { + String message; + if (args.length >= 4) { + InstanceId instance = InstanceId.of(args[0], args[1]); + String networkInterface = args[2]; + String accessConfig = args[3]; + if (args.length == 4) { + return Triple.of(instance, networkInterface, + AccessConfig.builder().name(accessConfig).build()); + } else if (args.length == 5) { + return Triple.of(instance, networkInterface, + AccessConfig.builder().name(accessConfig).natIp(args[4]).build()); + } else { + message = "Too many arguments."; + } + } else { + message = "Missing required arguments."; + } + throw new IllegalArgumentException(message); + } + + @Override + protected String params() { + return " ?"; + } + } + + /** + * This class demonstrates how to delete an access configuration from a Compute instance network + * interface. + * + * @see + * Instances: deleteAccessConfig + */ + private static class DeleteAccessConfigAction extends + ComputeAction> { + @Override + public void run(Compute compute, Triple interfaceAndConfig) + throws InterruptedException { + InstanceId instance = interfaceAndConfig.x(); + String networkInterface = interfaceAndConfig.y(); + String accessConfig = interfaceAndConfig.z(); + Operation operation = compute.deleteAccessConfig(instance, networkInterface, accessConfig); + if (operation == null) { + System.out.println("Instance " + instance + " does not exist"); + return; + } + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Access config deleted from network interface " + networkInterface + + " of instance " + instance); + } else { + System.out.println("Attempt to delete access config from network interface " + + networkInterface + " of instance " + instance + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + + @Override + Triple parse(String... args) throws Exception { + String message; + if (args.length == 4) { + InstanceId instance = InstanceId.of(args[0], args[1]); + String networkInterface = args[2]; + String accessConfig = args[3]; + return Triple.of(instance, networkInterface, accessConfig); + } else if (args.length > 4) { + message = "Too many arguments."; + } else { + message = "Missing required arguments."; + } + throw new IllegalArgumentException(message); + } + + @Override + protected String params() { + return " "; + } + } + + /** + * This class demonstrates how to attach a persistent disk to a Compute instance. + * + * @see + * Instances: attachDisk + */ + private static class AttachDiskAction + extends ComputeAction> { + @Override + public void run(Compute compute, Triple + instanceAndDisk) throws InterruptedException { + InstanceId instance = instanceAndDisk.x(); + String deviceName = instanceAndDisk.y(); + PersistentDiskConfiguration diskConfiguration = instanceAndDisk.z(); + Operation operation = compute.attachDisk(instance, deviceName, diskConfiguration); + if (operation == null) { + System.out.println("Instance " + instance + " does not exist"); + return; + } + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Disk attached to instance " + instance); + } else { + System.out.println("Attempt to attach disk to instance " + instance + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + + @Override + Triple parse(String... args) throws Exception { + String message; + if (args.length == 4) { + String zone = args[0]; + String instance = args[1]; + String deviceName = args[2]; + String disk = args[3]; + return Triple.of(InstanceId.of(zone, instance), deviceName, + PersistentDiskConfiguration.of(DiskId.of(zone, disk))); + } else if (args.length > 4) { + message = "Too many arguments."; + } else { + message = "Missing required arguments."; + } + throw new IllegalArgumentException(message); + } + + @Override + protected String params() { + return " "; + } + } + + /** + * This class demonstrates how to detach a persistent disk from a Compute instance. + * + * @see + * Instances: detachDisk + */ + private static class DetachDiskAction extends ComputeAction> { + @Override + public void run(Compute compute, Tuple instanceAndDevice) + throws InterruptedException { + InstanceId instance = instanceAndDevice.x(); + String deviceName = instanceAndDevice.y(); + Operation operation = compute.detachDisk(instance, deviceName); + if (operation == null) { + System.out.println("Instance " + instance + " does not exist"); + return; + } + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Disk detached from instance " + instance); + } else { + System.out.println("Attempt to detach disk from instance " + instance + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + + @Override + Tuple parse(String... args) throws Exception { + String message; + if (args.length == 3) { + String zone = args[0]; + String instance = args[1]; + String deviceName = args[2]; + return Tuple.of(InstanceId.of(zone, instance), deviceName); + } else if (args.length > 4) { + message = "Too many arguments."; + } else { + message = "Missing required arguments."; + } + throw new IllegalArgumentException(message); + } + + @Override + protected String params() { + return " "; + } + } + + /** + * This class demonstrates how to set the auto-delete property of a disk attached to a Compute + * instance. + * + * @see + * Instances: setDiskAutoDelete + */ + private static class SetDiskAutoDeleteAction + extends ComputeAction> { + @Override + public void run(Compute compute, Triple deviceAndAutoDelete) + throws InterruptedException { + InstanceId instance = deviceAndAutoDelete.x(); + String deviceName = deviceAndAutoDelete.y(); + Boolean autoDelete = deviceAndAutoDelete.z(); + Operation operation = compute.setDiskAutoDelete(instance, deviceName, autoDelete); + if (operation == null) { + System.out.println("Instance " + instance + " does not exist"); + return; + } + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Auto-delete set for device " + deviceName + " of instance " + instance); + } else { + System.out.println("Attempt to set auto-delete for device " + deviceName + " of instance " + + instance + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + + @Override + Triple parse(String... args) throws Exception { + String message; + if (args.length == 4) { + InstanceId instance = InstanceId.of(args[0], args[1]); + String deviceName = args[2]; + boolean autoDelete; + switch (args[3]) { + case "true": + autoDelete = true; + break; + case "false": + autoDelete = false; + break; + default: + throw new IllegalArgumentException( + "Couldn't parse autoDelete argument (must be either true or false)."); + } + return Triple.of(instance, deviceName, autoDelete); + } else if (args.length > 3) { + message = "Too many arguments."; + } else { + message = "Missing required arguments."; + } + throw new IllegalArgumentException(message); + } + + @Override + protected String params() { + return " true|false"; + } + } + + /** + * This class demonstrates how to set the machine type for a Compute instance. + * + * @see + * Instances: setMachineType + */ + private static class SetMachineTypeAction + extends ComputeAction> { + @Override + public void run(Compute compute, Tuple instanceAndType) + throws InterruptedException { + InstanceId instance = instanceAndType.x(); + MachineTypeId machineType = instanceAndType.y(); + Operation operation = compute.setMachineType(instance, machineType); + if (operation == null) { + System.out.println("Instance " + instance + " does not exist"); + return; + } + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Machine type set for instance " + instance); + } else { + System.out.println("Attempt to set machine type for instance " + instance + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + + @Override + Tuple parse(String... args) throws Exception { + String message; + if (args.length == 3) { + String zone = args[0]; + String instance = args[1]; + String machineType = args[2]; + return Tuple.of(InstanceId.of(zone, instance), MachineTypeId.of(zone, machineType)); + } else if (args.length > 3) { + message = "Too many arguments."; + } else { + message = "Missing required arguments."; + } + throw new IllegalArgumentException(message); + } + + @Override + protected String params() { + return " "; + } + } + + /** + * This class demonstrates how to set the tags for a Compute instance. + * + * @see + * Instances: setTags + */ + private static class SetTagsAction extends ComputeAction>> { + @Override + public void run(Compute compute, Tuple> instanceAndTags) + throws InterruptedException { + InstanceId instanceId = instanceAndTags.x(); + List tags = instanceAndTags.y(); + Instance instance = compute.getInstance(instanceId); + if (instance == null) { + System.out.println("Instance " + instance + " does not exist"); + return; + } + Operation operation = instance.setTags(tags); + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Tags set for instance " + instanceId); + } else { + System.out.println("Attempt to set tags for instance " + instanceId + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + + @Override + Tuple> parse(String... args) throws Exception { + if (args.length >= 2) { + InstanceId instanceId = InstanceId.of(args[0], args[1]); + List tags = Lists.newArrayListWithCapacity(args.length - 2); + tags.addAll(Arrays.asList(args).subList(2, args.length)); + return Tuple.of(instanceId, tags); + } else { + throw new IllegalArgumentException("Missing required arguments."); + } + } + + @Override + protected String params() { + return " *"; + } + } + + /** + * This class demonstrates how to set the metadata for a Compute instance. + * + * @see + * Instances: setMetadata + */ + private static class SetMetadataAction extends ComputeAction>> { + @Override + public void run(Compute compute, Tuple> instanceAndMetadata) + throws InterruptedException { + InstanceId instanceId = instanceAndMetadata.x(); + Map metadata = instanceAndMetadata.y(); + Instance instance = compute.getInstance(instanceId); + if (instance == null) { + System.out.println("Instance " + instance + " does not exist"); + return; + } + Operation operation = instance.setMetadata(metadata); + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Metadata set for instance " + instanceId); + } else { + System.out.println("Attempt to set metadata for instance " + instanceId + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + + @Override + Tuple> parse(String... args) throws Exception { + if (args.length >= 2) { + if ((args.length & 0x1) == 0x1) { + throw new IllegalArgumentException("Metadata must be a list of key-value pairs."); + } + InstanceId instanceId = InstanceId.of(args[0], args[1]); + Map metadata = Maps.newHashMapWithExpectedSize((args.length / 2) - 1); + for (int i = 2; i < args.length; i += 2) { + metadata.put(args[i], args[i + 1]); + } + return Tuple.of(instanceId, metadata); + } else { + throw new IllegalArgumentException("Missing required arguments."); + } + } + + @Override + protected String params() { + return " ( )*"; + } + } + + /** + * This class demonstrates how to set the scheduling options for a Compute instance. + * + * @see + * Instances: setScheduling + */ + private static class SetSchedulingOptionsAction extends ComputeAction> { + @Override + public void run(Compute compute, Tuple instanceAndScheduling) + throws InterruptedException { + InstanceId instanceId = instanceAndScheduling.x(); + SchedulingOptions schedulingOptions = instanceAndScheduling.y(); + Operation operation = compute.setSchedulingOptions(instanceId, schedulingOptions); + if (operation == null) { + System.out.println("Instance " + instanceId + " does not exist"); + return; + } + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Scheduling options set for instance " + instanceId); + } else { + System.out.println( + "Attempt to set scheduling options for instance " + instanceId + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + + @Override + Tuple parse(String... args) throws Exception { + String message; + if (args.length > 2) { + InstanceId instanceId = InstanceId.of(args[0], args[1]); + if (args.length == 3 && args[2].equals("preemptible")) { + return Tuple.of(instanceId, SchedulingOptions.preemptible()); + } else if (args.length == 5 && args[2].equals("standard")) { + boolean automaticRestart; + switch (args[3]) { + case "true": + automaticRestart = true; + break; + case "false": + automaticRestart = false; + break; + default: + throw new IllegalArgumentException( + "Couldn't parse automaticRestart argument (must be either true or false)."); + } + Maintenance maintenance = Maintenance.valueOf(args[4]); + return Tuple.of(instanceId, SchedulingOptions.standard(automaticRestart, maintenance)); + } else { + message = "Unexpected command line arguments."; + } + } else { + message = "Missing required arguments."; + } + throw new IllegalArgumentException(message); + } + + @Override + protected String params() { + return " preemptible|(standard true|false MIGRATE|TERMINATE)"; + } + } + + /** + * This class demonstrates how to reset a Compute instance. + * + * @see + * Instances: reset + */ + private static class ResetInstanceAction extends InstanceAction { + @Override + public void run(Compute compute, InstanceId instance) throws InterruptedException { + Operation operation = compute.reset(instance); + if (operation == null) { + System.out.println("Instance " + instance + " does not exist"); + return; + } + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Instance " + instance + " was reset"); + } else { + System.out.println("Attempt to reset instance " + instance + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + } + + /** + * This class demonstrates how to stop a Compute instance. + * + * @see + * Instances: stop + */ + private static class StopInstanceAction extends InstanceAction { + @Override + public void run(Compute compute, InstanceId instance) throws InterruptedException { + Operation operation = compute.stop(instance); + if (operation == null) { + System.out.println("Instance " + instance + " does not exist"); + return; + } + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Instance " + instance + " was stopped"); + } else { + System.out.println("Attempt to stop instance " + instance + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + } + + /** + * This class demonstrates how to start a Compute instance. + * + * @see + * Instances: start + */ + private static class StartInstanceAction extends InstanceAction { + @Override + public void run(Compute compute, InstanceId instance) throws InterruptedException { + Operation operation = compute.start(instance); + if (operation == null) { + System.out.println("Instance " + instance + " does not exist"); + return; + } + while (!operation.isDone()) { + System.out.println( + "Waiting for operation " + operation.operationId().operation() + " to complete"); + Thread.sleep(1000L); + } + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Instance " + instance + " was started"); + } else { + System.out.println("Attempt to start instance " + instance + " failed"); + System.out.println("Error: " + operation.errors()); + } + } + } + + static { + CREATE_ACTIONS.put("address", new CreateAddressAction()); + CREATE_ACTIONS.put("snapshot", new CreateSnapshotAction()); + CREATE_ACTIONS.put("image", new CreateImageAction()); + CREATE_ACTIONS.put("standard-disk", new CreateStandardDiskAction()); + CREATE_ACTIONS.put("snapshot-disk", new CreateSnapshotDiskAction()); + CREATE_ACTIONS.put("image-disk", new CreateImageDiskAction()); + CREATE_ACTIONS.put("standard-network", new CreateStandardNetworkAction()); + CREATE_ACTIONS.put("subnet-network", new CreateSubnetNetworkAction()); + CREATE_ACTIONS.put("subnetwork", new CreateSubnetworkAction()); + CREATE_ACTIONS.put("instance", new CreateInstanceAction()); + INFO_ACTIONS.put("diskType", new DiskTypeInfoAction()); + INFO_ACTIONS.put("machineType", new MachineTypeInfoAction()); + INFO_ACTIONS.put("region", new RegionInfoAction()); + INFO_ACTIONS.put("zone", new ZoneInfoAction()); + INFO_ACTIONS.put("global-operation", new GlobalOperationInfoAction()); + INFO_ACTIONS.put("zone-operation", new ZoneOperationInfoAction()); + INFO_ACTIONS.put("region-operation", new RegionOperationInfoAction()); + INFO_ACTIONS.put("license", new LicenseInfoAction()); + INFO_ACTIONS.put("address", new AddressInfoAction()); + INFO_ACTIONS.put("snapshot", new SnapshotInfoAction()); + INFO_ACTIONS.put("image", new ImageInfoAction()); + INFO_ACTIONS.put("disk", new DiskInfoAction()); + INFO_ACTIONS.put("network", new NetworkInfoAction()); + INFO_ACTIONS.put("subnetwork", new SubnetworkInfoAction()); + INFO_ACTIONS.put("instance", new InstanceInfoAction()); + LIST_ACTIONS.put("diskTypes", new ListDiskTypesAction()); + LIST_ACTIONS.put("machineTypes", new ListMachineTypesAction()); + LIST_ACTIONS.put("regions", new ListRegionsAction()); + LIST_ACTIONS.put("zones", new ListZonesAction()); + LIST_ACTIONS.put("global-operations", new ListGlobalOperationsAction()); + LIST_ACTIONS.put("zone-operations", new ListZoneOperationsAction()); + LIST_ACTIONS.put("region-operations", new ListRegionOperationsAction()); + LIST_ACTIONS.put("addresses", new ListAddressesAction()); + LIST_ACTIONS.put("snapshots", new ListSnapshotsAction()); + LIST_ACTIONS.put("images", new ListImagesAction()); + LIST_ACTIONS.put("disks", new ListDisksAction()); + LIST_ACTIONS.put("networks", new ListNetworksAction()); + LIST_ACTIONS.put("subnetworks", new ListSubnetworksAction()); + LIST_ACTIONS.put("instances", new ListInstancesAction()); + DELETE_ACTIONS.put("global-operation", new DeleteGlobalOperationAction()); + DELETE_ACTIONS.put("zone-operation", new DeleteZoneOperationAction()); + DELETE_ACTIONS.put("region-operation", new DeleteRegionOperationAction()); + DELETE_ACTIONS.put("address", new DeleteAddressAction()); + DELETE_ACTIONS.put("snapshot", new DeleteSnapshotAction()); + DELETE_ACTIONS.put("image", new DeleteImageAction()); + DELETE_ACTIONS.put("disk", new DeleteDiskAction()); + DELETE_ACTIONS.put("network", new DeleteNetworkAction()); + DELETE_ACTIONS.put("subnetwork", new DeleteSubnetworkAction()); + DELETE_ACTIONS.put("instance", new DeleteInstanceAction()); + ACTIONS.put("create", new ParentAction(CREATE_ACTIONS)); + ACTIONS.put("info", new ParentAction(INFO_ACTIONS)); + ACTIONS.put("list", new ParentAction(LIST_ACTIONS)); + ACTIONS.put("delete", new ParentAction(DELETE_ACTIONS)); + ACTIONS.put("get-serial-port", new GetSerialPortAction()); + ACTIONS.put("add-access-config", new AddAccessConfigAction()); + ACTIONS.put("delete-access-config", new DeleteAccessConfigAction()); + ACTIONS.put("attach-disk", new AttachDiskAction()); + ACTIONS.put("detach-disk", new DetachDiskAction()); + ACTIONS.put("set-disk-auto-delete", new SetDiskAutoDeleteAction()); + ACTIONS.put("set-machine-type", new SetMachineTypeAction()); + ACTIONS.put("set-tags", new SetTagsAction()); + ACTIONS.put("set-metadata", new SetMetadataAction()); + ACTIONS.put("set-scheduling-options", new SetSchedulingOptionsAction()); + ACTIONS.put("reset", new ResetInstanceAction()); + ACTIONS.put("stop", new StopInstanceAction()); + ACTIONS.put("start", new StartInstanceAction()); + } + + private static void printUsage() { + StringBuilder actionAndParams = new StringBuilder(); + for (Map.Entry entry : ACTIONS.entrySet()) { + actionAndParams.append("\n\t").append(entry.getKey()); + + String param = entry.getValue().params(); + if (param != null && !param.isEmpty()) { + actionAndParams.append(' ').append(param.replace("\n", "\n\t\t")); + } + } + System.out.printf("Usage: %s [] operation [entity] *%s%n", + ComputeExample.class.getSimpleName(), actionAndParams); + } + + @SuppressWarnings("unchecked") + public static void main(String... args) throws Exception { + if (args.length < 1) { + System.out.println("Missing required project id and action"); + printUsage(); + return; + } + ComputeOptions.Builder optionsBuilder = ComputeOptions.builder(); + ComputeAction action; + String actionName; + if (args.length >= 2 && !ACTIONS.containsKey(args[0])) { + actionName = args[1]; + optionsBuilder.projectId(args[0]); + action = ACTIONS.get(args[1]); + args = Arrays.copyOfRange(args, 2, args.length); + } else { + actionName = args[0]; + action = ACTIONS.get(args[0]); + args = Arrays.copyOfRange(args, 1, args.length); + } + if (action == null) { + System.out.println("Unrecognized action."); + printUsage(); + return; + } + Compute compute = optionsBuilder.build().service(); + Object request; + try { + request = action.parse(args); + } catch (IllegalArgumentException ex) { + System.out.println("Invalid input for action '" + actionName + "'. " + ex.getMessage()); + System.out.println("Expected: " + action.params()); + return; + } catch (Exception ex) { + System.out.println("Failed to parse request."); + ex.printStackTrace(); + return; + } + action.run(compute, request); + } +} diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateAddressDiskAndInstance.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateAddressDiskAndInstance.java new file mode 100644 index 000000000000..ea1857479fda --- /dev/null +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateAddressDiskAndInstance.java @@ -0,0 +1,111 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.examples.compute.snippets; + +import com.google.gcloud.compute.Address; +import com.google.gcloud.compute.AddressInfo; +import com.google.gcloud.compute.AttachedDisk; +import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; +import com.google.gcloud.compute.Compute; +import com.google.gcloud.compute.ComputeOptions; +import com.google.gcloud.compute.DiskId; +import com.google.gcloud.compute.DiskInfo; +import com.google.gcloud.compute.ImageDiskConfiguration; +import com.google.gcloud.compute.ImageId; +import com.google.gcloud.compute.InstanceId; +import com.google.gcloud.compute.InstanceInfo; +import com.google.gcloud.compute.MachineTypeId; +import com.google.gcloud.compute.NetworkId; +import com.google.gcloud.compute.NetworkInterface; +import com.google.gcloud.compute.NetworkInterface.AccessConfig; +import com.google.gcloud.compute.Operation; +import com.google.gcloud.compute.RegionAddressId; + +/** + * A snippet for Google Cloud Compute Engine showing how to create a disk and an address. The + * snippet also shows how to create a virtual machine instance using the created disk and address. + */ +public class CreateAddressDiskAndInstance { + + public static void main(String... args) throws InterruptedException { + // Create a service object + // Credentials are inferred from the environment. + Compute compute = ComputeOptions.defaultInstance().service(); + + // Create an external region address + RegionAddressId addressId = RegionAddressId.of("us-central1", "test-address"); + Operation operation = compute.create(AddressInfo.of(addressId)); + // Wait for operation to complete + while (!operation.isDone()) { + Thread.sleep(1000L); + } + // Check operation errors + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Address " + addressId + " was successfully created"); + } else { + // inspect operation.errors() + throw new RuntimeException("Address creation failed"); + } + + // Create a persistent disk + ImageId imageId = ImageId.of("debian-cloud", "debian-8-jessie-v20160329"); + DiskId diskId = DiskId.of("us-central1-a", "test-disk"); + ImageDiskConfiguration diskConfiguration = ImageDiskConfiguration.of(imageId); + DiskInfo disk = DiskInfo.of(diskId, diskConfiguration); + operation = compute.create(disk); + // Wait for operation to complete + while (!operation.isDone()) { + Thread.sleep(1000L); + } + // Check operation errors + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Disk " + diskId + " was successfully created"); + } else { + // inspect operation.errors() + throw new RuntimeException("Disk creation failed"); + } + + // Create a virtual machine instance + Address externalIp = compute.getAddress(addressId); + InstanceId instanceId = InstanceId.of("us-central1-a", "test-instance"); + NetworkId networkId = NetworkId.of("default"); + PersistentDiskConfiguration attachConfiguration = + PersistentDiskConfiguration.builder(diskId).boot(true).build(); + AttachedDisk attachedDisk = AttachedDisk.of("dev0", attachConfiguration); + NetworkInterface networkInterface = NetworkInterface.builder(networkId) + .accessConfigurations(AccessConfig.of(externalIp.address())) + .build(); + MachineTypeId machineTypeId = MachineTypeId.of("us-central1-a", "n1-standard-1"); + InstanceInfo instance = + InstanceInfo.of(instanceId, machineTypeId, attachedDisk, networkInterface); + operation = compute.create(instance); + // Wait for operation to complete + while (!operation.isDone()) { + Thread.sleep(1000L); + } + // Check operation errors + operation = operation.reload(); + if (operation.errors() == null) { + System.out.println("Instance " + instanceId + " was successfully created"); + } else { + // inspect operation.errors() + throw new RuntimeException("Instance creation failed"); + } + } +} diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateInstance.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateInstance.java new file mode 100644 index 000000000000..db72f25cc90e --- /dev/null +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateInstance.java @@ -0,0 +1,54 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.examples.compute.snippets; + +import com.google.gcloud.compute.AttachedDisk; +import com.google.gcloud.compute.Compute; +import com.google.gcloud.compute.ComputeOptions; +import com.google.gcloud.compute.ImageId; +import com.google.gcloud.compute.Instance; +import com.google.gcloud.compute.InstanceId; +import com.google.gcloud.compute.InstanceInfo; +import com.google.gcloud.compute.MachineTypeId; +import com.google.gcloud.compute.NetworkId; +import com.google.gcloud.compute.NetworkInterface; +import com.google.gcloud.compute.Operation; + +/** + * A snippet for Google Cloud Compute Engine showing how to create a virtual machine instance. + */ +public class CreateInstance { + + public static void main(String... args) throws InterruptedException { + Compute compute = ComputeOptions.defaultInstance().service(); + ImageId imageId = ImageId.of("debian-cloud", "debian-8-jessie-v20160329"); + NetworkId networkId = NetworkId.of("default"); + AttachedDisk attachedDisk = AttachedDisk.of(AttachedDisk.CreateDiskConfiguration.of(imageId)); + NetworkInterface networkInterface = NetworkInterface.of(networkId); + InstanceId instanceId = InstanceId.of("us-central1-a", "instance-name"); + MachineTypeId machineTypeId = MachineTypeId.of("us-central1-a", "n1-standard-1"); + Operation operation = + compute.create(InstanceInfo.of(instanceId, machineTypeId, attachedDisk, networkInterface)); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + if (operation.errors() == null) { + // use instance + Instance instance = compute.getInstance(instanceId); + } + } +} diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateSnapshot.java b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateSnapshot.java new file mode 100644 index 000000000000..a0684d63d9fb --- /dev/null +++ b/gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateSnapshot.java @@ -0,0 +1,48 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.gcloud.examples.compute.snippets; + +import com.google.gcloud.compute.Compute; +import com.google.gcloud.compute.ComputeOptions; +import com.google.gcloud.compute.Disk; +import com.google.gcloud.compute.DiskId; +import com.google.gcloud.compute.Operation; +import com.google.gcloud.compute.Snapshot; + +/** + * A snippet for Google Cloud Compute Engine showing how to create a snapshot of a disk if the disk + * exists. + */ +public class CreateSnapshot { + + public static void main(String... args) throws InterruptedException { + Compute compute = ComputeOptions.defaultInstance().service(); + DiskId diskId = DiskId.of("us-central1-a", "disk-name"); + Disk disk = compute.getDisk(diskId, Compute.DiskOption.fields()); + if (disk != null) { + String snapshotName = "disk-name-snapshot"; + Operation operation = disk.createSnapshot(snapshotName); + while (!operation.isDone()) { + Thread.sleep(1000L); + } + if (operation.errors() == null) { + // use snapshot + Snapshot snapshot = compute.getSnapshot("disk-name-snapshot"); + } + } + } +} From dd0b186dbbaa92a81486a478dbda1528695eb394 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 29 Apr 2016 12:41:02 +0200 Subject: [PATCH 328/375] Rename package com.google.gcloud to com.google.cloud --- README.md | 44 +- gcloud-java-compute/README.md | 62 +- gcloud-java-compute/pom.xml | 4 +- .../{gcloud => cloud}/compute/Address.java | 11 +- .../{gcloud => cloud}/compute/AddressId.java | 2 +- .../compute/AddressInfo.java | 2 +- .../compute/AttachedDisk.java | 2 +- .../{gcloud => cloud}/compute/Compute.java | 12 +- .../compute/ComputeException.java | 8 +- .../compute/ComputeFactory.java | 4 +- .../compute/ComputeImpl.java | 20 +- .../compute/ComputeOptions.java | 10 +- .../compute/DeprecationStatus.java | 2 +- .../{gcloud => cloud}/compute/Disk.java | 6 +- .../compute/DiskConfiguration.java | 2 +- .../{gcloud => cloud}/compute/DiskId.java | 2 +- .../compute/DiskImageConfiguration.java | 2 +- .../{gcloud => cloud}/compute/DiskInfo.java | 2 +- .../{gcloud => cloud}/compute/DiskType.java | 2 +- .../{gcloud => cloud}/compute/DiskTypeId.java | 2 +- .../compute/ForwardingRuleId.java | 2 +- .../compute/GlobalAddressId.java | 2 +- .../compute/GlobalForwardingRuleId.java | 2 +- .../compute/GlobalOperationId.java | 2 +- .../{gcloud => cloud}/compute/Image.java | 6 +- .../compute/ImageConfiguration.java | 2 +- .../compute/ImageDiskConfiguration.java | 2 +- .../{gcloud => cloud}/compute/ImageId.java | 2 +- .../{gcloud => cloud}/compute/ImageInfo.java | 2 +- .../{gcloud => cloud}/compute/Instance.java | 10 +- .../{gcloud => cloud}/compute/InstanceId.java | 2 +- .../compute/InstanceInfo.java | 2 +- .../{gcloud => cloud}/compute/License.java | 2 +- .../{gcloud => cloud}/compute/LicenseId.java | 2 +- .../compute/MachineType.java | 2 +- .../compute/MachineTypeId.java | 2 +- .../{gcloud => cloud}/compute/Metadata.java | 2 +- .../{gcloud => cloud}/compute/Network.java | 6 +- .../compute/NetworkConfiguration.java | 2 +- .../{gcloud => cloud}/compute/NetworkId.java | 2 +- .../compute/NetworkInfo.java | 2 +- .../compute/NetworkInterface.java | 2 +- .../{gcloud => cloud}/compute/Operation.java | 11 +- .../compute/OperationId.java | 2 +- .../{gcloud => cloud}/compute/Option.java | 4 +- .../{gcloud => cloud}/compute/Region.java | 2 +- .../compute/RegionAddressId.java | 2 +- .../compute/RegionForwardingRuleId.java | 2 +- .../{gcloud => cloud}/compute/RegionId.java | 2 +- .../compute/RegionOperationId.java | 2 +- .../{gcloud => cloud}/compute/ResourceId.java | 2 +- .../compute/SchedulingOptions.java | 2 +- .../compute/ServiceAccount.java | 2 +- .../{gcloud => cloud}/compute/Snapshot.java | 6 +- .../compute/SnapshotDiskConfiguration.java | 2 +- .../{gcloud => cloud}/compute/SnapshotId.java | 2 +- .../compute/SnapshotInfo.java | 2 +- .../compute/StandardDiskConfiguration.java | 2 +- .../compute/StandardNetworkConfiguration.java | 2 +- .../compute/StorageImageConfiguration.java | 2 +- .../compute/SubnetNetworkConfiguration.java | 2 +- .../{gcloud => cloud}/compute/Subnetwork.java | 6 +- .../compute/SubnetworkId.java | 2 +- .../compute/SubnetworkInfo.java | 2 +- .../{gcloud => cloud}/compute/Tags.java | 2 +- .../{gcloud => cloud}/compute/Zone.java | 2 +- .../{gcloud => cloud}/compute/ZoneId.java | 2 +- .../compute/ZoneOperationId.java | 2 +- .../compute/package-info.java | 6 +- .../compute/spi/ComputeRpc.java | 4 +- .../compute/spi/ComputeRpcFactory.java | 6 +- .../compute/spi/DefaultComputeRpc.java | 260 +++-- .../compute/testing/RemoteComputeHelper.java | 8 +- .../compute/testing/package-info.java | 2 +- .../compute/AddressIdTest.java | 2 +- .../compute/AddressInfoTest.java | 30 +- .../compute/AddressTest.java | 2 +- .../compute/AttachedDiskTest.java | 12 +- .../compute/ComputeExceptionTest.java | 6 +- .../compute/ComputeImplTest.java | 936 ++++++++---------- .../compute/DeprecationStatusTest.java | 6 +- .../{gcloud => cloud}/compute/DiskIdTest.java | 2 +- .../compute/DiskImageConfigurationTest.java | 12 +- .../compute/DiskInfoTest.java | 5 +- .../{gcloud => cloud}/compute/DiskTest.java | 5 +- .../compute/DiskTypeIdTest.java | 2 +- .../compute/DiskTypeTest.java | 2 +- .../compute/ForwardingRuleIdTest.java | 2 +- .../compute/ImageDiskConfigurationTest.java | 6 +- .../compute/ImageIdTest.java | 2 +- .../compute/ImageInfoTest.java | 4 +- .../{gcloud => cloud}/compute/ImageTest.java | 12 +- .../compute/InstanceIdTest.java | 2 +- .../compute/InstanceInfoTest.java | 7 +- .../compute/InstanceTest.java | 99 +- .../compute/LicenseIdTest.java | 2 +- .../compute/LicenseTest.java | 2 +- .../compute/MachineTypeIdTest.java | 2 +- .../compute/MachineTypeTest.java | 2 +- .../compute/MetadataTest.java | 2 +- .../compute/NetworkIdTest.java | 2 +- .../compute/NetworkInfoTest.java | 2 +- .../compute/NetworkInterfaceTest.java | 29 +- .../compute/NetworkTest.java | 2 +- .../compute/OperationIdTest.java | 2 +- .../compute/OperationTest.java | 27 +- .../compute/RegionIdTest.java | 2 +- .../{gcloud => cloud}/compute/RegionTest.java | 2 +- .../compute/SchedulingOptionsTest.java | 2 +- .../compute/SerializationTest.java | 14 +- .../compute/ServiceAccountTest.java | 2 +- .../SnapshotDiskConfigurationTest.java | 6 +- .../compute/SnapshotIdTest.java | 2 +- .../compute/SnapshotInfoTest.java | 6 +- .../compute/SnapshotTest.java | 2 +- .../StandardDiskConfigurationTest.java | 6 +- .../StandardNetworkConfigurationTest.java | 6 +- .../StorageImageConfigurationTest.java | 15 +- .../SubnetNetworkConfigurationTest.java | 12 +- .../compute/SubnetworkIdTest.java | 2 +- .../compute/SubnetworkInfoTest.java | 2 +- .../compute/SubnetworkTest.java | 2 +- .../{gcloud => cloud}/compute/TagsTest.java | 2 +- .../{gcloud => cloud}/compute/ZoneIdTest.java | 2 +- .../{gcloud => cloud}/compute/ZoneTest.java | 2 +- .../compute/it/ITComputeTest.java | 145 ++- .../testing/RemoteComputeHelperTest.java | 6 +- gcloud-java-examples/README.md | 10 +- .../examples/compute/ComputeExample.java | 108 +- .../CreateAddressDiskAndInstance.java | 38 +- .../compute/snippets/CreateInstance.java | 24 +- .../compute/snippets/CreateSnapshot.java | 14 +- 132 files changed, 1104 insertions(+), 1178 deletions(-) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/Address.java (94%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/AddressId.java (98%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/AddressInfo.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/AttachedDisk.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/Compute.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/ComputeException.java (90%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/ComputeFactory.java (90%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/ComputeImpl.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/ComputeOptions.java (92%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/DeprecationStatus.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/Disk.java (98%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/DiskConfiguration.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/DiskId.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/DiskImageConfiguration.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/DiskInfo.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/DiskType.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/DiskTypeId.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/ForwardingRuleId.java (98%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/GlobalAddressId.java (98%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/GlobalForwardingRuleId.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/GlobalOperationId.java (98%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/Image.java (97%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/ImageConfiguration.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/ImageDiskConfiguration.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/ImageId.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/ImageInfo.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/Instance.java (98%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/InstanceId.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/InstanceInfo.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/License.java (98%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/LicenseId.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/MachineType.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/MachineTypeId.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/Metadata.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/Network.java (97%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/NetworkConfiguration.java (98%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/NetworkId.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/NetworkInfo.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/NetworkInterface.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/Operation.java (98%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/OperationId.java (98%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/Option.java (95%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/Region.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/RegionAddressId.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/RegionForwardingRuleId.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/RegionId.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/RegionOperationId.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/ResourceId.java (98%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/SchedulingOptions.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/ServiceAccount.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/Snapshot.java (97%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/SnapshotDiskConfiguration.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/SnapshotId.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/SnapshotInfo.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/StandardDiskConfiguration.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/StandardNetworkConfiguration.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/StorageImageConfiguration.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/SubnetNetworkConfiguration.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/Subnetwork.java (97%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/SubnetworkId.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/SubnetworkInfo.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/Tags.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/Zone.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/ZoneId.java (98%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/ZoneOperationId.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/package-info.java (91%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/spi/ComputeRpc.java (99%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/spi/ComputeRpcFactory.java (85%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/spi/DefaultComputeRpc.java (82%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/testing/RemoteComputeHelper.java (96%) rename gcloud-java-compute/src/main/java/com/google/{gcloud => cloud}/compute/testing/package-info.java (96%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/AddressIdTest.java (99%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/AddressInfoTest.java (89%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/AddressTest.java (99%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/AttachedDiskTest.java (97%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/ComputeExceptionTest.java (96%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/ComputeImplTest.java (80%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/DeprecationStatusTest.java (98%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/DiskIdTest.java (98%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/DiskImageConfigurationTest.java (92%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/DiskInfoTest.java (98%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/DiskTest.java (99%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/DiskTypeIdTest.java (98%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/DiskTypeTest.java (98%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/ForwardingRuleIdTest.java (99%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/ImageDiskConfigurationTest.java (97%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/ImageIdTest.java (98%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/ImageInfoTest.java (98%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/ImageTest.java (96%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/InstanceIdTest.java (98%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/InstanceInfoTest.java (96%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/InstanceTest.java (89%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/LicenseIdTest.java (98%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/LicenseTest.java (97%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/MachineTypeIdTest.java (98%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/MachineTypeTest.java (99%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/MetadataTest.java (98%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/NetworkIdTest.java (98%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/NetworkInfoTest.java (99%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/NetworkInterfaceTest.java (84%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/NetworkTest.java (99%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/OperationIdTest.java (99%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/OperationTest.java (94%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/RegionIdTest.java (98%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/RegionTest.java (99%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/SchedulingOptionsTest.java (98%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/SerializationTest.java (97%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/ServiceAccountTest.java (97%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/SnapshotDiskConfigurationTest.java (97%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/SnapshotIdTest.java (98%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/SnapshotInfoTest.java (97%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/SnapshotTest.java (99%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/StandardDiskConfigurationTest.java (97%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/StandardNetworkConfigurationTest.java (96%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/StorageImageConfigurationTest.java (88%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/SubnetNetworkConfigurationTest.java (88%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/SubnetworkIdTest.java (98%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/SubnetworkInfoTest.java (99%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/SubnetworkTest.java (99%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/TagsTest.java (98%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/ZoneIdTest.java (98%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/ZoneTest.java (98%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/it/ITComputeTest.java (95%) rename gcloud-java-compute/src/test/java/com/google/{gcloud => cloud}/compute/testing/RemoteComputeHelperTest.java (96%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/compute/ComputeExample.java (97%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/compute/snippets/CreateAddressDiskAndInstance.java (79%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/compute/snippets/CreateInstance.java (75%) rename gcloud-java-examples/src/main/java/com/google/{gcloud => cloud}/examples/compute/snippets/CreateSnapshot.java (81%) diff --git a/README.md b/README.md index daa3813b1fb7..0768939df6b3 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,8 @@ Example Applications - [`BigQueryExample`](./gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java) - A simple command line interface providing some of Cloud BigQuery's functionality - Read more about using this application on the [`BigQueryExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/cloud/examples/bigquery/BigQueryExample.html). -- [`ComputeExample`](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/ComputeExample.java) - A simple command line interface providing some of Cloud Compute's functionality - - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/compute/ComputeExample.html). +- [`ComputeExample`](./gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/ComputeExample.java) - A simple command line interface providing some of Cloud Compute's functionality + - Read more about using this application on the [`gcloud-java-examples` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/cloud/examples/compute/ComputeExample.html). - [`Bookshelf`](https://github.com/GoogleCloudPlatform/getting-started-java/tree/master/bookshelf) - An App Engine app that manages a virtual bookshelf. - This app uses `gcloud-java` to interface with Cloud Datastore and Cloud Storage. It also uses Cloud SQL, another Google Cloud Platform service. - [`DatastoreExample`](./gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/DatastoreExample.java) - A simple command line interface for Cloud Datastore @@ -189,15 +189,15 @@ you must [supply credentials](#authentication) and a project ID if running this The first snippet shows how to create a snapshot from an existing disk. Complete source code can be found at -[CreateSnapshot.java](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateSnapshot.java). +[CreateSnapshot.java](./gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateSnapshot.java). ```java -import com.google.gcloud.compute.Compute; -import com.google.gcloud.compute.ComputeOptions; -import com.google.gcloud.compute.Disk; -import com.google.gcloud.compute.DiskId; -import com.google.gcloud.compute.Operation; -import com.google.gcloud.compute.Snapshot; +import com.google.cloud.compute.Compute; +import com.google.cloud.compute.ComputeOptions; +import com.google.cloud.compute.Disk; +import com.google.cloud.compute.DiskId; +import com.google.cloud.compute.Operation; +import com.google.cloud.compute.Snapshot; Compute compute = ComputeOptions.defaultInstance().service(); DiskId diskId = DiskId.of("us-central1-a", "disk-name"); @@ -216,19 +216,19 @@ if (disk != null) { ``` The second snippet shows how to create a virtual machine instance. Complete source code can be found at -[CreateInstance.java](./gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateInstance.java). +[CreateInstance.java](./gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateInstance.java). ```java -import com.google.gcloud.compute.AttachedDisk; -import com.google.gcloud.compute.Compute; -import com.google.gcloud.compute.ComputeOptions; -import com.google.gcloud.compute.ImageId; -import com.google.gcloud.compute.Instance; -import com.google.gcloud.compute.InstanceId; -import com.google.gcloud.compute.InstanceInfo; -import com.google.gcloud.compute.MachineTypeId; -import com.google.gcloud.compute.NetworkId; -import com.google.gcloud.compute.NetworkInterface; -import com.google.gcloud.compute.Operation; +import com.google.cloud.compute.AttachedDisk; +import com.google.cloud.compute.Compute; +import com.google.cloud.compute.ComputeOptions; +import com.google.cloud.compute.ImageId; +import com.google.cloud.compute.Instance; +import com.google.cloud.compute.InstanceId; +import com.google.cloud.compute.InstanceInfo; +import com.google.cloud.compute.MachineTypeId; +import com.google.cloud.compute.NetworkId; +import com.google.cloud.compute.NetworkInterface; +import com.google.cloud.compute.Operation; Compute compute = ComputeOptions.defaultInstance().service(); ImageId imageId = ImageId.of("debian-cloud", "debian-8-jessie-v20160329"); @@ -533,4 +533,4 @@ Apache 2.0 - See [LICENSE] for more information. [cloud-compute]: https://cloud.google.com/compute/ [cloud-compute-docs]: https://cloud.google.com/compute/docs/overview -[compute-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/compute/package-summary.html +[compute-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/compute/package-summary.html diff --git a/gcloud-java-compute/README.md b/gcloud-java-compute/README.md index 2b9dbd63cc3d..7bd7c83ee523 100644 --- a/gcloud-java-compute/README.md +++ b/gcloud-java-compute/README.md @@ -10,7 +10,7 @@ Java idiomatic client for [Google Cloud Compute](https://cloud.google.com/comput [![Dependency Status](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969/badge.svg?style=flat)](https://www.versioneye.com/user/projects/56bd8ee72a29ed002d2b0969) - [Homepage](https://googlecloudplatform.github.io/gcloud-java/) -- [API Documentation](http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/compute/package-summary.html) +- [API Documentation](http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/compute/package-summary.html) > Note: This client is a work-in-progress, and may occasionally > make backwards-incompatible changes. @@ -18,19 +18,29 @@ Java idiomatic client for [Google Cloud Compute](https://cloud.google.com/comput Quickstart ---------- If you are using Maven, add this to your pom.xml file - +```xml + + com.google.cloud + gcloud-java-compute + 0.2.0 + +``` If you are using Gradle, add this to your dependencies - +```Groovy +compile 'com.google.cloud:gcloud-java-compute:0.2.0' +``` If you are using SBT, add this to your dependencies - +```Scala +libraryDependencies += "com.google.cloud" % "gcloud-java-compute" % "0.2.0" +``` Example Application ------------------- -[`ComputeExample`](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/ComputeExample.java) +[`ComputeExample`](../gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/ComputeExample.java) is a simple command line interface that provides some of Google Cloud Compute Engine's functionality. Read more about using the application on the -[`ComputeExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/gcloud/examples/compute/ComputeExample.html). +[`ComputeExample` docs page](http://googlecloudplatform.github.io/gcloud-java/apidocs/?com/google/cloud/examples/compute/ComputeExample.html). Authentication -------------- @@ -75,8 +85,8 @@ These credentials are automatically inferred from your environment, so you only code to create your service object: ```java -import com.google.gcloud.compute.Compute; -import com.google.gcloud.compute.ComputeOptions; +import com.google.cloud.compute.Compute; +import com.google.cloud.compute.ComputeOptions; Compute compute = ComputeOptions.defaultInstance().service(); ``` @@ -92,9 +102,9 @@ Engine. In this code snippet, we will create a new external region address. Add the following imports at the top of your file: ```java -import com.google.gcloud.compute.AddressInfo; -import com.google.gcloud.compute.Operation; -import com.google.gcloud.compute.RegionAddressId; +import com.google.cloud.compute.AddressInfo; +import com.google.cloud.compute.Operation; +import com.google.cloud.compute.RegionAddressId; ``` Then add the following code to create an address. Most Compute Engine calls return an `Operation` @@ -126,10 +136,10 @@ a publicly-available image. Add the following imports at the top of your file: ```java -import com.google.gcloud.compute.DiskInfo; -import com.google.gcloud.compute.DiskId; -import com.google.gcloud.compute.ImageDiskConfiguration; -import com.google.gcloud.compute.ImageId; +import com.google.cloud.compute.DiskInfo; +import com.google.cloud.compute.DiskId; +import com.google.cloud.compute.ImageDiskConfiguration; +import com.google.cloud.compute.ImageId; ``` Then add the following code to create a disk and wait for disk creation to terminate. @@ -161,15 +171,15 @@ boot disk the disk we have just created and assigning to it the just created IP Add the following imports at the top of your file: ```java -import com.google.gcloud.compute.AttachedDisk; -import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; -import com.google.gcloud.compute.InstanceId; -import com.google.gcloud.compute.InstanceInfo; -import com.google.gcloud.compute.MachineTypeId; -import com.google.gcloud.compute.NetworkConfiguration; -import com.google.gcloud.compute.NetworkConfiguration.AccessConfig; -import com.google.gcloud.compute.NetworkId; -import com.google.gcloud.compute.NetworkInterface; +import com.google.cloud.compute.AttachedDisk; +import com.google.cloud.compute.AttachedDisk.PersistentDiskConfiguration; +import com.google.cloud.compute.InstanceId; +import com.google.cloud.compute.InstanceInfo; +import com.google.cloud.compute.MachineTypeId; +import com.google.cloud.compute.NetworkConfiguration; +import com.google.cloud.compute.NetworkConfiguration.AccessConfig; +import com.google.cloud.compute.NetworkId; +import com.google.cloud.compute.NetworkInterface; ``` Then add the following code to create an instance and wait for instance creation to terminate. @@ -203,7 +213,7 @@ if (operation.errors() == null) { #### Complete source code In -[CreateAddressDiskAndInstance.java](../gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateAddressDiskAndInstance.java) +[CreateAddressDiskAndInstance.java](../gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateAddressDiskAndInstance.java) we put together all the code shown above into one program. The program assumes that you are running on Compute Engine or from your own desktop. To run the example on App Engine, simply move the code from the main method to your application's servlet class and change the print statements to @@ -254,4 +264,4 @@ Apache 2.0 - See [LICENSE] for more information. [cloud-platform]: https://cloud.google.com/ [cloud-compute]: https://cloud.google.com/compute/ -[compute-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/gcloud/compute/package-summary.html +[compute-api]: http://googlecloudplatform.github.io/gcloud-java/apidocs/index.html?com/google/cloud/compute/package-summary.html diff --git a/gcloud-java-compute/pom.xml b/gcloud-java-compute/pom.xml index 5b9b42efc731..3fdc63a9ad81 100644 --- a/gcloud-java-compute/pom.xml +++ b/gcloud-java-compute/pom.xml @@ -9,9 +9,9 @@ Java idiomatic client for Google Cloud Compute Engine. - com.google.gcloud + com.google.cloud gcloud-java-pom - 0.1.5-SNAPSHOT + 0.2.1-SNAPSHOT gcloud-java-compute diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Address.java similarity index 94% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/Address.java index 9eb343cd5e74..65abad09eac3 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Address.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Address.java @@ -14,10 +14,13 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; +import com.google.cloud.compute.Compute.AddressOption; +import com.google.cloud.compute.Compute.OperationOption; + import java.io.IOException; import java.io.ObjectInputStream; import java.util.Objects; @@ -122,7 +125,7 @@ public Address build() { * @throws ComputeException upon failure */ public boolean exists() { - return reload(Compute.AddressOption.fields()) != null; + return reload(AddressOption.fields()) != null; } /** @@ -133,7 +136,7 @@ public boolean exists() { * @return an {@code Address} object with latest information or {@code null} if not found * @throws ComputeException upon failure */ - public Address reload(Compute.AddressOption... options) { + public Address reload(AddressOption... options) { return compute.getAddress(addressId(), options); } @@ -144,7 +147,7 @@ public Address reload(Compute.AddressOption... options) { * the address was not found * @throws ComputeException upon failure */ - public Operation delete(Compute.OperationOption... options) { + public Operation delete(OperationOption... options) { return compute.deleteAddress(addressId(), options); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/AddressId.java similarity index 98% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressId.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/AddressId.java index c418ec2ae1ba..e5440e6f6d34 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/AddressId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressInfo.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/AddressInfo.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressInfo.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/AddressInfo.java index a18123027989..3848e21fbcbc 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AddressInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/AddressInfo.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AttachedDisk.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/AttachedDisk.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/AttachedDisk.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/AttachedDisk.java index 376b2738df39..d4ad674a8a5e 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/AttachedDisk.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/AttachedDisk.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Compute.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/Compute.java index da25d63a5c2c..6de874f51d16 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Compute.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Compute.java @@ -14,18 +14,18 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; +import com.google.cloud.Page; +import com.google.cloud.Service; +import com.google.cloud.compute.AttachedDisk.PersistentDiskConfiguration; +import com.google.cloud.compute.NetworkInterface.AccessConfig; +import com.google.cloud.compute.spi.ComputeRpc; import com.google.common.base.Joiner; import com.google.common.base.MoreObjects; import com.google.common.collect.Sets; -import com.google.gcloud.Page; -import com.google.gcloud.Service; -import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; -import com.google.gcloud.compute.NetworkInterface.AccessConfig; -import com.google.gcloud.compute.spi.ComputeRpc; import java.io.Serializable; import java.util.Objects; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeException.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeException.java similarity index 90% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeException.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeException.java index c6e7ef734442..1a69457040d6 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeException.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeException.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; +import com.google.cloud.BaseServiceException; +import com.google.cloud.RetryHelper.RetryHelperException; +import com.google.cloud.RetryHelper.RetryInterruptedException; import com.google.common.collect.ImmutableSet; -import com.google.gcloud.BaseServiceException; -import com.google.gcloud.RetryHelper.RetryHelperException; -import com.google.gcloud.RetryHelper.RetryInterruptedException; import java.io.IOException; import java.util.Set; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeFactory.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeFactory.java similarity index 90% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeFactory.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeFactory.java index 100631eef91d..a4daac3f4d56 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeFactory.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeFactory.java @@ -14,9 +14,9 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; -import com.google.gcloud.ServiceFactory; +import com.google.cloud.ServiceFactory; /** * An interface for Compute factories. diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeImpl.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeImpl.java index f70477fea0d7..c0846749d326 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeImpl.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeImpl.java @@ -14,23 +14,23 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; +import static com.google.cloud.RetryHelper.runWithRetries; import static com.google.common.base.Preconditions.checkArgument; -import static com.google.gcloud.RetryHelper.runWithRetries; +import com.google.cloud.BaseService; +import com.google.cloud.Page; +import com.google.cloud.PageImpl; +import com.google.cloud.PageImpl.NextPageFetcher; +import com.google.cloud.RetryHelper; +import com.google.cloud.compute.AttachedDisk.PersistentDiskConfiguration; +import com.google.cloud.compute.NetworkInterface.AccessConfig; +import com.google.cloud.compute.spi.ComputeRpc; import com.google.common.base.Function; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.Maps; -import com.google.gcloud.BaseService; -import com.google.gcloud.Page; -import com.google.gcloud.PageImpl; -import com.google.gcloud.PageImpl.NextPageFetcher; -import com.google.gcloud.RetryHelper; -import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; -import com.google.gcloud.compute.NetworkInterface.AccessConfig; -import com.google.gcloud.compute.spi.ComputeRpc; import java.util.Map; import java.util.concurrent.Callable; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeOptions.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeOptions.java similarity index 92% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeOptions.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeOptions.java index 2585cc42e3d0..7e458b9363e6 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ComputeOptions.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeOptions.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; +import com.google.cloud.ServiceOptions; +import com.google.cloud.compute.spi.ComputeRpc; +import com.google.cloud.compute.spi.ComputeRpcFactory; +import com.google.cloud.compute.spi.DefaultComputeRpc; import com.google.common.collect.ImmutableSet; -import com.google.gcloud.ServiceOptions; -import com.google.gcloud.compute.spi.ComputeRpc; -import com.google.gcloud.compute.spi.ComputeRpcFactory; -import com.google.gcloud.compute.spi.DefaultComputeRpc; import java.util.Set; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/DeprecationStatus.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/DeprecationStatus.java index 896aeebe096f..eb21d6e512f7 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DeprecationStatus.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/DeprecationStatus.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Disk.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Disk.java similarity index 98% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/Disk.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/Disk.java index 5b0507afafd7..39e133110ebf 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Disk.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Disk.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; -import com.google.gcloud.compute.Compute.DiskOption; -import com.google.gcloud.compute.Compute.OperationOption; +import com.google.cloud.compute.Compute.DiskOption; +import com.google.cloud.compute.Compute.OperationOption; import java.io.IOException; import java.io.ObjectInputStream; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskConfiguration.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskConfiguration.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskConfiguration.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskConfiguration.java index 0c48e3442515..1670bcf8b56b 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskConfiguration.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import com.google.api.services.compute.model.Disk; import com.google.common.base.MoreObjects; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskId.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskId.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskId.java index 7338e04ef5d8..58f55beb9a9a 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskImageConfiguration.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskImageConfiguration.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskImageConfiguration.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskImageConfiguration.java index 259ff0ef9fc3..d43f1a50c276 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskImageConfiguration.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskImageConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskInfo.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskInfo.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskInfo.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskInfo.java index bfe7d21911e6..9c2e83005886 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskInfo.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskType.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskType.java index 2e245f438508..7a836dc0316f 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskType.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskType.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import com.google.common.base.Function; import com.google.common.base.MoreObjects; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskTypeId.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskTypeId.java index 836ee907abe3..1ed0cfdea472 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/DiskTypeId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskTypeId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ForwardingRuleId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ForwardingRuleId.java similarity index 98% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/ForwardingRuleId.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/ForwardingRuleId.java index 546dcf596246..09d447cb8072 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ForwardingRuleId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ForwardingRuleId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalAddressId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/GlobalAddressId.java similarity index 98% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalAddressId.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/GlobalAddressId.java index dcda73ac7370..7954cd37826f 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalAddressId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/GlobalAddressId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalForwardingRuleId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/GlobalForwardingRuleId.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalForwardingRuleId.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/GlobalForwardingRuleId.java index 1b37e9a1adef..85094f8e584d 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalForwardingRuleId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/GlobalForwardingRuleId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import com.google.common.base.Function; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalOperationId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/GlobalOperationId.java similarity index 98% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalOperationId.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/GlobalOperationId.java index 343b0cacc94c..082add14109a 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/GlobalOperationId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/GlobalOperationId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Image.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Image.java similarity index 97% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/Image.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/Image.java index 66e71fb1c196..510c21b40435 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Image.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Image.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; -import com.google.gcloud.compute.Compute.ImageOption; -import com.google.gcloud.compute.Compute.OperationOption; +import com.google.cloud.compute.Compute.ImageOption; +import com.google.cloud.compute.Compute.OperationOption; import java.io.IOException; import java.io.ObjectInputStream; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageConfiguration.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ImageConfiguration.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageConfiguration.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/ImageConfiguration.java index c47f9d73157f..34b12dab16af 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageConfiguration.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ImageConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import com.google.api.services.compute.model.Image; import com.google.common.base.MoreObjects; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageDiskConfiguration.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ImageDiskConfiguration.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageDiskConfiguration.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/ImageDiskConfiguration.java index 5961f94c80d4..20914f7611ae 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageDiskConfiguration.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ImageDiskConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ImageId.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageId.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/ImageId.java index eacea6402cba..51a252afd6cc 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ImageId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageInfo.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ImageInfo.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageInfo.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/ImageInfo.java index 6de9c52b455b..a3e9a6db9530 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ImageInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ImageInfo.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Instance.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Instance.java similarity index 98% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/Instance.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/Instance.java index 415b4d1cfa4e..e1ee91f4e58d 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Instance.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Instance.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; +import com.google.cloud.compute.AttachedDisk.PersistentDiskConfiguration; +import com.google.cloud.compute.Compute.InstanceOption; +import com.google.cloud.compute.Compute.OperationOption; +import com.google.cloud.compute.NetworkInterface.AccessConfig; import com.google.common.collect.ImmutableList; -import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; -import com.google.gcloud.compute.Compute.InstanceOption; -import com.google.gcloud.compute.Compute.OperationOption; -import com.google.gcloud.compute.NetworkInterface.AccessConfig; import java.io.IOException; import java.io.ObjectInputStream; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/InstanceId.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceId.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/InstanceId.java index 408d95e641b4..8fde843020f3 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/InstanceId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceInfo.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/InstanceInfo.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceInfo.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/InstanceInfo.java index 67b0568e2ebc..5f794481b4d0 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/InstanceInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/InstanceInfo.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/License.java similarity index 98% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/License.java index d69c78d0bbf4..b65937bf5685 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/License.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/License.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/LicenseId.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/LicenseId.java index 0166e03ed325..284572ba58bb 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/LicenseId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/LicenseId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/MachineType.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/MachineType.java index cab5ecb1bded..d1f989ae7e9b 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineType.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/MachineType.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import com.google.api.services.compute.model.MachineType.ScratchDisks; import com.google.common.base.Function; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/MachineTypeId.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/MachineTypeId.java index 1d1e214a1475..bb439c1e29fe 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/MachineTypeId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/MachineTypeId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Metadata.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Metadata.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/Metadata.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/Metadata.java index bf489caf141d..22ba59834d4b 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Metadata.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Metadata.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Network.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Network.java similarity index 97% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/Network.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/Network.java index 854cb72ce7d1..51a0287f3fed 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Network.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Network.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; -import com.google.gcloud.compute.Compute.NetworkOption; -import com.google.gcloud.compute.Compute.OperationOption; +import com.google.cloud.compute.Compute.NetworkOption; +import com.google.cloud.compute.Compute.OperationOption; import java.io.IOException; import java.io.ObjectInputStream; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkConfiguration.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/NetworkConfiguration.java similarity index 98% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkConfiguration.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/NetworkConfiguration.java index f1d118347175..4a7500f66d07 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkConfiguration.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/NetworkConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import com.google.api.services.compute.model.Network; import com.google.common.base.MoreObjects; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/NetworkId.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkId.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/NetworkId.java index 09bf05fb6b9c..1108f126588b 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/NetworkId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInfo.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/NetworkInfo.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInfo.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/NetworkInfo.java index fc5d0464d534..a7864135b810 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/NetworkInfo.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInterface.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/NetworkInterface.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInterface.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/NetworkInterface.java index 8226eae7b56c..06964f6641af 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkInterface.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/NetworkInterface.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Operation.java similarity index 98% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/Operation.java index 10f1d968608b..59ccafc8e30a 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Operation.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Operation.java @@ -14,10 +14,11 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; +import com.google.cloud.compute.Compute.OperationOption; import com.google.common.base.Function; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; @@ -41,7 +42,7 @@ * {@link #operationId()} returns {@link GlobalOperationId} for global operations, * {@link RegionOperationId} for region operations, and {@link ZoneOperationId} for zone operations. * To get an {@code Operation} object with the most recent information, use - * {@link #reload(Compute.OperationOption...)}. + * {@link #reload(OperationOption...)}. */ public class Operation implements Serializable { @@ -635,7 +636,7 @@ public String description() { * @throws ComputeException upon failure */ public boolean exists() throws ComputeException { - return reload(Compute.OperationOption.fields()) != null; + return reload(OperationOption.fields()) != null; } /** @@ -653,7 +654,7 @@ public boolean exists() throws ComputeException { */ public boolean isDone() throws ComputeException { Operation operation = compute.getOperation(operationId, - Compute.OperationOption.fields(Compute.OperationField.STATUS)); + OperationOption.fields(Compute.OperationField.STATUS)); return operation == null || operation.status() == Status.DONE; } @@ -665,7 +666,7 @@ public boolean isDone() throws ComputeException { * @return an {@code Operation} object with latest information or {@code null} if not found * @throws ComputeException upon failure */ - public Operation reload(Compute.OperationOption... options) throws ComputeException { + public Operation reload(OperationOption... options) throws ComputeException { return compute.getOperation(operationId, options); } diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/OperationId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/OperationId.java similarity index 98% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/OperationId.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/OperationId.java index 5ddf2dae43a2..2a3dc2a28d76 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/OperationId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/OperationId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Option.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Option.java similarity index 95% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/Option.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/Option.java index 5a9ea946aeea..de8676b2ac79 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Option.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Option.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; +import com.google.cloud.compute.spi.ComputeRpc; import com.google.common.base.MoreObjects; -import com.google.gcloud.compute.spi.ComputeRpc; import java.io.Serializable; import java.util.Objects; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Region.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/Region.java index afc761df2e0d..d6c25ad16aab 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Region.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Region.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import com.google.common.base.Function; import com.google.common.base.MoreObjects; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionAddressId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/RegionAddressId.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionAddressId.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/RegionAddressId.java index 6ea0538b0edf..9e81b3ca909a 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionAddressId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/RegionAddressId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionForwardingRuleId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/RegionForwardingRuleId.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionForwardingRuleId.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/RegionForwardingRuleId.java index b6e7e120f94a..f1f2460ef811 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionForwardingRuleId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/RegionForwardingRuleId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/RegionId.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/RegionId.java index 7e0f03e1e3ac..1f3c74084692 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/RegionId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionOperationId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/RegionOperationId.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionOperationId.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/RegionOperationId.java index b244c60fadf0..f66f3cc615bc 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/RegionOperationId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/RegionOperationId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ResourceId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ResourceId.java similarity index 98% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/ResourceId.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/ResourceId.java index 38e0fe576ac8..fed67c8fd72a 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ResourceId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ResourceId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import com.google.common.base.MoreObjects; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SchedulingOptions.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/SchedulingOptions.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/SchedulingOptions.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/SchedulingOptions.java index c5d7c293cc10..8abac14f8fcb 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SchedulingOptions.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/SchedulingOptions.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import com.google.common.base.MoreObjects; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ServiceAccount.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ServiceAccount.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/ServiceAccount.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/ServiceAccount.java index ccdb2ecb0d79..65508a0a4c3f 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ServiceAccount.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ServiceAccount.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import com.google.common.base.Function; import com.google.common.base.MoreObjects; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Snapshot.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Snapshot.java similarity index 97% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/Snapshot.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/Snapshot.java index a12404a9fd4f..f09f1da07d31 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Snapshot.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Snapshot.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; -import com.google.gcloud.compute.Compute.OperationOption; -import com.google.gcloud.compute.Compute.SnapshotOption; +import com.google.cloud.compute.Compute.OperationOption; +import com.google.cloud.compute.Compute.SnapshotOption; import java.io.IOException; import java.io.ObjectInputStream; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotDiskConfiguration.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/SnapshotDiskConfiguration.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotDiskConfiguration.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/SnapshotDiskConfiguration.java index 178c54f0038e..8f900f2b4c0b 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotDiskConfiguration.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/SnapshotDiskConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/SnapshotId.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotId.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/SnapshotId.java index 5df2d9f0f9a8..a30d531b65be 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/SnapshotId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotInfo.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/SnapshotInfo.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotInfo.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/SnapshotInfo.java index 34f6c53884bf..dc67893261b3 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SnapshotInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/SnapshotInfo.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/StandardDiskConfiguration.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/StandardDiskConfiguration.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/StandardDiskConfiguration.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/StandardDiskConfiguration.java index 1d1e0e56bb6b..ecf819ea288a 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/StandardDiskConfiguration.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/StandardDiskConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import com.google.api.services.compute.model.Disk; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/StandardNetworkConfiguration.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/StandardNetworkConfiguration.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/StandardNetworkConfiguration.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/StandardNetworkConfiguration.java index d4595efb6eb6..16aa8a128d0a 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/StandardNetworkConfiguration.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/StandardNetworkConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/StorageImageConfiguration.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/StorageImageConfiguration.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/StorageImageConfiguration.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/StorageImageConfiguration.java index 88d37e5180b8..6da6d1e37e96 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/StorageImageConfiguration.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/StorageImageConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetNetworkConfiguration.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/SubnetNetworkConfiguration.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetNetworkConfiguration.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/SubnetNetworkConfiguration.java index 0d4c9f07b85f..d060e91eab73 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetNetworkConfiguration.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/SubnetNetworkConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import com.google.api.services.compute.model.Network; import com.google.common.base.MoreObjects; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Subnetwork.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Subnetwork.java similarity index 97% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/Subnetwork.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/Subnetwork.java index 31fc72a0f3de..b3929dd937ea 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Subnetwork.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Subnetwork.java @@ -14,12 +14,12 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; -import com.google.gcloud.compute.Compute.OperationOption; -import com.google.gcloud.compute.Compute.SubnetworkOption; +import com.google.cloud.compute.Compute.OperationOption; +import com.google.cloud.compute.Compute.SubnetworkOption; import java.io.IOException; import java.io.ObjectInputStream; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/SubnetworkId.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkId.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/SubnetworkId.java index 7ed56f4ba3cf..b750847a3d10 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/SubnetworkId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkInfo.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/SubnetworkInfo.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkInfo.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/SubnetworkInfo.java index e61a2c82b5de..a89a5d713f0f 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/SubnetworkInfo.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Tags.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Tags.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/Tags.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/Tags.java index 275bad05f4fe..7be604cd5a64 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Tags.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Tags.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Zone.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/Zone.java index ff5ed877408c..d04e527a8ae8 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/Zone.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Zone.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import com.google.common.base.Function; import com.google.common.base.MoreObjects; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ZoneId.java similarity index 98% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/ZoneId.java index 56386ace5455..1a1e2bf207be 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ZoneId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneOperationId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ZoneOperationId.java similarity index 99% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneOperationId.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/ZoneOperationId.java index 99161b0f4eda..4868fa4bd3f6 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/ZoneOperationId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ZoneOperationId.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static com.google.common.base.Preconditions.checkNotNull; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/package-info.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/package-info.java similarity index 91% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/package-info.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/package-info.java index 88dab612c599..b7f589ea3b3f 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/package-info.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/package-info.java @@ -19,7 +19,7 @@ * *

    Here's a simple usage example for using gcloud-java from App/Compute Engine. This example * shows how to create a snapshot from an existing disk. For the complete source code see - * + * * CreateSnapshot.java. *

     {@code
      * Compute compute = ComputeOptions.defaultInstance().service();
    @@ -38,7 +38,7 @@
      * }}
    *

    This second example shows how to create a virtual machine instance. Complete source code can * be found at - * + * * CreateInstance.java. *

     {@code
      * Compute compute = ComputeOptions.defaultInstance().service();
    @@ -60,4 +60,4 @@
      *
      * @see Google Cloud Compute
      */
    -package com.google.gcloud.compute;
    +package com.google.cloud.compute;
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/ComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/spi/ComputeRpc.java
    similarity index 99%
    rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/ComputeRpc.java
    rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/spi/ComputeRpc.java
    index 4da5931d064c..2209da1f6951 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/ComputeRpc.java
    +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/spi/ComputeRpc.java
    @@ -14,7 +14,7 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.compute.spi;
    +package com.google.cloud.compute.spi;
     
     import com.google.api.services.compute.model.AccessConfig;
     import com.google.api.services.compute.model.Address;
    @@ -35,7 +35,7 @@
     import com.google.api.services.compute.model.Subnetwork;
     import com.google.api.services.compute.model.Tags;
     import com.google.api.services.compute.model.Zone;
    -import com.google.gcloud.compute.ComputeException;
    +import com.google.cloud.compute.ComputeException;
     
     import java.util.Map;
     
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/ComputeRpcFactory.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/spi/ComputeRpcFactory.java
    similarity index 85%
    rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/ComputeRpcFactory.java
    rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/spi/ComputeRpcFactory.java
    index e7a6cbe72d6f..a9d1593b9930 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/ComputeRpcFactory.java
    +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/spi/ComputeRpcFactory.java
    @@ -14,10 +14,10 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.compute.spi;
    +package com.google.cloud.compute.spi;
     
    -import com.google.gcloud.compute.ComputeOptions;
    -import com.google.gcloud.spi.ServiceRpcFactory;
    +import com.google.cloud.compute.ComputeOptions;
    +import com.google.cloud.spi.ServiceRpcFactory;
     
     /**
      * An interface for Compute RPC factory.
    diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/DefaultComputeRpc.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/spi/DefaultComputeRpc.java
    similarity index 82%
    rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/DefaultComputeRpc.java
    rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/spi/DefaultComputeRpc.java
    index 48f9f8d187d5..542a2aa2fcb7 100644
    --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/spi/DefaultComputeRpc.java
    +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/spi/DefaultComputeRpc.java
    @@ -14,12 +14,8 @@
      * limitations under the License.
      */
     
    -package com.google.gcloud.compute.spi;
    +package com.google.cloud.compute.spi;
     
    -import static com.google.gcloud.compute.spi.ComputeRpc.Option.FIELDS;
    -import static com.google.gcloud.compute.spi.ComputeRpc.Option.FILTER;
    -import static com.google.gcloud.compute.spi.ComputeRpc.Option.MAX_RESULTS;
    -import static com.google.gcloud.compute.spi.ComputeRpc.Option.PAGE_TOKEN;
     import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
     
     import com.google.api.client.http.HttpRequestInitializer;
    @@ -72,9 +68,9 @@
     import com.google.api.services.compute.model.Tags;
     import com.google.api.services.compute.model.Zone;
     import com.google.api.services.compute.model.ZoneList;
    +import com.google.cloud.compute.ComputeException;
    +import com.google.cloud.compute.ComputeOptions;
     import com.google.common.collect.ImmutableList;
    -import com.google.gcloud.compute.ComputeException;
    -import com.google.gcloud.compute.ComputeOptions;
     
     import java.io.IOException;
     import java.util.Map;
    @@ -103,7 +99,7 @@ public DiskType getDiskType(String zone, String diskType, Map options
         try {
           return compute.diskTypes()
               .get(this.options.projectId(), zone, diskType)
    -          .setFields(FIELDS.getString(options))
    +          .setFields(Option.FIELDS.getString(options))
               .execute();
         } catch (IOException ex) {
           return nullForNotFound(ex);
    @@ -115,10 +111,10 @@ public Tuple> listDiskTypes(String zone, Map diskTypes = diskTypesList.getItems();
           return Tuple.of(diskTypesList.getNextPageToken(), diskTypes);
    @@ -132,9 +128,9 @@ public Tuple> listDiskTypes(Map options) {
         try {
           DiskTypeAggregatedList aggregatedList = compute.diskTypes()
               .aggregatedList(this.options.projectId())
    -          .setFilter(FILTER.getString(options))
    -          .setMaxResults(MAX_RESULTS.getLong(options))
    -          .setPageToken(PAGE_TOKEN.getString(options))
    +          .setFilter(Option.FILTER.getString(options))
    +          .setMaxResults(Option.MAX_RESULTS.getLong(options))
    +          .setPageToken(Option.PAGE_TOKEN.getString(options))
               // todo(mziccard): uncomment or remove once #711 is closed
               // .setFields(FIELDS.getString(options))
               .execute();
    @@ -159,7 +155,7 @@ public MachineType getMachineType(String zone, String machineType, Map> listMachineTypes(String zone,
         try {
           MachineTypeList machineTypesList = compute.machineTypes()
               .list(this.options.projectId(), zone)
    -          .setFilter(FILTER.getString(options))
    -          .setMaxResults(MAX_RESULTS.getLong(options))
    -          .setPageToken(PAGE_TOKEN.getString(options))
    -          .setFields(FIELDS.getString(options))
    +          .setFilter(Option.FILTER.getString(options))
    +          .setMaxResults(Option.MAX_RESULTS.getLong(options))
    +          .setPageToken(Option.PAGE_TOKEN.getString(options))
    +          .setFields(Option.FIELDS.getString(options))
               .execute();
           Iterable machineTypes = machineTypesList.getItems();
           return Tuple.of(machineTypesList.getNextPageToken(), machineTypes);
    @@ -189,9 +185,9 @@ public Tuple> listMachineTypes(Map opti
         try {
           MachineTypeAggregatedList aggregatedList = compute.machineTypes()
               .aggregatedList(this.options.projectId())
    -          .setFilter(FILTER.getString(options))
    -          .setMaxResults(MAX_RESULTS.getLong(options))
    -          .setPageToken(PAGE_TOKEN.getString(options))
    +          .setFilter(Option.FILTER.getString(options))
    +          .setMaxResults(Option.MAX_RESULTS.getLong(options))
    +          .setPageToken(Option.PAGE_TOKEN.getString(options))
               // todo(mziccard): uncomment or remove once #711 is closed
               // .setFields(FIELDS.getString(options))
               .execute();
    @@ -216,7 +212,7 @@ public Region getRegion(String region, Map options) {
         try {
           return compute.regions()
               .get(this.options.projectId(), region)
    -          .setFields(FIELDS.getString(options))
    +          .setFields(Option.FIELDS.getString(options))
               .execute();
         } catch (IOException ex) {
           return nullForNotFound(ex);
    @@ -228,10 +224,10 @@ public Tuple> listRegions(Map options) {
         try {
           RegionList regionsList = compute.regions()
               .list(this.options.projectId())
    -          .setFilter(FILTER.getString(options))
    -          .setMaxResults(MAX_RESULTS.getLong(options))
    -          .setPageToken(PAGE_TOKEN.getString(options))
    -          .setFields(FIELDS.getString(options))
    +          .setFilter(Option.FILTER.getString(options))
    +          .setMaxResults(Option.MAX_RESULTS.getLong(options))
    +          .setPageToken(Option.PAGE_TOKEN.getString(options))
    +          .setFields(Option.FIELDS.getString(options))
               .execute();
           Iterable regions = regionsList.getItems();
           return Tuple.of(regionsList.getNextPageToken(), regions);
    @@ -245,7 +241,7 @@ public Zone getZone(String zone, Map options) {
         try {
           return compute.zones()
               .get(this.options.projectId(), zone)
    -          .setFields(FIELDS.getString(options))
    +          .setFields(Option.FIELDS.getString(options))
               .execute();
         } catch (IOException ex) {
           return nullForNotFound(ex);
    @@ -257,10 +253,10 @@ public Tuple> listZones(Map options) {
         try {
           ZoneList zonesList = compute.zones()
               .list(this.options.projectId())
    -          .setFilter(FILTER.getString(options))
    -          .setMaxResults(MAX_RESULTS.getLong(options))
    -          .setPageToken(PAGE_TOKEN.getString(options))
    -          .setFields(FIELDS.getString(options))
    +          .setFilter(Option.FILTER.getString(options))
    +          .setMaxResults(Option.MAX_RESULTS.getLong(options))
    +          .setPageToken(Option.PAGE_TOKEN.getString(options))
    +          .setFields(Option.FIELDS.getString(options))
               .execute();
           Iterable zones = zonesList.getItems();
           return Tuple.of(zonesList.getNextPageToken(), zones);
    @@ -274,7 +270,7 @@ public License getLicense(String project, String license, Map options
         try {
           return compute.licenses()
               .get(project, license)
    -          .setFields(FIELDS.getString(options))
    +          .setFields(Option.FIELDS.getString(options))
               .execute();
         } catch (IOException ex) {
           return nullForNotFound(ex);
    @@ -286,7 +282,7 @@ public Operation getGlobalOperation(String operation, Map options) {
         try {
           return compute.globalOperations()
               .get(this.options.projectId(), operation)
    -          .setFields(FIELDS.getString(options))
    +          .setFields(Option.FIELDS.getString(options))
               .execute();
         } catch (IOException ex) {
           return nullForNotFound(ex);
    @@ -298,10 +294,10 @@ public Tuple> listGlobalOperations(Map op
         try {
           OperationList operationsList = compute.globalOperations()
               .list(this.options.projectId())
    -          .setFilter(FILTER.getString(options))
    -          .setMaxResults(MAX_RESULTS.getLong(options))
    -          .setPageToken(PAGE_TOKEN.getString(options))
    -          .setFields(FIELDS.getString(options))
    +          .setFilter(Option.FILTER.getString(options))
    +          .setMaxResults(Option.MAX_RESULTS.getLong(options))
    +          .setPageToken(Option.PAGE_TOKEN.getString(options))
    +          .setFields(Option.FIELDS.getString(options))
               .execute();
           Iterable operations = operationsList.getItems();
           return Tuple.of(operationsList.getNextPageToken(), operations);
    @@ -325,7 +321,7 @@ public Operation getRegionOperation(String region, String operation, Map> listRegionOperations(String region,
         try {
           OperationList operationsList = compute.regionOperations()
               .list(this.options.projectId(), region)
    -          .setFilter(FILTER.getString(options))
    -          .setMaxResults(MAX_RESULTS.getLong(options))
    -          .setPageToken(PAGE_TOKEN.getString(options))
    -          .setFields(FIELDS.getString(options))
    +          .setFilter(Option.FILTER.getString(options))
    +          .setMaxResults(Option.MAX_RESULTS.getLong(options))
    +          .setPageToken(Option.PAGE_TOKEN.getString(options))
    +          .setFields(Option.FIELDS.getString(options))
               .execute();
           Iterable operations = operationsList.getItems();
           return Tuple.of(operationsList.getNextPageToken(), operations);
    @@ -365,7 +361,7 @@ public Operation getZoneOperation(String zone, String operation, Map
         try {
           return compute.zoneOperations()
               .get(this.options.projectId(), zone, operation)
    -          .setFields(FIELDS.getString(options))
    +          .setFields(Option.FIELDS.getString(options))
               .execute();
         } catch (IOException ex) {
           return nullForNotFound(ex);
    @@ -378,10 +374,10 @@ public Tuple> listZoneOperations(String zone,
         try {
           OperationList operationsList = compute.zoneOperations()
               .list(this.options.projectId(), zone)
    -          .setFilter(FILTER.getString(options))
    -          .setMaxResults(MAX_RESULTS.getLong(options))
    -          .setPageToken(PAGE_TOKEN.getString(options))
    -          .setFields(FIELDS.getString(options))
    +          .setFilter(Option.FILTER.getString(options))
    +          .setMaxResults(Option.MAX_RESULTS.getLong(options))
    +          .setPageToken(Option.PAGE_TOKEN.getString(options))
    +          .setFields(Option.FIELDS.getString(options))
               .execute();
           Iterable operations = operationsList.getItems();
           return Tuple.of(operationsList.getNextPageToken(), operations);
    @@ -405,7 +401,7 @@ public Address getGlobalAddress(String address, Map options) {
         try {
           return compute.globalAddresses()
               .get(this.options.projectId(), address)
    -          .setFields(FIELDS.getString(options))
    +          .setFields(Option.FIELDS.getString(options))
               .execute();
         } catch (IOException ex) {
           return nullForNotFound(ex);
    @@ -417,7 +413,7 @@ public Operation createGlobalAddress(Address address, Map options) {
         try {
           return compute.globalAddresses()
               .insert(this.options.projectId(), address)
    -          .setFields(FIELDS.getString(options))
    +          .setFields(Option.FIELDS.getString(options))
               .execute();
         } catch (IOException ex) {
           throw translate(ex);
    @@ -429,10 +425,10 @@ public Tuple> listGlobalAddresses(Map optio
         try {
           AddressList addressList = compute.globalAddresses()
               .list(this.options.projectId())
    -          .setFilter(FILTER.getString(options))
    -          .setMaxResults(MAX_RESULTS.getLong(options))
    -          .setPageToken(PAGE_TOKEN.getString(options))
    -          .setFields(FIELDS.getString(options))
    +          .setFilter(Option.FILTER.getString(options))
    +          .setMaxResults(Option.MAX_RESULTS.getLong(options))
    +          .setPageToken(Option.PAGE_TOKEN.getString(options))
    +          .setFields(Option.FIELDS.getString(options))
               .execute();
           Iterable
    operations = addressList.getItems(); return Tuple.of(addressList.getNextPageToken(), operations); @@ -446,7 +442,7 @@ public Operation deleteGlobalAddress(String address, Map options) { try { return compute.globalAddresses() .delete(this.options.projectId(), address) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); @@ -458,7 +454,7 @@ public Address getRegionAddress(String region, String address, Map op try { return compute.addresses() .get(this.options.projectId(), region, address) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); @@ -470,7 +466,7 @@ public Operation createRegionAddress(String region, Address address, Map> listRegionAddresses(String region, try { AddressList addressList = compute.addresses() .list(this.options.projectId(), region) - .setFilter(FILTER.getString(options)) - .setMaxResults(MAX_RESULTS.getLong(options)) - .setPageToken(PAGE_TOKEN.getString(options)) - .setFields(FIELDS.getString(options)) + .setFilter(Option.FILTER.getString(options)) + .setMaxResults(Option.MAX_RESULTS.getLong(options)) + .setPageToken(Option.PAGE_TOKEN.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); Iterable
    operations = addressList.getItems(); return Tuple.of(addressList.getNextPageToken(), operations); @@ -500,9 +496,9 @@ public Tuple> listAddresses(Map options) { try { AddressAggregatedList aggregatedList = compute.addresses() .aggregatedList(this.options.projectId()) - .setFilter(FILTER.getString(options)) - .setMaxResults(MAX_RESULTS.getLong(options)) - .setPageToken(PAGE_TOKEN.getString(options)) + .setFilter(Option.FILTER.getString(options)) + .setMaxResults(Option.MAX_RESULTS.getLong(options)) + .setPageToken(Option.PAGE_TOKEN.getString(options)) // todo(mziccard): uncomment or remove once #711 is closed // .setFields(FIELDS.getString(options)) .execute(); @@ -527,7 +523,7 @@ public Operation deleteRegionAddress(String region, String address, Map options) { try { return compute.snapshots() .get(this.options.projectId(), snapshot) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); @@ -565,10 +561,10 @@ public Tuple> listSnapshots(Map options) { try { SnapshotList snapshotList = compute.snapshots() .list(this.options.projectId()) - .setFilter(FILTER.getString(options)) - .setMaxResults(MAX_RESULTS.getLong(options)) - .setPageToken(PAGE_TOKEN.getString(options)) - .setFields(FIELDS.getString(options)) + .setFilter(Option.FILTER.getString(options)) + .setMaxResults(Option.MAX_RESULTS.getLong(options)) + .setPageToken(Option.PAGE_TOKEN.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); Iterable snapshots = snapshotList.getItems(); return Tuple.of(snapshotList.getNextPageToken(), snapshots); @@ -582,7 +578,7 @@ public Operation deleteSnapshot(String snapshot, Map options) { try { return compute.snapshots() .delete(this.options.projectId(), snapshot) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); @@ -594,7 +590,7 @@ public Operation createImage(Image image, Map options) { try { return compute.images() .insert(this.options.projectId(), image) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { throw translate(ex); @@ -606,7 +602,7 @@ public Image getImage(String project, String image, Map options) { try { return compute.images() .get(project, image) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); @@ -618,10 +614,10 @@ public Tuple> listImages(String project, Map try { ImageList imageList = compute.images() .list(project) - .setFilter(FILTER.getString(options)) - .setMaxResults(MAX_RESULTS.getLong(options)) - .setPageToken(PAGE_TOKEN.getString(options)) - .setFields(FIELDS.getString(options)) + .setFilter(Option.FILTER.getString(options)) + .setMaxResults(Option.MAX_RESULTS.getLong(options)) + .setPageToken(Option.PAGE_TOKEN.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); Iterable images = imageList.getItems(); return Tuple.of(imageList.getNextPageToken(), images); @@ -635,7 +631,7 @@ public Operation deleteImage(String project, String image, Map option try { return compute.images() .delete(project, image) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); @@ -648,7 +644,7 @@ public Operation deprecateImage(String project, String image, DeprecationStatus try { return compute.images() .deprecate(project, image, deprecationStatus) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); @@ -660,7 +656,7 @@ public Disk getDisk(String zone, String disk, Map options) { try { return compute.disks() .get(this.options.projectId(), zone, disk) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); @@ -672,7 +668,7 @@ public Operation createDisk(String zone, Disk disk, Map options) { try { return compute.disks() .insert(this.options.projectId(), zone, disk) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { throw translate(ex); @@ -684,10 +680,10 @@ public Tuple> listDisks(String zone, Map optio try { DiskList diskList = compute.disks() .list(this.options.projectId(), zone) - .setFilter(FILTER.getString(options)) - .setMaxResults(MAX_RESULTS.getLong(options)) - .setPageToken(PAGE_TOKEN.getString(options)) - .setFields(FIELDS.getString(options)) + .setFilter(Option.FILTER.getString(options)) + .setMaxResults(Option.MAX_RESULTS.getLong(options)) + .setPageToken(Option.PAGE_TOKEN.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); Iterable disks = diskList.getItems(); return Tuple.of(diskList.getNextPageToken(), disks); @@ -701,9 +697,9 @@ public Tuple> listDisks(Map options) { try { DiskAggregatedList aggregatedList = compute.disks() .aggregatedList(this.options.projectId()) - .setFilter(FILTER.getString(options)) - .setMaxResults(MAX_RESULTS.getLong(options)) - .setPageToken(PAGE_TOKEN.getString(options)) + .setFilter(Option.FILTER.getString(options)) + .setMaxResults(Option.MAX_RESULTS.getLong(options)) + .setPageToken(Option.PAGE_TOKEN.getString(options)) // todo(mziccard): uncomment or remove once #711 is closed // .setFields(FIELDS.getString(options)) .execute(); @@ -728,7 +724,7 @@ public Operation deleteDisk(String zone, String disk, Map options) { try { return compute.disks() .delete(this.options.projectId(), zone, disk) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); @@ -740,7 +736,7 @@ public Operation resizeDisk(String zone, String disk, long sizeGb, Map try { return compute.subnetworks() .get(this.options.projectId(), region, subnetwork) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); @@ -776,10 +772,10 @@ public Tuple> listSubnetworks(String region, try { SubnetworkList subnetworkList = compute.subnetworks() .list(this.options.projectId(), region) - .setFilter(FILTER.getString(options)) - .setMaxResults(MAX_RESULTS.getLong(options)) - .setPageToken(PAGE_TOKEN.getString(options)) - .setFields(FIELDS.getString(options)) + .setFilter(Option.FILTER.getString(options)) + .setMaxResults(Option.MAX_RESULTS.getLong(options)) + .setPageToken(Option.PAGE_TOKEN.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); Iterable subnetworks = subnetworkList.getItems(); return Tuple.of(subnetworkList.getNextPageToken(), subnetworks); @@ -793,9 +789,9 @@ public Tuple> listSubnetworks(Map option try { SubnetworkAggregatedList aggregatedList = compute.subnetworks() .aggregatedList(this.options.projectId()) - .setFilter(FILTER.getString(options)) - .setMaxResults(MAX_RESULTS.getLong(options)) - .setPageToken(PAGE_TOKEN.getString(options)) + .setFilter(Option.FILTER.getString(options)) + .setMaxResults(Option.MAX_RESULTS.getLong(options)) + .setPageToken(Option.PAGE_TOKEN.getString(options)) // todo(mziccard): uncomment or remove once #711 is closed // .setFields(FIELDS.getString(options)) .execute(); @@ -820,7 +816,7 @@ public Operation deleteSubnetwork(String region, String subnetwork, Map options) { try { return compute.networks() .insert(this.options.projectId(), network) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { throw translate(ex); @@ -844,7 +840,7 @@ public Network getNetwork(String network, Map options) { try { return compute.networks() .get(this.options.projectId(), network) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); @@ -856,10 +852,10 @@ public Tuple> listNetworks(Map options) { try { NetworkList networkList = compute.networks() .list(this.options.projectId()) - .setFilter(FILTER.getString(options)) - .setMaxResults(MAX_RESULTS.getLong(options)) - .setPageToken(PAGE_TOKEN.getString(options)) - .setFields(FIELDS.getString(options)) + .setFilter(Option.FILTER.getString(options)) + .setMaxResults(Option.MAX_RESULTS.getLong(options)) + .setPageToken(Option.PAGE_TOKEN.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); Iterable networks = networkList.getItems(); return Tuple.of(networkList.getNextPageToken(), networks); @@ -873,7 +869,7 @@ public Operation deleteNetwork(String network, Map options) { try { return compute.networks() .delete(this.options.projectId(), network) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); @@ -885,7 +881,7 @@ public Operation createInstance(String zone, Instance instance, Map o try { return compute.instances() .insert(this.options.projectId(), zone, instance) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { throw translate(ex); @@ -897,7 +893,7 @@ public Instance getInstance(String zone, String instance, Map options try { return compute.instances() .get(this.options.projectId(), zone, instance) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); @@ -909,10 +905,10 @@ public Tuple> listInstances(String zone, Map instances = instanceList.getItems(); return Tuple.of(instanceList.getNextPageToken(), instances); @@ -926,9 +922,9 @@ public Tuple> listInstances(Map options) { try { InstanceAggregatedList aggregatedList = compute.instances() .aggregatedList(this.options.projectId()) - .setFilter(FILTER.getString(options)) - .setMaxResults(MAX_RESULTS.getLong(options)) - .setPageToken(PAGE_TOKEN.getString(options)) + .setFilter(Option.FILTER.getString(options)) + .setMaxResults(Option.MAX_RESULTS.getLong(options)) + .setPageToken(Option.PAGE_TOKEN.getString(options)) // todo(mziccard): uncomment or remove once #711 is closed // .setFields(FIELDS.getString(options)) .execute(); @@ -953,7 +949,7 @@ public Operation deleteInstance(String zone, String instance, Map opt try { return compute.instances() .delete(this.options.projectId(), zone, instance) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); @@ -966,7 +962,7 @@ public Operation addAccessConfig(String zone, String instance, String networkInt try { return compute.instances() .addAccessConfig(this.options.projectId(), zone, instance, networkInterface, accessConfig) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { throw translate(ex); @@ -979,7 +975,7 @@ public Operation attachDisk(String zone, String instance, AttachedDisk attachedD try { return compute.instances() .attachDisk(this.options.projectId(), zone, instance, attachedDisk) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { throw translate(ex); @@ -993,7 +989,7 @@ public Operation deleteAccessConfig(String zone, String instance, String network return compute.instances() .deleteAccessConfig(this.options.projectId(), zone, instance, accessConfig, networkInterface) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); @@ -1006,7 +1002,7 @@ public Operation detachDisk(String zone, String instance, String deviceName, try { return compute.instances() .detachDisk(this.options.projectId(), zone, instance, deviceName) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); @@ -1020,7 +1016,7 @@ public String getSerialPortOutput(String zone, String instance, Integer port, SerialPortOutput portOutput = compute.instances() .getSerialPortOutput(this.options.projectId(), zone, instance) .setPort(port) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); return portOutput != null ? portOutput.getContents() : null; } catch (IOException ex) { @@ -1033,7 +1029,7 @@ public Operation reset(String zone, String instance, Map options) { try { return compute.instances() .reset(this.options.projectId(), zone, instance) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); @@ -1046,7 +1042,7 @@ public Operation setDiskAutoDelete(String zone, String instance, String deviceNa try { return compute.instances() .setDiskAutoDelete(this.options.projectId(), zone, instance, autoDelete, deviceName) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); @@ -1061,7 +1057,7 @@ public Operation setMachineType(String zone, String instance, String machineType new InstancesSetMachineTypeRequest().setMachineType(machineTypeUrl); return compute.instances() .setMachineType(this.options.projectId(), zone, instance, request) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); @@ -1074,7 +1070,7 @@ public Operation setMetadata(String zone, String instance, Metadata metadata, try { return compute.instances() .setMetadata(this.options.projectId(), zone, instance, metadata) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); @@ -1087,7 +1083,7 @@ public Operation setScheduling(String zone, String instance, Scheduling scheduli try { return compute.instances() .setScheduling(this.options.projectId(), zone, instance, scheduling) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); @@ -1099,7 +1095,7 @@ public Operation setTags(String zone, String instance, Tags tags, Map try { return compute.instances() .setTags(this.options.projectId(), zone, instance, tags) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); @@ -1111,7 +1107,7 @@ public Operation start(String zone, String instance, Map options) { try { return compute.instances() .start(this.options.projectId(), zone, instance) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); @@ -1123,7 +1119,7 @@ public Operation stop(String zone, String instance, Map options) { try { return compute.instances() .stop(this.options.projectId(), zone, instance) - .setFields(FIELDS.getString(options)) + .setFields(Option.FIELDS.getString(options)) .execute(); } catch (IOException ex) { return nullForNotFound(ex); diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/RemoteComputeHelper.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/testing/RemoteComputeHelper.java similarity index 96% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/RemoteComputeHelper.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/testing/RemoteComputeHelper.java index 3613c75a4b7c..eb443a25af28 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/RemoteComputeHelper.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/testing/RemoteComputeHelper.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package com.google.gcloud.compute.testing; +package com.google.cloud.compute.testing; -import com.google.gcloud.AuthCredentials; -import com.google.gcloud.RetryParams; -import com.google.gcloud.compute.ComputeOptions; +import com.google.cloud.AuthCredentials; +import com.google.cloud.RetryParams; +import com.google.cloud.compute.ComputeOptions; import java.io.IOException; import java.io.InputStream; diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/package-info.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/testing/package-info.java similarity index 96% rename from gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/package-info.java rename to gcloud-java-compute/src/main/java/com/google/cloud/compute/testing/package-info.java index 86f1c2428cde..30da2872a66c 100644 --- a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/testing/package-info.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/testing/package-info.java @@ -28,4 +28,4 @@ * @see * gcloud-java tools for testing */ -package com.google.gcloud.compute.testing; +package com.google.cloud.compute.testing; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressIdTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/AddressIdTest.java similarity index 99% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressIdTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/AddressIdTest.java index 804744af5615..361012f3a30f 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/AddressIdTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressInfoTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/AddressInfoTest.java similarity index 89% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressInfoTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/AddressInfoTest.java index d476cf275268..1e69608c8d40 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressInfoTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/AddressInfoTest.java @@ -14,16 +14,14 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import com.google.common.collect.ImmutableList; -import com.google.gcloud.compute.AddressInfo.GlobalForwardingUsage; -import com.google.gcloud.compute.AddressInfo.InstanceUsage; -import com.google.gcloud.compute.AddressInfo.RegionForwardingUsage; +import org.junit.Assert; import org.junit.Test; import java.util.List; @@ -44,12 +42,12 @@ public class AddressInfoTest { private static final List REGION_FORWARDING_RULES = ImmutableList.of(RegionForwardingRuleId.of("project", "region", "forwardingRule1"), RegionForwardingRuleId.of("project", "region", "forwardingRule2")); - private static final InstanceUsage INSTANCE_USAGE = - new InstanceUsage(InstanceId.of("project", "zone", "instance1")); - private static final GlobalForwardingUsage GLOBAL_FORWARDING_USAGE = - new GlobalForwardingUsage(GLOBAL_FORWARDING_RULES); - private static final RegionForwardingUsage REGION_FORWARDING_USAGE = - new RegionForwardingUsage(REGION_FORWARDING_RULES); + private static final AddressInfo.InstanceUsage INSTANCE_USAGE = + new AddressInfo.InstanceUsage(InstanceId.of("project", "zone", "instance1")); + private static final AddressInfo.GlobalForwardingUsage GLOBAL_FORWARDING_USAGE = + new AddressInfo.GlobalForwardingUsage(GLOBAL_FORWARDING_RULES); + private static final AddressInfo.RegionForwardingUsage REGION_FORWARDING_USAGE = + new AddressInfo.RegionForwardingUsage(REGION_FORWARDING_RULES); private static final AddressInfo INSTANCE_ADDRESS_INFO = AddressInfo.builder(REGION_ADDRESS_ID) .address(ADDRESS) .creationTimestamp(CREATION_TIMESTAMP) @@ -110,8 +108,8 @@ public void testBuilder() { assertEquals(REGION_ADDRESS_ID, INSTANCE_ADDRESS_INFO.addressId()); assertEquals(STATUS, INSTANCE_ADDRESS_INFO.status()); assertEquals(INSTANCE_USAGE, INSTANCE_ADDRESS_INFO.usage()); - assertEquals(INSTANCE_USAGE.instance(), - INSTANCE_ADDRESS_INFO.usage().instance()); + Assert.assertEquals(INSTANCE_USAGE.instance(), + INSTANCE_ADDRESS_INFO.usage().instance()); assertEquals(ADDRESS, REGION_FORWARDING_ADDRESS_INFO.address()); assertEquals(CREATION_TIMESTAMP, REGION_FORWARDING_ADDRESS_INFO.creationTimestamp()); assertEquals(DESCRIPTION, REGION_FORWARDING_ADDRESS_INFO.description()); @@ -119,8 +117,8 @@ public void testBuilder() { assertEquals(REGION_ADDRESS_ID, REGION_FORWARDING_ADDRESS_INFO.addressId()); assertEquals(STATUS, REGION_FORWARDING_ADDRESS_INFO.status()); assertEquals(REGION_FORWARDING_USAGE, REGION_FORWARDING_ADDRESS_INFO.usage()); - assertEquals(REGION_FORWARDING_RULES, - REGION_FORWARDING_ADDRESS_INFO.usage().forwardingRules()); + Assert.assertEquals(REGION_FORWARDING_RULES, + REGION_FORWARDING_ADDRESS_INFO.usage().forwardingRules()); assertEquals(ADDRESS, GLOBAL_FORWARDING_ADDRESS_INFO.address()); assertEquals(CREATION_TIMESTAMP, GLOBAL_FORWARDING_ADDRESS_INFO.creationTimestamp()); assertEquals(DESCRIPTION, GLOBAL_FORWARDING_ADDRESS_INFO.description()); @@ -128,8 +126,8 @@ public void testBuilder() { assertEquals(GLOBAL_ADDRESS_ID, GLOBAL_FORWARDING_ADDRESS_INFO.addressId()); assertEquals(STATUS, GLOBAL_FORWARDING_ADDRESS_INFO.status()); assertEquals(GLOBAL_FORWARDING_USAGE, GLOBAL_FORWARDING_ADDRESS_INFO.usage()); - assertEquals(GLOBAL_FORWARDING_RULES, - GLOBAL_FORWARDING_ADDRESS_INFO.usage().forwardingRules()); + Assert.assertEquals(GLOBAL_FORWARDING_RULES, + GLOBAL_FORWARDING_ADDRESS_INFO.usage().forwardingRules()); } @Test diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/AddressTest.java similarity index 99% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/AddressTest.java index e6b7cbee888d..914d7e510b3a 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AddressTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/AddressTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createStrictMock; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AttachedDiskTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/AttachedDiskTest.java similarity index 97% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/AttachedDiskTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/AttachedDiskTest.java index 4a9cfbfdc7a9..6e68e18590c2 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/AttachedDiskTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/AttachedDiskTest.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import com.google.cloud.compute.AttachedDisk.AttachedDiskConfiguration.InterfaceType; +import com.google.cloud.compute.AttachedDisk.AttachedDiskConfiguration.Type; +import com.google.cloud.compute.AttachedDisk.CreateDiskConfiguration; +import com.google.cloud.compute.AttachedDisk.PersistentDiskConfiguration; +import com.google.cloud.compute.AttachedDisk.ScratchDiskConfiguration; import com.google.common.collect.ImmutableList; -import com.google.gcloud.compute.AttachedDisk.AttachedDiskConfiguration.InterfaceType; -import com.google.gcloud.compute.AttachedDisk.AttachedDiskConfiguration.Type; -import com.google.gcloud.compute.AttachedDisk.CreateDiskConfiguration; -import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; -import com.google.gcloud.compute.AttachedDisk.ScratchDiskConfiguration; import org.junit.Test; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeExceptionTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/ComputeExceptionTest.java similarity index 96% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeExceptionTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/ComputeExceptionTest.java index f98bfa150d8c..2705a739814b 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeExceptionTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/ComputeExceptionTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; @@ -26,8 +26,8 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; -import com.google.gcloud.BaseServiceException; -import com.google.gcloud.RetryHelper.RetryHelperException; +import com.google.cloud.BaseServiceException; +import com.google.cloud.RetryHelper.RetryHelperException; import org.junit.Test; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/ComputeImplTest.java similarity index 80% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/ComputeImplTest.java index 07c7b851e0bf..6d1226df1a08 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ComputeImplTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/ComputeImplTest.java @@ -14,11 +14,8 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; -import static com.google.gcloud.compute.spi.ComputeRpc.Option.FILTER; -import static com.google.gcloud.compute.spi.ComputeRpc.Option.MAX_RESULTS; -import static com.google.gcloud.compute.spi.ComputeRpc.Option.PAGE_TOKEN; import static org.easymock.EasyMock.capture; import static org.easymock.EasyMock.eq; import static org.junit.Assert.assertArrayEquals; @@ -28,68 +25,15 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import com.google.cloud.Page; +import com.google.cloud.RetryParams; +import com.google.cloud.compute.NetworkInterface.AccessConfig; +import com.google.cloud.compute.spi.ComputeRpc; +import com.google.cloud.compute.spi.ComputeRpcFactory; import com.google.common.base.Function; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; -import com.google.gcloud.Page; -import com.google.gcloud.RetryParams; -import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; -import com.google.gcloud.compute.Compute.AddressAggregatedListOption; -import com.google.gcloud.compute.Compute.AddressFilter; -import com.google.gcloud.compute.Compute.AddressListOption; -import com.google.gcloud.compute.Compute.AddressOption; -import com.google.gcloud.compute.Compute.DiskAggregatedListOption; -import com.google.gcloud.compute.Compute.DiskField; -import com.google.gcloud.compute.Compute.DiskFilter; -import com.google.gcloud.compute.Compute.DiskListOption; -import com.google.gcloud.compute.Compute.DiskOption; -import com.google.gcloud.compute.Compute.DiskTypeAggregatedListOption; -import com.google.gcloud.compute.Compute.DiskTypeFilter; -import com.google.gcloud.compute.Compute.DiskTypeListOption; -import com.google.gcloud.compute.Compute.DiskTypeOption; -import com.google.gcloud.compute.Compute.ImageField; -import com.google.gcloud.compute.Compute.ImageFilter; -import com.google.gcloud.compute.Compute.ImageListOption; -import com.google.gcloud.compute.Compute.ImageOption; -import com.google.gcloud.compute.Compute.InstanceAggregatedListOption; -import com.google.gcloud.compute.Compute.InstanceField; -import com.google.gcloud.compute.Compute.InstanceFilter; -import com.google.gcloud.compute.Compute.InstanceListOption; -import com.google.gcloud.compute.Compute.InstanceOption; -import com.google.gcloud.compute.Compute.LicenseOption; -import com.google.gcloud.compute.Compute.MachineTypeAggregatedListOption; -import com.google.gcloud.compute.Compute.MachineTypeFilter; -import com.google.gcloud.compute.Compute.MachineTypeListOption; -import com.google.gcloud.compute.Compute.MachineTypeOption; -import com.google.gcloud.compute.Compute.NetworkField; -import com.google.gcloud.compute.Compute.NetworkFilter; -import com.google.gcloud.compute.Compute.NetworkListOption; -import com.google.gcloud.compute.Compute.NetworkOption; -import com.google.gcloud.compute.Compute.OperationFilter; -import com.google.gcloud.compute.Compute.OperationListOption; -import com.google.gcloud.compute.Compute.OperationOption; -import com.google.gcloud.compute.Compute.RegionFilter; -import com.google.gcloud.compute.Compute.RegionListOption; -import com.google.gcloud.compute.Compute.RegionOption; -import com.google.gcloud.compute.Compute.SnapshotFilter; -import com.google.gcloud.compute.Compute.SnapshotListOption; -import com.google.gcloud.compute.Compute.SnapshotOption; -import com.google.gcloud.compute.Compute.SubnetworkAggregatedListOption; -import com.google.gcloud.compute.Compute.SubnetworkField; -import com.google.gcloud.compute.Compute.SubnetworkFilter; -import com.google.gcloud.compute.Compute.SubnetworkListOption; -import com.google.gcloud.compute.Compute.SubnetworkOption; -import com.google.gcloud.compute.Compute.ZoneFilter; -import com.google.gcloud.compute.Compute.ZoneListOption; -import com.google.gcloud.compute.Compute.ZoneOption; -import com.google.gcloud.compute.NetworkInterface.AccessConfig; -import com.google.gcloud.compute.Operation.OperationError; -import com.google.gcloud.compute.Operation.OperationWarning; -import com.google.gcloud.compute.Operation.Status; -import com.google.gcloud.compute.spi.ComputeRpc; -import com.google.gcloud.compute.spi.ComputeRpc.Tuple; -import com.google.gcloud.compute.spi.ComputeRpcFactory; import org.easymock.Capture; import org.easymock.EasyMock; @@ -168,28 +112,28 @@ public class ComputeImplTest { private static final LicenseId LICENSE_ID = LicenseId.of("project", "license"); private static final Boolean CHARGES_USE_FEE = true; private static final License LICENSE = new License(LICENSE_ID, CHARGES_USE_FEE); - private static final OperationError OPERATION_ERROR1 = - new OperationError("code1", "location1", "message1"); - private static final OperationError OPERATION_ERROR2 = - new OperationError("code2", "location2", "message2"); - private static final OperationWarning OPERATION_WARNING1 = - new OperationWarning("code1", "message1", ImmutableMap.of("k1", "v1")); - private static final OperationWarning OPERATION_WARNING2 = - new OperationWarning("code2", "location2", ImmutableMap.of("k2", "v2")); + private static final Operation.OperationError OPERATION_ERROR1 = + new Operation.OperationError("code1", "location1", "message1"); + private static final Operation.OperationError OPERATION_ERROR2 = + new Operation.OperationError("code2", "location2", "message2"); + private static final Operation.OperationWarning OPERATION_WARNING1 = + new Operation.OperationWarning("code1", "message1", ImmutableMap.of("k1", "v1")); + private static final Operation.OperationWarning OPERATION_WARNING2 = + new Operation.OperationWarning("code2", "location2", ImmutableMap.of("k2", "v2")); private static final String CLIENT_OPERATION_ID = "clientOperationId"; private static final String OPERATION_TYPE = "delete"; private static final String TARGET_LINK = "targetLink"; private static final String TARGET_ID = "42"; - private static final Status STATUS = Status.DONE; + private static final Operation.Status STATUS = Operation.Status.DONE; private static final String STATUS_MESSAGE = "statusMessage"; private static final String USER = "user"; private static final Integer PROGRESS = 100; private static final Long INSERT_TIME = 1453293540000L; private static final Long START_TIME = 1453293420000L; private static final Long END_TIME = 1453293480000L; - private static final List ERRORS = + private static final List ERRORS = ImmutableList.of(OPERATION_ERROR1, OPERATION_ERROR2); - private static final List WARNINGS = + private static final List WARNINGS = ImmutableList.of(OPERATION_WARNING1, OPERATION_WARNING2); private static final Integer HTTP_ERROR_STATUS_CODE = 404; private static final String HTTP_ERROR_MESSAGE = "NOT FOUND"; @@ -221,8 +165,8 @@ public class ComputeImplTest { private static final NetworkInfo NETWORK = NetworkInfo.of(NETWORK_ID, StandardNetworkConfiguration.of("192.168.0.0/16")); private static final InstanceId INSTANCE_ID = InstanceId.of("project", "zone", "instance"); - private static final PersistentDiskConfiguration PERSISTENT_DISK_CONFIGURATION = - PersistentDiskConfiguration.of(DISK_ID); + private static final AttachedDisk.PersistentDiskConfiguration PERSISTENT_DISK_CONFIGURATION = + AttachedDisk.PersistentDiskConfiguration.of(DISK_ID); private static final AttachedDisk ATTACHED_DISK = AttachedDisk.of("device", PERSISTENT_DISK_CONFIGURATION); private static final NetworkInterface NETWORK_INTERFACE = NetworkInterface.of(NETWORK_ID); @@ -233,263 +177,263 @@ public class ComputeImplTest { private static final Map EMPTY_RPC_OPTIONS = ImmutableMap.of(); // DiskType options - private static final DiskTypeOption DISK_TYPE_OPTION_FIELDS = - DiskTypeOption.fields(Compute.DiskTypeField.ID, Compute.DiskTypeField.DESCRIPTION); + private static final Compute.DiskTypeOption DISK_TYPE_OPTION_FIELDS = + Compute.DiskTypeOption.fields(Compute.DiskTypeField.ID, Compute.DiskTypeField.DESCRIPTION); // DiskType list options - private static final DiskTypeFilter DISK_TYPE_FILTER = - DiskTypeFilter.equals(Compute.DiskTypeField.DESCRIPTION, "someDescription"); - private static final DiskTypeListOption DISK_TYPE_LIST_PAGE_TOKEN = - DiskTypeListOption.pageToken("cursor"); - private static final DiskTypeListOption DISK_TYPE_LIST_PAGE_SIZE = - DiskTypeListOption.pageSize(42L); - private static final DiskTypeListOption DISK_TYPE_LIST_FILTER = - DiskTypeListOption.filter(DISK_TYPE_FILTER); + private static final Compute.DiskTypeFilter DISK_TYPE_FILTER = + Compute.DiskTypeFilter.equals(Compute.DiskTypeField.DESCRIPTION, "someDescription"); + private static final Compute.DiskTypeListOption DISK_TYPE_LIST_PAGE_TOKEN = + Compute.DiskTypeListOption.pageToken("cursor"); + private static final Compute.DiskTypeListOption DISK_TYPE_LIST_PAGE_SIZE = + Compute.DiskTypeListOption.pageSize(42L); + private static final Compute.DiskTypeListOption DISK_TYPE_LIST_FILTER = + Compute.DiskTypeListOption.filter(DISK_TYPE_FILTER); private static final Map DISK_TYPE_LIST_OPTIONS = ImmutableMap.of( - PAGE_TOKEN, "cursor", - MAX_RESULTS, 42L, - FILTER, "description eq someDescription"); + ComputeRpc.Option.PAGE_TOKEN, "cursor", + ComputeRpc.Option.MAX_RESULTS, 42L, + ComputeRpc.Option.FILTER, "description eq someDescription"); // DiskType aggregated list options - private static final DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_PAGE_TOKEN = - DiskTypeAggregatedListOption.pageToken("cursor"); - private static final DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_PAGE_SIZE = - DiskTypeAggregatedListOption.pageSize(42L); - private static final DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_FILTER = - DiskTypeAggregatedListOption.filter(DISK_TYPE_FILTER); + private static final Compute.DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_PAGE_TOKEN = + Compute.DiskTypeAggregatedListOption.pageToken("cursor"); + private static final Compute.DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_PAGE_SIZE = + Compute.DiskTypeAggregatedListOption.pageSize(42L); + private static final Compute.DiskTypeAggregatedListOption DISK_TYPE_AGGREGATED_LIST_FILTER = + Compute.DiskTypeAggregatedListOption.filter(DISK_TYPE_FILTER); // MachineType options - private static final MachineTypeOption MACHINE_TYPE_OPTION_FIELDS = - MachineTypeOption.fields(Compute.MachineTypeField.ID, + private static final Compute.MachineTypeOption MACHINE_TYPE_OPTION_FIELDS = + Compute.MachineTypeOption.fields(Compute.MachineTypeField.ID, Compute.MachineTypeField.DESCRIPTION); // MachineType list options - private static final MachineTypeFilter MACHINE_TYPE_FILTER = - MachineTypeFilter.notEquals(Compute.MachineTypeField.MAXIMUM_PERSISTENT_DISKS, 42L); - private static final MachineTypeListOption MACHINE_TYPE_LIST_PAGE_TOKEN = - MachineTypeListOption.pageToken("cursor"); - private static final MachineTypeListOption MACHINE_TYPE_LIST_PAGE_SIZE = - MachineTypeListOption.pageSize(42L); - private static final MachineTypeListOption MACHINE_TYPE_LIST_FILTER = - MachineTypeListOption.filter(MACHINE_TYPE_FILTER); + private static final Compute.MachineTypeFilter MACHINE_TYPE_FILTER = + Compute.MachineTypeFilter.notEquals(Compute.MachineTypeField.MAXIMUM_PERSISTENT_DISKS, 42L); + private static final Compute.MachineTypeListOption MACHINE_TYPE_LIST_PAGE_TOKEN = + Compute.MachineTypeListOption.pageToken("cursor"); + private static final Compute.MachineTypeListOption MACHINE_TYPE_LIST_PAGE_SIZE = + Compute.MachineTypeListOption.pageSize(42L); + private static final Compute.MachineTypeListOption MACHINE_TYPE_LIST_FILTER = + Compute.MachineTypeListOption.filter(MACHINE_TYPE_FILTER); private static final Map MACHINE_TYPE_LIST_OPTIONS = ImmutableMap.of( - PAGE_TOKEN, "cursor", - MAX_RESULTS, 42L, - FILTER, "maximumPersistentDisks ne 42"); + ComputeRpc.Option.PAGE_TOKEN, "cursor", + ComputeRpc.Option.MAX_RESULTS, 42L, + ComputeRpc.Option.FILTER, "maximumPersistentDisks ne 42"); // MachineType aggregated list options - private static final MachineTypeAggregatedListOption MACHINE_TYPE_AGGREGATED_LIST_PAGE_TOKEN = - MachineTypeAggregatedListOption.pageToken("cursor"); - private static final MachineTypeAggregatedListOption MACHINE_TYPE_AGGREGATED_LIST_PAGE_SIZE = - MachineTypeAggregatedListOption.pageSize(42L); - private static final MachineTypeAggregatedListOption MACHINE_TYPE_AGGREGATED_LIST_FILTER = - MachineTypeAggregatedListOption.filter(MACHINE_TYPE_FILTER); + private static final Compute.MachineTypeAggregatedListOption MACHINE_TYPE_AGGREGATED_LIST_PAGE_TOKEN = + Compute.MachineTypeAggregatedListOption.pageToken("cursor"); + private static final Compute.MachineTypeAggregatedListOption MACHINE_TYPE_AGGREGATED_LIST_PAGE_SIZE = + Compute.MachineTypeAggregatedListOption.pageSize(42L); + private static final Compute.MachineTypeAggregatedListOption MACHINE_TYPE_AGGREGATED_LIST_FILTER = + Compute.MachineTypeAggregatedListOption.filter(MACHINE_TYPE_FILTER); // Region options - private static final RegionOption REGION_OPTION_FIELDS = - RegionOption.fields(Compute.RegionField.ID, Compute.RegionField.DESCRIPTION); + private static final Compute.RegionOption REGION_OPTION_FIELDS = + Compute.RegionOption.fields(Compute.RegionField.ID, Compute.RegionField.DESCRIPTION); // Region list options - private static final RegionFilter REGION_FILTER = - RegionFilter.equals(Compute.RegionField.ID, "someId"); - private static final RegionListOption REGION_LIST_PAGE_TOKEN = - RegionListOption.pageToken("cursor"); - private static final RegionListOption REGION_LIST_PAGE_SIZE = - RegionListOption.pageSize(42L); - private static final RegionListOption REGION_LIST_FILTER = - RegionListOption.filter(REGION_FILTER); + private static final Compute.RegionFilter REGION_FILTER = + Compute.RegionFilter.equals(Compute.RegionField.ID, "someId"); + private static final Compute.RegionListOption REGION_LIST_PAGE_TOKEN = + Compute.RegionListOption.pageToken("cursor"); + private static final Compute.RegionListOption REGION_LIST_PAGE_SIZE = + Compute.RegionListOption.pageSize(42L); + private static final Compute.RegionListOption REGION_LIST_FILTER = + Compute.RegionListOption.filter(REGION_FILTER); private static final Map REGION_LIST_OPTIONS = ImmutableMap.of( - PAGE_TOKEN, "cursor", - MAX_RESULTS, 42L, - FILTER, "id eq someId"); + ComputeRpc.Option.PAGE_TOKEN, "cursor", + ComputeRpc.Option.MAX_RESULTS, 42L, + ComputeRpc.Option.FILTER, "id eq someId"); // Zone options - private static final ZoneOption ZONE_OPTION_FIELDS = - ZoneOption.fields(Compute.ZoneField.ID, Compute.ZoneField.DESCRIPTION); + private static final Compute.ZoneOption ZONE_OPTION_FIELDS = + Compute.ZoneOption.fields(Compute.ZoneField.ID, Compute.ZoneField.DESCRIPTION); // Zone list options - private static final ZoneFilter ZONE_FILTER = - ZoneFilter.notEquals(Compute.ZoneField.NAME, "someName"); - private static final ZoneListOption ZONE_LIST_PAGE_TOKEN = - ZoneListOption.pageToken("cursor"); - private static final ZoneListOption ZONE_LIST_PAGE_SIZE = ZoneListOption.pageSize(42L); - private static final ZoneListOption ZONE_LIST_FILTER = ZoneListOption.filter(ZONE_FILTER); + private static final Compute.ZoneFilter ZONE_FILTER = + Compute.ZoneFilter.notEquals(Compute.ZoneField.NAME, "someName"); + private static final Compute.ZoneListOption ZONE_LIST_PAGE_TOKEN = + Compute.ZoneListOption.pageToken("cursor"); + private static final Compute.ZoneListOption ZONE_LIST_PAGE_SIZE = Compute.ZoneListOption.pageSize(42L); + private static final Compute.ZoneListOption ZONE_LIST_FILTER = Compute.ZoneListOption.filter(ZONE_FILTER); private static final Map ZONE_LIST_OPTIONS = ImmutableMap.of( - PAGE_TOKEN, "cursor", - MAX_RESULTS, 42L, - FILTER, "name ne someName"); + ComputeRpc.Option.PAGE_TOKEN, "cursor", + ComputeRpc.Option.MAX_RESULTS, 42L, + ComputeRpc.Option.FILTER, "name ne someName"); // License options - private static final LicenseOption LICENSE_OPTION_FIELDS = - LicenseOption.fields(Compute.LicenseField.CHARGES_USE_FEE); + private static final Compute.LicenseOption LICENSE_OPTION_FIELDS = + Compute.LicenseOption.fields(Compute.LicenseField.CHARGES_USE_FEE); // Operation options - private static final OperationOption OPERATION_OPTION_FIELDS = - OperationOption.fields(Compute.OperationField.ID, Compute.OperationField.DESCRIPTION); + private static final Compute.OperationOption OPERATION_OPTION_FIELDS = + Compute.OperationOption.fields(Compute.OperationField.ID, Compute.OperationField.DESCRIPTION); // Operation list options - private static final OperationFilter OPERATION_FILTER = - OperationFilter.notEquals(Compute.OperationField.PROGRESS, 0); - private static final OperationListOption OPERATION_LIST_PAGE_TOKEN = - OperationListOption.pageToken("cursor"); - private static final OperationListOption OPERATION_LIST_PAGE_SIZE = - OperationListOption.pageSize(42L); - private static final OperationListOption OPERATION_LIST_FILTER = - OperationListOption.filter(OPERATION_FILTER); + private static final Compute.OperationFilter OPERATION_FILTER = + Compute.OperationFilter.notEquals(Compute.OperationField.PROGRESS, 0); + private static final Compute.OperationListOption OPERATION_LIST_PAGE_TOKEN = + Compute.OperationListOption.pageToken("cursor"); + private static final Compute.OperationListOption OPERATION_LIST_PAGE_SIZE = + Compute.OperationListOption.pageSize(42L); + private static final Compute.OperationListOption OPERATION_LIST_FILTER = + Compute.OperationListOption.filter(OPERATION_FILTER); private static final Map OPERATION_LIST_OPTIONS = ImmutableMap.of( - PAGE_TOKEN, "cursor", - MAX_RESULTS, 42L, - FILTER, "progress ne 0"); + ComputeRpc.Option.PAGE_TOKEN, "cursor", + ComputeRpc.Option.MAX_RESULTS, 42L, + ComputeRpc.Option.FILTER, "progress ne 0"); // Address options - private static final AddressOption ADDRESS_OPTION_FIELDS = - AddressOption.fields(Compute.AddressField.ID, Compute.AddressField.DESCRIPTION); + private static final Compute.AddressOption ADDRESS_OPTION_FIELDS = + Compute.AddressOption.fields(Compute.AddressField.ID, Compute.AddressField.DESCRIPTION); // Address list options - private static final AddressFilter ADDRESS_FILTER = - AddressFilter.notEquals(Compute.AddressField.REGION, "someRegion"); - private static final AddressListOption ADDRESS_LIST_PAGE_TOKEN = - AddressListOption.pageToken("cursor"); - private static final AddressListOption ADDRESS_LIST_PAGE_SIZE = AddressListOption.pageSize(42L); - private static final AddressListOption ADDRESS_LIST_FILTER = - AddressListOption.filter(ADDRESS_FILTER); + private static final Compute.AddressFilter ADDRESS_FILTER = + Compute.AddressFilter.notEquals(Compute.AddressField.REGION, "someRegion"); + private static final Compute.AddressListOption ADDRESS_LIST_PAGE_TOKEN = + Compute.AddressListOption.pageToken("cursor"); + private static final Compute.AddressListOption ADDRESS_LIST_PAGE_SIZE = Compute.AddressListOption.pageSize(42L); + private static final Compute.AddressListOption ADDRESS_LIST_FILTER = + Compute.AddressListOption.filter(ADDRESS_FILTER); private static final Map ADDRESS_LIST_OPTIONS = ImmutableMap.of( - PAGE_TOKEN, "cursor", - MAX_RESULTS, 42L, - FILTER, "region ne someRegion"); + ComputeRpc.Option.PAGE_TOKEN, "cursor", + ComputeRpc.Option.MAX_RESULTS, 42L, + ComputeRpc.Option.FILTER, "region ne someRegion"); // Address aggregated list options - private static final AddressAggregatedListOption ADDRESS_AGGREGATED_LIST_PAGE_TOKEN = - AddressAggregatedListOption.pageToken("cursor"); - private static final AddressAggregatedListOption ADDRESS_AGGREGATED_LIST_PAGE_SIZE = - AddressAggregatedListOption.pageSize(42L); - private static final AddressAggregatedListOption ADDRESS_AGGREGATED_LIST_FILTER = - AddressAggregatedListOption.filter(ADDRESS_FILTER); + private static final Compute.AddressAggregatedListOption ADDRESS_AGGREGATED_LIST_PAGE_TOKEN = + Compute.AddressAggregatedListOption.pageToken("cursor"); + private static final Compute.AddressAggregatedListOption ADDRESS_AGGREGATED_LIST_PAGE_SIZE = + Compute.AddressAggregatedListOption.pageSize(42L); + private static final Compute.AddressAggregatedListOption ADDRESS_AGGREGATED_LIST_FILTER = + Compute.AddressAggregatedListOption.filter(ADDRESS_FILTER); // Snapshot options - private static final SnapshotOption SNAPSHOT_OPTION_FIELDS = - SnapshotOption.fields(Compute.SnapshotField.ID, Compute.SnapshotField.DESCRIPTION); + private static final Compute.SnapshotOption SNAPSHOT_OPTION_FIELDS = + Compute.SnapshotOption.fields(Compute.SnapshotField.ID, Compute.SnapshotField.DESCRIPTION); // Snapshot list options - private static final SnapshotFilter SNAPSHOT_FILTER = - SnapshotFilter.equals(Compute.SnapshotField.DISK_SIZE_GB, 500L); - private static final SnapshotListOption SNAPSHOT_LIST_PAGE_TOKEN = - SnapshotListOption.pageToken("cursor"); - private static final SnapshotListOption SNAPSHOT_LIST_PAGE_SIZE = - SnapshotListOption.pageSize(42L); - private static final SnapshotListOption SNAPSHOT_LIST_FILTER = - SnapshotListOption.filter(SNAPSHOT_FILTER); + private static final Compute.SnapshotFilter SNAPSHOT_FILTER = + Compute.SnapshotFilter.equals(Compute.SnapshotField.DISK_SIZE_GB, 500L); + private static final Compute.SnapshotListOption SNAPSHOT_LIST_PAGE_TOKEN = + Compute.SnapshotListOption.pageToken("cursor"); + private static final Compute.SnapshotListOption SNAPSHOT_LIST_PAGE_SIZE = + Compute.SnapshotListOption.pageSize(42L); + private static final Compute.SnapshotListOption SNAPSHOT_LIST_FILTER = + Compute.SnapshotListOption.filter(SNAPSHOT_FILTER); private static final Map SNAPSHOT_LIST_OPTIONS = ImmutableMap.of( - PAGE_TOKEN, "cursor", - MAX_RESULTS, 42L, - FILTER, "diskSizeGb eq 500"); + ComputeRpc.Option.PAGE_TOKEN, "cursor", + ComputeRpc.Option.MAX_RESULTS, 42L, + ComputeRpc.Option.FILTER, "diskSizeGb eq 500"); // Image options - private static final ImageOption IMAGE_OPTION_FIELDS = - ImageOption.fields(ImageField.ID, ImageField.DESCRIPTION); + private static final Compute.ImageOption IMAGE_OPTION_FIELDS = + Compute.ImageOption.fields(Compute.ImageField.ID, Compute.ImageField.DESCRIPTION); // Image list options - private static final ImageFilter IMAGE_FILTER = - ImageFilter.notEquals(ImageField.DISK_SIZE_GB, 500L); - private static final ImageListOption IMAGE_LIST_PAGE_TOKEN = ImageListOption.pageToken("cursor"); - private static final ImageListOption IMAGE_LIST_PAGE_SIZE = ImageListOption.pageSize(42L); - private static final ImageListOption IMAGE_LIST_FILTER = ImageListOption.filter(IMAGE_FILTER); + private static final Compute.ImageFilter IMAGE_FILTER = + Compute.ImageFilter.notEquals(Compute.ImageField.DISK_SIZE_GB, 500L); + private static final Compute.ImageListOption IMAGE_LIST_PAGE_TOKEN = Compute.ImageListOption.pageToken("cursor"); + private static final Compute.ImageListOption IMAGE_LIST_PAGE_SIZE = Compute.ImageListOption.pageSize(42L); + private static final Compute.ImageListOption IMAGE_LIST_FILTER = Compute.ImageListOption.filter(IMAGE_FILTER); private static final Map IMAGE_LIST_OPTIONS = ImmutableMap.of( - PAGE_TOKEN, "cursor", - MAX_RESULTS, 42L, - FILTER, "diskSizeGb ne 500"); + ComputeRpc.Option.PAGE_TOKEN, "cursor", + ComputeRpc.Option.MAX_RESULTS, 42L, + ComputeRpc.Option.FILTER, "diskSizeGb ne 500"); // Disk options - private static final DiskOption DISK_OPTION_FIELDS = - DiskOption.fields(DiskField.ID, DiskField.DESCRIPTION); + private static final Compute.DiskOption DISK_OPTION_FIELDS = + Compute.DiskOption.fields(Compute.DiskField.ID, Compute.DiskField.DESCRIPTION); // Disk list options - private static final DiskFilter DISK_FILTER = DiskFilter.notEquals(DiskField.SIZE_GB, 500L); - private static final DiskListOption DISK_LIST_PAGE_TOKEN = DiskListOption.pageToken("cursor"); - private static final DiskListOption DISK_LIST_PAGE_SIZE = DiskListOption.pageSize(42L); - private static final DiskListOption DISK_LIST_FILTER = DiskListOption.filter(DISK_FILTER); + private static final Compute.DiskFilter DISK_FILTER = Compute.DiskFilter.notEquals(Compute.DiskField.SIZE_GB, 500L); + private static final Compute.DiskListOption DISK_LIST_PAGE_TOKEN = Compute.DiskListOption.pageToken("cursor"); + private static final Compute.DiskListOption DISK_LIST_PAGE_SIZE = Compute.DiskListOption.pageSize(42L); + private static final Compute.DiskListOption DISK_LIST_FILTER = Compute.DiskListOption.filter(DISK_FILTER); private static final Map DISK_LIST_OPTIONS = ImmutableMap.of( - PAGE_TOKEN, "cursor", - MAX_RESULTS, 42L, - FILTER, "sizeGb ne 500"); + ComputeRpc.Option.PAGE_TOKEN, "cursor", + ComputeRpc.Option.MAX_RESULTS, 42L, + ComputeRpc.Option.FILTER, "sizeGb ne 500"); // Disk aggregated list options - private static final DiskAggregatedListOption DISK_AGGREGATED_LIST_PAGE_TOKEN = - DiskAggregatedListOption.pageToken("cursor"); - private static final DiskAggregatedListOption DISK_AGGREGATED_LIST_PAGE_SIZE = - DiskAggregatedListOption.pageSize(42L); - private static final DiskAggregatedListOption DISK_AGGREGATED_LIST_FILTER = - DiskAggregatedListOption.filter(DISK_FILTER); + private static final Compute.DiskAggregatedListOption DISK_AGGREGATED_LIST_PAGE_TOKEN = + Compute.DiskAggregatedListOption.pageToken("cursor"); + private static final Compute.DiskAggregatedListOption DISK_AGGREGATED_LIST_PAGE_SIZE = + Compute.DiskAggregatedListOption.pageSize(42L); + private static final Compute.DiskAggregatedListOption DISK_AGGREGATED_LIST_FILTER = + Compute.DiskAggregatedListOption.filter(DISK_FILTER); // Subnetwork options - private static final SubnetworkOption SUBNETWORK_OPTION_FIELDS = - SubnetworkOption.fields(SubnetworkField.ID, SubnetworkField.DESCRIPTION); + private static final Compute.SubnetworkOption SUBNETWORK_OPTION_FIELDS = + Compute.SubnetworkOption.fields(Compute.SubnetworkField.ID, Compute.SubnetworkField.DESCRIPTION); // Subnetwork list options - private static final SubnetworkFilter SUBNETWORK_FILTER = - SubnetworkFilter.equals(SubnetworkField.IP_CIDR_RANGE, "192.168.0.0/16"); - private static final SubnetworkListOption SUBNETWORK_LIST_PAGE_TOKEN = - SubnetworkListOption.pageToken("cursor"); - private static final SubnetworkListOption SUBNETWORK_LIST_PAGE_SIZE = - SubnetworkListOption.pageSize(42L); - private static final SubnetworkListOption SUBNETWORK_LIST_FILTER = - SubnetworkListOption.filter(SUBNETWORK_FILTER); + private static final Compute.SubnetworkFilter SUBNETWORK_FILTER = + Compute.SubnetworkFilter.equals(Compute.SubnetworkField.IP_CIDR_RANGE, "192.168.0.0/16"); + private static final Compute.SubnetworkListOption SUBNETWORK_LIST_PAGE_TOKEN = + Compute.SubnetworkListOption.pageToken("cursor"); + private static final Compute.SubnetworkListOption SUBNETWORK_LIST_PAGE_SIZE = + Compute.SubnetworkListOption.pageSize(42L); + private static final Compute.SubnetworkListOption SUBNETWORK_LIST_FILTER = + Compute.SubnetworkListOption.filter(SUBNETWORK_FILTER); private static final Map SUBNETWORK_LIST_OPTIONS = ImmutableMap.of( - PAGE_TOKEN, "cursor", - MAX_RESULTS, 42L, - FILTER, "ipCidrRange eq 192.168.0.0/16"); + ComputeRpc.Option.PAGE_TOKEN, "cursor", + ComputeRpc.Option.MAX_RESULTS, 42L, + ComputeRpc.Option.FILTER, "ipCidrRange eq 192.168.0.0/16"); // Subnetwork aggregated list options - private static final SubnetworkAggregatedListOption SUBNETWORK_AGGREGATED_LIST_PAGE_TOKEN = - SubnetworkAggregatedListOption.pageToken("cursor"); - private static final SubnetworkAggregatedListOption SUBNETWORK_AGGREGATED_LIST_PAGE_SIZE = - SubnetworkAggregatedListOption.pageSize(42L); - private static final SubnetworkAggregatedListOption SUBNETWORK_AGGREGATED_LIST_FILTER = - SubnetworkAggregatedListOption.filter(SUBNETWORK_FILTER); + private static final Compute.SubnetworkAggregatedListOption SUBNETWORK_AGGREGATED_LIST_PAGE_TOKEN = + Compute.SubnetworkAggregatedListOption.pageToken("cursor"); + private static final Compute.SubnetworkAggregatedListOption SUBNETWORK_AGGREGATED_LIST_PAGE_SIZE = + Compute.SubnetworkAggregatedListOption.pageSize(42L); + private static final Compute.SubnetworkAggregatedListOption SUBNETWORK_AGGREGATED_LIST_FILTER = + Compute.SubnetworkAggregatedListOption.filter(SUBNETWORK_FILTER); // Network options - private static final NetworkOption NETWORK_OPTION_FIELDS = - NetworkOption.fields(NetworkField.ID, NetworkField.DESCRIPTION); + private static final Compute.NetworkOption NETWORK_OPTION_FIELDS = + Compute.NetworkOption.fields(Compute.NetworkField.ID, Compute.NetworkField.DESCRIPTION); // Network list options - private static final NetworkFilter NETWORK_FILTER = - NetworkFilter.equals(NetworkField.IPV4_RANGE, "192.168.0.0/16"); - private static final NetworkListOption NETWORK_LIST_PAGE_TOKEN = - NetworkListOption.pageToken("cursor"); - private static final NetworkListOption NETWORK_LIST_PAGE_SIZE = - NetworkListOption.pageSize(42L); - private static final NetworkListOption NETWORK_LIST_FILTER = - NetworkListOption.filter(NETWORK_FILTER); + private static final Compute.NetworkFilter NETWORK_FILTER = + Compute.NetworkFilter.equals(Compute.NetworkField.IPV4_RANGE, "192.168.0.0/16"); + private static final Compute.NetworkListOption NETWORK_LIST_PAGE_TOKEN = + Compute.NetworkListOption.pageToken("cursor"); + private static final Compute.NetworkListOption NETWORK_LIST_PAGE_SIZE = + Compute.NetworkListOption.pageSize(42L); + private static final Compute.NetworkListOption NETWORK_LIST_FILTER = + Compute.NetworkListOption.filter(NETWORK_FILTER); private static final Map NETWORK_LIST_OPTIONS = ImmutableMap.of( - PAGE_TOKEN, "cursor", - MAX_RESULTS, 42L, - FILTER, "IPv4Range eq 192.168.0.0/16"); + ComputeRpc.Option.PAGE_TOKEN, "cursor", + ComputeRpc.Option.MAX_RESULTS, 42L, + ComputeRpc.Option.FILTER, "IPv4Range eq 192.168.0.0/16"); // Instance options - private static final InstanceOption INSTANCE_OPTION_FIELDS = - InstanceOption.fields(InstanceField.ID, InstanceField.DESCRIPTION); + private static final Compute.InstanceOption INSTANCE_OPTION_FIELDS = + Compute.InstanceOption.fields(Compute.InstanceField.ID, Compute.InstanceField.DESCRIPTION); // Instance list options - private static final InstanceFilter INSTANCE_FILTER = - InstanceFilter.equals(InstanceField.CAN_IP_FORWARD, true); - private static final InstanceListOption INSTANCE_LIST_PAGE_TOKEN = - InstanceListOption.pageToken("cursor"); - private static final InstanceListOption INSTANCE_LIST_PAGE_SIZE = - InstanceListOption.pageSize(42L); - private static final InstanceListOption INSTANCE_LIST_FILTER = - InstanceListOption.filter(INSTANCE_FILTER); + private static final Compute.InstanceFilter INSTANCE_FILTER = + Compute.InstanceFilter.equals(Compute.InstanceField.CAN_IP_FORWARD, true); + private static final Compute.InstanceListOption INSTANCE_LIST_PAGE_TOKEN = + Compute.InstanceListOption.pageToken("cursor"); + private static final Compute.InstanceListOption INSTANCE_LIST_PAGE_SIZE = + Compute.InstanceListOption.pageSize(42L); + private static final Compute.InstanceListOption INSTANCE_LIST_FILTER = + Compute.InstanceListOption.filter(INSTANCE_FILTER); private static final Map INSTANCE_LIST_OPTIONS = ImmutableMap.of( - PAGE_TOKEN, "cursor", - MAX_RESULTS, 42L, - FILTER, "canIpForward eq true"); + ComputeRpc.Option.PAGE_TOKEN, "cursor", + ComputeRpc.Option.MAX_RESULTS, 42L, + ComputeRpc.Option.FILTER, "canIpForward eq true"); // Instance aggregated list options - private static final InstanceAggregatedListOption INSTANCE_AGGREGATED_LIST_PAGE_TOKEN = - InstanceAggregatedListOption.pageToken("cursor"); - private static final InstanceAggregatedListOption INSTANCE_AGGREGATED_LIST_PAGE_SIZE = - InstanceAggregatedListOption.pageSize(42L); - private static final InstanceAggregatedListOption INSTANCE_AGGREGATED_LIST_FILTER = - InstanceAggregatedListOption.filter(INSTANCE_FILTER); + private static final Compute.InstanceAggregatedListOption INSTANCE_AGGREGATED_LIST_PAGE_TOKEN = + Compute.InstanceAggregatedListOption.pageToken("cursor"); + private static final Compute.InstanceAggregatedListOption INSTANCE_AGGREGATED_LIST_PAGE_SIZE = + Compute.InstanceAggregatedListOption.pageSize(42L); + private static final Compute.InstanceAggregatedListOption INSTANCE_AGGREGATED_LIST_FILTER = + Compute.InstanceAggregatedListOption.filter(INSTANCE_FILTER); private static final Function OPERATION_TO_PB_FUNCTION = new Function diskTypeList = ImmutableList.of(DISK_TYPE, DISK_TYPE); - Tuple> result = - Tuple.of(cursor, Iterables.transform(diskTypeList, DiskType.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(diskTypeList, DiskType.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listDiskTypes(DISK_TYPE_ID.zone(), EMPTY_RPC_OPTIONS)) .andReturn(result); EasyMock.replay(computeRpcMock); @@ -671,12 +615,12 @@ public void testListDiskTypesNextPage() { String nextCursor = "nextCursor"; compute = options.service(); ImmutableList diskTypeList = ImmutableList.of(DISK_TYPE, DISK_TYPE); - Tuple> result = - Tuple.of(cursor, Iterables.transform(diskTypeList, DiskType.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(diskTypeList, DiskType.TO_PB_FUNCTION)); ImmutableList nextDiskTypeList = ImmutableList.of(DISK_TYPE); - Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextDiskTypeList, DiskType.TO_PB_FUNCTION)); - Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + ComputeRpc.Tuple> nextResult = + ComputeRpc.Tuple.of(nextCursor, Iterables.transform(nextDiskTypeList, DiskType.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(ComputeRpc.Option.PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listDiskTypes(DISK_TYPE_ID.zone(), EMPTY_RPC_OPTIONS)) .andReturn(result); EasyMock.expect(computeRpcMock.listDiskTypes(DISK_TYPE_ID.zone(), nextOptions)) @@ -693,8 +637,8 @@ public void testListDiskTypesNextPage() { @Test public void testListEmptyDiskTypes() { ImmutableList diskTypes = ImmutableList.of(); - Tuple> result = - Tuple.>of(null, diskTypes); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.>of(null, diskTypes); EasyMock.expect(computeRpcMock.listDiskTypes(DISK_TYPE_ID.zone(), EMPTY_RPC_OPTIONS)) .andReturn(result); EasyMock.replay(computeRpcMock); @@ -709,8 +653,8 @@ public void testListDiskTypesWithOptions() { String cursor = "cursor"; compute = options.service(); ImmutableList diskTypeList = ImmutableList.of(DISK_TYPE, DISK_TYPE); - Tuple> result = - Tuple.of(cursor, Iterables.transform(diskTypeList, DiskType.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(diskTypeList, DiskType.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listDiskTypes(DISK_TYPE_ID.zone(), DISK_TYPE_LIST_OPTIONS)) .andReturn(result); EasyMock.replay(computeRpcMock); @@ -725,8 +669,8 @@ public void testAggregatedListDiskTypes() { String cursor = "cursor"; compute = options.service(); ImmutableList diskTypeList = ImmutableList.of(DISK_TYPE, DISK_TYPE); - Tuple> result = - Tuple.of(cursor, Iterables.transform(diskTypeList, DiskType.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(diskTypeList, DiskType.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listDiskTypes(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listDiskTypes(); @@ -740,12 +684,12 @@ public void testAggregatedListDiskTypesNextPage() { String nextCursor = "nextCursor"; compute = options.service(); ImmutableList diskTypeList = ImmutableList.of(DISK_TYPE, DISK_TYPE); - Tuple> result = - Tuple.of(cursor, Iterables.transform(diskTypeList, DiskType.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(diskTypeList, DiskType.TO_PB_FUNCTION)); ImmutableList nextDiskTypeList = ImmutableList.of(DISK_TYPE); - Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextDiskTypeList, DiskType.TO_PB_FUNCTION)); - Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + ComputeRpc.Tuple> nextResult = + ComputeRpc.Tuple.of(nextCursor, Iterables.transform(nextDiskTypeList, DiskType.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(ComputeRpc.Option.PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listDiskTypes(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.expect(computeRpcMock.listDiskTypes(nextOptions)).andReturn(nextResult); EasyMock.replay(computeRpcMock); @@ -760,8 +704,8 @@ public void testAggregatedListDiskTypesNextPage() { @Test public void testAggregatedListEmptyDiskTypes() { ImmutableList diskTypes = ImmutableList.of(); - Tuple> result = - Tuple.>of(null, diskTypes); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.>of(null, diskTypes); EasyMock.expect(computeRpcMock.listDiskTypes(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); compute = options.service(); @@ -775,8 +719,8 @@ public void testAggregatedListDiskTypesWithOptions() { String cursor = "cursor"; compute = options.service(); ImmutableList diskTypeList = ImmutableList.of(DISK_TYPE, DISK_TYPE); - Tuple> result = - Tuple.of(cursor, Iterables.transform(diskTypeList, DiskType.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(diskTypeList, DiskType.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listDiskTypes(DISK_TYPE_LIST_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listDiskTypes(DISK_TYPE_AGGREGATED_LIST_PAGE_SIZE, @@ -844,8 +788,8 @@ public void testListMachineTypes() { String cursor = "cursor"; compute = options.service(); ImmutableList machineTypeList = ImmutableList.of(MACHINE_TYPE, MACHINE_TYPE); - Tuple> result = - Tuple.of(cursor, Iterables.transform(machineTypeList, MachineType.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(machineTypeList, MachineType.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listMachineTypes(MACHINE_TYPE_ID.zone(), EMPTY_RPC_OPTIONS)) .andReturn(result); EasyMock.replay(computeRpcMock); @@ -861,12 +805,12 @@ public void testListMachineTypesNextPage() { String nextCursor = "nextCursor"; compute = options.service(); ImmutableList machineTypeList = ImmutableList.of(MACHINE_TYPE, MACHINE_TYPE); - Tuple> result = - Tuple.of(cursor, Iterables.transform(machineTypeList, MachineType.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(machineTypeList, MachineType.TO_PB_FUNCTION)); ImmutableList nextMachineTypeList = ImmutableList.of(MACHINE_TYPE); - Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextMachineTypeList, MachineType.TO_PB_FUNCTION)); - Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + ComputeRpc.Tuple> nextResult = + ComputeRpc.Tuple.of(nextCursor, Iterables.transform(nextMachineTypeList, MachineType.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(ComputeRpc.Option.PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listMachineTypes(MACHINE_TYPE_ID.zone(), EMPTY_RPC_OPTIONS)) .andReturn(result); EasyMock.expect(computeRpcMock.listMachineTypes(MACHINE_TYPE_ID.zone(), nextOptions)) @@ -886,8 +830,8 @@ public void testListMachineTypesNextPage() { public void testListEmptyMachineTypes() { ImmutableList machineTypes = ImmutableList.of(); - Tuple> result = - Tuple.>of(null, + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.>of(null, machineTypes); EasyMock.expect(computeRpcMock.listMachineTypes(MACHINE_TYPE_ID.zone(), EMPTY_RPC_OPTIONS)) .andReturn(result); @@ -903,8 +847,8 @@ public void testListMachineTypesWithOptions() { String cursor = "cursor"; compute = options.service(); ImmutableList machineTypeList = ImmutableList.of(MACHINE_TYPE, MACHINE_TYPE); - Tuple> result = - Tuple.of(cursor, Iterables.transform(machineTypeList, MachineType.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(machineTypeList, MachineType.TO_PB_FUNCTION)); EasyMock.expect( computeRpcMock.listMachineTypes(MACHINE_TYPE_ID.zone(), MACHINE_TYPE_LIST_OPTIONS)) .andReturn(result); @@ -921,8 +865,8 @@ public void testAggregatedListMachineTypes() { String cursor = "cursor"; compute = options.service(); ImmutableList machineTypeList = ImmutableList.of(MACHINE_TYPE, MACHINE_TYPE); - Tuple> result = - Tuple.of(cursor, Iterables.transform(machineTypeList, MachineType.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(machineTypeList, MachineType.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listMachineTypes(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listMachineTypes(); @@ -937,12 +881,12 @@ public void testAggregatedListMachineTypesNextPage() { String nextCursor = "nextCursor"; compute = options.service(); ImmutableList machineTypeList = ImmutableList.of(MACHINE_TYPE, MACHINE_TYPE); - Tuple> result = - Tuple.of(cursor, Iterables.transform(machineTypeList, MachineType.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(machineTypeList, MachineType.TO_PB_FUNCTION)); ImmutableList nextMachineTypeList = ImmutableList.of(MACHINE_TYPE); - Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextMachineTypeList, MachineType.TO_PB_FUNCTION)); - Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + ComputeRpc.Tuple> nextResult = + ComputeRpc.Tuple.of(nextCursor, Iterables.transform(nextMachineTypeList, MachineType.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(ComputeRpc.Option.PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listMachineTypes(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.expect(computeRpcMock.listMachineTypes(nextOptions)).andReturn(nextResult); EasyMock.replay(computeRpcMock); @@ -960,8 +904,8 @@ public void testAggregatedListMachineTypesNextPage() { public void testAggregatedListEmptyMachineTypes() { ImmutableList machineTypes = ImmutableList.of(); - Tuple> result = - Tuple.>of(null, + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.>of(null, machineTypes); EasyMock.expect(computeRpcMock.listMachineTypes(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); @@ -976,8 +920,8 @@ public void testAggregatedListMachineTypesWithOptions() { String cursor = "cursor"; compute = options.service(); ImmutableList machineTypeList = ImmutableList.of(MACHINE_TYPE, MACHINE_TYPE); - Tuple> result = - Tuple.of(cursor, Iterables.transform(machineTypeList, MachineType.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(machineTypeList, MachineType.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listMachineTypes(MACHINE_TYPE_LIST_OPTIONS)) .andReturn(result); EasyMock.replay(computeRpcMock); @@ -1028,8 +972,8 @@ public void testListRegions() { String cursor = "cursor"; compute = options.service(); ImmutableList regionList = ImmutableList.of(REGION, REGION); - Tuple> result = - Tuple.of(cursor, Iterables.transform(regionList, Region.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(regionList, Region.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listRegions(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listRegions(); @@ -1044,11 +988,11 @@ public void testListRegionsNextPage() { compute = options.service(); ImmutableList regionList = ImmutableList.of(REGION, REGION); ImmutableList nextRegionList = ImmutableList.of(REGION); - Tuple> result = - Tuple.of(cursor, Iterables.transform(regionList, Region.TO_PB_FUNCTION)); - Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextRegionList, Region.TO_PB_FUNCTION)); - Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(regionList, Region.TO_PB_FUNCTION)); + ComputeRpc.Tuple> nextResult = + ComputeRpc.Tuple.of(nextCursor, Iterables.transform(nextRegionList, Region.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(ComputeRpc.Option.PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listRegions(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.expect(computeRpcMock.listRegions(nextOptions)).andReturn(nextResult); EasyMock.replay(computeRpcMock); @@ -1063,8 +1007,8 @@ public void testListRegionsNextPage() { @Test public void testListEmptyRegions() { ImmutableList regions = ImmutableList.of(); - Tuple> result = - Tuple.>of(null, + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.>of(null, regions); EasyMock.expect(computeRpcMock.listRegions(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); @@ -1079,8 +1023,8 @@ public void testListRegionsWithOptions() { String cursor = "cursor"; compute = options.service(); ImmutableList regionList = ImmutableList.of(REGION, REGION); - Tuple> result = - Tuple.of(cursor, Iterables.transform(regionList, Region.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(regionList, Region.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listRegions(REGION_LIST_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listRegions(REGION_LIST_PAGE_SIZE, REGION_LIST_PAGE_TOKEN, @@ -1128,8 +1072,8 @@ public void testListZones() { String cursor = "cursor"; compute = options.service(); ImmutableList zoneList = ImmutableList.of(ZONE, ZONE); - Tuple> result = - Tuple.of(cursor, Iterables.transform(zoneList, Zone.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(zoneList, Zone.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listZones(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listZones(); @@ -1144,11 +1088,11 @@ public void testListZonesNextPage() { compute = options.service(); ImmutableList zoneList = ImmutableList.of(ZONE, ZONE); ImmutableList nextZoneList = ImmutableList.of(ZONE); - Tuple> result = - Tuple.of(cursor, Iterables.transform(zoneList, Zone.TO_PB_FUNCTION)); - Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextZoneList, Zone.TO_PB_FUNCTION)); - Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(zoneList, Zone.TO_PB_FUNCTION)); + ComputeRpc.Tuple> nextResult = + ComputeRpc.Tuple.of(nextCursor, Iterables.transform(nextZoneList, Zone.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(ComputeRpc.Option.PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listZones(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.expect(computeRpcMock.listZones(nextOptions)).andReturn(nextResult); EasyMock.replay(computeRpcMock); @@ -1163,8 +1107,8 @@ public void testListZonesNextPage() { @Test public void testListEmptyZones() { ImmutableList zones = ImmutableList.of(); - Tuple> result = - Tuple.>of(null, zones); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.>of(null, zones); EasyMock.expect(computeRpcMock.listZones(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); compute = options.service(); @@ -1178,8 +1122,8 @@ public void testListZonesWithOptions() { String cursor = "cursor"; compute = options.service(); ImmutableList zoneList = ImmutableList.of(ZONE, ZONE); - Tuple> result = - Tuple.of(cursor, Iterables.transform(zoneList, Zone.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(zoneList, Zone.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listZones(ZONE_LIST_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = @@ -1307,8 +1251,8 @@ public void testListGlobalOperations() { String cursor = "cursor"; compute = options.service(); ImmutableList operationList = ImmutableList.of(globalOperation, globalOperation); - Tuple> result = - Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listGlobalOperations(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listGlobalOperations(); @@ -1323,11 +1267,11 @@ public void testListGlobalOperationsNextPage() { compute = options.service(); ImmutableList operationList = ImmutableList.of(globalOperation, globalOperation); ImmutableList nextOperationList = ImmutableList.of(globalOperation); - Tuple> result = - Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); - Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextOperationList, OPERATION_TO_PB_FUNCTION)); - Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); + ComputeRpc.Tuple> nextResult = + ComputeRpc.Tuple.of(nextCursor, Iterables.transform(nextOperationList, OPERATION_TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(ComputeRpc.Option.PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listGlobalOperations(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.expect(computeRpcMock.listGlobalOperations(nextOptions)).andReturn(nextResult); EasyMock.replay(computeRpcMock); @@ -1343,8 +1287,8 @@ public void testListGlobalOperationsNextPage() { @Test public void testListEmptyGlobalOperations() { ImmutableList operations = ImmutableList.of(); - Tuple> result = - Tuple.>of(null, + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.>of(null, operations); EasyMock.expect(computeRpcMock.listGlobalOperations(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); @@ -1359,8 +1303,8 @@ public void testListGlobalOperationsWithOptions() { String cursor = "cursor"; compute = options.service(); ImmutableList operationList = ImmutableList.of(globalOperation, globalOperation); - Tuple> result = - Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listGlobalOperations(OPERATION_LIST_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listGlobalOperations(OPERATION_LIST_PAGE_SIZE, @@ -1431,8 +1375,8 @@ public void testListRegionOperations() { String cursor = "cursor"; compute = options.service(); ImmutableList operationList = ImmutableList.of(regionOperation, regionOperation); - Tuple> result = - Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); EasyMock.expect( computeRpcMock.listRegionOperations(REGION_OPERATION_ID.region(), EMPTY_RPC_OPTIONS)) .andReturn(result); @@ -1449,11 +1393,11 @@ public void testListRegionOperationsNextPage() { compute = options.service(); ImmutableList operationList = ImmutableList.of(regionOperation, regionOperation); ImmutableList nextOperationList = ImmutableList.of(regionOperation); - Tuple> result = - Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); - Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextOperationList, OPERATION_TO_PB_FUNCTION)); - Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); + ComputeRpc.Tuple> nextResult = + ComputeRpc.Tuple.of(nextCursor, Iterables.transform(nextOperationList, OPERATION_TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(ComputeRpc.Option.PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listRegionOperations(REGION_OPERATION_ID.region(), EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.expect(computeRpcMock.listRegionOperations(REGION_OPERATION_ID.region(), @@ -1471,8 +1415,8 @@ public void testListRegionOperationsNextPage() { @Test public void testListEmptyRegionOperations() { ImmutableList operations = ImmutableList.of(); - Tuple> result = - Tuple.>of(null, + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.>of(null, operations); EasyMock.expect( computeRpcMock.listRegionOperations(REGION_OPERATION_ID.region(), EMPTY_RPC_OPTIONS)) @@ -1489,8 +1433,8 @@ public void testListRegionOperationsWithOptions() { String cursor = "cursor"; compute = options.service(); ImmutableList operationList = ImmutableList.of(regionOperation, regionOperation); - Tuple> result = - Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); EasyMock.expect( computeRpcMock.listRegionOperations(REGION_OPERATION_ID.region(), OPERATION_LIST_OPTIONS)) .andReturn(result); @@ -1560,8 +1504,8 @@ public void testListZoneOperations() { String cursor = "cursor"; compute = options.service(); ImmutableList operationList = ImmutableList.of(zoneOperation, zoneOperation); - Tuple> result = - Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); EasyMock.expect( computeRpcMock.listZoneOperations(ZONE_OPERATION_ID.zone(), EMPTY_RPC_OPTIONS)) .andReturn(result); @@ -1578,11 +1522,11 @@ public void testListZoneOperationsNextPage() { compute = options.service(); ImmutableList operationList = ImmutableList.of(zoneOperation, zoneOperation); ImmutableList nextOperationList = ImmutableList.of(zoneOperation); - Tuple> result = - Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); - Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextOperationList, OPERATION_TO_PB_FUNCTION)); - Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); + ComputeRpc.Tuple> nextResult = + ComputeRpc.Tuple.of(nextCursor, Iterables.transform(nextOperationList, OPERATION_TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(ComputeRpc.Option.PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listZoneOperations(ZONE_OPERATION_ID.zone(), EMPTY_RPC_OPTIONS)) .andReturn(result); EasyMock.expect(computeRpcMock.listZoneOperations(ZONE_OPERATION_ID.zone(), nextOptions)) @@ -1600,8 +1544,8 @@ public void testListZoneOperationsNextPage() { @Test public void testListEmptyZoneOperations() { ImmutableList operations = ImmutableList.of(); - Tuple> result = - Tuple.>of(null, + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.>of(null, operations); EasyMock.expect( computeRpcMock.listZoneOperations(ZONE_OPERATION_ID.zone(), EMPTY_RPC_OPTIONS)) @@ -1618,8 +1562,8 @@ public void testListZoneOperationsWithOptions() { String cursor = "cursor"; compute = options.service(); ImmutableList operationList = ImmutableList.of(zoneOperation, zoneOperation); - Tuple> result = - Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(operationList, OPERATION_TO_PB_FUNCTION)); EasyMock.expect( computeRpcMock.listZoneOperations(ZONE_OPERATION_ID.zone(), OPERATION_LIST_OPTIONS)) .andReturn(result); @@ -1799,8 +1743,8 @@ public void testListGlobalAddresses() { ImmutableList
    addressList = ImmutableList.of( new Address(compute, new AddressInfo.BuilderImpl(GLOBAL_ADDRESS)), new Address(compute, new AddressInfo.BuilderImpl(GLOBAL_ADDRESS))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listGlobalAddresses(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page
    page = compute.listGlobalAddresses(); @@ -1818,11 +1762,11 @@ public void testListGlobalAddressesNextPage() { new Address(compute, new AddressInfo.BuilderImpl(GLOBAL_ADDRESS))); ImmutableList
    nextAddressList = ImmutableList.of( new Address(compute, new AddressInfo.BuilderImpl(GLOBAL_ADDRESS))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); - Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextAddressList, AddressInfo.TO_PB_FUNCTION)); - Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> nextResult = + ComputeRpc.Tuple.of(nextCursor, Iterables.transform(nextAddressList, AddressInfo.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(ComputeRpc.Option.PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listGlobalAddresses(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.expect(computeRpcMock.listGlobalAddresses(nextOptions)).andReturn(nextResult); EasyMock.replay(computeRpcMock); @@ -1837,8 +1781,8 @@ public void testListGlobalAddressesNextPage() { @Test public void testListEmptyGlobalAddresses() { ImmutableList addresses = ImmutableList.of(); - Tuple> result = - Tuple.>of(null, addresses); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.>of(null, addresses); EasyMock.expect(computeRpcMock.listGlobalAddresses(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); compute = options.service(); @@ -1854,8 +1798,8 @@ public void testListGlobalAddressesWithOptions() { ImmutableList
    addressList = ImmutableList.of( new Address(compute, new AddressInfo.BuilderImpl(GLOBAL_ADDRESS)), new Address(compute, new AddressInfo.BuilderImpl(GLOBAL_ADDRESS))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listGlobalAddresses(ADDRESS_LIST_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page
    page = compute.listGlobalAddresses(ADDRESS_LIST_PAGE_SIZE, @@ -1871,8 +1815,8 @@ public void testListRegionAddresses() { ImmutableList
    addressList = ImmutableList.of( new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS)), new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); EasyMock.expect( computeRpcMock.listRegionAddresses(REGION_ADDRESS_ID.region(), EMPTY_RPC_OPTIONS)) .andReturn(result); @@ -1892,11 +1836,11 @@ public void testListRegionAddressesNextPage() { new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS))); ImmutableList
    nextAddressList = ImmutableList.of( new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); - Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextAddressList, AddressInfo.TO_PB_FUNCTION)); - Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> nextResult = + ComputeRpc.Tuple.of(nextCursor, Iterables.transform(nextAddressList, AddressInfo.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(ComputeRpc.Option.PAGE_TOKEN, cursor); EasyMock.expect( computeRpcMock.listRegionAddresses(REGION_ADDRESS_ID.region(), EMPTY_RPC_OPTIONS)) .andReturn(result); @@ -1915,8 +1859,8 @@ public void testListRegionAddressesNextPage() { @Test public void testListEmptyRegionAddresses() { ImmutableList addresses = ImmutableList.of(); - Tuple> result = - Tuple.>of(null, addresses); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.>of(null, addresses); EasyMock.expect( computeRpcMock.listRegionAddresses(REGION_ADDRESS_ID.region(), EMPTY_RPC_OPTIONS)) .andReturn(result); @@ -1934,8 +1878,8 @@ public void testListRegionAddressesWithOptions() { ImmutableList
    addressList = ImmutableList.of( new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS)), new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); EasyMock.expect( computeRpcMock.listRegionAddresses(REGION_ADDRESS_ID.region(), ADDRESS_LIST_OPTIONS)) .andReturn(result); @@ -1953,8 +1897,8 @@ public void testAggregatedListAddresses() { ImmutableList
    addressList = ImmutableList.of( new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS)), new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listAddresses(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page
    page = compute.listAddresses(); @@ -1972,11 +1916,11 @@ public void testAggregatedListAddressesNextPage() { new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS))); ImmutableList
    nextAddressList = ImmutableList.of( new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); - Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextAddressList, AddressInfo.TO_PB_FUNCTION)); - Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> nextResult = + ComputeRpc.Tuple.of(nextCursor, Iterables.transform(nextAddressList, AddressInfo.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(ComputeRpc.Option.PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listAddresses(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.expect(computeRpcMock.listAddresses(nextOptions)).andReturn(nextResult); EasyMock.replay(computeRpcMock); @@ -1991,8 +1935,8 @@ public void testAggregatedListAddressesNextPage() { @Test public void testAggregatedListEmptyAddresses() { ImmutableList addresses = ImmutableList.of(); - Tuple> result = - Tuple.>of(null, addresses); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.>of(null, addresses); EasyMock.expect(computeRpcMock.listAddresses(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); compute = options.service(); @@ -2008,8 +1952,8 @@ public void testAggregatedListAddressesWithOptions() { ImmutableList
    addressList = ImmutableList.of( new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS)), new Address(compute, new AddressInfo.BuilderImpl(REGION_ADDRESS))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(addressList, AddressInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listAddresses(ADDRESS_LIST_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page
    page = compute.listAddresses(ADDRESS_AGGREGATED_LIST_PAGE_SIZE, @@ -2178,8 +2122,8 @@ public void testListSnapshots() { ImmutableList snapshotList = ImmutableList.of( new Snapshot(compute, new SnapshotInfo.BuilderImpl(SNAPSHOT)), new Snapshot(compute, new SnapshotInfo.BuilderImpl(SNAPSHOT))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(snapshotList, SnapshotInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(snapshotList, SnapshotInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listSnapshots(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listSnapshots(); @@ -2197,11 +2141,11 @@ public void testListSnapshotsNextPage() { new Snapshot(compute, new SnapshotInfo.BuilderImpl(SNAPSHOT))); ImmutableList nextSnapshotList = ImmutableList.of( new Snapshot(compute, new SnapshotInfo.BuilderImpl(SNAPSHOT))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(snapshotList, SnapshotInfo.TO_PB_FUNCTION)); - Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextSnapshotList, SnapshotInfo.TO_PB_FUNCTION)); - Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(snapshotList, SnapshotInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> nextResult = + ComputeRpc.Tuple.of(nextCursor, Iterables.transform(nextSnapshotList, SnapshotInfo.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(ComputeRpc.Option.PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listSnapshots(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.expect(computeRpcMock.listSnapshots(nextOptions)).andReturn(nextResult); EasyMock.replay(computeRpcMock); @@ -2217,8 +2161,8 @@ public void testListSnapshotsNextPage() { public void testListEmptySnapshots() { compute = options.service(); ImmutableList snapshots = ImmutableList.of(); - Tuple> result = - Tuple.>of(null, snapshots); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.>of(null, snapshots); EasyMock.expect(computeRpcMock.listSnapshots(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listSnapshots(); @@ -2233,8 +2177,8 @@ public void testListSnapshotsWithOptions() { ImmutableList snapshotList = ImmutableList.of( new Snapshot(compute, new SnapshotInfo.BuilderImpl(SNAPSHOT)), new Snapshot(compute, new SnapshotInfo.BuilderImpl(SNAPSHOT))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(snapshotList, SnapshotInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(snapshotList, SnapshotInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listSnapshots(SNAPSHOT_LIST_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listSnapshots(SNAPSHOT_LIST_PAGE_SIZE, SNAPSHOT_LIST_PAGE_TOKEN, @@ -2384,8 +2328,8 @@ public void testListImages() { ImmutableList imageList = ImmutableList.of( new Image(compute, new ImageInfo.BuilderImpl(IMAGE)), new Image(compute, new ImageInfo.BuilderImpl(IMAGE))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(imageList, ImageInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(imageList, ImageInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listImages(PROJECT, EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listImages(); @@ -2403,11 +2347,11 @@ public void testListImagesNextPage() { new Image(compute, new ImageInfo.BuilderImpl(IMAGE))); ImmutableList nextImageList = ImmutableList.of( new Image(compute, new ImageInfo.BuilderImpl(IMAGE))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(imageList, ImageInfo.TO_PB_FUNCTION)); - Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextImageList, ImageInfo.TO_PB_FUNCTION)); - Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(imageList, ImageInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> nextResult = + ComputeRpc.Tuple.of(nextCursor, Iterables.transform(nextImageList, ImageInfo.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(ComputeRpc.Option.PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listImages(PROJECT, EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.expect(computeRpcMock.listImages(PROJECT, nextOptions)).andReturn(nextResult); EasyMock.replay(computeRpcMock); @@ -2426,8 +2370,8 @@ public void testListImagesForProject() { ImmutableList imageList = ImmutableList.of( new Image(compute, new ImageInfo.BuilderImpl(IMAGE)), new Image(compute, new ImageInfo.BuilderImpl(IMAGE))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(imageList, ImageInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(imageList, ImageInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listImages("otherProject", EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listImages("otherProject"); @@ -2439,8 +2383,8 @@ public void testListImagesForProject() { public void testListEmptyImages() { compute = options.service(); ImmutableList images = ImmutableList.of(); - Tuple> result = - Tuple.>of(null, images); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.>of(null, images); EasyMock.expect(computeRpcMock.listImages(PROJECT, EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listImages(); @@ -2452,8 +2396,8 @@ public void testListEmptyImages() { public void testListEmptyImagesForProject() { compute = options.service(); ImmutableList images = ImmutableList.of(); - Tuple> result = - Tuple.>of(null, images); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.>of(null, images); EasyMock.expect(computeRpcMock.listImages("otherProject", EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listImages("otherProject"); @@ -2468,8 +2412,8 @@ public void testListImagesWithOptions() { ImmutableList imageList = ImmutableList.of( new Image(compute, new ImageInfo.BuilderImpl(IMAGE)), new Image(compute, new ImageInfo.BuilderImpl(IMAGE))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(imageList, ImageInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(imageList, ImageInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listImages(PROJECT, IMAGE_LIST_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listImages(IMAGE_LIST_PAGE_SIZE, IMAGE_LIST_PAGE_TOKEN, @@ -2485,8 +2429,8 @@ public void testListImagesForProjectWithOptions() { ImmutableList imageList = ImmutableList.of( new Image(compute, new ImageInfo.BuilderImpl(IMAGE)), new Image(compute, new ImageInfo.BuilderImpl(IMAGE))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(imageList, ImageInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(imageList, ImageInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listImages("other", IMAGE_LIST_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listImages("other", IMAGE_LIST_PAGE_SIZE, IMAGE_LIST_PAGE_TOKEN, @@ -2574,8 +2518,8 @@ public void testListDisks() { ImmutableList diskList = ImmutableList.of( new Disk(compute, new DiskInfo.BuilderImpl(DISK)), new Disk(compute, new DiskInfo.BuilderImpl(DISK))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(diskList, DiskInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(diskList, DiskInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listDisks(DISK_ID.zone(), EMPTY_RPC_OPTIONS)) .andReturn(result); EasyMock.replay(computeRpcMock); @@ -2594,11 +2538,11 @@ public void testListDisksNextPage() { new Disk(compute, new DiskInfo.BuilderImpl(DISK))); ImmutableList nextDiskList = ImmutableList.of( new Disk(compute, new DiskInfo.BuilderImpl(DISK))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(diskList, DiskInfo.TO_PB_FUNCTION)); - Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextDiskList, DiskInfo.TO_PB_FUNCTION)); - Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(diskList, DiskInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> nextResult = + ComputeRpc.Tuple.of(nextCursor, Iterables.transform(nextDiskList, DiskInfo.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(ComputeRpc.Option.PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listDisks(DISK_ID.zone(), EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.expect(computeRpcMock.listDisks(DISK_ID.zone(), nextOptions)).andReturn(nextResult); EasyMock.replay(computeRpcMock); @@ -2614,8 +2558,8 @@ public void testListDisksNextPage() { public void testListEmptyDisks() { compute = options.service(); ImmutableList disks = ImmutableList.of(); - Tuple> result = - Tuple.>of(null, disks); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.>of(null, disks); EasyMock.expect(computeRpcMock.listDisks(DISK_ID.zone(), EMPTY_RPC_OPTIONS)) .andReturn(result); EasyMock.replay(computeRpcMock); @@ -2631,8 +2575,8 @@ public void testListDisksWithOptions() { ImmutableList diskList = ImmutableList.of( new Disk(compute, new DiskInfo.BuilderImpl(DISK)), new Disk(compute, new DiskInfo.BuilderImpl(DISK))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(diskList, DiskInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(diskList, DiskInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listDisks(DISK_ID.zone(), DISK_LIST_OPTIONS)) .andReturn(result); EasyMock.replay(computeRpcMock); @@ -2649,8 +2593,8 @@ public void testAggregatedListDisks() { ImmutableList diskList = ImmutableList.of( new Disk(compute, new DiskInfo.BuilderImpl(DISK)), new Disk(compute, new DiskInfo.BuilderImpl(DISK))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(diskList, DiskInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(diskList, DiskInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listDisks(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listDisks(); @@ -2668,11 +2612,11 @@ public void testAggregatedListDisksNextPage() { new Disk(compute, new DiskInfo.BuilderImpl(DISK))); ImmutableList nextDiskList = ImmutableList.of( new Disk(compute, new DiskInfo.BuilderImpl(DISK))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(diskList, DiskInfo.TO_PB_FUNCTION)); - Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextDiskList, DiskInfo.TO_PB_FUNCTION)); - Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(diskList, DiskInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> nextResult = + ComputeRpc.Tuple.of(nextCursor, Iterables.transform(nextDiskList, DiskInfo.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(ComputeRpc.Option.PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listDisks(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.expect(computeRpcMock.listDisks(nextOptions)).andReturn(nextResult); EasyMock.replay(computeRpcMock); @@ -2688,8 +2632,8 @@ public void testAggregatedListDisksNextPage() { public void testAggregatedListEmptyDisks() { compute = options.service(); ImmutableList diskList = ImmutableList.of(); - Tuple> result = - Tuple.>of(null, diskList); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.>of(null, diskList); EasyMock.expect(computeRpcMock.listDisks(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listDisks(); @@ -2704,8 +2648,8 @@ public void testAggregatedListDisksWithOptions() { ImmutableList diskList = ImmutableList.of( new Disk(compute, new DiskInfo.BuilderImpl(DISK)), new Disk(compute, new DiskInfo.BuilderImpl(DISK))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(diskList, DiskInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(diskList, DiskInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listDisks(DISK_LIST_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listDisks(DISK_AGGREGATED_LIST_PAGE_SIZE, @@ -2857,8 +2801,8 @@ public void testListSubnetworks() { ImmutableList subnetworkList = ImmutableList.of( new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK)), new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(subnetworkList, SubnetworkInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(subnetworkList, SubnetworkInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listSubnetworks(SUBNETWORK_ID.region(), EMPTY_RPC_OPTIONS)) .andReturn(result); EasyMock.replay(computeRpcMock); @@ -2877,12 +2821,12 @@ public void testListSubnetworksNextPage() { new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK))); ImmutableList nextSubnetworkList = ImmutableList.of( new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(subnetworkList, SubnetworkInfo.TO_PB_FUNCTION)); - Tuple> nextResult = - Tuple.of(nextCursor, + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(subnetworkList, SubnetworkInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> nextResult = + ComputeRpc.Tuple.of(nextCursor, Iterables.transform(nextSubnetworkList, SubnetworkInfo.TO_PB_FUNCTION)); - Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + Map nextOptions = ImmutableMap.of(ComputeRpc.Option.PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listSubnetworks(SUBNETWORK_ID.region(), EMPTY_RPC_OPTIONS)) .andReturn(result); EasyMock.expect(computeRpcMock.listSubnetworks(SUBNETWORK_ID.region(), nextOptions)) @@ -2902,8 +2846,8 @@ public void testListEmptySubnetworks() { compute = options.service(); ImmutableList subnetworks = ImmutableList.of(); - Tuple> result = - Tuple.>of(null, + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.>of(null, subnetworks); EasyMock.expect(computeRpcMock.listSubnetworks(SUBNETWORK_ID.region(), EMPTY_RPC_OPTIONS)) .andReturn(result); @@ -2920,8 +2864,8 @@ public void testListSubnetworksWithOptions() { ImmutableList subnetworkList = ImmutableList.of( new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK)), new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(subnetworkList, SubnetworkInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(subnetworkList, SubnetworkInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listSubnetworks(SUBNETWORK_ID.region(), SUBNETWORK_LIST_OPTIONS)) .andReturn(result); EasyMock.replay(computeRpcMock); @@ -2938,8 +2882,8 @@ public void testAggregatedListSubnetworks() { ImmutableList subnetworkList = ImmutableList.of( new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK)), new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(subnetworkList, SubnetworkInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(subnetworkList, SubnetworkInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listSubnetworks(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listSubnetworks(); @@ -2957,12 +2901,12 @@ public void testAggregatedListSubnetworksNextPage() { new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK))); ImmutableList nextSubnetworkList = ImmutableList.of( new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(subnetworkList, SubnetworkInfo.TO_PB_FUNCTION)); - Tuple> nextResult = - Tuple.of(nextCursor, + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(subnetworkList, SubnetworkInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> nextResult = + ComputeRpc.Tuple.of(nextCursor, Iterables.transform(nextSubnetworkList, SubnetworkInfo.TO_PB_FUNCTION)); - Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + Map nextOptions = ImmutableMap.of(ComputeRpc.Option.PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listSubnetworks(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.expect(computeRpcMock.listSubnetworks(nextOptions)).andReturn(nextResult); EasyMock.replay(computeRpcMock); @@ -2980,8 +2924,8 @@ public void testAggregatedListEmptySubnetworks() { compute = options.service(); ImmutableList subnetworks = ImmutableList.of(); - Tuple> result = - Tuple.>of(null, + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.>of(null, subnetworks); EasyMock.expect(computeRpcMock.listSubnetworks(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); @@ -2997,8 +2941,8 @@ public void testAggregatedListSubnetworksWithOptions() { ImmutableList subnetworkList = ImmutableList.of( new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK)), new Subnetwork(compute, new SubnetworkInfo.BuilderImpl(SUBNETWORK))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(subnetworkList, SubnetworkInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(subnetworkList, SubnetworkInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listSubnetworks(SUBNETWORK_LIST_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listSubnetworks(SUBNETWORK_AGGREGATED_LIST_PAGE_SIZE, @@ -3114,8 +3058,8 @@ public void testListNetworks() { ImmutableList networkList = ImmutableList.of( new Network(compute, new NetworkInfo.BuilderImpl(NETWORK)), new Network(compute, new NetworkInfo.BuilderImpl(NETWORK))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(networkList, NetworkInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(networkList, NetworkInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listNetworks(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listNetworks(); @@ -3133,11 +3077,11 @@ public void testListNetworksNextPage() { new Network(compute, new NetworkInfo.BuilderImpl(NETWORK))); ImmutableList nextNetworkList = ImmutableList.of( new Network(compute, new NetworkInfo.BuilderImpl(NETWORK))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(networkList, NetworkInfo.TO_PB_FUNCTION)); - Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextNetworkList, NetworkInfo.TO_PB_FUNCTION)); - Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(networkList, NetworkInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> nextResult = + ComputeRpc.Tuple.of(nextCursor, Iterables.transform(nextNetworkList, NetworkInfo.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(ComputeRpc.Option.PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listNetworks(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.expect(computeRpcMock.listNetworks(nextOptions)).andReturn(nextResult); EasyMock.replay(computeRpcMock); @@ -3153,8 +3097,8 @@ public void testListNetworksNextPage() { public void testListEmptyNetworks() { compute = options.service(); ImmutableList networks = ImmutableList.of(); - Tuple> result = - Tuple.>of(null, networks); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.>of(null, networks); EasyMock.expect(computeRpcMock.listNetworks(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listNetworks(); @@ -3169,8 +3113,8 @@ public void testListNetworksWithOptions() { ImmutableList networkList = ImmutableList.of( new Network(compute, new NetworkInfo.BuilderImpl(NETWORK)), new Network(compute, new NetworkInfo.BuilderImpl(NETWORK))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(networkList, NetworkInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(networkList, NetworkInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listNetworks(NETWORK_LIST_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listNetworks(NETWORK_LIST_PAGE_SIZE, NETWORK_LIST_PAGE_TOKEN, @@ -3283,8 +3227,8 @@ public void testListInstances() { ImmutableList instanceList = ImmutableList.of( new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE)), new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(instanceList, InstanceInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(instanceList, InstanceInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listInstances(INSTANCE_ID.zone(), EMPTY_RPC_OPTIONS)) .andReturn(result); EasyMock.replay(computeRpcMock); @@ -3303,11 +3247,11 @@ public void testListInstancesNextPage() { new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE))); ImmutableList nextInstanceList = ImmutableList.of( new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(instanceList, InstanceInfo.TO_PB_FUNCTION)); - Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextInstanceList, InstanceInfo.TO_PB_FUNCTION)); - Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(instanceList, InstanceInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> nextResult = + ComputeRpc.Tuple.of(nextCursor, Iterables.transform(nextInstanceList, InstanceInfo.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(ComputeRpc.Option.PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listInstances(INSTANCE_ID.zone(), EMPTY_RPC_OPTIONS)) .andReturn(result); EasyMock.expect(computeRpcMock.listInstances(INSTANCE_ID.zone(), nextOptions)) @@ -3325,8 +3269,8 @@ public void testListInstancesNextPage() { public void testListEmptyInstances() { compute = options.service(); ImmutableList instances = ImmutableList.of(); - Tuple> result = - Tuple.>of(null, instances); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.>of(null, instances); EasyMock.expect(computeRpcMock.listInstances(INSTANCE_ID.zone(), EMPTY_RPC_OPTIONS)) .andReturn(result); EasyMock.replay(computeRpcMock); @@ -3342,8 +3286,8 @@ public void testListInstancesWithOptions() { ImmutableList instanceList = ImmutableList.of( new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE)), new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(instanceList, InstanceInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(instanceList, InstanceInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listInstances(INSTANCE_ID.zone(), INSTANCE_LIST_OPTIONS)) .andReturn(result); EasyMock.replay(computeRpcMock); @@ -3360,8 +3304,8 @@ public void testAggregatedListInstances() { ImmutableList instanceList = ImmutableList.of( new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE)), new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(instanceList, InstanceInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(instanceList, InstanceInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listInstances(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listInstances(); @@ -3379,11 +3323,11 @@ public void testAggregatedListInstancesNextPage() { new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE))); ImmutableList nextInstanceList = ImmutableList.of( new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(instanceList, InstanceInfo.TO_PB_FUNCTION)); - Tuple> nextResult = - Tuple.of(nextCursor, Iterables.transform(nextInstanceList, InstanceInfo.TO_PB_FUNCTION)); - Map nextOptions = ImmutableMap.of(PAGE_TOKEN, cursor); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(instanceList, InstanceInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> nextResult = + ComputeRpc.Tuple.of(nextCursor, Iterables.transform(nextInstanceList, InstanceInfo.TO_PB_FUNCTION)); + Map nextOptions = ImmutableMap.of(ComputeRpc.Option.PAGE_TOKEN, cursor); EasyMock.expect(computeRpcMock.listInstances(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.expect(computeRpcMock.listInstances(nextOptions)).andReturn(nextResult); EasyMock.replay(computeRpcMock); @@ -3399,8 +3343,8 @@ public void testAggregatedListInstancesNextPage() { public void testAggregatedListEmptyInstances() { compute = options.service(); ImmutableList instanceList = ImmutableList.of(); - Tuple> result = - Tuple.>of(null, + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.>of(null, instanceList); EasyMock.expect(computeRpcMock.listInstances(EMPTY_RPC_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); @@ -3416,8 +3360,8 @@ public void testAggregatedListInstancesWithOptions() { ImmutableList instanceList = ImmutableList.of( new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE)), new Instance(compute, new InstanceInfo.BuilderImpl(INSTANCE))); - Tuple> result = - Tuple.of(cursor, Iterables.transform(instanceList, InstanceInfo.TO_PB_FUNCTION)); + ComputeRpc.Tuple> result = + ComputeRpc.Tuple.of(cursor, Iterables.transform(instanceList, InstanceInfo.TO_PB_FUNCTION)); EasyMock.expect(computeRpcMock.listInstances(INSTANCE_LIST_OPTIONS)).andReturn(result); EasyMock.replay(computeRpcMock); Page page = compute.listInstances(INSTANCE_AGGREGATED_LIST_PAGE_SIZE, diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/DeprecationStatusTest.java similarity index 98% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/DeprecationStatusTest.java index 389d470bd300..57fc8ba0a786 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DeprecationStatusTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/DeprecationStatusTest.java @@ -14,14 +14,12 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; -import com.google.gcloud.compute.DeprecationStatus.Status; - import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.ISODateTimeFormat; import org.junit.Test; @@ -38,7 +36,7 @@ public class DeprecationStatusTest { private static final DiskTypeId DISK_TYPE_ID = DiskTypeId.of("project", "zone", "diskType"); private static final MachineTypeId MACHINE_TYPE_ID = MachineTypeId.of("project", "zone", "machineType"); - private static final Status STATUS = Status.DELETED; + private static final DeprecationStatus.Status STATUS = DeprecationStatus.Status.DELETED; private static final DeprecationStatus DISK_TYPE_STATUS = DeprecationStatus.builder(STATUS) .replacement(DISK_TYPE_ID) diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskIdTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/DiskIdTest.java similarity index 98% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskIdTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/DiskIdTest.java index 216f3237f8a5..df5fee9e6ac7 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/DiskIdTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskImageConfigurationTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/DiskImageConfigurationTest.java similarity index 92% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskImageConfigurationTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/DiskImageConfigurationTest.java index df1e8bf62a4c..f5ecf03ddf2a 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskImageConfigurationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/DiskImageConfigurationTest.java @@ -14,15 +14,13 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import com.google.gcloud.compute.ImageConfiguration.SourceType; -import com.google.gcloud.compute.ImageConfiguration.Type; - +import org.junit.Assert; import org.junit.Test; public class DiskImageConfigurationTest { @@ -30,7 +28,7 @@ public class DiskImageConfigurationTest { private static final DiskId SOURCE_DISK = DiskId.of("project", "zone", "disk"); private static final String SOURCE_DISK_ID = "diskId"; private static final Long ARCHIVE_SIZE_BYTES = 42L; - private static final SourceType SOURCE_TYPE = SourceType.RAW; + private static final ImageConfiguration.SourceType SOURCE_TYPE = ImageConfiguration.SourceType.RAW; private static final DiskImageConfiguration CONFIGURATION = DiskImageConfiguration.builder(SOURCE_DISK) .sourceDiskId(SOURCE_DISK_ID) @@ -68,7 +66,7 @@ public void testBuilder() { assertEquals(SOURCE_DISK, CONFIGURATION.sourceDisk()); assertEquals(SOURCE_DISK_ID, CONFIGURATION.sourceDiskId()); assertEquals(ARCHIVE_SIZE_BYTES, CONFIGURATION.archiveSizeBytes()); - assertEquals(Type.DISK, CONFIGURATION.type()); + Assert.assertEquals(ImageConfiguration.Type.DISK, CONFIGURATION.type()); } @Test @@ -84,7 +82,7 @@ public void testToAndFromPb() { @Test public void testOf() { DiskImageConfiguration configuration = DiskImageConfiguration.of(SOURCE_DISK); - assertEquals(Type.DISK, configuration.type()); + Assert.assertEquals(ImageConfiguration.Type.DISK, configuration.type()); assertNull(configuration.sourceDiskId()); assertNull(configuration.sourceType()); assertNull(configuration.archiveSizeBytes()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskInfoTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/DiskInfoTest.java similarity index 98% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskInfoTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/DiskInfoTest.java index 4011af7eb04f..7e4bbc31b617 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskInfoTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/DiskInfoTest.java @@ -14,14 +14,13 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import com.google.api.services.compute.model.Disk; import com.google.common.collect.ImmutableList; -import com.google.gcloud.compute.DiskInfo.CreationStatus; import org.junit.Test; @@ -32,7 +31,7 @@ public class DiskInfoTest { private static final String GENERATED_ID = "42"; private static final DiskId DISK_ID = DiskId.of("project", "zone", "disk"); private static final Long CREATION_TIMESTAMP = 1453293540000L; - private static final CreationStatus CREATION_STATUS = CreationStatus.READY; + private static final DiskInfo.CreationStatus CREATION_STATUS = DiskInfo.CreationStatus.READY; private static final String DESCRIPTION = "description"; private static final Long SIZE_GB = 500L; private static final DiskTypeId TYPE = DiskTypeId.of("project", "zone", "disk"); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/DiskTest.java similarity index 99% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/DiskTest.java index db50d8a22cd6..03182493803c 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/DiskTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createStrictMock; @@ -28,7 +28,6 @@ import static org.junit.Assert.assertTrue; import com.google.common.collect.ImmutableList; -import com.google.gcloud.compute.DiskInfo.CreationStatus; import org.junit.Test; @@ -39,7 +38,7 @@ public class DiskTest { private static final String GENERATED_ID = "42"; private static final DiskId DISK_ID = DiskId.of("project", "zone", "disk"); private static final Long CREATION_TIMESTAMP = 1453293540000L; - private static final CreationStatus CREATION_STATUS = CreationStatus.READY; + private static final DiskInfo.CreationStatus CREATION_STATUS = DiskInfo.CreationStatus.READY; private static final String DESCRIPTION = "description"; private static final Long SIZE_GB = 500L; private static final DiskTypeId TYPE = DiskTypeId.of("project", "zone", "disk"); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/DiskTypeIdTest.java similarity index 98% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/DiskTypeIdTest.java index c71099de1ecb..ac6788329a32 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/DiskTypeIdTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/DiskTypeTest.java similarity index 98% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/DiskTypeTest.java index f322a4b05ed0..691d1fcd336d 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/DiskTypeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/DiskTypeTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ForwardingRuleIdTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/ForwardingRuleIdTest.java similarity index 99% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/ForwardingRuleIdTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/ForwardingRuleIdTest.java index 9a6ab4b8668e..3afc0c187c05 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ForwardingRuleIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/ForwardingRuleIdTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageDiskConfigurationTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/ImageDiskConfigurationTest.java similarity index 97% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageDiskConfigurationTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/ImageDiskConfigurationTest.java index 54e0e1607109..db8974ddeee4 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageDiskConfigurationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/ImageDiskConfigurationTest.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.google.gcloud.compute; - -import com.google.gcloud.compute.DiskConfiguration.Type; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import com.google.cloud.compute.DiskConfiguration.Type; + import org.junit.Test; public class ImageDiskConfigurationTest { diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageIdTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/ImageIdTest.java similarity index 98% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageIdTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/ImageIdTest.java index 0a11b7fe60f6..32f8ac7c024b 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/ImageIdTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageInfoTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/ImageInfoTest.java similarity index 98% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageInfoTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/ImageInfoTest.java index a0c9ca6bc134..4433fbe96ffb 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageInfoTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/ImageInfoTest.java @@ -14,13 +14,13 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import com.google.cloud.compute.ImageConfiguration.SourceType; import com.google.common.collect.ImmutableList; -import com.google.gcloud.compute.ImageConfiguration.SourceType; import org.junit.Test; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/ImageTest.java similarity index 96% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/ImageTest.java index 1512bdcb30b1..ca1cd009c5eb 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ImageTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/ImageTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createStrictMock; @@ -28,8 +28,6 @@ import static org.junit.Assert.assertTrue; import com.google.common.collect.ImmutableList; -import com.google.gcloud.compute.DeprecationStatus.Status; -import com.google.gcloud.compute.ImageConfiguration.SourceType; import org.junit.Test; @@ -50,7 +48,7 @@ public class ImageTest { private static final String SHA1_CHECKSUM = "checksum"; private static final DiskId SOURCE_DISK = DiskId.of("project", "zone", "disk"); private static final String SOURCE_DISK_ID = "diskId"; - private static final SourceType SOURCE_TYPE = SourceType.RAW; + private static final ImageConfiguration.SourceType SOURCE_TYPE = ImageConfiguration.SourceType.RAW; private static final StorageImageConfiguration STORAGE_CONFIGURATION = StorageImageConfiguration.builder(STORAGE_SOURCE) .archiveSizeBytes(ARCHIVE_SIZE_BYTES) @@ -65,7 +63,7 @@ public class ImageTest { .sourceType(SOURCE_TYPE) .build(); private static final DeprecationStatus DEPRECATION_STATUS = - DeprecationStatus.of(Status.DELETED, IMAGE_ID); + DeprecationStatus.of(DeprecationStatus.Status.DELETED, IMAGE_ID); private final Compute serviceMockReturnsOptions = createStrictMock(Compute.class); private final ComputeOptions mockOptions = createMock(ComputeOptions.class); @@ -271,7 +269,7 @@ public void testDeprecateImage() { Operation operation = new Operation.Builder(serviceMockReturnsOptions) .operationId(GlobalOperationId.of("project", "op")) .build(); - DeprecationStatus status = DeprecationStatus.of(Status.DEPRECATED, IMAGE_ID); + DeprecationStatus status = DeprecationStatus.of(DeprecationStatus.Status.DEPRECATED, IMAGE_ID); expect(compute.deprecate(IMAGE_ID, status)).andReturn(operation); replay(compute); initializeImage(); @@ -282,7 +280,7 @@ public void testDeprecateImage() { public void testDeprecateNull() { initializeExpectedImage(2); expect(compute.options()).andReturn(mockOptions); - DeprecationStatus status = DeprecationStatus.of(Status.DEPRECATED, IMAGE_ID); + DeprecationStatus status = DeprecationStatus.of(DeprecationStatus.Status.DEPRECATED, IMAGE_ID); expect(compute.deprecate(IMAGE_ID, status)).andReturn(null); replay(compute); initializeImage(); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceIdTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/InstanceIdTest.java similarity index 98% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceIdTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/InstanceIdTest.java index 782c8eb4ec31..5c02e6d7c7ee 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/InstanceIdTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceInfoTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/InstanceInfoTest.java similarity index 96% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceInfoTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/InstanceInfoTest.java index be0a866e0df7..13e7a87af06e 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceInfoTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/InstanceInfoTest.java @@ -14,13 +14,12 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import com.google.common.collect.ImmutableList; -import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; import org.junit.Test; @@ -43,7 +42,7 @@ public class InstanceInfoTest { ImmutableList.of(NETWORK_INTERFACE); private static final DiskId DISK_ID = DiskId.of("project", "zone", "disk"); private static final AttachedDisk ATTACHED_DISK = - AttachedDisk.of(PersistentDiskConfiguration.of(DISK_ID)); + AttachedDisk.of(AttachedDisk.PersistentDiskConfiguration.of(DISK_ID)); private static final List ATTACHED_DISKS = ImmutableList.of(ATTACHED_DISK); private static final Metadata METADATA = Metadata.builder() .add("key1", "value1") @@ -155,7 +154,7 @@ public void testSetProjectId() { InstanceInfo instance = InstanceInfo.of( InstanceId.of("zone", "instance"), MachineTypeId.of("zone", "type"), - AttachedDisk.of(PersistentDiskConfiguration.of(DiskId.of("zone", "disk"))), + AttachedDisk.of(AttachedDisk.PersistentDiskConfiguration.of(DiskId.of("zone", "disk"))), NetworkInterface.of(NetworkId.of("project", "network"))); InstanceInfo instanceWithProject = InstanceInfo.of(INSTANCE_ID, MACHINE_TYPE, ATTACHED_DISK, NETWORK_INTERFACE); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/InstanceTest.java similarity index 89% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/InstanceTest.java index 44f726f4165b..522e1a7daf28 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/InstanceTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/InstanceTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createStrictMock; @@ -29,11 +29,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; -import com.google.gcloud.compute.Compute.InstanceOption; -import com.google.gcloud.compute.Compute.OperationOption; -import com.google.gcloud.compute.NetworkInterface.AccessConfig; -import com.google.gcloud.compute.SchedulingOptions.Maintenance; import org.junit.Test; @@ -60,7 +55,7 @@ public class InstanceTest { ImmutableList.of(NETWORK_INTERFACE); private static final DiskId DISK_ID = DiskId.of("project", "zone", "disk"); private static final AttachedDisk ATTACHED_DISK = - AttachedDisk.of(PersistentDiskConfiguration.of(DISK_ID)); + AttachedDisk.of(AttachedDisk.PersistentDiskConfiguration.of(DISK_ID)); private static final List ATTACHED_DISKS = ImmutableList.of(ATTACHED_DISK); private static final Metadata METADATA = Metadata.builder() .add("key1", "value1") @@ -214,7 +209,7 @@ public void testDeleteNull() { @Test public void testExists_True() throws Exception { initializeExpectedInstance(1); - InstanceOption[] expectedOptions = {InstanceOption.fields()}; + Compute.InstanceOption[] expectedOptions = {Compute.InstanceOption.fields()}; expect(compute.options()).andReturn(mockOptions); expect(compute.getInstance(INSTANCE_ID, expectedOptions)).andReturn(expectedInstance); replay(compute); @@ -226,7 +221,7 @@ public void testExists_True() throws Exception { @Test public void testExists_False() throws Exception { initializeExpectedInstance(1); - InstanceOption[] expectedOptions = {InstanceOption.fields()}; + Compute.InstanceOption[] expectedOptions = {Compute.InstanceOption.fields()}; expect(compute.options()).andReturn(mockOptions); expect(compute.getInstance(INSTANCE_ID, expectedOptions)).andReturn(null); replay(compute); @@ -262,10 +257,10 @@ public void testReloadNull() throws Exception { public void testReloadWithOptions() throws Exception { initializeExpectedInstance(3); expect(compute.options()).andReturn(mockOptions); - expect(compute.getInstance(INSTANCE_ID, InstanceOption.fields())).andReturn(expectedInstance); + expect(compute.getInstance(INSTANCE_ID, Compute.InstanceOption.fields())).andReturn(expectedInstance); replay(compute); initializeInstance(); - Instance updateInstance = instance.reload(InstanceOption.fields()); + Instance updateInstance = instance.reload(Compute.InstanceOption.fields()); compareInstance(expectedInstance, updateInstance); verify(compute); } @@ -274,7 +269,7 @@ public void testReloadWithOptions() throws Exception { public void testAddAccessConfig() throws Exception { initializeExpectedInstance(2); expect(compute.options()).andReturn(mockOptions); - AccessConfig accessConfig = AccessConfig.of("192.168.1.1"); + NetworkInterface.AccessConfig accessConfig = NetworkInterface.AccessConfig.of("192.168.1.1"); Operation operation = new Operation.Builder(serviceMockReturnsOptions) .operationId(ZoneOperationId.of("project", "op")) .build(); @@ -288,7 +283,7 @@ public void testAddAccessConfig() throws Exception { public void testAddAccessConfig_Null() throws Exception { initializeExpectedInstance(1); expect(compute.options()).andReturn(mockOptions); - AccessConfig accessConfig = AccessConfig.of("192.168.1.1"); + NetworkInterface.AccessConfig accessConfig = NetworkInterface.AccessConfig.of("192.168.1.1"); expect(compute.addAccessConfig(INSTANCE_ID, "nic0", accessConfig)).andReturn(null); replay(compute); initializeInstance(); @@ -299,22 +294,22 @@ public void testAddAccessConfig_Null() throws Exception { public void testAddAccessConfigWithOptions() throws Exception { initializeExpectedInstance(2); expect(compute.options()).andReturn(mockOptions); - AccessConfig accessConfig = AccessConfig.of("192.168.1.1"); + NetworkInterface.AccessConfig accessConfig = NetworkInterface.AccessConfig.of("192.168.1.1"); Operation operation = new Operation.Builder(serviceMockReturnsOptions) .operationId(ZoneOperationId.of("project", "op")) .build(); - expect(compute.addAccessConfig(INSTANCE_ID, "nic0", accessConfig, OperationOption.fields())) + expect(compute.addAccessConfig(INSTANCE_ID, "nic0", accessConfig, Compute.OperationOption.fields())) .andReturn(operation); replay(compute); initializeInstance(); - assertSame(operation, instance.addAccessConfig("nic0", accessConfig, OperationOption.fields())); + assertSame(operation, instance.addAccessConfig("nic0", accessConfig, Compute.OperationOption.fields())); } @Test public void testAttachDisk() throws Exception { initializeExpectedInstance(2); expect(compute.options()).andReturn(mockOptions); - PersistentDiskConfiguration configuration = PersistentDiskConfiguration.of(DISK_ID); + AttachedDisk.PersistentDiskConfiguration configuration = AttachedDisk.PersistentDiskConfiguration.of(DISK_ID); Operation operation = new Operation.Builder(serviceMockReturnsOptions) .operationId(ZoneOperationId.of("project", "op")) .build(); @@ -328,7 +323,7 @@ public void testAttachDisk() throws Exception { public void testAttachDisk_Null() throws Exception { initializeExpectedInstance(1); expect(compute.options()).andReturn(mockOptions); - PersistentDiskConfiguration configuration = PersistentDiskConfiguration.of(DISK_ID); + AttachedDisk.PersistentDiskConfiguration configuration = AttachedDisk.PersistentDiskConfiguration.of(DISK_ID); expect(compute.attachDisk(INSTANCE_ID, configuration)).andReturn(null); replay(compute); initializeInstance(); @@ -339,22 +334,22 @@ public void testAttachDisk_Null() throws Exception { public void testAttachDiskWithOptions() throws Exception { initializeExpectedInstance(2); expect(compute.options()).andReturn(mockOptions); - PersistentDiskConfiguration configuration = PersistentDiskConfiguration.of(DISK_ID); + AttachedDisk.PersistentDiskConfiguration configuration = AttachedDisk.PersistentDiskConfiguration.of(DISK_ID); Operation operation = new Operation.Builder(serviceMockReturnsOptions) .operationId(ZoneOperationId.of("project", "op")) .build(); - expect(compute.attachDisk(INSTANCE_ID, configuration, OperationOption.fields())) + expect(compute.attachDisk(INSTANCE_ID, configuration, Compute.OperationOption.fields())) .andReturn(operation); replay(compute); initializeInstance(); - assertSame(operation, instance.attachDisk(configuration, OperationOption.fields())); + assertSame(operation, instance.attachDisk(configuration, Compute.OperationOption.fields())); } @Test public void testAttachDiskName() throws Exception { initializeExpectedInstance(2); expect(compute.options()).andReturn(mockOptions); - PersistentDiskConfiguration configuration = PersistentDiskConfiguration.of(DISK_ID); + AttachedDisk.PersistentDiskConfiguration configuration = AttachedDisk.PersistentDiskConfiguration.of(DISK_ID); Operation operation = new Operation.Builder(serviceMockReturnsOptions) .operationId(ZoneOperationId.of("project", "op")) .build(); @@ -368,7 +363,7 @@ public void testAttachDiskName() throws Exception { public void testAttachDiskName_Null() throws Exception { initializeExpectedInstance(1); expect(compute.options()).andReturn(mockOptions); - PersistentDiskConfiguration configuration = PersistentDiskConfiguration.of(DISK_ID); + AttachedDisk.PersistentDiskConfiguration configuration = AttachedDisk.PersistentDiskConfiguration.of(DISK_ID); expect(compute.attachDisk(INSTANCE_ID, "dev0", configuration)).andReturn(null); replay(compute); initializeInstance(); @@ -379,22 +374,22 @@ public void testAttachDiskName_Null() throws Exception { public void testAttachDiskNameWithOptions() throws Exception { initializeExpectedInstance(2); expect(compute.options()).andReturn(mockOptions); - PersistentDiskConfiguration configuration = PersistentDiskConfiguration.of(DISK_ID); + AttachedDisk.PersistentDiskConfiguration configuration = AttachedDisk.PersistentDiskConfiguration.of(DISK_ID); Operation operation = new Operation.Builder(serviceMockReturnsOptions) .operationId(ZoneOperationId.of("project", "op")) .build(); - expect(compute.attachDisk(INSTANCE_ID, "dev0", configuration, OperationOption.fields())) + expect(compute.attachDisk(INSTANCE_ID, "dev0", configuration, Compute.OperationOption.fields())) .andReturn(operation); replay(compute); initializeInstance(); - assertSame(operation, instance.attachDisk("dev0", configuration, OperationOption.fields())); + assertSame(operation, instance.attachDisk("dev0", configuration, Compute.OperationOption.fields())); } @Test public void testAttachDiskNameIndex() throws Exception { initializeExpectedInstance(2); expect(compute.options()).andReturn(mockOptions); - PersistentDiskConfiguration configuration = PersistentDiskConfiguration.of(DISK_ID); + AttachedDisk.PersistentDiskConfiguration configuration = AttachedDisk.PersistentDiskConfiguration.of(DISK_ID); Operation operation = new Operation.Builder(serviceMockReturnsOptions) .operationId(ZoneOperationId.of("project", "op")) .build(); @@ -408,7 +403,7 @@ public void testAttachDiskNameIndex() throws Exception { public void testAttachDiskNameIndex_Null() throws Exception { initializeExpectedInstance(1); expect(compute.options()).andReturn(mockOptions); - PersistentDiskConfiguration configuration = PersistentDiskConfiguration.of(DISK_ID); + AttachedDisk.PersistentDiskConfiguration configuration = AttachedDisk.PersistentDiskConfiguration.of(DISK_ID); expect(compute.attachDisk(INSTANCE_ID, "dev0", configuration, 1)).andReturn(null); replay(compute); initializeInstance(); @@ -419,16 +414,16 @@ public void testAttachDiskNameIndex_Null() throws Exception { public void testAttachDiskNameIndexWithOptions() throws Exception { initializeExpectedInstance(2); expect(compute.options()).andReturn(mockOptions); - PersistentDiskConfiguration configuration = PersistentDiskConfiguration.of(DISK_ID); + AttachedDisk.PersistentDiskConfiguration configuration = AttachedDisk.PersistentDiskConfiguration.of(DISK_ID); Operation operation = new Operation.Builder(serviceMockReturnsOptions) .operationId(ZoneOperationId.of("project", "op")) .build(); - expect(compute.attachDisk(INSTANCE_ID, "dev0", configuration, 1, OperationOption.fields())) + expect(compute.attachDisk(INSTANCE_ID, "dev0", configuration, 1, Compute.OperationOption.fields())) .andReturn(operation); replay(compute); initializeInstance(); assertSame(operation, - instance.attachDisk("dev0", configuration, 1, OperationOption.fields())); + instance.attachDisk("dev0", configuration, 1, Compute.OperationOption.fields())); } @Test @@ -461,11 +456,11 @@ public void testDeleteAccessConfigWithOptions() throws Exception { Operation operation = new Operation.Builder(serviceMockReturnsOptions) .operationId(ZoneOperationId.of("project", "op")) .build(); - expect(compute.deleteAccessConfig(INSTANCE_ID, "nic0", "NAT", OperationOption.fields())) + expect(compute.deleteAccessConfig(INSTANCE_ID, "nic0", "NAT", Compute.OperationOption.fields())) .andReturn(operation); replay(compute); initializeInstance(); - assertSame(operation, instance.deleteAccessConfig("nic0", "NAT", OperationOption.fields())); + assertSame(operation, instance.deleteAccessConfig("nic0", "NAT", Compute.OperationOption.fields())); } @Test @@ -498,10 +493,10 @@ public void testDetachDiskWithOptions() throws Exception { Operation operation = new Operation.Builder(serviceMockReturnsOptions) .operationId(ZoneOperationId.of("project", "op")) .build(); - expect(compute.detachDisk(INSTANCE_ID, "dev0", OperationOption.fields())).andReturn(operation); + expect(compute.detachDisk(INSTANCE_ID, "dev0", Compute.OperationOption.fields())).andReturn(operation); replay(compute); initializeInstance(); - assertSame(operation, instance.detachDisk("dev0", OperationOption.fields())); + assertSame(operation, instance.detachDisk("dev0", Compute.OperationOption.fields())); } @Test @@ -577,11 +572,11 @@ public void testSetDiskAutodeleteWithOptions() throws Exception { Operation operation = new Operation.Builder(serviceMockReturnsOptions) .operationId(ZoneOperationId.of("project", "op")) .build(); - expect(compute.setDiskAutoDelete(INSTANCE_ID, "dev0", true, OperationOption.fields())) + expect(compute.setDiskAutoDelete(INSTANCE_ID, "dev0", true, Compute.OperationOption.fields())) .andReturn(operation); replay(compute); initializeInstance(); - assertSame(operation, instance.setDiskAutoDelete("dev0", true, OperationOption.fields())); + assertSame(operation, instance.setDiskAutoDelete("dev0", true, Compute.OperationOption.fields())); } @Test @@ -614,11 +609,11 @@ public void testSetMachineTypeWithOptions() throws Exception { Operation operation = new Operation.Builder(serviceMockReturnsOptions) .operationId(ZoneOperationId.of("project", "op")) .build(); - expect(compute.setMachineType(INSTANCE_ID, MACHINE_TYPE, OperationOption.fields())) + expect(compute.setMachineType(INSTANCE_ID, MACHINE_TYPE, Compute.OperationOption.fields())) .andReturn(operation); replay(compute); initializeInstance(); - assertSame(operation, instance.setMachineType(MACHINE_TYPE, OperationOption.fields())); + assertSame(operation, instance.setMachineType(MACHINE_TYPE, Compute.OperationOption.fields())); } @Test @@ -654,11 +649,11 @@ public void testSetMetadataWithOptions() throws Exception { .operationId(ZoneOperationId.of("project", "op")) .build(); Metadata metadata = Metadata.builder().add("k", "v").fingerprint("fingerprint").build(); - expect(compute.setMetadata(INSTANCE_ID, metadata, OperationOption.fields())) + expect(compute.setMetadata(INSTANCE_ID, metadata, Compute.OperationOption.fields())) .andReturn(operation); replay(compute); initializeInstance(); - assertSame(operation, instance.setMetadata(metadata, OperationOption.fields())); + assertSame(operation, instance.setMetadata(metadata, Compute.OperationOption.fields())); } @Test @@ -697,11 +692,11 @@ public void testSetMetadataFromMapWithOptions() throws Exception { .build(); Map metadataMap = ImmutableMap.of("k", "v"); Metadata metadata = Metadata.builder().values(metadataMap).fingerprint("fingerprint").build(); - expect(compute.setMetadata(INSTANCE_ID, metadata, OperationOption.fields())) + expect(compute.setMetadata(INSTANCE_ID, metadata, Compute.OperationOption.fields())) .andReturn(operation); replay(compute); initializeInstance(); - assertSame(operation, instance.setMetadata(metadataMap, OperationOption.fields())); + assertSame(operation, instance.setMetadata(metadataMap, Compute.OperationOption.fields())); } @Test @@ -711,7 +706,7 @@ public void testSetSchedulingOptions() throws Exception { Operation operation = new Operation.Builder(serviceMockReturnsOptions) .operationId(ZoneOperationId.of("project", "op")) .build(); - SchedulingOptions schedulingOptions = SchedulingOptions.standard(true, Maintenance.MIGRATE); + SchedulingOptions schedulingOptions = SchedulingOptions.standard(true, SchedulingOptions.Maintenance.MIGRATE); expect(compute.setSchedulingOptions(INSTANCE_ID, schedulingOptions)).andReturn(operation); replay(compute); initializeInstance(); @@ -722,7 +717,7 @@ public void testSetSchedulingOptions() throws Exception { public void testSetSchedulingOptions_Null() throws Exception { initializeExpectedInstance(1); expect(compute.options()).andReturn(mockOptions); - SchedulingOptions schedulingOptions = SchedulingOptions.standard(true, Maintenance.MIGRATE); + SchedulingOptions schedulingOptions = SchedulingOptions.standard(true, SchedulingOptions.Maintenance.MIGRATE); expect(compute.setSchedulingOptions(INSTANCE_ID, schedulingOptions)).andReturn(null); replay(compute); initializeInstance(); @@ -736,13 +731,13 @@ public void testSetSchedulingOptionsWithOptions() throws Exception { Operation operation = new Operation.Builder(serviceMockReturnsOptions) .operationId(ZoneOperationId.of("project", "op")) .build(); - SchedulingOptions schedulingOptions = SchedulingOptions.standard(true, Maintenance.MIGRATE); - expect(compute.setSchedulingOptions(INSTANCE_ID, schedulingOptions, OperationOption.fields())) + SchedulingOptions schedulingOptions = SchedulingOptions.standard(true, SchedulingOptions.Maintenance.MIGRATE); + expect(compute.setSchedulingOptions(INSTANCE_ID, schedulingOptions, Compute.OperationOption.fields())) .andReturn(operation); replay(compute); initializeInstance(); assertSame(operation, - instance.setSchedulingOptions(schedulingOptions, OperationOption.fields())); + instance.setSchedulingOptions(schedulingOptions, Compute.OperationOption.fields())); } @Test @@ -778,10 +773,10 @@ public void testSetTagsWithOptions() throws Exception { .operationId(ZoneOperationId.of("project", "op")) .build(); Tags tags = Tags.builder().values("v1", "v2").fingerprint("fingerprint").build(); - expect(compute.setTags(INSTANCE_ID, tags, OperationOption.fields())).andReturn(operation); + expect(compute.setTags(INSTANCE_ID, tags, Compute.OperationOption.fields())).andReturn(operation); replay(compute); initializeInstance(); - assertSame(operation, instance.setTags(tags, OperationOption.fields())); + assertSame(operation, instance.setTags(tags, Compute.OperationOption.fields())); } @Test @@ -820,10 +815,10 @@ public void testSetTagsFromListWithOptions() throws Exception { .build(); List tagList = ImmutableList.of("v1", "v2"); Tags tags = Tags.builder().values(tagList).fingerprint("fingerprint").build(); - expect(compute.setTags(INSTANCE_ID, tags, OperationOption.fields())).andReturn(operation); + expect(compute.setTags(INSTANCE_ID, tags, Compute.OperationOption.fields())).andReturn(operation); replay(compute); initializeInstance(); - assertSame(operation, instance.setTags(tagList, OperationOption.fields())); + assertSame(operation, instance.setTags(tagList, Compute.OperationOption.fields())); } @Test diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/LicenseIdTest.java similarity index 98% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/LicenseIdTest.java index d06fd48cff9a..cdb5e7adf992 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/LicenseIdTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/LicenseTest.java similarity index 97% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/LicenseTest.java index c9fb95fab9c6..6bbe50b71489 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/LicenseTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/LicenseTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/MachineTypeIdTest.java similarity index 98% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/MachineTypeIdTest.java index 10a607235a9e..f7f776aec5a5 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/MachineTypeIdTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/MachineTypeTest.java similarity index 99% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/MachineTypeTest.java index f57f35a8ec3b..924d22bde36c 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MachineTypeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/MachineTypeTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MetadataTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/MetadataTest.java similarity index 98% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/MetadataTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/MetadataTest.java index be43c4fd433f..9de656ff24d0 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/MetadataTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/MetadataTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkIdTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/NetworkIdTest.java similarity index 98% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkIdTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/NetworkIdTest.java index 08b012d25d62..fb785852cf71 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/NetworkIdTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkInfoTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/NetworkInfoTest.java similarity index 99% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkInfoTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/NetworkInfoTest.java index a57ee91901b8..e2d9c4451ee4 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkInfoTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/NetworkInfoTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkInterfaceTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/NetworkInterfaceTest.java similarity index 84% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkInterfaceTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/NetworkInterfaceTest.java index 22913937d0b1..c36d52d8bd0f 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkInterfaceTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/NetworkInterfaceTest.java @@ -14,15 +14,14 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import com.google.common.collect.ImmutableList; -import com.google.gcloud.compute.NetworkInterface.AccessConfig; -import com.google.gcloud.compute.NetworkInterface.AccessConfig.Type; +import org.junit.Assert; import org.junit.Test; import java.util.List; @@ -33,12 +32,12 @@ public class NetworkInterfaceTest { private static final NetworkId NETWORK = NetworkId.of("project", "network"); private static final String NETWORK_IP = "192.168.1.1"; private static final SubnetworkId SUBNETWORK = SubnetworkId.of("project", "region", "subnetwork"); - private static final AccessConfig ACCESS_CONFIG = AccessConfig.builder() + private static final NetworkInterface.AccessConfig ACCESS_CONFIG = NetworkInterface.AccessConfig.builder() .name("accessConfig") .natIp("192.168.1.1") - .type(Type.ONE_TO_ONE_NAT) + .type(NetworkInterface.AccessConfig.Type.ONE_TO_ONE_NAT) .build(); - private static final List ACCESS_CONFIGURATIONS = + private static final List ACCESS_CONFIGURATIONS = ImmutableList.of(ACCESS_CONFIG); private static final NetworkInterface NETWORK_INTERFACE = NetworkInterface.builder(NETWORK) .name(NAME) @@ -49,14 +48,14 @@ public class NetworkInterfaceTest { @Test public void testAccessConfigToBuilder() { - AccessConfig accessConfig = ACCESS_CONFIG.toBuilder().name("newName").build(); + NetworkInterface.AccessConfig accessConfig = ACCESS_CONFIG.toBuilder().name("newName").build(); assertEquals("newName", accessConfig.name()); compareAccessConfig(ACCESS_CONFIG, accessConfig.toBuilder().name("accessConfig").build()); } @Test public void testAccessConfigToBuilderIncomplete() { - AccessConfig accessConfig = AccessConfig.of(); + NetworkInterface.AccessConfig accessConfig = NetworkInterface.AccessConfig.of(); compareAccessConfig(accessConfig, accessConfig.toBuilder().build()); } @@ -81,7 +80,7 @@ public void testToBuilderIncomplete() { public void testAccessConfigBuilder() { assertEquals("accessConfig", ACCESS_CONFIG.name()); assertEquals("192.168.1.1", ACCESS_CONFIG.natIp()); - assertEquals(Type.ONE_TO_ONE_NAT, ACCESS_CONFIG.type()); + Assert.assertEquals(NetworkInterface.AccessConfig.Type.ONE_TO_ONE_NAT, ACCESS_CONFIG.type()); } @Test @@ -106,11 +105,11 @@ public void testBuilder() { @Test public void testAccessConfigOf() { - AccessConfig accessConfig = AccessConfig.of("192.168.1.1"); + NetworkInterface.AccessConfig accessConfig = NetworkInterface.AccessConfig.of("192.168.1.1"); assertNull(accessConfig.name()); assertEquals("192.168.1.1", accessConfig.natIp()); assertNull(accessConfig.type()); - accessConfig = AccessConfig.of(); + accessConfig = NetworkInterface.AccessConfig.of(); assertNull(accessConfig.name()); assertNull(accessConfig.natIp()); assertNull(accessConfig.type()); @@ -133,10 +132,10 @@ public void testOf() { @Test public void testAccessConfigToAndFromPb() { - AccessConfig accessConfig = AccessConfig.fromPb(ACCESS_CONFIG.toPb()); + NetworkInterface.AccessConfig accessConfig = NetworkInterface.AccessConfig.fromPb(ACCESS_CONFIG.toPb()); compareAccessConfig(ACCESS_CONFIG, accessConfig); - accessConfig = AccessConfig.of(); - compareAccessConfig(accessConfig, AccessConfig.fromPb(accessConfig.toPb())); + accessConfig = NetworkInterface.AccessConfig.of(); + compareAccessConfig(accessConfig, NetworkInterface.AccessConfig.fromPb(accessConfig.toPb())); } @Test @@ -159,7 +158,7 @@ public void testSetProjectId() { compareNetworkInterface(NETWORK_INTERFACE, networkInterface.setProjectId("project")); } - public void compareAccessConfig(AccessConfig expected, AccessConfig value) { + public void compareAccessConfig(NetworkInterface.AccessConfig expected, NetworkInterface.AccessConfig value) { assertEquals(expected, value); assertEquals(expected.name(), value.name()); assertEquals(expected.natIp(), value.natIp()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/NetworkTest.java similarity index 99% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/NetworkTest.java index 21978180f3b6..5bc240fafddc 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/NetworkTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createStrictMock; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationIdTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/OperationIdTest.java similarity index 99% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationIdTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/OperationIdTest.java index 76a53cdd1cd2..9944a6fc7585 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/OperationIdTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/OperationTest.java similarity index 94% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/OperationTest.java index 05cba345d171..d45fe48c1134 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/OperationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/OperationTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createStrictMock; @@ -30,9 +30,6 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.google.gcloud.compute.Operation.OperationError; -import com.google.gcloud.compute.Operation.OperationWarning; -import com.google.gcloud.compute.Operation.Status; import org.junit.After; import org.junit.Test; @@ -41,29 +38,29 @@ public class OperationTest { - private static final OperationError OPERATION_ERROR1 = - new OperationError("code1", "location1", "message1"); - private static final OperationError OPERATION_ERROR2 = - new OperationError("code2", "location2", "message2"); - private static final OperationWarning OPERATION_WARNING1 = - new OperationWarning("code1", "message1", ImmutableMap.of("k1", "v1")); - private static final OperationWarning OPERATION_WARNING2 = - new OperationWarning("code2", "location2", ImmutableMap.of("k2", "v2")); + private static final Operation.OperationError OPERATION_ERROR1 = + new Operation.OperationError("code1", "location1", "message1"); + private static final Operation.OperationError OPERATION_ERROR2 = + new Operation.OperationError("code2", "location2", "message2"); + private static final Operation.OperationWarning OPERATION_WARNING1 = + new Operation.OperationWarning("code1", "message1", ImmutableMap.of("k1", "v1")); + private static final Operation.OperationWarning OPERATION_WARNING2 = + new Operation.OperationWarning("code2", "location2", ImmutableMap.of("k2", "v2")); private static final String GENERATED_ID = "1"; private static final String CLIENT_OPERATION_ID = "clientOperationId"; private static final String OPERATION_TYPE = "delete"; private static final String TARGET_LINK = "targetLink"; private static final String TARGET_ID = "42"; - private static final Status STATUS = Status.DONE; + private static final Operation.Status STATUS = Operation.Status.DONE; private static final String STATUS_MESSAGE = "statusMessage"; private static final String USER = "user"; private static final Integer PROGRESS = 100; private static final Long INSERT_TIME = 1453293540000L; private static final Long START_TIME = 1453293420000L; private static final Long END_TIME = 1453293480000L; - private static final List ERRORS = + private static final List ERRORS = ImmutableList.of(OPERATION_ERROR1, OPERATION_ERROR2); - private static final List WARNINGS = + private static final List WARNINGS = ImmutableList.of(OPERATION_WARNING1, OPERATION_WARNING2); private static final Integer HTTP_ERROR_STATUS_CODE = 404; private static final String HTTP_ERROR_MESSAGE = "NOT FOUND"; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/RegionIdTest.java similarity index 98% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/RegionIdTest.java index 3474a73c3030..c6646db93acf 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/RegionIdTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/RegionTest.java similarity index 99% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/RegionTest.java index 5b1947a585ab..80e2fdc0b027 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/RegionTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/RegionTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SchedulingOptionsTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/SchedulingOptionsTest.java similarity index 98% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/SchedulingOptionsTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/SchedulingOptionsTest.java index 258c880d783f..de2c66a5ff1e 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SchedulingOptionsTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/SchedulingOptionsTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/SerializationTest.java similarity index 97% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/SerializationTest.java index 4761ccc80f5c..b43bbe62d62b 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/SerializationTest.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; +import com.google.cloud.AuthCredentials; +import com.google.cloud.RetryParams; +import com.google.cloud.compute.AttachedDisk.CreateDiskConfiguration; +import com.google.cloud.compute.AttachedDisk.PersistentDiskConfiguration; +import com.google.cloud.compute.AttachedDisk.ScratchDiskConfiguration; +import com.google.cloud.compute.NetworkInterface.AccessConfig; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import com.google.gcloud.AuthCredentials; -import com.google.gcloud.RetryParams; -import com.google.gcloud.compute.AttachedDisk.CreateDiskConfiguration; -import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; -import com.google.gcloud.compute.AttachedDisk.ScratchDiskConfiguration; -import com.google.gcloud.compute.NetworkInterface.AccessConfig; import org.junit.Test; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ServiceAccountTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/ServiceAccountTest.java similarity index 97% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/ServiceAccountTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/ServiceAccountTest.java index 4d7c08d79f55..dd29589e5037 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ServiceAccountTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/ServiceAccountTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotDiskConfigurationTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/SnapshotDiskConfigurationTest.java similarity index 97% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotDiskConfigurationTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/SnapshotDiskConfigurationTest.java index 313ece829b25..5f95891b3252 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotDiskConfigurationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/SnapshotDiskConfigurationTest.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.google.gcloud.compute; - -import com.google.gcloud.compute.DiskConfiguration.Type; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import com.google.cloud.compute.DiskConfiguration.Type; + import org.junit.Test; public class SnapshotDiskConfigurationTest { diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotIdTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/SnapshotIdTest.java similarity index 98% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotIdTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/SnapshotIdTest.java index 13dadee790b9..b723832dbbac 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/SnapshotIdTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotInfoTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/SnapshotInfoTest.java similarity index 97% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotInfoTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/SnapshotInfoTest.java index b9febeb9f011..38d295184ae6 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotInfoTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/SnapshotInfoTest.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import com.google.cloud.compute.SnapshotInfo.Status; +import com.google.cloud.compute.SnapshotInfo.StorageBytesStatus; import com.google.common.collect.ImmutableList; -import com.google.gcloud.compute.SnapshotInfo.Status; -import com.google.gcloud.compute.SnapshotInfo.StorageBytesStatus; import org.junit.Test; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/SnapshotTest.java similarity index 99% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/SnapshotTest.java index 9959b875b92a..d74cdf988f8c 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SnapshotTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/SnapshotTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createStrictMock; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/StandardDiskConfigurationTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/StandardDiskConfigurationTest.java similarity index 97% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/StandardDiskConfigurationTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/StandardDiskConfigurationTest.java index 9240a758ab58..3651eef2ad99 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/StandardDiskConfigurationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/StandardDiskConfigurationTest.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.google.gcloud.compute; - -import com.google.gcloud.compute.DiskConfiguration.Type; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import com.google.cloud.compute.DiskConfiguration.Type; + import org.junit.Test; public class StandardDiskConfigurationTest { diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/StandardNetworkConfigurationTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/StandardNetworkConfigurationTest.java similarity index 96% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/StandardNetworkConfigurationTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/StandardNetworkConfigurationTest.java index 7546f0b70494..4949327415f0 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/StandardNetworkConfigurationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/StandardNetworkConfigurationTest.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.google.gcloud.compute; - -import com.google.gcloud.compute.NetworkConfiguration.Type; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import com.google.cloud.compute.NetworkConfiguration.Type; + import org.junit.Test; public class StandardNetworkConfigurationTest { diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/StorageImageConfigurationTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/StorageImageConfigurationTest.java similarity index 88% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/StorageImageConfigurationTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/StorageImageConfigurationTest.java index dc05686a478f..3ecd80c66097 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/StorageImageConfigurationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/StorageImageConfigurationTest.java @@ -14,24 +14,21 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; -import com.google.gcloud.compute.ImageConfiguration.SourceType; -import com.google.gcloud.compute.StorageImageConfiguration.ContainerType; -import com.google.gcloud.compute.ImageConfiguration.Type; - +import org.junit.Assert; import org.junit.Test; public class StorageImageConfigurationTest { private static final String SOURCE = "source"; - private static final SourceType SOURCE_TYPE = SourceType.RAW; - private static final ContainerType CONTAINER_TYPE = ContainerType.TAR; + private static final ImageConfiguration.SourceType SOURCE_TYPE = ImageConfiguration.SourceType.RAW; + private static final StorageImageConfiguration.ContainerType CONTAINER_TYPE = StorageImageConfiguration.ContainerType.TAR; private static final Long ARCHIVE_SIZE_BYTES = 42L; private static final String SHA1 = "sha1"; private static final StorageImageConfiguration CONFIGURATION = @@ -65,7 +62,7 @@ public void testBuilder() { assertEquals(CONTAINER_TYPE, CONFIGURATION.containerType()); assertEquals(ARCHIVE_SIZE_BYTES, CONFIGURATION.archiveSizeBytes()); assertEquals(SHA1, CONFIGURATION.sha1()); - assertEquals(Type.STORAGE, CONFIGURATION.type()); + Assert.assertEquals(ImageConfiguration.Type.STORAGE, CONFIGURATION.type()); } @Test @@ -81,7 +78,7 @@ public void testToAndFromPb() { @Test public void testOf() { StorageImageConfiguration configuration = StorageImageConfiguration.of(SOURCE); - assertEquals(Type.STORAGE, configuration.type()); + Assert.assertEquals(ImageConfiguration.Type.STORAGE, configuration.type()); assertNull(configuration.sourceType()); assertEquals(SOURCE, configuration.source()); assertNull(configuration.containerType()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetNetworkConfigurationTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/SubnetNetworkConfigurationTest.java similarity index 88% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetNetworkConfigurationTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/SubnetNetworkConfigurationTest.java index c2a5ddafcd0e..5fbec3e99c93 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetNetworkConfigurationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/SubnetNetworkConfigurationTest.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import com.google.common.collect.ImmutableList; -import com.google.gcloud.compute.NetworkConfiguration.Type; +import org.junit.Assert; import org.junit.Test; import java.util.List; @@ -39,12 +39,12 @@ public class SubnetNetworkConfigurationTest { @Test public void testConstructor() { assertEquals(AUTO_CREATE_SUBNETWORKS, NETWORK_CONFIGURATION.autoCreateSubnetworks()); - assertEquals(Type.SUBNET, NETWORK_CONFIGURATION.type()); + Assert.assertEquals(NetworkConfiguration.Type.SUBNET, NETWORK_CONFIGURATION.type()); assertEquals(SUBNETWORKS, NETWORK_CONFIGURATION.subnetworks()); - assertEquals(Type.SUBNET, NETWORK_CONFIGURATION.type()); + Assert.assertEquals(NetworkConfiguration.Type.SUBNET, NETWORK_CONFIGURATION.type()); SubnetNetworkConfiguration networkConfiguration = new SubnetNetworkConfiguration(AUTO_CREATE_SUBNETWORKS, null); - assertEquals(Type.SUBNET, networkConfiguration.type()); + Assert.assertEquals(NetworkConfiguration.Type.SUBNET, networkConfiguration.type()); assertEquals(AUTO_CREATE_SUBNETWORKS, networkConfiguration.autoCreateSubnetworks()); assertNull(networkConfiguration.subnetworks()); } @@ -69,7 +69,7 @@ public void testOf() { SubnetNetworkConfiguration.of(AUTO_CREATE_SUBNETWORKS); assertEquals(AUTO_CREATE_SUBNETWORKS, configuration.autoCreateSubnetworks()); assertNull(configuration.subnetworks()); - assertEquals(Type.SUBNET, configuration.type()); + Assert.assertEquals(NetworkConfiguration.Type.SUBNET, configuration.type()); } private void compareNetworkConfiguration(SubnetNetworkConfiguration expected, diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkIdTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/SubnetworkIdTest.java similarity index 98% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkIdTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/SubnetworkIdTest.java index 25e428c9009b..972c0d5f1d13 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/SubnetworkIdTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkInfoTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/SubnetworkInfoTest.java similarity index 99% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkInfoTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/SubnetworkInfoTest.java index 721072ef9065..17907ea2ac3a 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkInfoTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/SubnetworkInfoTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/SubnetworkTest.java similarity index 99% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/SubnetworkTest.java index e394e0daf737..6a710738b935 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/SubnetworkTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createStrictMock; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/TagsTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/TagsTest.java similarity index 98% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/TagsTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/TagsTest.java index d9e998fd47e7..f626a418fefd 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/TagsTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/TagsTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/ZoneIdTest.java similarity index 98% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/ZoneIdTest.java index a147f0e21f63..90bdc6de2bf3 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneIdTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/ZoneIdTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/ZoneTest.java similarity index 98% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/ZoneTest.java index 624fd4d2d62b..b03aabc5b34e 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/ZoneTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/ZoneTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute; +package com.google.cloud.compute; import static org.junit.Assert.assertEquals; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/it/ITComputeTest.java similarity index 95% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/it/ITComputeTest.java index edd469b8969a..71013a3c1120 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/it/ITComputeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/it/ITComputeTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.google.gcloud.compute.it; +package com.google.cloud.compute.it; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -23,67 +23,62 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import com.google.cloud.Page; +import com.google.cloud.compute.Address; +import com.google.cloud.compute.AddressId; +import com.google.cloud.compute.AddressInfo; +import com.google.cloud.compute.AttachedDisk; +import com.google.cloud.compute.Compute; +import com.google.cloud.compute.DeprecationStatus; +import com.google.cloud.compute.Disk; +import com.google.cloud.compute.DiskConfiguration; +import com.google.cloud.compute.DiskId; +import com.google.cloud.compute.DiskImageConfiguration; +import com.google.cloud.compute.DiskInfo; +import com.google.cloud.compute.DiskType; +import com.google.cloud.compute.DiskTypeId; +import com.google.cloud.compute.GlobalAddressId; +import com.google.cloud.compute.Image; +import com.google.cloud.compute.ImageConfiguration; +import com.google.cloud.compute.ImageDiskConfiguration; +import com.google.cloud.compute.ImageId; +import com.google.cloud.compute.ImageInfo; +import com.google.cloud.compute.Instance; +import com.google.cloud.compute.InstanceId; +import com.google.cloud.compute.InstanceInfo; +import com.google.cloud.compute.License; +import com.google.cloud.compute.LicenseId; +import com.google.cloud.compute.MachineType; +import com.google.cloud.compute.MachineTypeId; +import com.google.cloud.compute.Network; +import com.google.cloud.compute.NetworkConfiguration; +import com.google.cloud.compute.NetworkId; +import com.google.cloud.compute.NetworkInfo; +import com.google.cloud.compute.NetworkInterface; +import com.google.cloud.compute.Operation; +import com.google.cloud.compute.Region; +import com.google.cloud.compute.RegionAddressId; +import com.google.cloud.compute.RegionOperationId; +import com.google.cloud.compute.SchedulingOptions; +import com.google.cloud.compute.Snapshot; +import com.google.cloud.compute.SnapshotDiskConfiguration; +import com.google.cloud.compute.SnapshotId; +import com.google.cloud.compute.SnapshotInfo; +import com.google.cloud.compute.StandardDiskConfiguration; +import com.google.cloud.compute.StandardNetworkConfiguration; +import com.google.cloud.compute.StorageImageConfiguration; +import com.google.cloud.compute.SubnetNetworkConfiguration; +import com.google.cloud.compute.Subnetwork; +import com.google.cloud.compute.SubnetworkId; +import com.google.cloud.compute.SubnetworkInfo; +import com.google.cloud.compute.Zone; +import com.google.cloud.compute.ZoneOperationId; +import com.google.cloud.compute.testing.RemoteComputeHelper; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; -import com.google.gcloud.Page; -import com.google.gcloud.compute.Address; -import com.google.gcloud.compute.AddressId; -import com.google.gcloud.compute.AddressInfo; -import com.google.gcloud.compute.AttachedDisk; -import com.google.gcloud.compute.AttachedDisk.AttachedDiskConfiguration; -import com.google.gcloud.compute.AttachedDisk.CreateDiskConfiguration; -import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; -import com.google.gcloud.compute.AttachedDisk.ScratchDiskConfiguration; -import com.google.gcloud.compute.Compute; -import com.google.gcloud.compute.DeprecationStatus; -import com.google.gcloud.compute.Disk; -import com.google.gcloud.compute.DiskConfiguration; -import com.google.gcloud.compute.DiskId; -import com.google.gcloud.compute.DiskImageConfiguration; -import com.google.gcloud.compute.DiskInfo; -import com.google.gcloud.compute.DiskType; -import com.google.gcloud.compute.DiskTypeId; -import com.google.gcloud.compute.GlobalAddressId; -import com.google.gcloud.compute.Image; -import com.google.gcloud.compute.ImageConfiguration; -import com.google.gcloud.compute.ImageDiskConfiguration; -import com.google.gcloud.compute.ImageId; -import com.google.gcloud.compute.ImageInfo; -import com.google.gcloud.compute.Instance; -import com.google.gcloud.compute.InstanceId; -import com.google.gcloud.compute.InstanceInfo; -import com.google.gcloud.compute.License; -import com.google.gcloud.compute.LicenseId; -import com.google.gcloud.compute.MachineType; -import com.google.gcloud.compute.MachineTypeId; -import com.google.gcloud.compute.Network; -import com.google.gcloud.compute.NetworkConfiguration; -import com.google.gcloud.compute.NetworkId; -import com.google.gcloud.compute.NetworkInfo; -import com.google.gcloud.compute.NetworkInterface; -import com.google.gcloud.compute.NetworkInterface.AccessConfig; -import com.google.gcloud.compute.Operation; -import com.google.gcloud.compute.Region; -import com.google.gcloud.compute.RegionAddressId; -import com.google.gcloud.compute.RegionOperationId; -import com.google.gcloud.compute.SchedulingOptions; -import com.google.gcloud.compute.SchedulingOptions.Maintenance; -import com.google.gcloud.compute.Snapshot; -import com.google.gcloud.compute.SnapshotDiskConfiguration; -import com.google.gcloud.compute.SnapshotId; -import com.google.gcloud.compute.SnapshotInfo; -import com.google.gcloud.compute.StandardDiskConfiguration; -import com.google.gcloud.compute.StandardNetworkConfiguration; -import com.google.gcloud.compute.StorageImageConfiguration; -import com.google.gcloud.compute.SubnetNetworkConfiguration; -import com.google.gcloud.compute.Subnetwork; -import com.google.gcloud.compute.SubnetworkId; -import com.google.gcloud.compute.SubnetworkInfo; -import com.google.gcloud.compute.Zone; -import com.google.gcloud.compute.ZoneOperationId; -import com.google.gcloud.compute.testing.RemoteComputeHelper; +import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; @@ -630,7 +625,7 @@ public void testListZoneOperations() { Operation operation = operationIterator.next(); assertNotNull(operation.generatedId()); assertNotNull(operation.operationId()); - assertEquals(ZONE, operation.operationId().zone()); + Assert.assertEquals(ZONE, operation.operationId().zone()); // todo(mziccard): uncomment or remove once #727 is closed // assertNotNull(operation.creationTimestamp()); assertNotNull(operation.operationType()); @@ -1282,7 +1277,7 @@ public void testCreateGetAndDeprecateImage() throws InterruptedException { assertNotNull(image.configuration()); assertTrue(image.configuration() instanceof DiskImageConfiguration); DiskImageConfiguration remoteConfiguration = image.configuration(); - assertEquals(ImageConfiguration.Type.DISK, remoteConfiguration.type()); + Assert.assertEquals(ImageConfiguration.Type.DISK, remoteConfiguration.type()); assertEquals(diskName, remoteConfiguration.sourceDisk().disk()); assertNull(image.status()); assertNull(image.diskSizeGb()); @@ -1633,12 +1628,12 @@ public void testCreateGetAndDeleteInstance() throws InterruptedException { InstanceId instanceId = InstanceId.of(ZONE, instanceName); NetworkId networkId = NetworkId.of("default"); NetworkInterface networkInterface = NetworkInterface.builder(networkId) - .accessConfigurations(AccessConfig.builder().name("NAT").natIp(address.address()).build()) + .accessConfigurations(NetworkInterface.AccessConfig.builder().name("NAT").natIp(address.address()).build()) .build(); AttachedDisk disk1 = AttachedDisk.of("dev0", - CreateDiskConfiguration.builder(IMAGE_ID).autoDelete(true).build()); + AttachedDisk.CreateDiskConfiguration.builder(IMAGE_ID).autoDelete(true).build()); AttachedDisk disk2 = - AttachedDisk.of("dev1", ScratchDiskConfiguration.of(DiskTypeId.of(ZONE, DISK_TYPE))); + AttachedDisk.of("dev1", AttachedDisk.ScratchDiskConfiguration.of(DiskTypeId.of(ZONE, DISK_TYPE))); InstanceInfo instanceInfo = InstanceInfo.builder(instanceId, MachineTypeId.of(ZONE, "n1-standard-1")) .attachedDisks(disk1, disk2) @@ -1661,9 +1656,9 @@ public void testCreateGetAndDeleteInstance() throws InterruptedException { for (AttachedDisk remoteAttachedDisk : remoteInstance.attachedDisks()) { assertTrue(deviceSet.contains(remoteAttachedDisk.deviceName())); } - assertEquals(AttachedDiskConfiguration.Type.PERSISTENT, + Assert.assertEquals(AttachedDisk.AttachedDiskConfiguration.Type.PERSISTENT, remoteInstance.attachedDisks().get(0).configuration().type()); - PersistentDiskConfiguration remoteConfiguration = + AttachedDisk.PersistentDiskConfiguration remoteConfiguration = remoteInstance.attachedDisks().get(0).configuration(); assertEquals(instanceName, remoteConfiguration.sourceDisk().disk()); assertEquals(ZONE, remoteConfiguration.sourceDisk().zone()); @@ -1673,10 +1668,10 @@ public void testCreateGetAndDeleteInstance() throws InterruptedException { NetworkInterface remoteNetworkInterface = remoteInstance.networkInterfaces().get(0); assertNotNull(remoteNetworkInterface.name()); assertEquals("default", remoteNetworkInterface.network().network()); - List remoteAccessConfigurations = remoteNetworkInterface.accessConfigurations(); + List remoteAccessConfigurations = remoteNetworkInterface.accessConfigurations(); assertNotNull(remoteAccessConfigurations); assertEquals(1, remoteAccessConfigurations.size()); - AccessConfig remoteAccessConfig = remoteAccessConfigurations.get(0); + NetworkInterface.AccessConfig remoteAccessConfig = remoteAccessConfigurations.get(0); assertEquals(address.address(), remoteAccessConfig.natIp()); assertEquals("NAT", remoteAccessConfig.name()); assertNotNull(remoteInstance.metadata()); @@ -1713,7 +1708,7 @@ public void testStartStopAndResetInstance() throws InterruptedException { NetworkId networkId = NetworkId.of("default"); NetworkInterface networkInterface = NetworkInterface.builder(networkId).build(); AttachedDisk disk = AttachedDisk.of("dev0", - CreateDiskConfiguration.builder(IMAGE_ID).autoDelete(true).build()); + AttachedDisk.CreateDiskConfiguration.builder(IMAGE_ID).autoDelete(true).build()); InstanceInfo instanceInfo = InstanceInfo.builder(instanceId, MachineTypeId.of(ZONE, MACHINE_TYPE)) .attachedDisks(disk) @@ -1757,7 +1752,7 @@ public void testSetInstanceProperties() throws InterruptedException { NetworkId networkId = NetworkId.of("default"); NetworkInterface networkInterface = NetworkInterface.builder(networkId).build(); AttachedDisk disk = AttachedDisk.of("dev0", - CreateDiskConfiguration.builder(IMAGE_ID).autoDelete(true).build()); + AttachedDisk.CreateDiskConfiguration.builder(IMAGE_ID).autoDelete(true).build()); InstanceInfo instanceInfo = InstanceInfo.builder(instanceId, MachineTypeId.of(ZONE, MACHINE_TYPE)) .attachedDisks(disk) @@ -1797,7 +1792,7 @@ public void testSetInstanceProperties() throws InterruptedException { assertEquals("n1-standard-1", remoteInstance.machineType().type()); assertEquals(ZONE, remoteInstance.machineType().zone()); // test set scheduling options - SchedulingOptions options = SchedulingOptions.standard(false, Maintenance.TERMINATE); + SchedulingOptions options = SchedulingOptions.standard(false, SchedulingOptions.Maintenance.TERMINATE); operation = remoteInstance.setSchedulingOptions(options); while (!operation.isDone()) { Thread.sleep(1000L); @@ -1815,7 +1810,7 @@ public void testAttachAndDetachDisk() throws InterruptedException { NetworkId networkId = NetworkId.of("default"); NetworkInterface networkInterface = NetworkInterface.builder(networkId).build(); AttachedDisk disk = AttachedDisk.of("dev0", - CreateDiskConfiguration.builder(IMAGE_ID).autoDelete(true).build()); + AttachedDisk.CreateDiskConfiguration.builder(IMAGE_ID).autoDelete(true).build()); InstanceInfo instanceInfo = InstanceInfo.builder(instanceId, MachineTypeId.of(ZONE, MACHINE_TYPE)) .attachedDisks(disk) @@ -1834,7 +1829,7 @@ public void testAttachAndDetachDisk() throws InterruptedException { Instance remoteInstance = compute.getInstance(instanceId); // test attach disk instanceOperation = remoteInstance.attachDisk("dev1", - PersistentDiskConfiguration.builder(diskId).build()); + AttachedDisk.PersistentDiskConfiguration.builder(diskId).build()); while (!instanceOperation.isDone()) { Thread.sleep(1000L); } @@ -1875,7 +1870,7 @@ public void testAddAndRemoveAccessConfig() throws InterruptedException { NetworkId networkId = NetworkId.of("default"); NetworkInterface networkInterface = NetworkInterface.builder(networkId).build(); AttachedDisk disk = AttachedDisk.of("dev0", - CreateDiskConfiguration.builder(IMAGE_ID).autoDelete(true).build()); + AttachedDisk.CreateDiskConfiguration.builder(IMAGE_ID).autoDelete(true).build()); InstanceInfo instanceInfo = InstanceInfo.builder(instanceId, MachineTypeId.of(ZONE, MACHINE_TYPE)) .attachedDisks(disk) @@ -1898,7 +1893,7 @@ public void testAddAndRemoveAccessConfig() throws InterruptedException { Instance remoteInstance = compute.getInstance(instanceId); String networkInterfaceName = remoteInstance.networkInterfaces().get(0).name(); // test add access config - AccessConfig accessConfig = AccessConfig.builder() + NetworkInterface.AccessConfig accessConfig = NetworkInterface.AccessConfig.builder() .natIp(remoteAddress.address()) .name("NAT") .build(); @@ -1907,7 +1902,7 @@ public void testAddAndRemoveAccessConfig() throws InterruptedException { Thread.sleep(1000L); } remoteInstance = compute.getInstance(instanceId); - List accessConfigurations = + List accessConfigurations = remoteInstance.networkInterfaces().get(0).accessConfigurations(); assertEquals(1, accessConfigurations.size()); assertEquals("NAT", accessConfigurations.get(0).name()); diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/testing/RemoteComputeHelperTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/testing/RemoteComputeHelperTest.java similarity index 96% rename from gcloud-java-compute/src/test/java/com/google/gcloud/compute/testing/RemoteComputeHelperTest.java rename to gcloud-java-compute/src/test/java/com/google/cloud/compute/testing/RemoteComputeHelperTest.java index 5714ce7e0224..947bd4f1ea8c 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/testing/RemoteComputeHelperTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/testing/RemoteComputeHelperTest.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package com.google.gcloud.compute.testing; +package com.google.cloud.compute.testing; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; -import com.google.gcloud.compute.ComputeOptions; -import com.google.gcloud.compute.testing.RemoteComputeHelper.ComputeHelperException; +import com.google.cloud.compute.ComputeOptions; +import com.google.cloud.compute.testing.RemoteComputeHelper.ComputeHelperException; import org.junit.Test; diff --git a/gcloud-java-examples/README.md b/gcloud-java-examples/README.md index 10c2d0ce3650..f8bbde47b701 100644 --- a/gcloud-java-examples/README.md +++ b/gcloud-java-examples/README.md @@ -67,11 +67,11 @@ To run examples from your command line: Before running the example, go to the [Google Developers Console][developers-console] to ensure that Compute API is enabled. ``` - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.compute.ComputeExample" -Dexec.args="create image-disk us-central1-a test-disk debian-cloud debian-8-jessie-v20160329" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.compute.ComputeExample" -Dexec.args="create instance us-central1-a test-instance n1-standard-1 test-disk default" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.compute.ComputeExample" -Dexec.args="add-access-config us-central1-a test-instance nic0 NAT" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.compute.ComputeExample" -Dexec.args="delete instance us-central1-a test-instance" - mvn exec:java -Dexec.mainClass="com.google.gcloud.examples.compute.ComputeExample" -Dexec.args="delete disk us-central1-a test-disk" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.compute.ComputeExample" -Dexec.args="create image-disk us-central1-a test-disk debian-cloud debian-8-jessie-v20160329" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.compute.ComputeExample" -Dexec.args="create instance us-central1-a test-instance n1-standard-1 test-disk default" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.compute.ComputeExample" -Dexec.args="add-access-config us-central1-a test-instance nic0 NAT" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.compute.ComputeExample" -Dexec.args="delete instance us-central1-a test-instance" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.compute.ComputeExample" -Dexec.args="delete disk us-central1-a test-disk" ``` * Here's an example run of `DatastoreExample`. diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/ComputeExample.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/ComputeExample.java similarity index 97% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/ComputeExample.java rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/ComputeExample.java index afc2d6c049c2..d7f8e671cb72 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/ComputeExample.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/ComputeExample.java @@ -14,63 +14,63 @@ * limitations under the License. */ -package com.google.gcloud.examples.compute; - +package com.google.cloud.examples.compute; + +import com.google.cloud.compute.Address; +import com.google.cloud.compute.AddressId; +import com.google.cloud.compute.AddressInfo; +import com.google.cloud.compute.AttachedDisk; +import com.google.cloud.compute.AttachedDisk.PersistentDiskConfiguration; +import com.google.cloud.compute.Compute; +import com.google.cloud.compute.ComputeOptions; +import com.google.cloud.compute.Disk; +import com.google.cloud.compute.DiskConfiguration; +import com.google.cloud.compute.DiskId; +import com.google.cloud.compute.DiskImageConfiguration; +import com.google.cloud.compute.DiskInfo; +import com.google.cloud.compute.DiskType; +import com.google.cloud.compute.DiskTypeId; +import com.google.cloud.compute.GlobalAddressId; +import com.google.cloud.compute.GlobalOperationId; +import com.google.cloud.compute.Image; +import com.google.cloud.compute.ImageDiskConfiguration; +import com.google.cloud.compute.ImageId; +import com.google.cloud.compute.ImageInfo; +import com.google.cloud.compute.Instance; +import com.google.cloud.compute.InstanceId; +import com.google.cloud.compute.InstanceInfo; +import com.google.cloud.compute.LicenseId; +import com.google.cloud.compute.MachineType; +import com.google.cloud.compute.MachineTypeId; +import com.google.cloud.compute.Network; +import com.google.cloud.compute.NetworkId; +import com.google.cloud.compute.NetworkInfo; +import com.google.cloud.compute.NetworkInterface; +import com.google.cloud.compute.NetworkInterface.AccessConfig; +import com.google.cloud.compute.Operation; +import com.google.cloud.compute.Region; +import com.google.cloud.compute.RegionAddressId; +import com.google.cloud.compute.RegionId; +import com.google.cloud.compute.RegionOperationId; +import com.google.cloud.compute.SchedulingOptions; +import com.google.cloud.compute.SchedulingOptions.Maintenance; +import com.google.cloud.compute.Snapshot; +import com.google.cloud.compute.SnapshotDiskConfiguration; +import com.google.cloud.compute.SnapshotId; +import com.google.cloud.compute.SnapshotInfo; +import com.google.cloud.compute.StandardDiskConfiguration; +import com.google.cloud.compute.StandardNetworkConfiguration; +import com.google.cloud.compute.SubnetNetworkConfiguration; +import com.google.cloud.compute.Subnetwork; +import com.google.cloud.compute.SubnetworkId; +import com.google.cloud.compute.SubnetworkInfo; +import com.google.cloud.compute.Zone; +import com.google.cloud.compute.ZoneId; +import com.google.cloud.compute.ZoneOperationId; +import com.google.cloud.compute.spi.ComputeRpc.Tuple; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import com.google.gcloud.compute.Address; -import com.google.gcloud.compute.AddressId; -import com.google.gcloud.compute.AddressInfo; -import com.google.gcloud.compute.AttachedDisk; -import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; -import com.google.gcloud.compute.Compute; -import com.google.gcloud.compute.ComputeOptions; -import com.google.gcloud.compute.Disk; -import com.google.gcloud.compute.DiskConfiguration; -import com.google.gcloud.compute.DiskId; -import com.google.gcloud.compute.DiskImageConfiguration; -import com.google.gcloud.compute.DiskInfo; -import com.google.gcloud.compute.DiskType; -import com.google.gcloud.compute.DiskTypeId; -import com.google.gcloud.compute.GlobalAddressId; -import com.google.gcloud.compute.GlobalOperationId; -import com.google.gcloud.compute.Image; -import com.google.gcloud.compute.ImageDiskConfiguration; -import com.google.gcloud.compute.ImageId; -import com.google.gcloud.compute.ImageInfo; -import com.google.gcloud.compute.Instance; -import com.google.gcloud.compute.InstanceId; -import com.google.gcloud.compute.InstanceInfo; -import com.google.gcloud.compute.LicenseId; -import com.google.gcloud.compute.MachineType; -import com.google.gcloud.compute.MachineTypeId; -import com.google.gcloud.compute.Network; -import com.google.gcloud.compute.NetworkId; -import com.google.gcloud.compute.NetworkInfo; -import com.google.gcloud.compute.NetworkInterface; -import com.google.gcloud.compute.NetworkInterface.AccessConfig; -import com.google.gcloud.compute.Operation; -import com.google.gcloud.compute.Region; -import com.google.gcloud.compute.RegionAddressId; -import com.google.gcloud.compute.RegionId; -import com.google.gcloud.compute.RegionOperationId; -import com.google.gcloud.compute.SchedulingOptions; -import com.google.gcloud.compute.SchedulingOptions.Maintenance; -import com.google.gcloud.compute.Snapshot; -import com.google.gcloud.compute.SnapshotDiskConfiguration; -import com.google.gcloud.compute.SnapshotId; -import com.google.gcloud.compute.SnapshotInfo; -import com.google.gcloud.compute.StandardDiskConfiguration; -import com.google.gcloud.compute.StandardNetworkConfiguration; -import com.google.gcloud.compute.SubnetNetworkConfiguration; -import com.google.gcloud.compute.Subnetwork; -import com.google.gcloud.compute.SubnetworkId; -import com.google.gcloud.compute.SubnetworkInfo; -import com.google.gcloud.compute.Zone; -import com.google.gcloud.compute.ZoneId; -import com.google.gcloud.compute.ZoneOperationId; -import com.google.gcloud.compute.spi.ComputeRpc.Tuple; import java.util.Arrays; import java.util.HashMap; diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateAddressDiskAndInstance.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateAddressDiskAndInstance.java similarity index 79% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateAddressDiskAndInstance.java rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateAddressDiskAndInstance.java index ea1857479fda..5334f746c95b 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateAddressDiskAndInstance.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateAddressDiskAndInstance.java @@ -14,26 +14,26 @@ * limitations under the License. */ -package com.google.gcloud.examples.compute.snippets; +package com.google.cloud.examples.compute.snippets; -import com.google.gcloud.compute.Address; -import com.google.gcloud.compute.AddressInfo; -import com.google.gcloud.compute.AttachedDisk; -import com.google.gcloud.compute.AttachedDisk.PersistentDiskConfiguration; -import com.google.gcloud.compute.Compute; -import com.google.gcloud.compute.ComputeOptions; -import com.google.gcloud.compute.DiskId; -import com.google.gcloud.compute.DiskInfo; -import com.google.gcloud.compute.ImageDiskConfiguration; -import com.google.gcloud.compute.ImageId; -import com.google.gcloud.compute.InstanceId; -import com.google.gcloud.compute.InstanceInfo; -import com.google.gcloud.compute.MachineTypeId; -import com.google.gcloud.compute.NetworkId; -import com.google.gcloud.compute.NetworkInterface; -import com.google.gcloud.compute.NetworkInterface.AccessConfig; -import com.google.gcloud.compute.Operation; -import com.google.gcloud.compute.RegionAddressId; +import com.google.cloud.compute.Address; +import com.google.cloud.compute.AddressInfo; +import com.google.cloud.compute.AttachedDisk; +import com.google.cloud.compute.AttachedDisk.PersistentDiskConfiguration; +import com.google.cloud.compute.Compute; +import com.google.cloud.compute.ComputeOptions; +import com.google.cloud.compute.DiskId; +import com.google.cloud.compute.DiskInfo; +import com.google.cloud.compute.ImageDiskConfiguration; +import com.google.cloud.compute.ImageId; +import com.google.cloud.compute.InstanceId; +import com.google.cloud.compute.InstanceInfo; +import com.google.cloud.compute.MachineTypeId; +import com.google.cloud.compute.NetworkId; +import com.google.cloud.compute.NetworkInterface; +import com.google.cloud.compute.NetworkInterface.AccessConfig; +import com.google.cloud.compute.Operation; +import com.google.cloud.compute.RegionAddressId; /** * A snippet for Google Cloud Compute Engine showing how to create a disk and an address. The diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateInstance.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateInstance.java similarity index 75% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateInstance.java rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateInstance.java index db72f25cc90e..d8162908d133 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateInstance.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateInstance.java @@ -14,19 +14,19 @@ * limitations under the License. */ -package com.google.gcloud.examples.compute.snippets; +package com.google.cloud.examples.compute.snippets; -import com.google.gcloud.compute.AttachedDisk; -import com.google.gcloud.compute.Compute; -import com.google.gcloud.compute.ComputeOptions; -import com.google.gcloud.compute.ImageId; -import com.google.gcloud.compute.Instance; -import com.google.gcloud.compute.InstanceId; -import com.google.gcloud.compute.InstanceInfo; -import com.google.gcloud.compute.MachineTypeId; -import com.google.gcloud.compute.NetworkId; -import com.google.gcloud.compute.NetworkInterface; -import com.google.gcloud.compute.Operation; +import com.google.cloud.compute.AttachedDisk; +import com.google.cloud.compute.Compute; +import com.google.cloud.compute.ComputeOptions; +import com.google.cloud.compute.ImageId; +import com.google.cloud.compute.Instance; +import com.google.cloud.compute.InstanceId; +import com.google.cloud.compute.InstanceInfo; +import com.google.cloud.compute.MachineTypeId; +import com.google.cloud.compute.NetworkId; +import com.google.cloud.compute.NetworkInterface; +import com.google.cloud.compute.Operation; /** * A snippet for Google Cloud Compute Engine showing how to create a virtual machine instance. diff --git a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateSnapshot.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateSnapshot.java similarity index 81% rename from gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateSnapshot.java rename to gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateSnapshot.java index a0684d63d9fb..cc8029936186 100644 --- a/gcloud-java-examples/src/main/java/com/google/gcloud/examples/compute/snippets/CreateSnapshot.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateSnapshot.java @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.google.gcloud.examples.compute.snippets; +package com.google.cloud.examples.compute.snippets; -import com.google.gcloud.compute.Compute; -import com.google.gcloud.compute.ComputeOptions; -import com.google.gcloud.compute.Disk; -import com.google.gcloud.compute.DiskId; -import com.google.gcloud.compute.Operation; -import com.google.gcloud.compute.Snapshot; +import com.google.cloud.compute.Compute; +import com.google.cloud.compute.ComputeOptions; +import com.google.cloud.compute.Disk; +import com.google.cloud.compute.DiskId; +import com.google.cloud.compute.Operation; +import com.google.cloud.compute.Snapshot; /** * A snippet for Google Cloud Compute Engine showing how to create a snapshot of a disk if the disk From 17c6eba167e3f5d9867ae3e452f044208fb138b1 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 29 Apr 2016 14:18:21 +0200 Subject: [PATCH 329/375] Use BaseSerializationTest in compute's serialization test --- gcloud-java-compute/pom.xml | 7 +++ .../cloud/compute/SerializationTest.java | 55 ++++--------------- 2 files changed, 19 insertions(+), 43 deletions(-) diff --git a/gcloud-java-compute/pom.xml b/gcloud-java-compute/pom.xml index 3fdc63a9ad81..40a09b008076 100644 --- a/gcloud-java-compute/pom.xml +++ b/gcloud-java-compute/pom.xml @@ -34,6 +34,13 @@ + + ${project.groupId} + gcloud-java-core + ${project.version} + test-jar + test + junit junit diff --git a/gcloud-java-compute/src/test/java/com/google/cloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/SerializationTest.java index b43bbe62d62b..0ef68731183d 100644 --- a/gcloud-java-compute/src/test/java/com/google/cloud/compute/SerializationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/SerializationTest.java @@ -16,10 +16,9 @@ package com.google.cloud.compute; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotSame; - import com.google.cloud.AuthCredentials; +import com.google.cloud.BaseSerializationTest; +import com.google.cloud.Restorable; import com.google.cloud.RetryParams; import com.google.cloud.compute.AttachedDisk.CreateDiskConfiguration; import com.google.cloud.compute.AttachedDisk.PersistentDiskConfiguration; @@ -28,17 +27,10 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; -import org.junit.Test; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.List; -public class SerializationTest { +public class SerializationTest extends BaseSerializationTest { private static final Compute COMPUTE = ComputeOptions.builder().projectId("p").build().service(); private static final Long CREATION_TIMESTAMP = 1453293540000L; @@ -269,27 +261,18 @@ public class SerializationTest { private static final Compute.InstanceAggregatedListOption INSTANCE_AGGREGATED_LIST_OPTION = Compute.InstanceAggregatedListOption.filter(INSTANCE_FILTER); - @Test - public void testServiceOptions() throws Exception { + @Override + protected Serializable[] serializableObjects() { ComputeOptions options = ComputeOptions.builder() .projectId("p1") .authCredentials(AuthCredentials.createForAppEngine()) .build(); - ComputeOptions serializedCopy = serializeAndDeserialize(options); - assertEquals(options, serializedCopy); - - options = options.toBuilder() + ComputeOptions otherOptions = options.toBuilder() .projectId("p2") .retryParams(RetryParams.defaultInstance()) .authCredentials(null) .build(); - serializedCopy = serializeAndDeserialize(options); - assertEquals(options, serializedCopy); - } - - @Test - public void testModelAndRequests() throws Exception { - Serializable[] objects = {DISK_TYPE_ID, DISK_TYPE, MACHINE_TYPE_ID, MACHINE_TYPE, REGION_ID, + return new Serializable[]{DISK_TYPE_ID, DISK_TYPE, MACHINE_TYPE_ID, MACHINE_TYPE, REGION_ID, REGION, ZONE_ID, ZONE, LICENSE_ID, LICENSE, DEPRECATION_STATUS, GLOBAL_OPERATION_ID, REGION_OPERATION_ID, ZONE_OPERATION_ID, GLOBAL_OPERATION, REGION_OPERATION, ZONE_OPERATION, INSTANCE_ID, REGION_FORWARDING_RULE_ID, GLOBAL_FORWARDING_RULE_ID, GLOBAL_ADDRESS_ID, @@ -311,26 +294,12 @@ public void testModelAndRequests() throws Exception { IMAGE_LIST_OPTION, DISK_OPTION, DISK_FILTER, DISK_LIST_OPTION, DISK_AGGREGATED_LIST_OPTION, SUBNETWORK_OPTION, SUBNETWORK_FILTER, SUBNETWORK_LIST_OPTION, SUBNETWORK_AGGREGATED_LIST_OPTION, NETWORK_OPTION, NETWORK_FILTER, NETWORK_LIST_OPTION, - INSTANCE_OPTION, INSTANCE_FILTER, INSTANCE_LIST_OPTION, INSTANCE_AGGREGATED_LIST_OPTION}; - for (Serializable obj : objects) { - Object copy = serializeAndDeserialize(obj); - assertEquals(obj, obj); - assertEquals(obj, copy); - assertNotSame(obj, copy); - assertEquals(copy, copy); - } + INSTANCE_OPTION, INSTANCE_FILTER, INSTANCE_LIST_OPTION, INSTANCE_AGGREGATED_LIST_OPTION, + options, otherOptions}; } - @SuppressWarnings("unchecked") - private T serializeAndDeserialize(T obj) - throws IOException, ClassNotFoundException { - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - try (ObjectOutputStream output = new ObjectOutputStream(bytes)) { - output.writeObject(obj); - } - try (ObjectInputStream input = - new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray()))) { - return (T) input.readObject(); - } + @Override + protected Restorable[] restorableObjects() { + return null; } } From ae0a6d209737e3d1718a42c3bb87313344c7f3d3 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 29 Apr 2016 15:35:38 +0200 Subject: [PATCH 330/375] Use FieldSelector interface and Helper in compute --- .../com/google/cloud/compute/Compute.java | 298 +++++++----------- 1 file changed, 109 insertions(+), 189 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/Compute.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Compute.java index 6de874f51d16..47d594ba6ec5 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/Compute.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Compute.java @@ -18,18 +18,19 @@ import static com.google.common.base.Preconditions.checkNotNull; +import com.google.cloud.FieldSelector; +import com.google.cloud.FieldSelector.Helper; import com.google.cloud.Page; import com.google.cloud.Service; import com.google.cloud.compute.AttachedDisk.PersistentDiskConfiguration; import com.google.cloud.compute.NetworkInterface.AccessConfig; import com.google.cloud.compute.spi.ComputeRpc; -import com.google.common.base.Joiner; import com.google.common.base.MoreObjects; -import com.google.common.collect.Sets; +import com.google.common.collect.ImmutableList; import java.io.Serializable; +import java.util.List; import java.util.Objects; -import java.util.Set; /** * An interface for Google Cloud Compute Engine. @@ -44,7 +45,7 @@ public interface Compute extends Service { * @see Disk * Type Resource */ - enum DiskTypeField { + enum DiskTypeField implements FieldSelector { CREATION_TIMESTAMP("creationTimestamp"), DEFAULT_DISK_SIZE_GB("defaultDiskSizeGb"), DESCRIPTION("description"), @@ -55,24 +56,18 @@ enum DiskTypeField { ZONE("zone"), DEPRECATED("deprecated"); + static final List REQUIRED_FIELDS = ImmutableList.of(SELF_LINK); + private final String selector; DiskTypeField(String selector) { this.selector = selector; } + @Override public String selector() { return selector; } - - static String selector(DiskTypeField... fields) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); - fieldStrings.add(SELF_LINK.selector()); - for (DiskTypeField field : fields) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } } /** @@ -81,7 +76,7 @@ static String selector(DiskTypeField... fields) { * @see * Machine Type Resource */ - enum MachineTypeField { + enum MachineTypeField implements FieldSelector { CREATION_TIMESTAMP("creationTimestamp"), DESCRIPTION("description"), GUEST_CPUS("guestCpus"), @@ -96,24 +91,18 @@ enum MachineTypeField { ZONE("zone"), DEPRECATED("deprecated"); + static final List REQUIRED_FIELDS = ImmutableList.of(SELF_LINK); + private final String selector; MachineTypeField(String selector) { this.selector = selector; } + @Override public String selector() { return selector; } - - static String selector(MachineTypeField... fields) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); - fieldStrings.add(SELF_LINK.selector()); - for (MachineTypeField field : fields) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } } /** @@ -122,7 +111,7 @@ static String selector(MachineTypeField... fields) { * @see * Region Resource */ - enum RegionField { + enum RegionField implements FieldSelector { CREATION_TIMESTAMP("creationTimestamp"), DESCRIPTION("description"), ID("id"), @@ -133,24 +122,18 @@ enum RegionField { ZONES("zones"), DEPRECATED("deprecated"); + static final List REQUIRED_FIELDS = ImmutableList.of(SELF_LINK); + private final String selector; RegionField(String selector) { this.selector = selector; } + @Override public String selector() { return selector; } - - static String selector(RegionField... fields) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); - fieldStrings.add(SELF_LINK.selector()); - for (RegionField field : fields) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } } /** @@ -159,7 +142,7 @@ static String selector(RegionField... fields) { * @see Zone * Resource */ - enum ZoneField { + enum ZoneField implements FieldSelector { CREATION_TIMESTAMP("creationTimestamp"), DESCRIPTION("description"), ID("id"), @@ -169,24 +152,18 @@ enum ZoneField { STATUS("status"), DEPRECATED("deprecated"); + static final List REQUIRED_FIELDS = ImmutableList.of(SELF_LINK); + private final String selector; ZoneField(String selector) { this.selector = selector; } + @Override public String selector() { return selector; } - - static String selector(ZoneField... fields) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); - fieldStrings.add(SELF_LINK.selector()); - for (ZoneField field : fields) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } } /** @@ -195,29 +172,23 @@ static String selector(ZoneField... fields) { * @see License * Resource */ - enum LicenseField { + enum LicenseField implements FieldSelector { CHARGES_USE_FEE("chargesUseFee"), NAME("name"), SELF_LINK("selfLink"); + static final List REQUIRED_FIELDS = ImmutableList.of(SELF_LINK); + private final String selector; LicenseField(String selector) { this.selector = selector; } + @Override public String selector() { return selector; } - - static String selector(LicenseField... fields) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); - fieldStrings.add(SELF_LINK.selector()); - for (LicenseField field : fields) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } } /** @@ -232,7 +203,7 @@ static String selector(LicenseField... fields) { * @see * ZoneOperation Resource */ - enum OperationField { + enum OperationField implements FieldSelector { CLIENT_OPERATION_ID("clientOperationId"), DESCRIPTION("description"), END_TIME("endTime"), @@ -255,24 +226,18 @@ enum OperationField { WARNINGS("warnings"), ZONE("zone"); + static final List REQUIRED_FIELDS = ImmutableList.of(SELF_LINK); + private final String selector; OperationField(String selector) { this.selector = selector; } + @Override public String selector() { return selector; } - - static String selector(OperationField... fields) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); - fieldStrings.add(SELF_LINK.selector()); - for (OperationField field : fields) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } } /** @@ -283,7 +248,7 @@ static String selector(OperationField... fields) { * @see * Global Address Resource */ - enum AddressField { + enum AddressField implements FieldSelector { ADDRESS("address"), CREATION_TIMESTAMP("creationTimestamp"), DESCRIPTION("description"), @@ -294,24 +259,18 @@ enum AddressField { STATUS("status"), USERS("users"); + static final List REQUIRED_FIELDS = ImmutableList.of(SELF_LINK); + private final String selector; AddressField(String selector) { this.selector = selector; } + @Override public String selector() { return selector; } - - static String selector(AddressField... fields) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); - fieldStrings.add(SELF_LINK.selector()); - for (AddressField field : fields) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } } /** @@ -320,7 +279,7 @@ static String selector(AddressField... fields) { * @see Disk * Resource */ - enum DiskField { + enum DiskField implements FieldSelector { CREATION_TIMESTAMP("creationTimestamp"), DESCRIPTION("description"), ID("id"), @@ -340,27 +299,19 @@ enum DiskField { USERS("users"), ZONE("zone"); + static final List REQUIRED_FIELDS = + ImmutableList.of(SELF_LINK, TYPE, SOURCE_IMAGE, SOURCE_SNAPSHOT); + private final String selector; DiskField(String selector) { this.selector = selector; } + @Override public String selector() { return selector; } - - static String selector(DiskField... fields) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 4); - fieldStrings.add(SELF_LINK.selector()); - fieldStrings.add(TYPE.selector()); - fieldStrings.add(SOURCE_IMAGE.selector()); - fieldStrings.add(SOURCE_SNAPSHOT.selector()); - for (DiskField field : fields) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } } /** @@ -369,7 +320,7 @@ static String selector(DiskField... fields) { * @see * Snapshot Resource */ - enum SnapshotField { + enum SnapshotField implements FieldSelector { CREATION_TIMESTAMP("creationTimestamp"), DESCRIPTION("description"), DISK_SIZE_GB("diskSizeGb"), @@ -383,24 +334,18 @@ enum SnapshotField { STORAGE_BYTES("storageBytes"), STORAGE_BYTES_STATUS("storageBytesStatus"); + static final List REQUIRED_FIELDS = ImmutableList.of(SELF_LINK); + private final String selector; SnapshotField(String selector) { this.selector = selector; } + @Override public String selector() { return selector; } - - static String selector(SnapshotField... fields) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); - fieldStrings.add(SELF_LINK.selector()); - for (SnapshotField field : fields) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } } /** @@ -409,7 +354,7 @@ static String selector(SnapshotField... fields) { * @see Image * Resource */ - enum ImageField { + enum ImageField implements FieldSelector { ARCHIVE_SIZE_BYTES("archiveSizeBytes"), CREATION_TIMESTAMP("creationTimestamp"), DEPRECATED("deprecated"), @@ -424,26 +369,19 @@ enum ImageField { SOURCE_DISK_ID("sourceDiskId"), SOURCE_TYPE("sourceType"); + static final List REQUIRED_FIELDS = + ImmutableList.of(SELF_LINK, SOURCE_DISK, RAW_DISK); + private final String selector; ImageField(String selector) { this.selector = selector; } + @Override public String selector() { return selector; } - - static String selector(ImageField... fields) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 3); - fieldStrings.add(SELF_LINK.selector()); - fieldStrings.add(SOURCE_DISK.selector()); - fieldStrings.add(RAW_DISK.selector()); - for (ImageField field : fields) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } } /** @@ -452,7 +390,7 @@ static String selector(ImageField... fields) { * @see * Subnetwork Resource */ - enum SubnetworkField { + enum SubnetworkField implements FieldSelector { CREATION_TIMESTAMP("creationTimestamp"), DESCRIPTION("description"), GATEWAY_ADDRESS("gatewayAddress"), @@ -463,24 +401,18 @@ enum SubnetworkField { REGION("region"), SELF_LINK("selfLink"); + static final List REQUIRED_FIELDS = ImmutableList.of(SELF_LINK); + private final String selector; SubnetworkField(String selector) { this.selector = selector; } + @Override public String selector() { return selector; } - - static String selector(SubnetworkField... fields) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); - fieldStrings.add(SELF_LINK.selector()); - for (SubnetworkField field : fields) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } } /** @@ -489,7 +421,7 @@ static String selector(SubnetworkField... fields) { * @see * Network Resource */ - enum NetworkField { + enum NetworkField implements FieldSelector { IPV4_RANGE("IPv4Range"), AUTO_CREATE_SUBNETWORKS("autoCreateSubnetworks"), CREATION_TIMESTAMP("creationTimestamp"), @@ -500,26 +432,19 @@ enum NetworkField { SELF_LINK("selfLink"), SUBNETWORKS("subnetworks"); + static final List REQUIRED_FIELDS = + ImmutableList.of(SELF_LINK, IPV4_RANGE, AUTO_CREATE_SUBNETWORKS); + private final String selector; NetworkField(String selector) { this.selector = selector; } + @Override public String selector() { return selector; } - - static String selector(NetworkField... fields) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 3); - fieldStrings.add(SELF_LINK.selector()); - fieldStrings.add(IPV4_RANGE.selector()); - fieldStrings.add(AUTO_CREATE_SUBNETWORKS.selector()); - for (NetworkField field : fields) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } } /** @@ -528,7 +453,7 @@ static String selector(NetworkField... fields) { * @see * Network Resource */ - enum InstanceField { + enum InstanceField implements FieldSelector { CAN_IP_FORWARD("canIpForward"), CPU_PLATFORM("cpuPlatform"), CREATION_TIMESTAMP("creationTimestamp"), @@ -547,24 +472,18 @@ enum InstanceField { TAGS("tags"), ZONE("zone"); + static final List REQUIRED_FIELDS = ImmutableList.of(SELF_LINK); + private final String selector; InstanceField(String selector) { this.selector = selector; } + @Override public String selector() { return selector; } - - static String selector(InstanceField... fields) { - Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); - fieldStrings.add(SELF_LINK.selector()); - for (InstanceField field : fields) { - fieldStrings.add(field.selector()); - } - return Joiner.on(',').join(fieldStrings); - } } /** @@ -1158,7 +1077,8 @@ private DiskTypeOption(ComputeRpc.Option option, Object value) { * returned, even if not specified. */ public static DiskTypeOption fields(DiskTypeField... fields) { - return new DiskTypeOption(ComputeRpc.Option.FIELDS, DiskTypeField.selector(fields)); + return new DiskTypeOption(ComputeRpc.Option.FIELDS, + Helper.selector(DiskTypeField.REQUIRED_FIELDS, fields)); } } @@ -1202,9 +1122,8 @@ public static DiskTypeListOption pageToken(String pageToken) { * {@link DiskType#diskTypeId()} is always returned, even if not specified. */ public static DiskTypeListOption fields(DiskTypeField... fields) { - StringBuilder builder = new StringBuilder(); - builder.append("items(").append(DiskTypeField.selector(fields)).append("),nextPageToken"); - return new DiskTypeListOption(ComputeRpc.Option.FIELDS, builder.toString()); + return new DiskTypeListOption(ComputeRpc.Option.FIELDS, + Helper.listSelector("items", DiskTypeField.REQUIRED_FIELDS, fields)); } } @@ -1260,7 +1179,8 @@ private MachineTypeOption(ComputeRpc.Option option, Object value) { * {@link MachineType#machineTypeId()} is always returned, even if not specified. */ public static MachineTypeOption fields(MachineTypeField... fields) { - return new MachineTypeOption(ComputeRpc.Option.FIELDS, MachineTypeField.selector(fields)); + return new MachineTypeOption(ComputeRpc.Option.FIELDS, + Helper.selector(MachineTypeField.REQUIRED_FIELDS, fields)); } } @@ -1304,9 +1224,8 @@ public static MachineTypeListOption pageToken(String pageToken) { * {@link MachineType#machineTypeId()} is always returned, even if not specified. */ public static MachineTypeListOption fields(MachineTypeField... fields) { - StringBuilder builder = new StringBuilder(); - builder.append("items(").append(MachineTypeField.selector(fields)).append("),nextPageToken"); - return new MachineTypeListOption(ComputeRpc.Option.FIELDS, builder.toString()); + return new MachineTypeListOption(ComputeRpc.Option.FIELDS, + Helper.listSelector("items", MachineTypeField.REQUIRED_FIELDS, fields)); } } @@ -1362,7 +1281,8 @@ private RegionOption(ComputeRpc.Option option, Object value) { * returned, even if not specified. */ public static RegionOption fields(RegionField... fields) { - return new RegionOption(ComputeRpc.Option.FIELDS, RegionField.selector(fields)); + return new RegionOption(ComputeRpc.Option.FIELDS, + Helper.selector(RegionField.REQUIRED_FIELDS, fields)); } } @@ -1406,9 +1326,8 @@ public static RegionListOption pageToken(String pageToken) { * returned, even if not specified. */ public static RegionListOption fields(RegionField... fields) { - StringBuilder builder = new StringBuilder(); - builder.append("items(").append(RegionField.selector(fields)).append("),nextPageToken"); - return new RegionListOption(ComputeRpc.Option.FIELDS, builder.toString()); + return new RegionListOption(ComputeRpc.Option.FIELDS, + Helper.listSelector("items", RegionField.REQUIRED_FIELDS, fields)); } } @@ -1430,7 +1349,8 @@ private ZoneOption(ComputeRpc.Option option, Object value) { * not specified. */ public static ZoneOption fields(ZoneField... fields) { - return new ZoneOption(ComputeRpc.Option.FIELDS, ZoneField.selector(fields)); + return new ZoneOption(ComputeRpc.Option.FIELDS, + Helper.selector(ZoneField.REQUIRED_FIELDS, fields)); } } @@ -1474,9 +1394,8 @@ public static ZoneListOption pageToken(String pageToken) { * not specified. */ public static ZoneListOption fields(ZoneField... fields) { - StringBuilder builder = new StringBuilder(); - builder.append("items(").append(ZoneField.selector(fields)).append("),nextPageToken"); - return new ZoneListOption(ComputeRpc.Option.FIELDS, builder.toString()); + return new ZoneListOption(ComputeRpc.Option.FIELDS, + Helper.listSelector("items", ZoneField.REQUIRED_FIELDS, fields)); } } @@ -1498,7 +1417,8 @@ private LicenseOption(ComputeRpc.Option option, Object value) { * returned, even if not specified. */ public static LicenseOption fields(LicenseField... fields) { - return new LicenseOption(ComputeRpc.Option.FIELDS, LicenseField.selector(fields)); + return new LicenseOption(ComputeRpc.Option.FIELDS, + Helper.selector(LicenseField.REQUIRED_FIELDS, fields)); } } @@ -1520,7 +1440,8 @@ private OperationOption(ComputeRpc.Option option, Object value) { * always returned, even if not specified. */ public static OperationOption fields(OperationField... fields) { - return new OperationOption(ComputeRpc.Option.FIELDS, OperationField.selector(fields)); + return new OperationOption(ComputeRpc.Option.FIELDS, + Helper.selector(OperationField.REQUIRED_FIELDS, fields)); } } @@ -1564,9 +1485,8 @@ public static OperationListOption pageToken(String pageToken) { * {@link Operation#operationId()} is always returned, even if not specified. */ public static OperationListOption fields(OperationField... fields) { - StringBuilder builder = new StringBuilder(); - builder.append("items(").append(OperationField.selector(fields)).append("),nextPageToken"); - return new OperationListOption(ComputeRpc.Option.FIELDS, builder.toString()); + return new OperationListOption(ComputeRpc.Option.FIELDS, + Helper.listSelector("items", OperationField.REQUIRED_FIELDS, fields)); } } @@ -1588,7 +1508,8 @@ private AddressOption(ComputeRpc.Option option, Object value) { * returned, even if not specified. */ public static AddressOption fields(AddressField... fields) { - return new AddressOption(ComputeRpc.Option.FIELDS, AddressField.selector(fields)); + return new AddressOption(ComputeRpc.Option.FIELDS, + Helper.selector(AddressField.REQUIRED_FIELDS, fields)); } } @@ -1632,9 +1553,8 @@ public static AddressListOption pageToken(String pageToken) { * returned, even if not specified. */ public static AddressListOption fields(AddressField... fields) { - StringBuilder builder = new StringBuilder(); - builder.append("items(").append(AddressField.selector(fields)).append("),nextPageToken"); - return new AddressListOption(ComputeRpc.Option.FIELDS, builder.toString()); + return new AddressListOption(ComputeRpc.Option.FIELDS, + Helper.listSelector("items", AddressField.REQUIRED_FIELDS, fields)); } } @@ -1690,7 +1610,8 @@ private SnapshotOption(ComputeRpc.Option option, Object value) { * returned, even if not specified. */ public static SnapshotOption fields(SnapshotField... fields) { - return new SnapshotOption(ComputeRpc.Option.FIELDS, SnapshotField.selector(fields)); + return new SnapshotOption(ComputeRpc.Option.FIELDS, + Helper.selector(SnapshotField.REQUIRED_FIELDS, fields)); } } @@ -1734,9 +1655,8 @@ public static SnapshotListOption pageToken(String pageToken) { * {@link Snapshot#snapshotId()} is always returned, even if not specified. */ public static SnapshotListOption fields(SnapshotField... fields) { - StringBuilder builder = new StringBuilder(); - builder.append("items(").append(SnapshotField.selector(fields)).append("),nextPageToken"); - return new SnapshotListOption(ComputeRpc.Option.FIELDS, builder.toString()); + return new SnapshotListOption(ComputeRpc.Option.FIELDS, + Helper.listSelector("items", SnapshotField.REQUIRED_FIELDS, fields)); } } @@ -1758,7 +1678,8 @@ private ImageOption(ComputeRpc.Option option, Object value) { * {@link Image#configuration()} are always returned, even if not specified. */ public static ImageOption fields(ImageField... fields) { - return new ImageOption(ComputeRpc.Option.FIELDS, ImageField.selector(fields)); + return new ImageOption(ComputeRpc.Option.FIELDS, + Helper.selector(ImageField.REQUIRED_FIELDS, fields)); } } @@ -1802,9 +1723,8 @@ public static ImageListOption pageToken(String pageToken) { * {@link Image#configuration()} are always returned, even if not specified. */ public static ImageListOption fields(ImageField... fields) { - StringBuilder builder = new StringBuilder(); - builder.append("items(").append(ImageField.selector(fields)).append("),nextPageToken"); - return new ImageListOption(ComputeRpc.Option.FIELDS, builder.toString()); + return new ImageListOption(ComputeRpc.Option.FIELDS, + Helper.listSelector("items", ImageField.REQUIRED_FIELDS, fields)); } } @@ -1828,7 +1748,8 @@ private DiskOption(ComputeRpc.Option option, Object value) { * {@link ImageDiskConfiguration#sourceImage()} are always returned, even if not specified. */ public static DiskOption fields(DiskField... fields) { - return new DiskOption(ComputeRpc.Option.FIELDS, DiskField.selector(fields)); + return new DiskOption(ComputeRpc.Option.FIELDS, + Helper.selector(DiskField.REQUIRED_FIELDS, fields)); } } @@ -1874,9 +1795,8 @@ public static DiskListOption pageToken(String pageToken) { * {@link ImageDiskConfiguration#sourceImage()} are always returned, even if not specified. */ public static DiskListOption fields(DiskField... fields) { - StringBuilder builder = new StringBuilder(); - builder.append("items(").append(DiskField.selector(fields)).append("),nextPageToken"); - return new DiskListOption(ComputeRpc.Option.FIELDS, builder.toString()); + return new DiskListOption(ComputeRpc.Option.FIELDS, + Helper.listSelector("items", DiskField.REQUIRED_FIELDS, fields)); } } @@ -1932,7 +1852,8 @@ private SubnetworkOption(ComputeRpc.Option option, Object value) { * always returned, even if not specified. */ public static SubnetworkOption fields(SubnetworkField... fields) { - return new SubnetworkOption(ComputeRpc.Option.FIELDS, SubnetworkField.selector(fields)); + return new SubnetworkOption(ComputeRpc.Option.FIELDS, + Helper.selector(SubnetworkField.REQUIRED_FIELDS, fields)); } } @@ -1976,9 +1897,8 @@ public static SubnetworkListOption pageToken(String pageToken) { * {@link Subnetwork#subnetworkId()} is always returned, even if not specified. */ public static SubnetworkListOption fields(SubnetworkField... fields) { - StringBuilder builder = new StringBuilder(); - builder.append("items(").append(SubnetworkField.selector(fields)).append("),nextPageToken"); - return new SubnetworkListOption(ComputeRpc.Option.FIELDS, builder.toString()); + return new SubnetworkListOption(ComputeRpc.Option.FIELDS, + Helper.listSelector("items", SubnetworkField.REQUIRED_FIELDS, fields)); } } @@ -2034,7 +1954,8 @@ private NetworkOption(ComputeRpc.Option option, Object value) { * {@link Network#configuration()} are always returned, even if not specified. */ public static NetworkOption fields(NetworkField... fields) { - return new NetworkOption(ComputeRpc.Option.FIELDS, NetworkField.selector(fields)); + return new NetworkOption(ComputeRpc.Option.FIELDS, + Helper.selector(NetworkField.REQUIRED_FIELDS, fields)); } } @@ -2078,9 +1999,8 @@ public static NetworkListOption pageToken(String pageToken) { * {@link Network#configuration()} are always returned, even if not specified. */ public static NetworkListOption fields(NetworkField... fields) { - StringBuilder builder = new StringBuilder(); - builder.append("items(").append(NetworkField.selector(fields)).append("),nextPageToken"); - return new NetworkListOption(ComputeRpc.Option.FIELDS, builder.toString()); + return new NetworkListOption(ComputeRpc.Option.FIELDS, + Helper.listSelector("items", NetworkField.REQUIRED_FIELDS, fields)); } } @@ -2102,7 +2022,8 @@ private InstanceOption(ComputeRpc.Option option, Object value) { * returned, even if not specified. */ public static InstanceOption fields(InstanceField... fields) { - return new InstanceOption(ComputeRpc.Option.FIELDS, InstanceField.selector(fields)); + return new InstanceOption(ComputeRpc.Option.FIELDS, + Helper.selector(InstanceField.REQUIRED_FIELDS, fields)); } } @@ -2146,9 +2067,8 @@ public static InstanceListOption pageToken(String pageToken) { * returned, even if not specified. */ public static InstanceListOption fields(InstanceField... fields) { - StringBuilder builder = new StringBuilder(); - builder.append("items(").append(InstanceField.selector(fields)).append("),nextPageToken"); - return new InstanceListOption(ComputeRpc.Option.FIELDS, builder.toString()); + return new InstanceListOption(ComputeRpc.Option.FIELDS, + Helper.listSelector("items", InstanceField.REQUIRED_FIELDS, fields)); } } From f0ae430bf5ab67f70cea5695d2c82c82cce61c47 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 29 Apr 2016 17:28:04 +0200 Subject: [PATCH 331/375] Update Compute equals methods to support mocking --- .../main/java/com/google/cloud/compute/Address.java | 11 ++++++++--- .../java/com/google/cloud/compute/AddressInfo.java | 3 ++- .../com/google/cloud/compute/DeprecationStatus.java | 3 ++- .../src/main/java/com/google/cloud/compute/Disk.java | 11 ++++++++--- .../google/cloud/compute/DiskImageConfiguration.java | 5 ++++- .../main/java/com/google/cloud/compute/DiskInfo.java | 3 ++- .../main/java/com/google/cloud/compute/DiskType.java | 5 ++++- .../com/google/cloud/compute/GlobalAddressId.java | 2 +- .../google/cloud/compute/GlobalForwardingRuleId.java | 4 +++- .../com/google/cloud/compute/GlobalOperationId.java | 2 +- .../src/main/java/com/google/cloud/compute/Image.java | 11 ++++++++--- .../google/cloud/compute/ImageDiskConfiguration.java | 5 ++++- .../main/java/com/google/cloud/compute/ImageInfo.java | 3 ++- .../java/com/google/cloud/compute/InstanceInfo.java | 4 +++- .../main/java/com/google/cloud/compute/License.java | 5 ++++- .../java/com/google/cloud/compute/MachineType.java | 5 ++++- .../main/java/com/google/cloud/compute/Operation.java | 11 ++++++++--- .../main/java/com/google/cloud/compute/Region.java | 5 ++++- .../main/java/com/google/cloud/compute/Snapshot.java | 11 ++++++++--- .../cloud/compute/SnapshotDiskConfiguration.java | 5 ++++- .../java/com/google/cloud/compute/SnapshotInfo.java | 3 ++- .../cloud/compute/StandardDiskConfiguration.java | 5 ++++- .../cloud/compute/StorageImageConfiguration.java | 5 ++++- .../src/main/java/com/google/cloud/compute/Zone.java | 5 ++++- .../com/google/cloud/compute/ZoneOperationId.java | 11 ++++++++--- 25 files changed, 106 insertions(+), 37 deletions(-) diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/Address.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Address.java index 65abad09eac3..10e99cadb60f 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/Address.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Address.java @@ -165,9 +165,14 @@ public Builder toBuilder() { @Override public final boolean equals(Object obj) { - return obj instanceof Address - && Objects.equals(toPb(), ((Address) obj).toPb()) - && Objects.equals(options, ((Address) obj).options); + if (obj == this) { + return true; + } + if (obj == null || !obj.getClass().equals(Address.class)) { + return false; + } + Address other = (Address) obj; + return Objects.equals(toPb(), other.toPb()) && Objects.equals(options, other.options); } @Override diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/AddressInfo.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/AddressInfo.java index 3848e21fbcbc..9a95c77119c8 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/AddressInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/AddressInfo.java @@ -496,7 +496,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj != null + return obj == this + || obj != null && obj.getClass().equals(AddressInfo.class) && Objects.equals(toPb(), ((AddressInfo) obj).toPb()); } diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/DeprecationStatus.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/DeprecationStatus.java index eb21d6e512f7..bdf7fa0a57b4 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/DeprecationStatus.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/DeprecationStatus.java @@ -304,7 +304,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof DeprecationStatus + return obj == this + || obj instanceof DeprecationStatus && Objects.equals(toPb(), ((DeprecationStatus) obj).toPb()); } diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/Disk.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Disk.java index 39e133110ebf..f1c6cd26291c 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/Disk.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Disk.java @@ -235,9 +235,14 @@ public Builder toBuilder() { @Override public final boolean equals(Object obj) { - return obj instanceof Disk - && Objects.equals(toPb(), ((Disk) obj).toPb()) - && Objects.equals(options, ((Disk) obj).options); + if (obj == this) { + return true; + } + if (obj == null || !obj.getClass().equals(Disk.class)) { + return false; + } + Disk other = (Disk) obj; + return Objects.equals(toPb(), other.toPb()) && Objects.equals(options, other.options); } @Override diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskImageConfiguration.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskImageConfiguration.java index d43f1a50c276..a31c8199ec07 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskImageConfiguration.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskImageConfiguration.java @@ -122,7 +122,10 @@ public final int hashCode() { @Override public final boolean equals(Object obj) { - return obj instanceof DiskImageConfiguration && baseEquals((DiskImageConfiguration) obj); + return obj == this + || obj != null + && obj.getClass().equals(DiskImageConfiguration.class) + && baseEquals((DiskImageConfiguration) obj); } @Override diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskInfo.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskInfo.java index 9c2e83005886..aab6d90ff345 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskInfo.java @@ -374,7 +374,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj != null + return obj == this + || obj != null && obj.getClass().equals(DiskInfo.class) && Objects.equals(toPb(), ((DiskInfo) obj).toPb()); } diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskType.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskType.java index 7a836dc0316f..cbe6f625e764 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskType.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/DiskType.java @@ -192,7 +192,10 @@ public final int hashCode() { @Override public final boolean equals(Object obj) { - return obj instanceof DiskType && Objects.equals(toPb(), ((DiskType) obj).toPb()); + return obj == this + || obj != null + && obj.getClass().equals(DiskType.class) + && Objects.equals(toPb(), ((DiskType) obj).toPb()); } com.google.api.services.compute.model.DiskType toPb() { diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/GlobalAddressId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/GlobalAddressId.java index 7954cd37826f..45232edeff48 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/GlobalAddressId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/GlobalAddressId.java @@ -49,7 +49,7 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof GlobalAddressId && baseEquals((GlobalAddressId) obj); + return obj == this || obj instanceof GlobalAddressId && baseEquals((GlobalAddressId) obj); } @Override diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/GlobalForwardingRuleId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/GlobalForwardingRuleId.java index 85094f8e584d..b9acfa989b85 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/GlobalForwardingRuleId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/GlobalForwardingRuleId.java @@ -66,7 +66,9 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof GlobalForwardingRuleId && baseEquals((GlobalForwardingRuleId) obj); + return obj == this + || obj instanceof GlobalForwardingRuleId + && baseEquals((GlobalForwardingRuleId) obj); } @Override diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/GlobalOperationId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/GlobalOperationId.java index 082add14109a..ee3e4fc2d40e 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/GlobalOperationId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/GlobalOperationId.java @@ -49,7 +49,7 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof GlobalOperationId && baseEquals((GlobalOperationId) obj); + return obj == this || obj instanceof GlobalOperationId && baseEquals((GlobalOperationId) obj); } @Override diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/Image.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Image.java index 510c21b40435..e457ee71da13 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/Image.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Image.java @@ -188,9 +188,14 @@ public Builder toBuilder() { @Override public final boolean equals(Object obj) { - return obj instanceof Image - && Objects.equals(toPb(), ((Image) obj).toPb()) - && Objects.equals(options, ((Image) obj).options); + if (obj == this) { + return true; + } + if (obj == null || !obj.getClass().equals(Image.class)) { + return false; + } + Image other = (Image) obj; + return Objects.equals(toPb(), other.toPb()) && Objects.equals(options, other.options); } @Override diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/ImageDiskConfiguration.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ImageDiskConfiguration.java index 20914f7611ae..cf8ede2f061a 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/ImageDiskConfiguration.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ImageDiskConfiguration.java @@ -137,7 +137,10 @@ public final int hashCode() { @Override public final boolean equals(Object obj) { - return obj instanceof ImageDiskConfiguration && baseEquals((ImageDiskConfiguration) obj); + return obj == this + || obj != null + && obj.getClass().equals(ImageDiskConfiguration.class) + && baseEquals((ImageDiskConfiguration) obj); } @Override diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/ImageInfo.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ImageInfo.java index a3e9a6db9530..102e2c742d71 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/ImageInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ImageInfo.java @@ -354,7 +354,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj != null + return obj == this + || obj != null && obj.getClass().equals(ImageInfo.class) && Objects.equals(toPb(), ((ImageInfo) obj).toPb()); } diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/InstanceInfo.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/InstanceInfo.java index 5f794481b4d0..7f85985afd2d 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/InstanceInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/InstanceInfo.java @@ -578,7 +578,9 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof InstanceInfo + return obj == this + || obj != null + && obj.getClass().equals(InstanceInfo.class) && Objects.equals(toPb(), ((InstanceInfo) obj).toPb()); } diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/License.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/License.java index b65937bf5685..dc0e49bace31 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/License.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/License.java @@ -71,7 +71,10 @@ public final int hashCode() { @Override public final boolean equals(Object obj) { - return obj instanceof License && Objects.equals(toPb(), ((License) obj).toPb()); + return obj == this + || obj != null + && obj.getClass().equals(License.class) + && Objects.equals(toPb(), ((License) obj).toPb()); } com.google.api.services.compute.model.License toPb() { diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/MachineType.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/MachineType.java index d1f989ae7e9b..c850b351c946 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/MachineType.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/MachineType.java @@ -248,7 +248,10 @@ public final int hashCode() { @Override public final boolean equals(Object obj) { - return obj instanceof MachineType && Objects.equals(toPb(), ((MachineType) obj).toPb()); + return obj == this + || obj != null + && obj.getClass().equals(MachineType.class) + && Objects.equals(toPb(), ((MachineType) obj).toPb()); } com.google.api.services.compute.model.MachineType toPb() { diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/Operation.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Operation.java index 59ccafc8e30a..326b681098a6 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/Operation.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Operation.java @@ -712,9 +712,14 @@ public final int hashCode() { @Override public final boolean equals(Object obj) { - return obj instanceof Operation - && Objects.equals(toPb(), ((Operation) obj).toPb()) - && Objects.equals(options, ((Operation) obj).options); + if (obj == this) { + return true; + } + if (obj == null || !obj.getClass().equals(Operation.class)) { + return false; + } + Operation other = (Operation) obj; + return Objects.equals(toPb(), other.toPb()) && Objects.equals(options, other.options); } com.google.api.services.compute.model.Operation toPb() { diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/Region.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Region.java index d6c25ad16aab..85845283010c 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/Region.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Region.java @@ -312,7 +312,10 @@ public final int hashCode() { @Override public final boolean equals(Object obj) { - return obj instanceof Region && Objects.equals(toPb(), ((Region) obj).toPb()); + return obj == this + || obj != null + && obj.getClass().equals(Region.class) + && Objects.equals(toPb(), ((Region) obj).toPb()); } com.google.api.services.compute.model.Region toPb() { diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/Snapshot.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Snapshot.java index f09f1da07d31..fee0e2fcfac5 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/Snapshot.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Snapshot.java @@ -189,9 +189,14 @@ public Builder toBuilder() { @Override public final boolean equals(Object obj) { - return obj instanceof Snapshot - && Objects.equals(toPb(), ((Snapshot) obj).toPb()) - && Objects.equals(options, ((Snapshot) obj).options); + if (obj == this) { + return true; + } + if (obj == null || !obj.getClass().equals(Snapshot.class)) { + return false; + } + Snapshot other = (Snapshot) obj; + return Objects.equals(toPb(), other.toPb()) && Objects.equals(options, other.options); } @Override diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/SnapshotDiskConfiguration.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/SnapshotDiskConfiguration.java index 8f900f2b4c0b..15909b6092d1 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/SnapshotDiskConfiguration.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/SnapshotDiskConfiguration.java @@ -141,7 +141,10 @@ public final int hashCode() { @Override public final boolean equals(Object obj) { - return obj instanceof SnapshotDiskConfiguration && baseEquals((SnapshotDiskConfiguration) obj); + return obj == this + || obj != null + && obj.getClass().equals(SnapshotDiskConfiguration.class) + && baseEquals((SnapshotDiskConfiguration) obj); } @Override diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/SnapshotInfo.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/SnapshotInfo.java index dc67893261b3..ce9ebbc7825c 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/SnapshotInfo.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/SnapshotInfo.java @@ -421,7 +421,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj != null + return obj == this + || obj != null && obj.getClass().equals(SnapshotInfo.class) && Objects.equals(toPb(), ((SnapshotInfo) obj).toPb()); } diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/StandardDiskConfiguration.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/StandardDiskConfiguration.java index ecf819ea288a..90cf9fb7c40b 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/StandardDiskConfiguration.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/StandardDiskConfiguration.java @@ -82,7 +82,10 @@ public final int hashCode() { @Override public final boolean equals(Object obj) { - return obj instanceof StandardDiskConfiguration && baseEquals((StandardDiskConfiguration) obj); + return obj == this + || obj != null + && obj.getClass().equals(StandardDiskConfiguration.class) + && baseEquals((StandardDiskConfiguration) obj); } @Override diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/StorageImageConfiguration.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/StorageImageConfiguration.java index 6da6d1e37e96..f90e9fa4e13a 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/StorageImageConfiguration.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/StorageImageConfiguration.java @@ -158,7 +158,10 @@ public final int hashCode() { @Override public final boolean equals(Object obj) { - return obj instanceof StorageImageConfiguration && baseEquals((StorageImageConfiguration) obj); + return obj == this + || obj != null + && obj.getClass().equals(StorageImageConfiguration.class) + && Objects.equals(toPb(), ((StorageImageConfiguration) obj).toPb()); } @Override diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/Zone.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Zone.java index d04e527a8ae8..1534506c55a3 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/Zone.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Zone.java @@ -201,7 +201,10 @@ public final int hashCode() { @Override public final boolean equals(Object obj) { - return obj instanceof Zone && Objects.equals(toPb(), ((Zone) obj).toPb()); + return obj == this + || obj != null + && obj.getClass().equals(Zone.class) + && Objects.equals(toPb(), ((Zone) obj).toPb()); } com.google.api.services.compute.model.Zone toPb() { diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/ZoneOperationId.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ZoneOperationId.java index 4868fa4bd3f6..1403773d2d99 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/ZoneOperationId.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ZoneOperationId.java @@ -76,9 +76,14 @@ public int hashCode() { @Override public boolean equals(Object obj) { - return obj instanceof ZoneOperationId - && baseEquals((ZoneOperationId) obj) - && Objects.equals(zone, ((ZoneOperationId) obj).zone); + if (obj == this) { + return true; + } + if (!(obj instanceof ZoneOperationId)) { + return false; + } + ZoneOperationId other = (ZoneOperationId) obj; + return baseEquals(other) && Objects.equals(zone, other.zone); } @Override From 8e38d5be7b5b1af248265fd5f1b1ed1c3547d8d3 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 29 Apr 2016 22:40:21 +0200 Subject: [PATCH 332/375] Release 0.2.1 --- gcloud-java-bigquery/pom.xml | 2 +- gcloud-java-compute/pom.xml | 2 +- gcloud-java-contrib/pom.xml | 2 +- gcloud-java-core/pom.xml | 2 +- gcloud-java-datastore/pom.xml | 2 +- gcloud-java-dns/pom.xml | 2 +- gcloud-java-examples/pom.xml | 2 +- gcloud-java-resourcemanager/pom.xml | 2 +- gcloud-java-storage/pom.xml | 2 +- gcloud-java/pom.xml | 2 +- pom.xml | 6 +++--- 11 files changed, 13 insertions(+), 13 deletions(-) diff --git a/gcloud-java-bigquery/pom.xml b/gcloud-java-bigquery/pom.xml index 4ad6a43b6be3..23fcae306b69 100644 --- a/gcloud-java-bigquery/pom.xml +++ b/gcloud-java-bigquery/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.1-SNAPSHOT + 0.2.1 gcloud-java-bigquery diff --git a/gcloud-java-compute/pom.xml b/gcloud-java-compute/pom.xml index 40a09b008076..5f34ecebdc35 100644 --- a/gcloud-java-compute/pom.xml +++ b/gcloud-java-compute/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.1-SNAPSHOT + 0.2.1 gcloud-java-compute diff --git a/gcloud-java-contrib/pom.xml b/gcloud-java-contrib/pom.xml index 1220c7c3776e..81bab5026648 100644 --- a/gcloud-java-contrib/pom.xml +++ b/gcloud-java-contrib/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.1-SNAPSHOT + 0.2.1 gcloud-java-contrib diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml index 22648d2e6ffa..c2ffc35d2f39 100644 --- a/gcloud-java-core/pom.xml +++ b/gcloud-java-core/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.1-SNAPSHOT + 0.2.1 gcloud-java-core diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index 2e76072b2881..0d1ba58a7ee8 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.1-SNAPSHOT + 0.2.1 gcloud-java-datastore diff --git a/gcloud-java-dns/pom.xml b/gcloud-java-dns/pom.xml index 8acd6abee783..8f330bde5ef2 100644 --- a/gcloud-java-dns/pom.xml +++ b/gcloud-java-dns/pom.xml @@ -13,7 +13,7 @@ com.google.cloud gcloud-java-pom - 0.2.1-SNAPSHOT + 0.2.1 gcloud-java-dns diff --git a/gcloud-java-examples/pom.xml b/gcloud-java-examples/pom.xml index 15b4e456494b..8d69744eae42 100644 --- a/gcloud-java-examples/pom.xml +++ b/gcloud-java-examples/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.1-SNAPSHOT + 0.2.1 gcloud-java-examples diff --git a/gcloud-java-resourcemanager/pom.xml b/gcloud-java-resourcemanager/pom.xml index 272c931326d6..19a1968a14e3 100644 --- a/gcloud-java-resourcemanager/pom.xml +++ b/gcloud-java-resourcemanager/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.1-SNAPSHOT + 0.2.1 gcloud-java-resourcemanager diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml index 1106c7479be7..3e48744a8e9f 100644 --- a/gcloud-java-storage/pom.xml +++ b/gcloud-java-storage/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.1-SNAPSHOT + 0.2.1 gcloud-java-storage diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml index e26dfa63ab01..af8a5d0e207c 100644 --- a/gcloud-java/pom.xml +++ b/gcloud-java/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.1-SNAPSHOT + 0.2.1 diff --git a/pom.xml b/pom.xml index 87de4a252021..ee40b1fa265a 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud gcloud-java-pom pom - 0.2.1-SNAPSHOT + 0.2.1 GCloud Java https://github.com/GoogleCloudPlatform/gcloud-java @@ -379,7 +379,7 @@ Test helpers packages - com.google.cloud.bigquery.testing:com.google.cloud.datastore.testing:com.google.cloud.dns.testing:com.google.cloud.resourcemanager.testing:com.google.cloud.storage.testing + com.google.cloud.bigquery.testing:com.google.cloud.compute.testing:com.google.cloud.datastore.testing:com.google.cloud.dns.testing:com.google.cloud.resourcemanager.testing:com.google.cloud.storage.testing Example packages @@ -387,7 +387,7 @@ SPI packages - com.google.cloud.spi:com.google.cloud.bigquery.spi:com.google.cloud.datastore.spi:com.google.cloud.dns.spi:com.google.cloud.resourcemanager.spi:com.google.cloud.storage.spi + com.google.cloud.spi:com.google.cloud.bigquery.spi:com.google.cloud.compute.spi:com.google.cloud.datastore.spi:com.google.cloud.dns.spi:com.google.cloud.resourcemanager.spi:com.google.cloud.storage.spi From 3c8da93b223e8522bb892aeaab86790176195303 Mon Sep 17 00:00:00 2001 From: travis-ci Date: Fri, 29 Apr 2016 21:26:09 +0000 Subject: [PATCH 333/375] Updating version in README files. [ci skip] --- README.md | 6 +++--- gcloud-java-bigquery/README.md | 6 +++--- gcloud-java-compute/README.md | 6 +++--- gcloud-java-contrib/README.md | 6 +++--- gcloud-java-core/README.md | 6 +++--- gcloud-java-datastore/README.md | 6 +++--- gcloud-java-dns/README.md | 6 +++--- gcloud-java-examples/README.md | 6 +++--- gcloud-java-resourcemanager/README.md | 6 +++--- gcloud-java-storage/README.md | 6 +++--- gcloud-java/README.md | 6 +++--- 11 files changed, 33 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 0768939df6b3..5abe1c50a3db 100644 --- a/README.md +++ b/README.md @@ -34,16 +34,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java - 0.2.0 + 0.2.1 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java:0.2.0' +compile 'com.google.cloud:gcloud-java:0.2.1' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java" % "0.2.0" +libraryDependencies += "com.google.cloud" % "gcloud-java" % "0.2.1" ``` Example Applications diff --git a/gcloud-java-bigquery/README.md b/gcloud-java-bigquery/README.md index 92fda2bad050..ba6d041a7aba 100644 --- a/gcloud-java-bigquery/README.md +++ b/gcloud-java-bigquery/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-bigquery - 0.2.0 + 0.2.1 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-bigquery:0.2.0' +compile 'com.google.cloud:gcloud-java-bigquery:0.2.1' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-bigquery" % "0.2.0" +libraryDependencies += "com.google.cloud" % "gcloud-java-bigquery" % "0.2.1" ``` Example Application diff --git a/gcloud-java-compute/README.md b/gcloud-java-compute/README.md index 7bd7c83ee523..db5461c9a47c 100644 --- a/gcloud-java-compute/README.md +++ b/gcloud-java-compute/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-compute - 0.2.0 + 0.2.1 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-compute:0.2.0' +compile 'com.google.cloud:gcloud-java-compute:0.2.1' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-compute" % "0.2.0" +libraryDependencies += "com.google.cloud" % "gcloud-java-compute" % "0.2.1" ``` Example Application diff --git a/gcloud-java-contrib/README.md b/gcloud-java-contrib/README.md index 547040449034..de1cad8bfdd5 100644 --- a/gcloud-java-contrib/README.md +++ b/gcloud-java-contrib/README.md @@ -16,16 +16,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-contrib - 0.2.0 + 0.2.1 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-contrib:0.2.0' +compile 'com.google.cloud:gcloud-java-contrib:0.2.1' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-contrib" % "0.2.0" +libraryDependencies += "com.google.cloud" % "gcloud-java-contrib" % "0.2.1" ``` Java Versions diff --git a/gcloud-java-core/README.md b/gcloud-java-core/README.md index 9a659c0f8cc0..ac137785f483 100644 --- a/gcloud-java-core/README.md +++ b/gcloud-java-core/README.md @@ -19,16 +19,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-core - 0.2.0 + 0.2.1 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-core:0.2.0' +compile 'com.google.cloud:gcloud-java-core:0.2.1' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-core" % "0.2.0" +libraryDependencies += "com.google.cloud" % "gcloud-java-core" % "0.2.1" ``` Troubleshooting diff --git a/gcloud-java-datastore/README.md b/gcloud-java-datastore/README.md index 86b77c6bf49a..00007645032e 100644 --- a/gcloud-java-datastore/README.md +++ b/gcloud-java-datastore/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-datastore - 0.2.0 + 0.2.1 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-datastore:0.2.0' +compile 'com.google.cloud:gcloud-java-datastore:0.2.1' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-datastore" % "0.2.0" +libraryDependencies += "com.google.cloud" % "gcloud-java-datastore" % "0.2.1" ``` Example Application diff --git a/gcloud-java-dns/README.md b/gcloud-java-dns/README.md index 994ab5615598..6e9cb0d25f1a 100644 --- a/gcloud-java-dns/README.md +++ b/gcloud-java-dns/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-dns - 0.2.0 + 0.2.1 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-dns:0.2.0' +compile 'com.google.cloud:gcloud-java-dns:0.2.1' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-dns" % "0.2.0" +libraryDependencies += "com.google.cloud" % "gcloud-java-dns" % "0.2.1" ``` Example Application diff --git a/gcloud-java-examples/README.md b/gcloud-java-examples/README.md index f8bbde47b701..98af1df5f3f2 100644 --- a/gcloud-java-examples/README.md +++ b/gcloud-java-examples/README.md @@ -19,16 +19,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-examples - 0.2.0 + 0.2.1 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-examples:0.2.0' +compile 'com.google.cloud:gcloud-java-examples:0.2.1' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-examples" % "0.2.0" +libraryDependencies += "com.google.cloud" % "gcloud-java-examples" % "0.2.1" ``` To run examples from your command line: diff --git a/gcloud-java-resourcemanager/README.md b/gcloud-java-resourcemanager/README.md index 906ef82710d7..a3ad3b30158a 100644 --- a/gcloud-java-resourcemanager/README.md +++ b/gcloud-java-resourcemanager/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-resourcemanager - 0.2.0 + 0.2.1 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-resourcemanager:0.2.0' +compile 'com.google.cloud:gcloud-java-resourcemanager:0.2.1' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-resourcemanager" % "0.2.0" +libraryDependencies += "com.google.cloud" % "gcloud-java-resourcemanager" % "0.2.1" ``` Example Application diff --git a/gcloud-java-storage/README.md b/gcloud-java-storage/README.md index bcf7c7068774..4b62c2407664 100644 --- a/gcloud-java-storage/README.md +++ b/gcloud-java-storage/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-storage - 0.2.0 + 0.2.1 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-storage:0.2.0' +compile 'com.google.cloud:gcloud-java-storage:0.2.1' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-storage" % "0.2.0" +libraryDependencies += "com.google.cloud" % "gcloud-java-storage" % "0.2.1" ``` Example Application diff --git a/gcloud-java/README.md b/gcloud-java/README.md index a01f794be966..7b4d85efb78e 100644 --- a/gcloud-java/README.md +++ b/gcloud-java/README.md @@ -27,16 +27,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java - 0.2.0 + 0.2.1 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java:0.2.0' +compile 'com.google.cloud:gcloud-java:0.2.1' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java" % "0.2.0" +libraryDependencies += "com.google.cloud" % "gcloud-java" % "0.2.1" ``` Troubleshooting From ddee42f691192507b61b947ae3736c3fff6e6de2 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Sat, 30 Apr 2016 00:16:13 +0200 Subject: [PATCH 334/375] update version to 0.2.2-SNAPSHOT --- gcloud-java-bigquery/pom.xml | 2 +- gcloud-java-compute/pom.xml | 2 +- gcloud-java-contrib/pom.xml | 2 +- gcloud-java-core/pom.xml | 2 +- gcloud-java-datastore/pom.xml | 2 +- gcloud-java-dns/pom.xml | 2 +- gcloud-java-examples/pom.xml | 2 +- gcloud-java-resourcemanager/pom.xml | 2 +- gcloud-java-storage/pom.xml | 2 +- gcloud-java/pom.xml | 2 +- pom.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/gcloud-java-bigquery/pom.xml b/gcloud-java-bigquery/pom.xml index 23fcae306b69..e5db6a5f189e 100644 --- a/gcloud-java-bigquery/pom.xml +++ b/gcloud-java-bigquery/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.1 + 0.2.2-SNAPSHOT gcloud-java-bigquery diff --git a/gcloud-java-compute/pom.xml b/gcloud-java-compute/pom.xml index 5f34ecebdc35..df53a9a713c6 100644 --- a/gcloud-java-compute/pom.xml +++ b/gcloud-java-compute/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.1 + 0.2.2-SNAPSHOT gcloud-java-compute diff --git a/gcloud-java-contrib/pom.xml b/gcloud-java-contrib/pom.xml index 81bab5026648..0ee4f2158287 100644 --- a/gcloud-java-contrib/pom.xml +++ b/gcloud-java-contrib/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.1 + 0.2.2-SNAPSHOT gcloud-java-contrib diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml index c2ffc35d2f39..e7b1242f0f9c 100644 --- a/gcloud-java-core/pom.xml +++ b/gcloud-java-core/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.1 + 0.2.2-SNAPSHOT gcloud-java-core diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index 0d1ba58a7ee8..4d0e394532ce 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.1 + 0.2.2-SNAPSHOT gcloud-java-datastore diff --git a/gcloud-java-dns/pom.xml b/gcloud-java-dns/pom.xml index 8f330bde5ef2..244989231278 100644 --- a/gcloud-java-dns/pom.xml +++ b/gcloud-java-dns/pom.xml @@ -13,7 +13,7 @@ com.google.cloud gcloud-java-pom - 0.2.1 + 0.2.2-SNAPSHOT gcloud-java-dns diff --git a/gcloud-java-examples/pom.xml b/gcloud-java-examples/pom.xml index 8d69744eae42..ae4e30050fa6 100644 --- a/gcloud-java-examples/pom.xml +++ b/gcloud-java-examples/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.1 + 0.2.2-SNAPSHOT gcloud-java-examples diff --git a/gcloud-java-resourcemanager/pom.xml b/gcloud-java-resourcemanager/pom.xml index 19a1968a14e3..fb04cf13299f 100644 --- a/gcloud-java-resourcemanager/pom.xml +++ b/gcloud-java-resourcemanager/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.1 + 0.2.2-SNAPSHOT gcloud-java-resourcemanager diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml index 3e48744a8e9f..2f5c42ee2a6a 100644 --- a/gcloud-java-storage/pom.xml +++ b/gcloud-java-storage/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.1 + 0.2.2-SNAPSHOT gcloud-java-storage diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml index af8a5d0e207c..2df6728d40d8 100644 --- a/gcloud-java/pom.xml +++ b/gcloud-java/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.1 + 0.2.2-SNAPSHOT diff --git a/pom.xml b/pom.xml index ee40b1fa265a..85b5f0b02ae1 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud gcloud-java-pom pom - 0.2.1 + 0.2.2-SNAPSHOT GCloud Java https://github.com/GoogleCloudPlatform/gcloud-java From 881a078973929c102eaf70a598443a2ef5ad9f59 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 3 May 2016 11:03:12 +0200 Subject: [PATCH 335/375] Add javadoc and unit tests for TopicInfo (#976) --- .../com/google/cloud/pubsub/PubSubImpl.java | 11 +++- .../java/com/google/cloud/pubsub/Topic.java | 2 +- .../com/google/cloud/pubsub/TopicInfo.java | 53 +++++++++++++--- .../google/cloud/pubsub/TopicInfoTest.java | 62 +++++++++++++++++++ 4 files changed, 117 insertions(+), 11 deletions(-) create mode 100644 gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/TopicInfoTest.java diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java index bc9e428b6ab1..df6aa283c1a3 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java @@ -22,6 +22,7 @@ import com.google.cloud.BaseService; import com.google.cloud.Page; import com.google.cloud.pubsub.spi.PubSubRpc; +import com.google.cloud.pubsub.spi.v1.PublisherApi; import com.google.common.base.Function; import com.google.common.base.Throwables; import com.google.common.util.concurrent.Uninterruptibles; @@ -59,7 +60,7 @@ public Topic create(TopicInfo topic) { @Override public Future createAsync(TopicInfo topic) { - return lazyTransform(rpc.create(topic.toPb()), Topic.fromPbFunction(this)); + return lazyTransform(rpc.create(topic.toPb(options().projectId())), Topic.fromPbFunction(this)); } @Override @@ -69,7 +70,9 @@ public Topic getTopic(String topic) { @Override public Future getTopicAsync(String topic) { - GetTopicRequest request = GetTopicRequest.newBuilder().setTopic(topic).build(); + GetTopicRequest request = GetTopicRequest.newBuilder() + .setTopic(PublisherApi.formatTopicName(options().projectId(), topic)) + .build(); return lazyTransform(rpc.get(request), Topic.fromPbFunction(this)); } @@ -80,7 +83,9 @@ public boolean deleteTopic(String topic) { @Override public Future deleteTopicAsync(String topic) { - DeleteTopicRequest request = DeleteTopicRequest.newBuilder().setTopic(topic).build(); + DeleteTopicRequest request = DeleteTopicRequest.newBuilder() + .setTopic(PublisherApi.formatTopicName(options().projectId(), topic)) + .build(); return lazyTransform(rpc.delete(request), new Function() { @Override public Boolean apply(Empty input) { diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Topic.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Topic.java index 77dd31fcd876..f2203d3a30d9 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Topic.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Topic.java @@ -86,7 +86,7 @@ public boolean equals(Object obj) { return false; } Topic other = (Topic) obj; - return Objects.equals(toPb(), other.toPb()) && Objects.equals(options, other.options); + return Objects.equals(name(), other.name()) && Objects.equals(options, other.options); } public PubSub pubSub() { diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicInfo.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicInfo.java index 37f4ae289b6f..d69cb92f3244 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicInfo.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicInfo.java @@ -18,13 +18,17 @@ import static com.google.common.base.Preconditions.checkNotNull; +import com.google.cloud.pubsub.spi.v1.PublisherApi; import com.google.common.base.MoreObjects; import java.io.Serializable; import java.util.Objects; /** - * Pub/Sub Topic information. + * A Google Cloud Pub/Sub topic. A topic is a named resource to which messages are sent by + * publishers. Subscribers can receive messages sent to a topic by creating subscriptions. + * + * @see Pub/Sub Data Model */ public class TopicInfo implements Serializable { @@ -33,12 +37,21 @@ public class TopicInfo implements Serializable { private final String name; /** - * Builder for TopicInfo. + * Builder for {@code TopicInfo} objects. */ public abstract static class Builder { + /** + * Sets the name of the topic. The name must start with a letter, and contain only letters + * ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores ({@code _}), + * periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs ({@code %}). It + * must be between 3 and 255 characters in length and cannot begin with the string {@code goog}. + */ public abstract Builder name(String name); + /** + * Creates a topic object. + */ public abstract TopicInfo build(); } @@ -70,6 +83,12 @@ public TopicInfo build() { name = builder.name; } + /** + * Returns the name of the topic. The name must start with a letter, and contain only letters + * ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores ({@code _}), + * periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs ({@code %}). It + * must be between 3 and 255 characters in length and cannot begin with the string {@code goog}. + */ public String name() { return name; } @@ -84,10 +103,10 @@ public boolean equals(Object obj) { if (this == obj) { return true; } - if (obj == null || getClass() != obj.getClass()) { + if (obj == null || !obj.getClass().equals(this.getClass())) { return false; } - return Objects.equals(toPb(), ((TopicInfo) obj).toPb()); + return Objects.equals(name, ((TopicInfo) obj).name); } @Override @@ -97,22 +116,42 @@ public String toString() { .toString(); } - com.google.pubsub.v1.Topic toPb() { - return com.google.pubsub.v1.Topic.newBuilder().setName(name).build(); + com.google.pubsub.v1.Topic toPb(String projectId) { + return com.google.pubsub.v1.Topic.newBuilder() + .setName(PublisherApi.formatTopicName(projectId, name)) + .build(); } static TopicInfo fromPb(com.google.pubsub.v1.Topic topicPb) { - return builder(topicPb.getName()).build(); + return builder(PublisherApi.parseTopicFromTopicName(topicPb.getName())).build(); } public Builder toBuilder() { return new BuilderImpl(this); } + /** + * Creates a {@code TopicInfo} object given the name of the topic. + * + * @param name the name of the topic. The name must start with a letter, and contain only letters + * ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores ({@code _}), + * periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs ({@code %}). + * It must be between 3 and 255 characters in length and cannot begin with the string + * {@code goog}. + */ public static TopicInfo of(String name) { return builder(name).build(); } + /** + * Creates a builder for {@code TopicInfo} objects given the name of the topic. + * + * @param name the name of the topic. The name must start with a letter, and contain only letters + * ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores ({@code _}), + * periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs ({@code %}). + * It must be between 3 and 255 characters in length and cannot begin with the string + * {@code goog}. + */ public static Builder builder(String name) { return new BuilderImpl(name); } diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/TopicInfoTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/TopicInfoTest.java new file mode 100644 index 000000000000..29970833cdef --- /dev/null +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/TopicInfoTest.java @@ -0,0 +1,62 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class TopicInfoTest { + + private static final String NAME = "topic"; + private static final TopicInfo TOPIC_INFO = TopicInfo.builder("topic").build(); + + @Test + public void testToBuilder() { + compareTopicInfo(TOPIC_INFO, TOPIC_INFO.toBuilder().build()); + TopicInfo topicInfo = TOPIC_INFO.toBuilder() + .name("newTopic") + .build(); + assertEquals("newTopic", topicInfo.name()); + topicInfo = topicInfo.toBuilder().name(NAME).build(); + compareTopicInfo(TOPIC_INFO, topicInfo); + } + + @Test + public void testBuilder() { + assertEquals(NAME, TOPIC_INFO.name()); + TopicInfo topicInfo = TopicInfo.builder("wrongName").name(NAME).build(); + compareTopicInfo(TOPIC_INFO, topicInfo); + } + + @Test + public void testOf() { + compareTopicInfo(TOPIC_INFO, TopicInfo.of(NAME)); + } + + @Test + public void testToAndFromPb() { + compareTopicInfo(TOPIC_INFO, TopicInfo.fromPb(TOPIC_INFO.toPb("project"))); + assertEquals("projects/project/topics/topic", TOPIC_INFO.toPb("project").getName()); + } + + private void compareTopicInfo(TopicInfo expected, TopicInfo value) { + assertEquals(expected, value); + assertEquals(expected.name(), value.name()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} From 97e4db2e83f4eef7a68a601a8d4b2a72abe48d13 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 4 May 2016 09:34:56 +0200 Subject: [PATCH 336/375] Add AsyncPage implementation and docs. Add related tests (#974) --- .../main/java/com/google/cloud/AsyncPage.java | 28 ++++ .../java/com/google/cloud/AsyncPageImpl.java | 82 +++++++++++ .../com/google/cloud/AsyncPageImplTest.java | 128 ++++++++++++++++++ .../java/com/google/cloud/PageImplTest.java | 2 + 4 files changed, 240 insertions(+) create mode 100644 gcloud-java-core/src/main/java/com/google/cloud/AsyncPageImpl.java create mode 100644 gcloud-java-core/src/test/java/com/google/cloud/AsyncPageImplTest.java diff --git a/gcloud-java-core/src/main/java/com/google/cloud/AsyncPage.java b/gcloud-java-core/src/main/java/com/google/cloud/AsyncPage.java index ea2905795e62..d82d46f19b2d 100644 --- a/gcloud-java-core/src/main/java/com/google/cloud/AsyncPage.java +++ b/gcloud-java-core/src/main/java/com/google/cloud/AsyncPage.java @@ -18,6 +18,34 @@ import java.util.concurrent.Future; +/** + * Interface for asynchronously consuming Google Cloud paginated results. + * + *

    Use {@code AsyncPage} to iterate through all values (also in next pages): + *

     {@code
    + * AsyncPage page = ...; // get an AsyncPage instance
    + * Iterator iterator = page.iterateAll();
    + * while (iterator.hasNext()) {
    + *   T value = iterator.next();
    + *   // do something with value
    + * }}
    + * + *

    Or handle pagination explicitly: + *

     {@code
    + * AsyncPage page = ...; // get a AsyncPage instance
    + * while (page != null) {
    + *   for (T value : page.values()) {
    + *     // do something with value
    + *   }
    + *   page = page.nextPage().get();
    + * }}
    + * + * @param the value type that the page holds + */ public interface AsyncPage extends Page { + + /** + * Returns a {@link Future} object for the next page. + */ Future> nextPageAsync(); } diff --git a/gcloud-java-core/src/main/java/com/google/cloud/AsyncPageImpl.java b/gcloud-java-core/src/main/java/com/google/cloud/AsyncPageImpl.java new file mode 100644 index 000000000000..42af7b34a943 --- /dev/null +++ b/gcloud-java-core/src/main/java/com/google/cloud/AsyncPageImpl.java @@ -0,0 +1,82 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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; + +import com.google.common.base.Throwables; +import com.google.common.util.concurrent.Uninterruptibles; + +import java.io.Serializable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +/** + * Base implementation for asynchronously consuming Google Cloud paginated results. + * + * @param the value type that the page holds + */ +public class AsyncPageImpl extends PageImpl implements AsyncPage { + + private static final long serialVersionUID = -6009473188630364906L; + + private final NextPageFetcher asyncPageFetcher; + + /** + * Interface for asynchronously fetching the next page of results from the service. + * + * @param the value type that the page holds + */ + public interface NextPageFetcher extends Serializable { + Future> nextPage(); + } + + private static class SyncNextPageFetcher implements PageImpl.NextPageFetcher { + + private static final long serialVersionUID = -4124568632363525351L; + + private NextPageFetcher asyncPageFetcher; + + private SyncNextPageFetcher(NextPageFetcher asyncPageFetcher) { + this.asyncPageFetcher = asyncPageFetcher; + } + + @Override + public Page nextPage() { + try { + return asyncPageFetcher != null + ? Uninterruptibles.getUninterruptibly(asyncPageFetcher.nextPage()) : null; + } catch (ExecutionException ex) { + throw Throwables.propagate(ex.getCause()); + } + } + } + + /** + * Creates an {@code AsyncPageImpl} object. + */ + public AsyncPageImpl(NextPageFetcher asyncPageFetcher, String cursor, Iterable results) { + super(new SyncNextPageFetcher(asyncPageFetcher), cursor, results); + this.asyncPageFetcher = asyncPageFetcher; + } + + @Override + public Future> nextPageAsync() { + if (nextPageCursor() == null || asyncPageFetcher == null) { + return null; + } + return asyncPageFetcher.nextPage(); + } +} diff --git a/gcloud-java-core/src/test/java/com/google/cloud/AsyncPageImplTest.java b/gcloud-java-core/src/test/java/com/google/cloud/AsyncPageImplTest.java new file mode 100644 index 000000000000..60189a055467 --- /dev/null +++ b/gcloud-java-core/src/test/java/com/google/cloud/AsyncPageImplTest.java @@ -0,0 +1,128 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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; + +import static org.junit.Assert.assertEquals; + +import com.google.common.collect.ImmutableList; +import com.google.common.util.concurrent.Futures; + +import org.junit.Test; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +public class AsyncPageImplTest { + + private static final ImmutableList VALUES1 = ImmutableList.of("1", "2"); + private static final ImmutableList VALUES2 = ImmutableList.of("3", "4"); + private static final ImmutableList VALUES3 = ImmutableList.of("5", "6"); + private static final ImmutableList ALL_VALUES = ImmutableList.builder() + .addAll(VALUES1) + .addAll(VALUES2) + .addAll(VALUES3) + .build(); + private static final ImmutableList SOME_VALUES = ImmutableList.builder() + .addAll(VALUES2) + .addAll(VALUES3) + .build(); + + @Test + public void testPage() { + final AsyncPageImpl nextResult = new AsyncPageImpl<>(null, "c", VALUES2); + AsyncPageImpl.NextPageFetcher fetcher = new AsyncPageImpl.NextPageFetcher() { + private static final long serialVersionUID = 4703765400378593176L; + + @Override + public Future> nextPage() { + return Futures.>immediateFuture(nextResult); + } + }; + AsyncPageImpl result = new AsyncPageImpl<>(fetcher, "c", VALUES1); + assertEquals(nextResult, result.nextPage()); + assertEquals("c", result.nextPageCursor()); + assertEquals(VALUES1, result.values()); + } + + @Test + public void testPageAsync() throws ExecutionException, InterruptedException { + final AsyncPageImpl nextResult = new AsyncPageImpl<>(null, "c", VALUES2); + AsyncPageImpl.NextPageFetcher fetcher = new AsyncPageImpl.NextPageFetcher() { + private static final long serialVersionUID = 4703765400378593176L; + + @Override + public Future> nextPage() { + return Futures.>immediateFuture(nextResult); + } + }; + AsyncPageImpl result = new AsyncPageImpl<>(fetcher, "c", VALUES1); + assertEquals(nextResult, result.nextPageAsync().get()); + assertEquals("c", result.nextPageCursor()); + assertEquals(VALUES1, result.values()); + } + + @Test + public void testIterateAll() { + final AsyncPageImpl nextResult2 = new AsyncPageImpl<>(null, "c3", VALUES3); + AsyncPageImpl.NextPageFetcher fetcher2 = new AsyncPageImpl.NextPageFetcher() { + private static final long serialVersionUID = -9203621430631884026L; + + @Override + public Future> nextPage() { + return Futures.>immediateFuture(nextResult2); + } + }; + final AsyncPageImpl nextResult1 = new AsyncPageImpl<>(fetcher2, "c2", VALUES2); + AsyncPageImpl.NextPageFetcher fetcher1 = new AsyncPageImpl.NextPageFetcher() { + private static final long serialVersionUID = -9203621430631884026L; + + @Override + public Future> nextPage() { + return Futures.>immediateFuture(nextResult1); + } + }; + AsyncPageImpl result = new AsyncPageImpl<>(fetcher1, "c1", VALUES1); + assertEquals(ALL_VALUES, ImmutableList.copyOf(result.iterateAll())); + } + + @Test + public void testAsyncPageAndIterateAll() throws ExecutionException, InterruptedException { + final AsyncPageImpl nextResult2 = new AsyncPageImpl<>(null, "c3", VALUES3); + AsyncPageImpl.NextPageFetcher fetcher2 = new AsyncPageImpl.NextPageFetcher() { + private static final long serialVersionUID = -9203621430631884026L; + + @Override + public Future> nextPage() { + return Futures.>immediateFuture(nextResult2); + } + }; + final AsyncPageImpl nextResult1 = new AsyncPageImpl<>(fetcher2, "c2", VALUES2); + AsyncPageImpl.NextPageFetcher fetcher1 = new AsyncPageImpl.NextPageFetcher() { + private static final long serialVersionUID = -9203621430631884026L; + + @Override + public Future> nextPage() { + return Futures.>immediateFuture(nextResult1); + } + }; + AsyncPageImpl result = new AsyncPageImpl<>(fetcher1, "c1", VALUES1); + assertEquals(nextResult1, result.nextPageAsync().get()); + assertEquals("c1", result.nextPageCursor()); + assertEquals(VALUES1, result.values()); + assertEquals(SOME_VALUES, ImmutableList.copyOf(result.nextPageAsync().get().iterateAll())); + } +} diff --git a/gcloud-java-core/src/test/java/com/google/cloud/PageImplTest.java b/gcloud-java-core/src/test/java/com/google/cloud/PageImplTest.java index 07d979ad857c..40db43b61da2 100644 --- a/gcloud-java-core/src/test/java/com/google/cloud/PageImplTest.java +++ b/gcloud-java-core/src/test/java/com/google/cloud/PageImplTest.java @@ -35,6 +35,8 @@ public class PageImplTest { public void testPage() { final PageImpl nextResult = new PageImpl<>(null, "c", NEXT_VALUES); PageImpl.NextPageFetcher fetcher = new PageImpl.NextPageFetcher() { + private static final long serialVersionUID = -1714571149183431798L; + @Override public PageImpl nextPage() { return nextResult; From ae1302c5da0579e36ec26ba80ac9f795e25206ae Mon Sep 17 00:00:00 2001 From: michaelbausor Date: Thu, 5 May 2016 01:31:26 -0700 Subject: [PATCH 337/375] Updating pubsub to match gax-java 0.0.12 (#981) --- .../cloud/pubsub/spi/v1/PublisherApi.java | 78 +++++----- .../pubsub/spi/v1/PublisherSettings.java | 138 ++++++++++++------ .../cloud/pubsub/spi/v1/SubscriberApi.java | 118 ++++++++++----- .../pubsub/spi/v1/SubscriberSettings.java | 133 +++++++++++------ gcloud-java-pubsub/pom.xml | 2 +- .../cloud/pubsub/spi/DefaultPubSubRpc.java | 17 +-- .../cloud/pubsub/spi/v1/PublisherApi.java | 78 +++++----- .../pubsub/spi/v1/PublisherSettings.java | 138 ++++++++++++------ .../cloud/pubsub/spi/v1/SubscriberApi.java | 118 ++++++++++----- .../pubsub/spi/v1/SubscriberSettings.java | 133 +++++++++++------ .../cloud/pubsub/spi/v1/PublisherApiTest.java | 6 +- 11 files changed, 622 insertions(+), 337 deletions(-) diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java index 6f7139bf4270..36d576767efb 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java @@ -52,6 +52,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.ScheduledExecutorService; // Manually-added imports: add custom (non-generated) imports after this point. @@ -65,10 +66,9 @@ * *
      * 
    - * try (PublisherApi publisherApi = PublisherApi.defaultInstance()) {
    - *   // make calls here
    - * String name = "";
    - * Topic callResult = createTopic(name);
    + * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    + *   String name = "";
    + *   Topic callResult = publisherApi.createTopic(name);
      * }
      * 
      * 
    @@ -100,15 +100,10 @@ *

    This class can be customized by passing in a custom instance of PublisherSettings to * create(). For example: * - * *

      * 
    - * ConnectionSettings defaultConnectionSettings =
    - *     PublisherSettings.defaultInstance().toBuilder().getConnectionSettings();
    - * ConnectionSettings updatedConnectionSettings =
    - *     defaultConnectionSettings.toBuilder().provideCredentialsWith(myCredentials).build();
    - * PublisherSettings publisherSettings = PublisherSettings.defaultInstance().toBuilder().
    - *     provideChannelWith(updatedConnectionSettings)
    + * PublisherSettings publisherSettings = PublisherSettings.defaultBuilder()
    + *     .provideChannelWith(myCredentials)
      *     .build();
      * PublisherApi publisherApi = PublisherApi.create(publisherSettings);
      * 
    @@ -119,7 +114,9 @@
      */
     @javax.annotation.Generated("by GAPIC")
     public class PublisherApi implements AutoCloseable {
    +  private final PublisherSettings settings;
       private final ManagedChannel channel;
    +  private final ScheduledExecutorService executor;
       private final List closeables = new ArrayList<>();
     
       private final ApiCallable createTopicCallable;
    @@ -133,11 +130,15 @@ public class PublisherApi implements AutoCloseable {
           listTopicSubscriptionsPagedCallable;
       private final ApiCallable deleteTopicCallable;
     
    +  public final PublisherSettings getSettings() {
    +    return settings;
    +  }
    +
       private static final PathTemplate PROJECT_PATH_TEMPLATE =
    -      PathTemplate.create("projects/{project}");
    +      PathTemplate.createWithoutUrlEncoding("projects/{project}");
     
       private static final PathTemplate TOPIC_PATH_TEMPLATE =
    -      PathTemplate.create("projects/{project}/topics/{topic}");
    +      PathTemplate.createWithoutUrlEncoding("projects/{project}/topics/{topic}");
     
       /**
        * Formats a string containing the fully-qualified path to represent
    @@ -200,8 +201,8 @@ public static final String parseTopicFromTopicName(String topicName) {
        * 
        * 
        */
    -  public static final PublisherApi defaultInstance() throws IOException {
    -    return create(PublisherSettings.defaultInstance());
    +  public static final PublisherApi createWithDefaults() throws IOException {
    +    return create(PublisherSettings.defaultBuilder().build());
       }
     
       /**
    @@ -225,24 +226,32 @@ public static final PublisherApi create(PublisherSettings settings) throws IOExc
        * 
        */
       protected PublisherApi(PublisherSettings settings) throws IOException {
    -    this.channel = settings.getChannel();
    -
    -    this.createTopicCallable = ApiCallable.create(settings.createTopicSettings(), settings);
    -    this.publishCallable = ApiCallable.create(settings.publishSettings(), settings);
    +    this.settings = settings;
    +    this.executor = settings.getExecutorProvider().getOrBuildExecutor();
    +    this.channel = settings.getChannelProvider().getOrBuildChannel(this.executor);
    +
    +    this.createTopicCallable =
    +        ApiCallable.create(settings.createTopicSettings(), this.channel, this.executor);
    +    this.publishCallable =
    +        ApiCallable.create(settings.publishSettings(), this.channel, this.executor);
         if (settings.publishSettings().getBundlerFactory() != null) {
           closeables.add(settings.publishSettings().getBundlerFactory());
         }
    -    this.getTopicCallable = ApiCallable.create(settings.getTopicSettings(), settings);
    -    this.listTopicsCallable = ApiCallable.create(settings.listTopicsSettings(), settings);
    +    this.getTopicCallable =
    +        ApiCallable.create(settings.getTopicSettings(), this.channel, this.executor);
    +    this.listTopicsCallable =
    +        ApiCallable.create(settings.listTopicsSettings(), this.channel, this.executor);
         this.listTopicsPagedCallable =
    -        ApiCallable.createPagedVariant(settings.listTopicsSettings(), settings);
    +        ApiCallable.createPagedVariant(settings.listTopicsSettings(), this.channel, this.executor);
         this.listTopicSubscriptionsCallable =
    -        ApiCallable.create(settings.listTopicSubscriptionsSettings(), settings);
    +        ApiCallable.create(settings.listTopicSubscriptionsSettings(), this.channel, this.executor);
         this.listTopicSubscriptionsPagedCallable =
    -        ApiCallable.createPagedVariant(settings.listTopicSubscriptionsSettings(), settings);
    -    this.deleteTopicCallable = ApiCallable.create(settings.deleteTopicSettings(), settings);
    +        ApiCallable.createPagedVariant(
    +            settings.listTopicSubscriptionsSettings(), this.channel, this.executor);
    +    this.deleteTopicCallable =
    +        ApiCallable.create(settings.deleteTopicSettings(), this.channel, this.executor);
     
    -    if (settings.shouldAutoCloseChannel()) {
    +    if (settings.getChannelProvider().shouldAutoClose()) {
           closeables.add(
               new Closeable() {
                 @Override
    @@ -251,6 +260,15 @@ public void close() throws IOException {
                 }
               });
         }
    +    if (settings.getExecutorProvider().shouldAutoClose()) {
    +      closeables.add(
    +          new Closeable() {
    +            @Override
    +            public void close() throws IOException {
    +              executor.shutdown();
    +            }
    +          });
    +    }
       }
     
       // ----- createTopic -----
    @@ -296,7 +314,6 @@ private Topic createTopic(Topic request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable createTopicCallable() {
         return createTopicCallable;
    @@ -348,7 +365,6 @@ public PublishResponse publish(PublishRequest request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable publishCallable() {
         return publishCallable;
    @@ -392,7 +408,6 @@ private Topic getTopic(GetTopicRequest request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable getTopicCallable() {
         return getTopicCallable;
    @@ -435,7 +450,6 @@ public final PageAccessor listTopics(ListTopicsRequest request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable> listTopicsPagedCallable() {
         return listTopicsPagedCallable;
    @@ -447,7 +461,6 @@ public final ApiCallable> listTopicsPaged
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable listTopicsCallable() {
         return listTopicsCallable;
    @@ -491,7 +504,6 @@ public final PageAccessor listTopicSubscriptions(ListTopicSubscriptionsR
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable>
           listTopicSubscriptionsPagedCallable() {
    @@ -504,7 +516,6 @@ public final PageAccessor listTopicSubscriptions(ListTopicSubscriptionsR
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable
           listTopicSubscriptionsCallable() {
    @@ -561,7 +572,6 @@ private void deleteTopic(DeleteTopicRequest request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable deleteTopicCallable() {
         return deleteTopicCallable;
    diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherSettings.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherSettings.java
    index 230adc5ec35c..9e2b9941d741 100644
    --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherSettings.java
    +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherSettings.java
    @@ -44,6 +44,7 @@
     import com.google.api.gax.grpc.RequestIssuer;
     import com.google.api.gax.grpc.ServiceApiSettings;
     import com.google.api.gax.grpc.SimpleCallSettings;
    +import com.google.auth.Credentials;
     import com.google.common.collect.ImmutableList;
     import com.google.common.collect.ImmutableMap;
     import com.google.common.collect.ImmutableSet;
    @@ -92,7 +93,7 @@
      * 
      * 
      * PublisherSettings.Builder publisherSettingsBuilder =
    - *     PublisherSettings.defaultInstance().toBuilder();
    + *     PublisherSettings.defaultBuilder();
      * publisherSettingsBuilder.CreateTopicSettings().getRetrySettingsBuilder()
      *     .setTotalTimeout(Duration.standardSeconds(30));
      * PublisherSettings publisherSettings = publisherSettingsBuilder.build();
    @@ -127,6 +128,16 @@ public class PublisherSettings extends ServiceApiSettings {
               .add("https://www.googleapis.com/auth/cloud-platform")
               .build();
     
    +  /**
    +   * The default connection settings of the service.
    +   */
    +  public static final ConnectionSettings DEFAULT_CONNECTION_SETTINGS =
    +      ConnectionSettings.newBuilder()
    +          .setServiceAddress(DEFAULT_SERVICE_ADDRESS)
    +          .setPort(DEFAULT_SERVICE_PORT)
    +          .provideCredentialsWith(DEFAULT_SERVICE_SCOPES)
    +          .build();
    +
       private final SimpleCallSettings createTopicSettings;
       private final BundlingCallSettings publishSettings;
       private final SimpleCallSettings getTopicSettings;
    @@ -185,10 +196,10 @@ public SimpleCallSettings deleteTopicSettings() {
       }
     
       /**
    -   * Returns an instance of this class with recommended defaults.
    +   * Returns a builder for this class with recommended defaults.
        */
    -  public static PublisherSettings defaultInstance() throws IOException {
    -    return newBuilder().build();
    +  public static Builder defaultBuilder() {
    +    return Builder.createDefault();
       }
     
       /**
    @@ -207,10 +218,8 @@ public Builder toBuilder() {
     
       private PublisherSettings(Builder settingsBuilder) throws IOException {
         super(
    -        settingsBuilder.getOrBuildChannel(),
    -        settingsBuilder.shouldAutoCloseChannel(),
    -        settingsBuilder.getOrBuildExecutor(),
    -        settingsBuilder.getConnectionSettings(),
    +        settingsBuilder.getChannelProvider(),
    +        settingsBuilder.getExecutorProvider(),
             settingsBuilder.getGeneratorName(),
             settingsBuilder.getGeneratorVersion(),
             settingsBuilder.getClientLibName(),
    @@ -387,54 +396,26 @@ public static class Builder extends ServiceApiSettings.Builder {
         }
     
         private Builder() {
    -      super(
    -          ConnectionSettings.newBuilder()
    -              .setServiceAddress(DEFAULT_SERVICE_ADDRESS)
    -              .setPort(DEFAULT_SERVICE_PORT)
    -              .provideCredentialsWith(DEFAULT_SERVICE_SCOPES)
    -              .build());
    -
    -      createTopicSettings =
    -          SimpleCallSettings.newBuilder(PublisherGrpc.METHOD_CREATE_TOPIC)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    -
    -      BundlingSettings.Builder publishBundlingSettingsBuilder =
    -          BundlingSettings.newBuilder()
    -              .setElementCountThreshold(800)
    -              .setElementCountLimit(1000)
    -              .setRequestByteThreshold(8388608)
    -              .setRequestByteLimit(10485760)
    -              .setDelayThreshold(Duration.millis(100))
    -              .setBlockingCallCountThreshold(1);
    +      super(DEFAULT_CONNECTION_SETTINGS);
    +
    +      createTopicSettings = SimpleCallSettings.newBuilder(PublisherGrpc.METHOD_CREATE_TOPIC);
    +
           publishSettings =
               BundlingCallSettings.newBuilder(PublisherGrpc.METHOD_PUBLISH, PUBLISH_BUNDLING_DESC)
    -              .setBundlingSettingsBuilder(publishBundlingSettingsBuilder)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +              .setBundlingSettingsBuilder(BundlingSettings.newBuilder());
     
    -      getTopicSettings =
    -          SimpleCallSettings.newBuilder(PublisherGrpc.METHOD_GET_TOPIC)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +      getTopicSettings = SimpleCallSettings.newBuilder(PublisherGrpc.METHOD_GET_TOPIC);
     
           listTopicsSettings =
               PageStreamingCallSettings.newBuilder(
    -                  PublisherGrpc.METHOD_LIST_TOPICS, LIST_TOPICS_PAGE_STR_DESC)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +              PublisherGrpc.METHOD_LIST_TOPICS, LIST_TOPICS_PAGE_STR_DESC);
     
           listTopicSubscriptionsSettings =
               PageStreamingCallSettings.newBuilder(
    -                  PublisherGrpc.METHOD_LIST_TOPIC_SUBSCRIPTIONS,
    -                  LIST_TOPIC_SUBSCRIPTIONS_PAGE_STR_DESC)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +              PublisherGrpc.METHOD_LIST_TOPIC_SUBSCRIPTIONS,
    +              LIST_TOPIC_SUBSCRIPTIONS_PAGE_STR_DESC);
     
    -      deleteTopicSettings =
    -          SimpleCallSettings.newBuilder(PublisherGrpc.METHOD_DELETE_TOPIC)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +      deleteTopicSettings = SimpleCallSettings.newBuilder(PublisherGrpc.METHOD_DELETE_TOPIC);
     
           methodSettingsBuilders =
               ImmutableList.of(
    @@ -446,6 +427,50 @@ private Builder() {
                   deleteTopicSettings);
         }
     
    +    private static Builder createDefault() {
    +      Builder builder = new Builder();
    +      builder
    +          .createTopicSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .publishSettings()
    +          .getBundlingSettingsBuilder()
    +          .setElementCountThreshold(800)
    +          .setElementCountLimit(1000)
    +          .setRequestByteThreshold(8388608)
    +          .setRequestByteLimit(10485760)
    +          .setDelayThreshold(Duration.millis(100))
    +          .setBlockingCallCountThreshold(1);
    +      builder
    +          .publishSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .getTopicSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .listTopicsSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .listTopicSubscriptionsSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .deleteTopicSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      return builder;
    +    }
    +
         private Builder(PublisherSettings settings) {
           super(settings);
     
    @@ -466,6 +491,17 @@ private Builder(PublisherSettings settings) {
                   deleteTopicSettings);
         }
     
    +    @Override
    +    protected ConnectionSettings getDefaultConnectionSettings() {
    +      return DEFAULT_CONNECTION_SETTINGS;
    +    }
    +
    +    @Override
    +    public Builder provideExecutorWith(ScheduledExecutorService executor, boolean shouldAutoClose) {
    +      super.provideExecutorWith(executor, shouldAutoClose);
    +      return this;
    +    }
    +
         @Override
         public Builder provideChannelWith(ManagedChannel channel, boolean shouldAutoClose) {
           super.provideChannelWith(channel, shouldAutoClose);
    @@ -479,8 +515,14 @@ public Builder provideChannelWith(ConnectionSettings settings) {
         }
     
         @Override
    -    public Builder setExecutor(ScheduledExecutorService executor) {
    -      super.setExecutor(executor);
    +    public Builder provideChannelWith(Credentials credentials) {
    +      super.provideChannelWith(credentials);
    +      return this;
    +    }
    +
    +    @Override
    +    public Builder provideChannelWith(List scopes) {
    +      super.provideChannelWith(scopes);
           return this;
         }
     
    diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java
    index 322154991e5b..dd6275bcd9d0 100644
    --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java
    +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java
    @@ -53,6 +53,7 @@
     import java.io.IOException;
     import java.util.ArrayList;
     import java.util.List;
    +import java.util.concurrent.ScheduledExecutorService;
     
     // Manually-added imports: add custom (non-generated) imports after this point.
     
    @@ -66,13 +67,12 @@
      *
      * 
      * 
    - * try (SubscriberApi subscriberApi = SubscriberApi.defaultInstance()) {
    - *   // make calls here
    - * String name = "";
    - * String topic = "";
    - * PushConfig pushConfig = PushConfig.newBuilder().build();
    - * int ackDeadlineSeconds = 0;
    - * Subscription callResult = createSubscription(name, topic, pushConfig, ackDeadlineSeconds);
    + * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    + *   String name = "";
    + *   String topic = "";
    + *   PushConfig pushConfig = PushConfig.newBuilder().build();
    + *   int ackDeadlineSeconds = 0;
    + *   Subscription callResult = subscriberApi.createSubscription(name, topic, pushConfig, ackDeadlineSeconds);
      * }
      * 
      * 
    @@ -104,15 +104,10 @@ *

    This class can be customized by passing in a custom instance of SubscriberSettings to * create(). For example: * - * *

      * 
    - * ConnectionSettings defaultConnectionSettings =
    - *     SubscriberSettings.defaultInstance().toBuilder().getConnectionSettings();
    - * ConnectionSettings updatedConnectionSettings =
    - *     defaultConnectionSettings.toBuilder().provideCredentialsWith(myCredentials).build();
    - * SubscriberSettings subscriberSettings = SubscriberSettings.defaultInstance().toBuilder().
    - *     provideChannelWith(updatedConnectionSettings)
    + * SubscriberSettings subscriberSettings = SubscriberSettings.defaultBuilder()
    + *     .provideChannelWith(myCredentials)
      *     .build();
      * SubscriberApi subscriberApi = SubscriberApi.create(subscriberSettings);
      * 
    @@ -123,7 +118,9 @@
      */
     @javax.annotation.Generated("by GAPIC")
     public class SubscriberApi implements AutoCloseable {
    +  private final SubscriberSettings settings;
       private final ManagedChannel channel;
    +  private final ScheduledExecutorService executor;
       private final List closeables = new ArrayList<>();
     
       private final ApiCallable createSubscriptionCallable;
    @@ -138,11 +135,18 @@ public class SubscriberApi implements AutoCloseable {
       private final ApiCallable pullCallable;
       private final ApiCallable modifyPushConfigCallable;
     
    +  public final SubscriberSettings getSettings() {
    +    return settings;
    +  }
    +
       private static final PathTemplate PROJECT_PATH_TEMPLATE =
    -      PathTemplate.create("projects/{project}");
    +      PathTemplate.createWithoutUrlEncoding("projects/{project}");
     
       private static final PathTemplate SUBSCRIPTION_PATH_TEMPLATE =
    -      PathTemplate.create("projects/{project}/subscriptions/{subscription}");
    +      PathTemplate.createWithoutUrlEncoding("projects/{project}/subscriptions/{subscription}");
    +
    +  private static final PathTemplate TOPIC_PATH_TEMPLATE =
    +      PathTemplate.createWithoutUrlEncoding("projects/{project}/topics/{topic}");
     
       /**
        * Formats a string containing the fully-qualified path to represent
    @@ -166,6 +170,17 @@ public static final String formatSubscriptionName(String project, String subscri
         return SUBSCRIPTION_PATH_TEMPLATE.instantiate("project", project, "subscription", subscription);
       }
     
    +  /**
    +   * Formats a string containing the fully-qualified path to represent
    +   * a topic resource.
    +   *
    +   * 
    +   * 
    +   */
    +  public static final String formatTopicName(String project, String topic) {
    +    return TOPIC_PATH_TEMPLATE.instantiate("project", project, "topic", topic);
    +  }
    +
       /**
        * Parses the project from the given fully-qualified path which
        * represents a project resource.
    @@ -199,14 +214,36 @@ public static final String parseSubscriptionFromSubscriptionName(String subscrip
         return SUBSCRIPTION_PATH_TEMPLATE.parse(subscriptionName).get("subscription");
       }
     
    +  /**
    +   * Parses the project from the given fully-qualified path which
    +   * represents a topic resource.
    +   *
    +   * 
    +   * 
    +   */
    +  public static final String parseProjectFromTopicName(String topicName) {
    +    return TOPIC_PATH_TEMPLATE.parse(topicName).get("project");
    +  }
    +
    +  /**
    +   * Parses the topic from the given fully-qualified path which
    +   * represents a topic resource.
    +   *
    +   * 
    +   * 
    +   */
    +  public static final String parseTopicFromTopicName(String topicName) {
    +    return TOPIC_PATH_TEMPLATE.parse(topicName).get("topic");
    +  }
    +
       /**
        * Constructs an instance of SubscriberApi with default settings.
        *
        * 
        * 
        */
    -  public static final SubscriberApi defaultInstance() throws IOException {
    -    return create(SubscriberSettings.defaultInstance());
    +  public static final SubscriberApi createWithDefaults() throws IOException {
    +    return create(SubscriberSettings.defaultBuilder().build());
       }
     
       /**
    @@ -230,25 +267,30 @@ public static final SubscriberApi create(SubscriberSettings settings) throws IOE
        * 
        */
       protected SubscriberApi(SubscriberSettings settings) throws IOException {
    -    this.channel = settings.getChannel();
    +    this.settings = settings;
    +    this.executor = settings.getExecutorProvider().getOrBuildExecutor();
    +    this.channel = settings.getChannelProvider().getOrBuildChannel(this.executor);
     
         this.createSubscriptionCallable =
    -        ApiCallable.create(settings.createSubscriptionSettings(), settings);
    -    this.getSubscriptionCallable = ApiCallable.create(settings.getSubscriptionSettings(), settings);
    +        ApiCallable.create(settings.createSubscriptionSettings(), this.channel, this.executor);
    +    this.getSubscriptionCallable =
    +        ApiCallable.create(settings.getSubscriptionSettings(), this.channel, this.executor);
         this.listSubscriptionsCallable =
    -        ApiCallable.create(settings.listSubscriptionsSettings(), settings);
    +        ApiCallable.create(settings.listSubscriptionsSettings(), this.channel, this.executor);
         this.listSubscriptionsPagedCallable =
    -        ApiCallable.createPagedVariant(settings.listSubscriptionsSettings(), settings);
    +        ApiCallable.createPagedVariant(
    +            settings.listSubscriptionsSettings(), this.channel, this.executor);
         this.deleteSubscriptionCallable =
    -        ApiCallable.create(settings.deleteSubscriptionSettings(), settings);
    +        ApiCallable.create(settings.deleteSubscriptionSettings(), this.channel, this.executor);
         this.modifyAckDeadlineCallable =
    -        ApiCallable.create(settings.modifyAckDeadlineSettings(), settings);
    -    this.acknowledgeCallable = ApiCallable.create(settings.acknowledgeSettings(), settings);
    -    this.pullCallable = ApiCallable.create(settings.pullSettings(), settings);
    +        ApiCallable.create(settings.modifyAckDeadlineSettings(), this.channel, this.executor);
    +    this.acknowledgeCallable =
    +        ApiCallable.create(settings.acknowledgeSettings(), this.channel, this.executor);
    +    this.pullCallable = ApiCallable.create(settings.pullSettings(), this.channel, this.executor);
         this.modifyPushConfigCallable =
    -        ApiCallable.create(settings.modifyPushConfigSettings(), settings);
    +        ApiCallable.create(settings.modifyPushConfigSettings(), this.channel, this.executor);
     
    -    if (settings.shouldAutoCloseChannel()) {
    +    if (settings.getChannelProvider().shouldAutoClose()) {
           closeables.add(
               new Closeable() {
                 @Override
    @@ -257,6 +299,15 @@ public void close() throws IOException {
                 }
               });
         }
    +    if (settings.getExecutorProvider().shouldAutoClose()) {
    +      closeables.add(
    +          new Closeable() {
    +            @Override
    +            public void close() throws IOException {
    +              executor.shutdown();
    +            }
    +          });
    +    }
       }
     
       // ----- createSubscription -----
    @@ -346,7 +397,6 @@ public Subscription createSubscription(Subscription request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable createSubscriptionCallable() {
         return createSubscriptionCallable;
    @@ -400,7 +450,6 @@ private Subscription getSubscription(GetSubscriptionRequest request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable getSubscriptionCallable() {
         return getSubscriptionCallable;
    @@ -453,7 +502,6 @@ public final PageAccessor listSubscriptions(ListSubscriptionsReque
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable>
           listSubscriptionsPagedCallable() {
    @@ -469,7 +517,6 @@ public final PageAccessor listSubscriptions(ListSubscriptionsReque
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable
           listSubscriptionsCallable() {
    @@ -527,7 +574,6 @@ private void deleteSubscription(DeleteSubscriptionRequest request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable deleteSubscriptionCallable() {
         return deleteSubscriptionCallable;
    @@ -592,7 +638,6 @@ public void modifyAckDeadline(ModifyAckDeadlineRequest request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable modifyAckDeadlineCallable() {
         return modifyAckDeadlineCallable;
    @@ -657,7 +702,6 @@ public void acknowledge(AcknowledgeRequest request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable acknowledgeCallable() {
         return acknowledgeCallable;
    @@ -721,7 +765,6 @@ public PullResponse pull(PullRequest request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable pullCallable() {
         return pullCallable;
    @@ -790,7 +833,6 @@ public void modifyPushConfig(ModifyPushConfigRequest request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable modifyPushConfigCallable() {
         return modifyPushConfigCallable;
    diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberSettings.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberSettings.java
    index 39fdadccea2a..b7a34d966b26 100644
    --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberSettings.java
    +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberSettings.java
    @@ -40,6 +40,7 @@
     import com.google.api.gax.grpc.PageStreamingDescriptor;
     import com.google.api.gax.grpc.ServiceApiSettings;
     import com.google.api.gax.grpc.SimpleCallSettings;
    +import com.google.auth.Credentials;
     import com.google.common.collect.ImmutableList;
     import com.google.common.collect.ImmutableMap;
     import com.google.common.collect.ImmutableSet;
    @@ -60,6 +61,7 @@
     import io.grpc.ManagedChannel;
     import io.grpc.Status;
     import java.io.IOException;
    +import java.util.List;
     import java.util.concurrent.ScheduledExecutorService;
     import org.joda.time.Duration;
     
    @@ -85,7 +87,7 @@
      * 
      * 
      * SubscriberSettings.Builder subscriberSettingsBuilder =
    - *     SubscriberSettings.defaultInstance().toBuilder();
    + *     SubscriberSettings.defaultBuilder();
      * subscriberSettingsBuilder.CreateSubscriptionSettings().getRetrySettingsBuilder()
      *     .setTotalTimeout(Duration.standardSeconds(30));
      * SubscriberSettings subscriberSettings = subscriberSettingsBuilder.build();
    @@ -120,6 +122,16 @@ public class SubscriberSettings extends ServiceApiSettings {
               .add("https://www.googleapis.com/auth/cloud-platform")
               .build();
     
    +  /**
    +   * The default connection settings of the service.
    +   */
    +  public static final ConnectionSettings DEFAULT_CONNECTION_SETTINGS =
    +      ConnectionSettings.newBuilder()
    +          .setServiceAddress(DEFAULT_SERVICE_ADDRESS)
    +          .setPort(DEFAULT_SERVICE_PORT)
    +          .provideCredentialsWith(DEFAULT_SERVICE_SCOPES)
    +          .build();
    +
       private final SimpleCallSettings createSubscriptionSettings;
       private final SimpleCallSettings getSubscriptionSettings;
       private final PageStreamingCallSettings<
    @@ -191,10 +203,10 @@ public SimpleCallSettings modifyPushConfigSettin
       }
     
       /**
    -   * Returns an instance of this class with recommended defaults.
    +   * Returns a builder for this class with recommended defaults.
        */
    -  public static SubscriberSettings defaultInstance() throws IOException {
    -    return newBuilder().build();
    +  public static Builder defaultBuilder() {
    +    return Builder.createDefault();
       }
     
       /**
    @@ -213,10 +225,8 @@ public Builder toBuilder() {
     
       private SubscriberSettings(Builder settingsBuilder) throws IOException {
         super(
    -        settingsBuilder.getOrBuildChannel(),
    -        settingsBuilder.shouldAutoCloseChannel(),
    -        settingsBuilder.getOrBuildExecutor(),
    -        settingsBuilder.getConnectionSettings(),
    +        settingsBuilder.getChannelProvider(),
    +        settingsBuilder.getExecutorProvider(),
             settingsBuilder.getGeneratorName(),
             settingsBuilder.getGeneratorVersion(),
             settingsBuilder.getClientLibName(),
    @@ -311,53 +321,30 @@ public static class Builder extends ServiceApiSettings.Builder {
         }
     
         private Builder() {
    -      super(
    -          ConnectionSettings.newBuilder()
    -              .setServiceAddress(DEFAULT_SERVICE_ADDRESS)
    -              .setPort(DEFAULT_SERVICE_PORT)
    -              .provideCredentialsWith(DEFAULT_SERVICE_SCOPES)
    -              .build());
    +      super(DEFAULT_CONNECTION_SETTINGS);
     
           createSubscriptionSettings =
    -          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_CREATE_SUBSCRIPTION)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_CREATE_SUBSCRIPTION);
     
           getSubscriptionSettings =
    -          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_GET_SUBSCRIPTION)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_GET_SUBSCRIPTION);
     
           listSubscriptionsSettings =
               PageStreamingCallSettings.newBuilder(
    -                  SubscriberGrpc.METHOD_LIST_SUBSCRIPTIONS, LIST_SUBSCRIPTIONS_PAGE_STR_DESC)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +              SubscriberGrpc.METHOD_LIST_SUBSCRIPTIONS, LIST_SUBSCRIPTIONS_PAGE_STR_DESC);
     
           deleteSubscriptionSettings =
    -          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_DELETE_SUBSCRIPTION)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_DELETE_SUBSCRIPTION);
     
           modifyAckDeadlineSettings =
    -          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_MODIFY_ACK_DEADLINE)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_MODIFY_ACK_DEADLINE);
     
    -      acknowledgeSettings =
    -          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_ACKNOWLEDGE)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +      acknowledgeSettings = SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_ACKNOWLEDGE);
     
    -      pullSettings =
    -          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_PULL)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +      pullSettings = SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_PULL);
     
           modifyPushConfigSettings =
    -          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_MODIFY_PUSH_CONFIG)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_MODIFY_PUSH_CONFIG);
     
           methodSettingsBuilders =
               ImmutableList.of(
    @@ -371,6 +358,51 @@ private Builder() {
                   modifyPushConfigSettings);
         }
     
    +    private static Builder createDefault() {
    +      Builder builder = new Builder();
    +      builder
    +          .createSubscriptionSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .getSubscriptionSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .listSubscriptionsSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .deleteSubscriptionSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .modifyAckDeadlineSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .acknowledgeSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .pullSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .modifyPushConfigSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      return builder;
    +    }
    +
         private Builder(SubscriberSettings settings) {
           super(settings);
     
    @@ -395,6 +427,17 @@ private Builder(SubscriberSettings settings) {
                   modifyPushConfigSettings);
         }
     
    +    @Override
    +    protected ConnectionSettings getDefaultConnectionSettings() {
    +      return DEFAULT_CONNECTION_SETTINGS;
    +    }
    +
    +    @Override
    +    public Builder provideExecutorWith(ScheduledExecutorService executor, boolean shouldAutoClose) {
    +      super.provideExecutorWith(executor, shouldAutoClose);
    +      return this;
    +    }
    +
         @Override
         public Builder provideChannelWith(ManagedChannel channel, boolean shouldAutoClose) {
           super.provideChannelWith(channel, shouldAutoClose);
    @@ -408,8 +451,14 @@ public Builder provideChannelWith(ConnectionSettings settings) {
         }
     
         @Override
    -    public Builder setExecutor(ScheduledExecutorService executor) {
    -      super.setExecutor(executor);
    +    public Builder provideChannelWith(Credentials credentials) {
    +      super.provideChannelWith(credentials);
    +      return this;
    +    }
    +
    +    @Override
    +    public Builder provideChannelWith(List scopes) {
    +      super.provideChannelWith(scopes);
           return this;
         }
     
    diff --git a/gcloud-java-pubsub/pom.xml b/gcloud-java-pubsub/pom.xml
    index 8724ed627e1c..f9b9b6533f78 100644
    --- a/gcloud-java-pubsub/pom.xml
    +++ b/gcloud-java-pubsub/pom.xml
    @@ -25,7 +25,7 @@
         
           com.google.api
           gax
    -      0.0.11
    +      0.0.12
         
         
           com.google.api.grpc
    diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java
    index ebe83841a4ac..d4f00fd7cf37 100644
    --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java
    +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java
    @@ -16,7 +16,6 @@
     
     package com.google.cloud.pubsub.spi;
     
    -import com.google.api.gax.core.ConnectionSettings;
     import com.google.api.gax.core.RetrySettings;
     import com.google.api.gax.grpc.ApiCallSettings;
     import com.google.api.gax.grpc.ApiException;
    @@ -69,15 +68,15 @@ public DefaultPubSubRpc(PubSubOptions options) throws IOException {
         try {
           // Provide (and use a common thread-pool).
           // This depends on https://github.com/googleapis/gax-java/issues/73
    -      PublisherSettings.Builder pbuilder = PublisherSettings.defaultInstance().toBuilder();
    -      pbuilder.provideChannelWith(ConnectionSettings.newBuilder()
    -          .provideCredentialsWith(options.authCredentials().credentials()).build());
    -      pbuilder.applyToAllApiMethods(apiCallSettings(options));
    +      PublisherSettings.Builder pbuilder =
    +          PublisherSettings.defaultBuilder()
    +              .provideChannelWith(options.authCredentials().credentials())
    +              .applyToAllApiMethods(apiCallSettings(options));
           publisherApi = PublisherApi.create(pbuilder.build());
    -      SubscriberSettings.Builder sBuilder = SubscriberSettings.defaultInstance().toBuilder();
    -      sBuilder.provideChannelWith(ConnectionSettings.newBuilder()
    -          .provideCredentialsWith(options.authCredentials().credentials()).build());
    -      sBuilder.applyToAllApiMethods(apiCallSettings(options));
    +      SubscriberSettings.Builder sBuilder =
    +          SubscriberSettings.defaultBuilder()
    +              .provideChannelWith(options.authCredentials().credentials())
    +              .applyToAllApiMethods(apiCallSettings(options));
           subscriberApi = SubscriberApi.create(sBuilder.build());
         } catch (Exception ex) {
           throw new IOException(ex);
    diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java
    index 6f7139bf4270..36d576767efb 100644
    --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java
    +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java
    @@ -52,6 +52,7 @@
     import java.io.IOException;
     import java.util.ArrayList;
     import java.util.List;
    +import java.util.concurrent.ScheduledExecutorService;
     
     // Manually-added imports: add custom (non-generated) imports after this point.
     
    @@ -65,10 +66,9 @@
      *
      * 
      * 
    - * try (PublisherApi publisherApi = PublisherApi.defaultInstance()) {
    - *   // make calls here
    - * String name = "";
    - * Topic callResult = createTopic(name);
    + * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    + *   String name = "";
    + *   Topic callResult = publisherApi.createTopic(name);
      * }
      * 
      * 
    @@ -100,15 +100,10 @@ *

    This class can be customized by passing in a custom instance of PublisherSettings to * create(). For example: * - * *

      * 
    - * ConnectionSettings defaultConnectionSettings =
    - *     PublisherSettings.defaultInstance().toBuilder().getConnectionSettings();
    - * ConnectionSettings updatedConnectionSettings =
    - *     defaultConnectionSettings.toBuilder().provideCredentialsWith(myCredentials).build();
    - * PublisherSettings publisherSettings = PublisherSettings.defaultInstance().toBuilder().
    - *     provideChannelWith(updatedConnectionSettings)
    + * PublisherSettings publisherSettings = PublisherSettings.defaultBuilder()
    + *     .provideChannelWith(myCredentials)
      *     .build();
      * PublisherApi publisherApi = PublisherApi.create(publisherSettings);
      * 
    @@ -119,7 +114,9 @@
      */
     @javax.annotation.Generated("by GAPIC")
     public class PublisherApi implements AutoCloseable {
    +  private final PublisherSettings settings;
       private final ManagedChannel channel;
    +  private final ScheduledExecutorService executor;
       private final List closeables = new ArrayList<>();
     
       private final ApiCallable createTopicCallable;
    @@ -133,11 +130,15 @@ public class PublisherApi implements AutoCloseable {
           listTopicSubscriptionsPagedCallable;
       private final ApiCallable deleteTopicCallable;
     
    +  public final PublisherSettings getSettings() {
    +    return settings;
    +  }
    +
       private static final PathTemplate PROJECT_PATH_TEMPLATE =
    -      PathTemplate.create("projects/{project}");
    +      PathTemplate.createWithoutUrlEncoding("projects/{project}");
     
       private static final PathTemplate TOPIC_PATH_TEMPLATE =
    -      PathTemplate.create("projects/{project}/topics/{topic}");
    +      PathTemplate.createWithoutUrlEncoding("projects/{project}/topics/{topic}");
     
       /**
        * Formats a string containing the fully-qualified path to represent
    @@ -200,8 +201,8 @@ public static final String parseTopicFromTopicName(String topicName) {
        * 
        * 
        */
    -  public static final PublisherApi defaultInstance() throws IOException {
    -    return create(PublisherSettings.defaultInstance());
    +  public static final PublisherApi createWithDefaults() throws IOException {
    +    return create(PublisherSettings.defaultBuilder().build());
       }
     
       /**
    @@ -225,24 +226,32 @@ public static final PublisherApi create(PublisherSettings settings) throws IOExc
        * 
        */
       protected PublisherApi(PublisherSettings settings) throws IOException {
    -    this.channel = settings.getChannel();
    -
    -    this.createTopicCallable = ApiCallable.create(settings.createTopicSettings(), settings);
    -    this.publishCallable = ApiCallable.create(settings.publishSettings(), settings);
    +    this.settings = settings;
    +    this.executor = settings.getExecutorProvider().getOrBuildExecutor();
    +    this.channel = settings.getChannelProvider().getOrBuildChannel(this.executor);
    +
    +    this.createTopicCallable =
    +        ApiCallable.create(settings.createTopicSettings(), this.channel, this.executor);
    +    this.publishCallable =
    +        ApiCallable.create(settings.publishSettings(), this.channel, this.executor);
         if (settings.publishSettings().getBundlerFactory() != null) {
           closeables.add(settings.publishSettings().getBundlerFactory());
         }
    -    this.getTopicCallable = ApiCallable.create(settings.getTopicSettings(), settings);
    -    this.listTopicsCallable = ApiCallable.create(settings.listTopicsSettings(), settings);
    +    this.getTopicCallable =
    +        ApiCallable.create(settings.getTopicSettings(), this.channel, this.executor);
    +    this.listTopicsCallable =
    +        ApiCallable.create(settings.listTopicsSettings(), this.channel, this.executor);
         this.listTopicsPagedCallable =
    -        ApiCallable.createPagedVariant(settings.listTopicsSettings(), settings);
    +        ApiCallable.createPagedVariant(settings.listTopicsSettings(), this.channel, this.executor);
         this.listTopicSubscriptionsCallable =
    -        ApiCallable.create(settings.listTopicSubscriptionsSettings(), settings);
    +        ApiCallable.create(settings.listTopicSubscriptionsSettings(), this.channel, this.executor);
         this.listTopicSubscriptionsPagedCallable =
    -        ApiCallable.createPagedVariant(settings.listTopicSubscriptionsSettings(), settings);
    -    this.deleteTopicCallable = ApiCallable.create(settings.deleteTopicSettings(), settings);
    +        ApiCallable.createPagedVariant(
    +            settings.listTopicSubscriptionsSettings(), this.channel, this.executor);
    +    this.deleteTopicCallable =
    +        ApiCallable.create(settings.deleteTopicSettings(), this.channel, this.executor);
     
    -    if (settings.shouldAutoCloseChannel()) {
    +    if (settings.getChannelProvider().shouldAutoClose()) {
           closeables.add(
               new Closeable() {
                 @Override
    @@ -251,6 +260,15 @@ public void close() throws IOException {
                 }
               });
         }
    +    if (settings.getExecutorProvider().shouldAutoClose()) {
    +      closeables.add(
    +          new Closeable() {
    +            @Override
    +            public void close() throws IOException {
    +              executor.shutdown();
    +            }
    +          });
    +    }
       }
     
       // ----- createTopic -----
    @@ -296,7 +314,6 @@ private Topic createTopic(Topic request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable createTopicCallable() {
         return createTopicCallable;
    @@ -348,7 +365,6 @@ public PublishResponse publish(PublishRequest request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable publishCallable() {
         return publishCallable;
    @@ -392,7 +408,6 @@ private Topic getTopic(GetTopicRequest request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable getTopicCallable() {
         return getTopicCallable;
    @@ -435,7 +450,6 @@ public final PageAccessor listTopics(ListTopicsRequest request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable> listTopicsPagedCallable() {
         return listTopicsPagedCallable;
    @@ -447,7 +461,6 @@ public final ApiCallable> listTopicsPaged
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable listTopicsCallable() {
         return listTopicsCallable;
    @@ -491,7 +504,6 @@ public final PageAccessor listTopicSubscriptions(ListTopicSubscriptionsR
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable>
           listTopicSubscriptionsPagedCallable() {
    @@ -504,7 +516,6 @@ public final PageAccessor listTopicSubscriptions(ListTopicSubscriptionsR
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable
           listTopicSubscriptionsCallable() {
    @@ -561,7 +572,6 @@ private void deleteTopic(DeleteTopicRequest request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable deleteTopicCallable() {
         return deleteTopicCallable;
    diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherSettings.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherSettings.java
    index 230adc5ec35c..9e2b9941d741 100644
    --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherSettings.java
    +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherSettings.java
    @@ -44,6 +44,7 @@
     import com.google.api.gax.grpc.RequestIssuer;
     import com.google.api.gax.grpc.ServiceApiSettings;
     import com.google.api.gax.grpc.SimpleCallSettings;
    +import com.google.auth.Credentials;
     import com.google.common.collect.ImmutableList;
     import com.google.common.collect.ImmutableMap;
     import com.google.common.collect.ImmutableSet;
    @@ -92,7 +93,7 @@
      * 
      * 
      * PublisherSettings.Builder publisherSettingsBuilder =
    - *     PublisherSettings.defaultInstance().toBuilder();
    + *     PublisherSettings.defaultBuilder();
      * publisherSettingsBuilder.CreateTopicSettings().getRetrySettingsBuilder()
      *     .setTotalTimeout(Duration.standardSeconds(30));
      * PublisherSettings publisherSettings = publisherSettingsBuilder.build();
    @@ -127,6 +128,16 @@ public class PublisherSettings extends ServiceApiSettings {
               .add("https://www.googleapis.com/auth/cloud-platform")
               .build();
     
    +  /**
    +   * The default connection settings of the service.
    +   */
    +  public static final ConnectionSettings DEFAULT_CONNECTION_SETTINGS =
    +      ConnectionSettings.newBuilder()
    +          .setServiceAddress(DEFAULT_SERVICE_ADDRESS)
    +          .setPort(DEFAULT_SERVICE_PORT)
    +          .provideCredentialsWith(DEFAULT_SERVICE_SCOPES)
    +          .build();
    +
       private final SimpleCallSettings createTopicSettings;
       private final BundlingCallSettings publishSettings;
       private final SimpleCallSettings getTopicSettings;
    @@ -185,10 +196,10 @@ public SimpleCallSettings deleteTopicSettings() {
       }
     
       /**
    -   * Returns an instance of this class with recommended defaults.
    +   * Returns a builder for this class with recommended defaults.
        */
    -  public static PublisherSettings defaultInstance() throws IOException {
    -    return newBuilder().build();
    +  public static Builder defaultBuilder() {
    +    return Builder.createDefault();
       }
     
       /**
    @@ -207,10 +218,8 @@ public Builder toBuilder() {
     
       private PublisherSettings(Builder settingsBuilder) throws IOException {
         super(
    -        settingsBuilder.getOrBuildChannel(),
    -        settingsBuilder.shouldAutoCloseChannel(),
    -        settingsBuilder.getOrBuildExecutor(),
    -        settingsBuilder.getConnectionSettings(),
    +        settingsBuilder.getChannelProvider(),
    +        settingsBuilder.getExecutorProvider(),
             settingsBuilder.getGeneratorName(),
             settingsBuilder.getGeneratorVersion(),
             settingsBuilder.getClientLibName(),
    @@ -387,54 +396,26 @@ public static class Builder extends ServiceApiSettings.Builder {
         }
     
         private Builder() {
    -      super(
    -          ConnectionSettings.newBuilder()
    -              .setServiceAddress(DEFAULT_SERVICE_ADDRESS)
    -              .setPort(DEFAULT_SERVICE_PORT)
    -              .provideCredentialsWith(DEFAULT_SERVICE_SCOPES)
    -              .build());
    -
    -      createTopicSettings =
    -          SimpleCallSettings.newBuilder(PublisherGrpc.METHOD_CREATE_TOPIC)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    -
    -      BundlingSettings.Builder publishBundlingSettingsBuilder =
    -          BundlingSettings.newBuilder()
    -              .setElementCountThreshold(800)
    -              .setElementCountLimit(1000)
    -              .setRequestByteThreshold(8388608)
    -              .setRequestByteLimit(10485760)
    -              .setDelayThreshold(Duration.millis(100))
    -              .setBlockingCallCountThreshold(1);
    +      super(DEFAULT_CONNECTION_SETTINGS);
    +
    +      createTopicSettings = SimpleCallSettings.newBuilder(PublisherGrpc.METHOD_CREATE_TOPIC);
    +
           publishSettings =
               BundlingCallSettings.newBuilder(PublisherGrpc.METHOD_PUBLISH, PUBLISH_BUNDLING_DESC)
    -              .setBundlingSettingsBuilder(publishBundlingSettingsBuilder)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +              .setBundlingSettingsBuilder(BundlingSettings.newBuilder());
     
    -      getTopicSettings =
    -          SimpleCallSettings.newBuilder(PublisherGrpc.METHOD_GET_TOPIC)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +      getTopicSettings = SimpleCallSettings.newBuilder(PublisherGrpc.METHOD_GET_TOPIC);
     
           listTopicsSettings =
               PageStreamingCallSettings.newBuilder(
    -                  PublisherGrpc.METHOD_LIST_TOPICS, LIST_TOPICS_PAGE_STR_DESC)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +              PublisherGrpc.METHOD_LIST_TOPICS, LIST_TOPICS_PAGE_STR_DESC);
     
           listTopicSubscriptionsSettings =
               PageStreamingCallSettings.newBuilder(
    -                  PublisherGrpc.METHOD_LIST_TOPIC_SUBSCRIPTIONS,
    -                  LIST_TOPIC_SUBSCRIPTIONS_PAGE_STR_DESC)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +              PublisherGrpc.METHOD_LIST_TOPIC_SUBSCRIPTIONS,
    +              LIST_TOPIC_SUBSCRIPTIONS_PAGE_STR_DESC);
     
    -      deleteTopicSettings =
    -          SimpleCallSettings.newBuilder(PublisherGrpc.METHOD_DELETE_TOPIC)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +      deleteTopicSettings = SimpleCallSettings.newBuilder(PublisherGrpc.METHOD_DELETE_TOPIC);
     
           methodSettingsBuilders =
               ImmutableList.of(
    @@ -446,6 +427,50 @@ private Builder() {
                   deleteTopicSettings);
         }
     
    +    private static Builder createDefault() {
    +      Builder builder = new Builder();
    +      builder
    +          .createTopicSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .publishSettings()
    +          .getBundlingSettingsBuilder()
    +          .setElementCountThreshold(800)
    +          .setElementCountLimit(1000)
    +          .setRequestByteThreshold(8388608)
    +          .setRequestByteLimit(10485760)
    +          .setDelayThreshold(Duration.millis(100))
    +          .setBlockingCallCountThreshold(1);
    +      builder
    +          .publishSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .getTopicSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .listTopicsSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .listTopicSubscriptionsSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .deleteTopicSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      return builder;
    +    }
    +
         private Builder(PublisherSettings settings) {
           super(settings);
     
    @@ -466,6 +491,17 @@ private Builder(PublisherSettings settings) {
                   deleteTopicSettings);
         }
     
    +    @Override
    +    protected ConnectionSettings getDefaultConnectionSettings() {
    +      return DEFAULT_CONNECTION_SETTINGS;
    +    }
    +
    +    @Override
    +    public Builder provideExecutorWith(ScheduledExecutorService executor, boolean shouldAutoClose) {
    +      super.provideExecutorWith(executor, shouldAutoClose);
    +      return this;
    +    }
    +
         @Override
         public Builder provideChannelWith(ManagedChannel channel, boolean shouldAutoClose) {
           super.provideChannelWith(channel, shouldAutoClose);
    @@ -479,8 +515,14 @@ public Builder provideChannelWith(ConnectionSettings settings) {
         }
     
         @Override
    -    public Builder setExecutor(ScheduledExecutorService executor) {
    -      super.setExecutor(executor);
    +    public Builder provideChannelWith(Credentials credentials) {
    +      super.provideChannelWith(credentials);
    +      return this;
    +    }
    +
    +    @Override
    +    public Builder provideChannelWith(List scopes) {
    +      super.provideChannelWith(scopes);
           return this;
         }
     
    diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java
    index 322154991e5b..dd6275bcd9d0 100644
    --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java
    +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java
    @@ -53,6 +53,7 @@
     import java.io.IOException;
     import java.util.ArrayList;
     import java.util.List;
    +import java.util.concurrent.ScheduledExecutorService;
     
     // Manually-added imports: add custom (non-generated) imports after this point.
     
    @@ -66,13 +67,12 @@
      *
      * 
      * 
    - * try (SubscriberApi subscriberApi = SubscriberApi.defaultInstance()) {
    - *   // make calls here
    - * String name = "";
    - * String topic = "";
    - * PushConfig pushConfig = PushConfig.newBuilder().build();
    - * int ackDeadlineSeconds = 0;
    - * Subscription callResult = createSubscription(name, topic, pushConfig, ackDeadlineSeconds);
    + * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    + *   String name = "";
    + *   String topic = "";
    + *   PushConfig pushConfig = PushConfig.newBuilder().build();
    + *   int ackDeadlineSeconds = 0;
    + *   Subscription callResult = subscriberApi.createSubscription(name, topic, pushConfig, ackDeadlineSeconds);
      * }
      * 
      * 
    @@ -104,15 +104,10 @@ *

    This class can be customized by passing in a custom instance of SubscriberSettings to * create(). For example: * - * *

      * 
    - * ConnectionSettings defaultConnectionSettings =
    - *     SubscriberSettings.defaultInstance().toBuilder().getConnectionSettings();
    - * ConnectionSettings updatedConnectionSettings =
    - *     defaultConnectionSettings.toBuilder().provideCredentialsWith(myCredentials).build();
    - * SubscriberSettings subscriberSettings = SubscriberSettings.defaultInstance().toBuilder().
    - *     provideChannelWith(updatedConnectionSettings)
    + * SubscriberSettings subscriberSettings = SubscriberSettings.defaultBuilder()
    + *     .provideChannelWith(myCredentials)
      *     .build();
      * SubscriberApi subscriberApi = SubscriberApi.create(subscriberSettings);
      * 
    @@ -123,7 +118,9 @@
      */
     @javax.annotation.Generated("by GAPIC")
     public class SubscriberApi implements AutoCloseable {
    +  private final SubscriberSettings settings;
       private final ManagedChannel channel;
    +  private final ScheduledExecutorService executor;
       private final List closeables = new ArrayList<>();
     
       private final ApiCallable createSubscriptionCallable;
    @@ -138,11 +135,18 @@ public class SubscriberApi implements AutoCloseable {
       private final ApiCallable pullCallable;
       private final ApiCallable modifyPushConfigCallable;
     
    +  public final SubscriberSettings getSettings() {
    +    return settings;
    +  }
    +
       private static final PathTemplate PROJECT_PATH_TEMPLATE =
    -      PathTemplate.create("projects/{project}");
    +      PathTemplate.createWithoutUrlEncoding("projects/{project}");
     
       private static final PathTemplate SUBSCRIPTION_PATH_TEMPLATE =
    -      PathTemplate.create("projects/{project}/subscriptions/{subscription}");
    +      PathTemplate.createWithoutUrlEncoding("projects/{project}/subscriptions/{subscription}");
    +
    +  private static final PathTemplate TOPIC_PATH_TEMPLATE =
    +      PathTemplate.createWithoutUrlEncoding("projects/{project}/topics/{topic}");
     
       /**
        * Formats a string containing the fully-qualified path to represent
    @@ -166,6 +170,17 @@ public static final String formatSubscriptionName(String project, String subscri
         return SUBSCRIPTION_PATH_TEMPLATE.instantiate("project", project, "subscription", subscription);
       }
     
    +  /**
    +   * Formats a string containing the fully-qualified path to represent
    +   * a topic resource.
    +   *
    +   * 
    +   * 
    +   */
    +  public static final String formatTopicName(String project, String topic) {
    +    return TOPIC_PATH_TEMPLATE.instantiate("project", project, "topic", topic);
    +  }
    +
       /**
        * Parses the project from the given fully-qualified path which
        * represents a project resource.
    @@ -199,14 +214,36 @@ public static final String parseSubscriptionFromSubscriptionName(String subscrip
         return SUBSCRIPTION_PATH_TEMPLATE.parse(subscriptionName).get("subscription");
       }
     
    +  /**
    +   * Parses the project from the given fully-qualified path which
    +   * represents a topic resource.
    +   *
    +   * 
    +   * 
    +   */
    +  public static final String parseProjectFromTopicName(String topicName) {
    +    return TOPIC_PATH_TEMPLATE.parse(topicName).get("project");
    +  }
    +
    +  /**
    +   * Parses the topic from the given fully-qualified path which
    +   * represents a topic resource.
    +   *
    +   * 
    +   * 
    +   */
    +  public static final String parseTopicFromTopicName(String topicName) {
    +    return TOPIC_PATH_TEMPLATE.parse(topicName).get("topic");
    +  }
    +
       /**
        * Constructs an instance of SubscriberApi with default settings.
        *
        * 
        * 
        */
    -  public static final SubscriberApi defaultInstance() throws IOException {
    -    return create(SubscriberSettings.defaultInstance());
    +  public static final SubscriberApi createWithDefaults() throws IOException {
    +    return create(SubscriberSettings.defaultBuilder().build());
       }
     
       /**
    @@ -230,25 +267,30 @@ public static final SubscriberApi create(SubscriberSettings settings) throws IOE
        * 
        */
       protected SubscriberApi(SubscriberSettings settings) throws IOException {
    -    this.channel = settings.getChannel();
    +    this.settings = settings;
    +    this.executor = settings.getExecutorProvider().getOrBuildExecutor();
    +    this.channel = settings.getChannelProvider().getOrBuildChannel(this.executor);
     
         this.createSubscriptionCallable =
    -        ApiCallable.create(settings.createSubscriptionSettings(), settings);
    -    this.getSubscriptionCallable = ApiCallable.create(settings.getSubscriptionSettings(), settings);
    +        ApiCallable.create(settings.createSubscriptionSettings(), this.channel, this.executor);
    +    this.getSubscriptionCallable =
    +        ApiCallable.create(settings.getSubscriptionSettings(), this.channel, this.executor);
         this.listSubscriptionsCallable =
    -        ApiCallable.create(settings.listSubscriptionsSettings(), settings);
    +        ApiCallable.create(settings.listSubscriptionsSettings(), this.channel, this.executor);
         this.listSubscriptionsPagedCallable =
    -        ApiCallable.createPagedVariant(settings.listSubscriptionsSettings(), settings);
    +        ApiCallable.createPagedVariant(
    +            settings.listSubscriptionsSettings(), this.channel, this.executor);
         this.deleteSubscriptionCallable =
    -        ApiCallable.create(settings.deleteSubscriptionSettings(), settings);
    +        ApiCallable.create(settings.deleteSubscriptionSettings(), this.channel, this.executor);
         this.modifyAckDeadlineCallable =
    -        ApiCallable.create(settings.modifyAckDeadlineSettings(), settings);
    -    this.acknowledgeCallable = ApiCallable.create(settings.acknowledgeSettings(), settings);
    -    this.pullCallable = ApiCallable.create(settings.pullSettings(), settings);
    +        ApiCallable.create(settings.modifyAckDeadlineSettings(), this.channel, this.executor);
    +    this.acknowledgeCallable =
    +        ApiCallable.create(settings.acknowledgeSettings(), this.channel, this.executor);
    +    this.pullCallable = ApiCallable.create(settings.pullSettings(), this.channel, this.executor);
         this.modifyPushConfigCallable =
    -        ApiCallable.create(settings.modifyPushConfigSettings(), settings);
    +        ApiCallable.create(settings.modifyPushConfigSettings(), this.channel, this.executor);
     
    -    if (settings.shouldAutoCloseChannel()) {
    +    if (settings.getChannelProvider().shouldAutoClose()) {
           closeables.add(
               new Closeable() {
                 @Override
    @@ -257,6 +299,15 @@ public void close() throws IOException {
                 }
               });
         }
    +    if (settings.getExecutorProvider().shouldAutoClose()) {
    +      closeables.add(
    +          new Closeable() {
    +            @Override
    +            public void close() throws IOException {
    +              executor.shutdown();
    +            }
    +          });
    +    }
       }
     
       // ----- createSubscription -----
    @@ -346,7 +397,6 @@ public Subscription createSubscription(Subscription request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable createSubscriptionCallable() {
         return createSubscriptionCallable;
    @@ -400,7 +450,6 @@ private Subscription getSubscription(GetSubscriptionRequest request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable getSubscriptionCallable() {
         return getSubscriptionCallable;
    @@ -453,7 +502,6 @@ public final PageAccessor listSubscriptions(ListSubscriptionsReque
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable>
           listSubscriptionsPagedCallable() {
    @@ -469,7 +517,6 @@ public final PageAccessor listSubscriptions(ListSubscriptionsReque
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable
           listSubscriptionsCallable() {
    @@ -527,7 +574,6 @@ private void deleteSubscription(DeleteSubscriptionRequest request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable deleteSubscriptionCallable() {
         return deleteSubscriptionCallable;
    @@ -592,7 +638,6 @@ public void modifyAckDeadline(ModifyAckDeadlineRequest request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable modifyAckDeadlineCallable() {
         return modifyAckDeadlineCallable;
    @@ -657,7 +702,6 @@ public void acknowledge(AcknowledgeRequest request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable acknowledgeCallable() {
         return acknowledgeCallable;
    @@ -721,7 +765,6 @@ public PullResponse pull(PullRequest request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable pullCallable() {
         return pullCallable;
    @@ -790,7 +833,6 @@ public void modifyPushConfig(ModifyPushConfigRequest request) {
        *
        * 
        * 
    -   * @throws com.google.api.gax.grpc.ApiException if the remote call fails
        */
       public final ApiCallable modifyPushConfigCallable() {
         return modifyPushConfigCallable;
    diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberSettings.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberSettings.java
    index 39fdadccea2a..b7a34d966b26 100644
    --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberSettings.java
    +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberSettings.java
    @@ -40,6 +40,7 @@
     import com.google.api.gax.grpc.PageStreamingDescriptor;
     import com.google.api.gax.grpc.ServiceApiSettings;
     import com.google.api.gax.grpc.SimpleCallSettings;
    +import com.google.auth.Credentials;
     import com.google.common.collect.ImmutableList;
     import com.google.common.collect.ImmutableMap;
     import com.google.common.collect.ImmutableSet;
    @@ -60,6 +61,7 @@
     import io.grpc.ManagedChannel;
     import io.grpc.Status;
     import java.io.IOException;
    +import java.util.List;
     import java.util.concurrent.ScheduledExecutorService;
     import org.joda.time.Duration;
     
    @@ -85,7 +87,7 @@
      * 
      * 
      * SubscriberSettings.Builder subscriberSettingsBuilder =
    - *     SubscriberSettings.defaultInstance().toBuilder();
    + *     SubscriberSettings.defaultBuilder();
      * subscriberSettingsBuilder.CreateSubscriptionSettings().getRetrySettingsBuilder()
      *     .setTotalTimeout(Duration.standardSeconds(30));
      * SubscriberSettings subscriberSettings = subscriberSettingsBuilder.build();
    @@ -120,6 +122,16 @@ public class SubscriberSettings extends ServiceApiSettings {
               .add("https://www.googleapis.com/auth/cloud-platform")
               .build();
     
    +  /**
    +   * The default connection settings of the service.
    +   */
    +  public static final ConnectionSettings DEFAULT_CONNECTION_SETTINGS =
    +      ConnectionSettings.newBuilder()
    +          .setServiceAddress(DEFAULT_SERVICE_ADDRESS)
    +          .setPort(DEFAULT_SERVICE_PORT)
    +          .provideCredentialsWith(DEFAULT_SERVICE_SCOPES)
    +          .build();
    +
       private final SimpleCallSettings createSubscriptionSettings;
       private final SimpleCallSettings getSubscriptionSettings;
       private final PageStreamingCallSettings<
    @@ -191,10 +203,10 @@ public SimpleCallSettings modifyPushConfigSettin
       }
     
       /**
    -   * Returns an instance of this class with recommended defaults.
    +   * Returns a builder for this class with recommended defaults.
        */
    -  public static SubscriberSettings defaultInstance() throws IOException {
    -    return newBuilder().build();
    +  public static Builder defaultBuilder() {
    +    return Builder.createDefault();
       }
     
       /**
    @@ -213,10 +225,8 @@ public Builder toBuilder() {
     
       private SubscriberSettings(Builder settingsBuilder) throws IOException {
         super(
    -        settingsBuilder.getOrBuildChannel(),
    -        settingsBuilder.shouldAutoCloseChannel(),
    -        settingsBuilder.getOrBuildExecutor(),
    -        settingsBuilder.getConnectionSettings(),
    +        settingsBuilder.getChannelProvider(),
    +        settingsBuilder.getExecutorProvider(),
             settingsBuilder.getGeneratorName(),
             settingsBuilder.getGeneratorVersion(),
             settingsBuilder.getClientLibName(),
    @@ -311,53 +321,30 @@ public static class Builder extends ServiceApiSettings.Builder {
         }
     
         private Builder() {
    -      super(
    -          ConnectionSettings.newBuilder()
    -              .setServiceAddress(DEFAULT_SERVICE_ADDRESS)
    -              .setPort(DEFAULT_SERVICE_PORT)
    -              .provideCredentialsWith(DEFAULT_SERVICE_SCOPES)
    -              .build());
    +      super(DEFAULT_CONNECTION_SETTINGS);
     
           createSubscriptionSettings =
    -          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_CREATE_SUBSCRIPTION)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_CREATE_SUBSCRIPTION);
     
           getSubscriptionSettings =
    -          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_GET_SUBSCRIPTION)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_GET_SUBSCRIPTION);
     
           listSubscriptionsSettings =
               PageStreamingCallSettings.newBuilder(
    -                  SubscriberGrpc.METHOD_LIST_SUBSCRIPTIONS, LIST_SUBSCRIPTIONS_PAGE_STR_DESC)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +              SubscriberGrpc.METHOD_LIST_SUBSCRIPTIONS, LIST_SUBSCRIPTIONS_PAGE_STR_DESC);
     
           deleteSubscriptionSettings =
    -          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_DELETE_SUBSCRIPTION)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_DELETE_SUBSCRIPTION);
     
           modifyAckDeadlineSettings =
    -          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_MODIFY_ACK_DEADLINE)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_MODIFY_ACK_DEADLINE);
     
    -      acknowledgeSettings =
    -          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_ACKNOWLEDGE)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +      acknowledgeSettings = SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_ACKNOWLEDGE);
     
    -      pullSettings =
    -          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_PULL)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +      pullSettings = SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_PULL);
     
           modifyPushConfigSettings =
    -          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_MODIFY_PUSH_CONFIG)
    -              .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    -              .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +          SimpleCallSettings.newBuilder(SubscriberGrpc.METHOD_MODIFY_PUSH_CONFIG);
     
           methodSettingsBuilders =
               ImmutableList.of(
    @@ -371,6 +358,51 @@ private Builder() {
                   modifyPushConfigSettings);
         }
     
    +    private static Builder createDefault() {
    +      Builder builder = new Builder();
    +      builder
    +          .createSubscriptionSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .getSubscriptionSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .listSubscriptionsSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .deleteSubscriptionSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .modifyAckDeadlineSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .acknowledgeSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .pullSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      builder
    +          .modifyPushConfigSettings()
    +          .setRetryableCodes(RETRYABLE_CODE_DEFINITIONS.get("non_idempotent"))
    +          .setRetrySettingsBuilder(RETRY_PARAM_DEFINITIONS.get("default"));
    +
    +      return builder;
    +    }
    +
         private Builder(SubscriberSettings settings) {
           super(settings);
     
    @@ -395,6 +427,17 @@ private Builder(SubscriberSettings settings) {
                   modifyPushConfigSettings);
         }
     
    +    @Override
    +    protected ConnectionSettings getDefaultConnectionSettings() {
    +      return DEFAULT_CONNECTION_SETTINGS;
    +    }
    +
    +    @Override
    +    public Builder provideExecutorWith(ScheduledExecutorService executor, boolean shouldAutoClose) {
    +      super.provideExecutorWith(executor, shouldAutoClose);
    +      return this;
    +    }
    +
         @Override
         public Builder provideChannelWith(ManagedChannel channel, boolean shouldAutoClose) {
           super.provideChannelWith(channel, shouldAutoClose);
    @@ -408,8 +451,14 @@ public Builder provideChannelWith(ConnectionSettings settings) {
         }
     
         @Override
    -    public Builder setExecutor(ScheduledExecutorService executor) {
    -      super.setExecutor(executor);
    +    public Builder provideChannelWith(Credentials credentials) {
    +      super.provideChannelWith(credentials);
    +      return this;
    +    }
    +
    +    @Override
    +    public Builder provideChannelWith(List scopes) {
    +      super.provideChannelWith(scopes);
           return this;
         }
     
    diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/spi/v1/PublisherApiTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/spi/v1/PublisherApiTest.java
    index 0b508efec143..fdb8234d51da 100644
    --- a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/spi/v1/PublisherApiTest.java
    +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/spi/v1/PublisherApiTest.java
    @@ -59,7 +59,7 @@ public void setUp() throws Exception {
         ManagedChannel channel = pubsubHelper.createChannel();
     
         PublisherSettings publisherSettings =
    -        PublisherSettings.newBuilder()
    +        PublisherSettings.defaultBuilder()
                 .provideChannelWith(channel, true)
                 .build();
         publisherApi = PublisherApi.create(publisherSettings);
    @@ -69,7 +69,7 @@ public void setUp() throws Exception {
                 .setElementCountThreshold(10)
                 .setDelayThreshold(Duration.standardSeconds(30));
     
    -    PublisherSettings.Builder bundledPublisherSettingsBuilder = PublisherSettings.newBuilder();
    +    PublisherSettings.Builder bundledPublisherSettingsBuilder = PublisherSettings.defaultBuilder();
         bundledPublisherSettingsBuilder
             .provideChannelWith(channel, true)
             .publishSettings()
    @@ -78,7 +78,7 @@ public void setUp() throws Exception {
         PublisherSettings bundledPublisherSettings = bundledPublisherSettingsBuilder.build();
         bundledPublisherApi = PublisherApi.create(bundledPublisherSettings);
     
    -    SubscriberSettings subscriberSettings = SubscriberSettings.newBuilder()
    +    SubscriberSettings subscriberSettings = SubscriberSettings.defaultBuilder()
             .provideChannelWith(channel, true)
             .build();
         subscriberApi = SubscriberApi.create(subscriberSettings);
    
    From 7857986129ecf139d54f801cc19ab8a9ba16cc3b Mon Sep 17 00:00:00 2001
    From: Marco Ziccardi 
    Date: Thu, 5 May 2016 10:46:52 +0200
    Subject: [PATCH 338/375] Add javadoc and unit tests for SubscriptionInfo
     (#977)
    
    ---
     .../com/google/cloud/pubsub/Subscription.java |  17 ++-
     .../google/cloud/pubsub/SubscriptionInfo.java | 143 ++++++++++++++++--
     .../com/google/cloud/pubsub/TopicInfo.java    |   7 +-
     .../cloud/pubsub/SubscriptionInfoTest.java    |  91 +++++++++++
     4 files changed, 243 insertions(+), 15 deletions(-)
     create mode 100644 gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionInfoTest.java
    
    diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java
    index d49328ad7486..effa3b59ef0c 100644
    --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java
    +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java
    @@ -21,6 +21,7 @@
     import com.google.cloud.pubsub.PubSub.MessageConsumer;
     import com.google.cloud.pubsub.PubSub.MessageProcessor;
     import com.google.cloud.pubsub.PubSub.PullOption;
    +import com.google.common.base.Function;
     
     import java.io.IOException;
     import java.io.ObjectInputStream;
    @@ -103,7 +104,11 @@ public boolean equals(Object obj) {
           return false;
         }
         Subscription other = (Subscription) obj;
    -    return Objects.equals(toPb(), other.toPb()) && Objects.equals(options, other.options);
    +    return Objects.equals(topic(), other.topic())
    +        && Objects.equals(name(), other.name())
    +        && Objects.equals(pushConfig(), other.pushConfig())
    +        && ackDeadlineSeconds() == other.ackDeadlineSeconds()
    +        && Objects.equals(options, other.options);
       }
     
       public PubSub pubSub() {
    @@ -155,4 +160,14 @@ static Subscription fromPb(PubSub storage, com.google.pubsub.v1.Subscription sub
         SubscriptionInfo subscriptionInfo = SubscriptionInfo.fromPb(subscriptionPb);
         return new Subscription(storage, new BuilderImpl(subscriptionInfo));
       }
    +
    +  static Function fromPbFunction(
    +      final PubSub pubsub) {
    +    return new Function() {
    +      @Override
    +      public Subscription apply(com.google.pubsub.v1.Subscription subscriptionPb) {
    +        return fromPb(pubsub, subscriptionPb);
    +      }
    +    };
    +  }
     }
    diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionInfo.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionInfo.java
    index 97e7b35becd9..4ec97ca7d3f7 100644
    --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionInfo.java
    +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionInfo.java
    @@ -18,13 +18,35 @@
     
     import static com.google.common.base.Preconditions.checkNotNull;
     
    +import com.google.cloud.pubsub.spi.v1.PublisherApi;
    +import com.google.cloud.pubsub.spi.v1.SubscriberApi;
     import com.google.common.base.MoreObjects;
     
     import java.io.Serializable;
     import java.util.Objects;
    +import java.util.concurrent.TimeUnit;
     
     /**
    - * Pub/Sub subscription information.
    + * A Google Cloud Pub/Sub subscription. A subscription represents the stream of messages from a
    + * single, specific topic, to be delivered to the subscribing application. Pub/Sub subscriptions
    + * support both push and pull message delivery.
    + *
    + * 

    In a push subscription, the Pub/Sub server sends a request to the subscriber application, at a + * preconfigured endpoint (see {@link PushConfig}). The subscriber's HTTP response serves as an + * implicit acknowledgement: a success response indicates that the message has been succesfully + * processed and the Pub/Sub system can delete it from the subscription; a non-success response + * indicates that the Pub/Sub server should resend it (implicit "nack"). + * + *

    In a pull subscription, the subscribing application must explicitly pull messages using one of + * {@link PubSub#pull(String, PubSub.PullOption...)}, + * {@link PubSub#pullAsync(String, PubSub.MessageProcessor)} or + * {@link PubSub#pullAsync(String, PubSub.PullOption...)}. The subscribing application must then + * explicitly acknowledge the messages using one of {@link PubSub#ack(String, Iterable)}, + * {@link PubSub#ack(String, String, String...)}, {@link PubSub#ackAsync(String, Iterable)} or + * {@link PubSub#ackAsync(String, String, String...)}. + * + * @see Pub/Sub Data Model + * @see Subscriber Guide */ public class SubscriptionInfo implements Serializable { @@ -35,20 +57,47 @@ public class SubscriptionInfo implements Serializable { private final PushConfig pushConfig; private final int ackDeadlineSeconds; - /** - * Builder for Subscription. + * Builder for {@code SubscriptionInfo} objects. */ public abstract static class Builder { + /** + * Sets the name of the subscription. The name must start with a letter, and contain only + * letters ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores + * ({@code _}), periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs + * ({@code %}). It must be between 3 and 255 characters in length and cannot begin with the + * string {@code goog}. + */ public abstract Builder name(String name); + /** + * Sets the name of the topic the subscription refers to. + */ public abstract Builder topic(String name); + /** + * Sets the push configuration for the subscription. If set, the subscription will be in + * push mode and the {@code pushConfig} parameter provides the push endpoint. If not set, the + * subscription will be in pull mode. + */ public abstract Builder pushConfig(PushConfig pushConfig); + /** + * Sets the maximum time after a subscriber receives a message before the subscriber should + * acknowledge the message. After message delivery but before the ack deadline expires and + * before the message is acknowledged, it is an outstanding message and will not be delivered + * again during that time (on a best-effort basis). For pull subscriptions, this value is used + * as the initial value for the ack deadline. To override the ack deadline value for a given + * message, use {@link PubSub#modifyAckDeadline(String, int, TimeUnit, Iterable)}. For push + * delivery, this value is used to set the request timeout for the call to the push endpoint. If + * not specified, the default value of 10 seconds is used. + */ public abstract Builder ackDeadLineSeconds(int ackDeadLineSeconds); + /** + * Creates a subscription object. + */ public abstract SubscriptionInfo build(); } @@ -108,31 +157,60 @@ public SubscriptionInfo build() { ackDeadlineSeconds = builder.ackDeadlineSeconds; } + /** + * Returns the name of the topic this subscription refers to. + */ public String topic() { return topic; } + /** + * Sets the name of the subscription. The name must start with a letter, and contain only + * letters ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores + * ({@code _}), periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs + * ({@code %}). It must be between 3 and 255 characters in length and cannot begin with the + * string {@code goog}. + */ public String name() { return name; } + /** + * Returns the push configuration for the subscription. If set, the subscription is in push mode + * and the returned value defines the push endpoint. If {@code null}, the subscription is in pull + * mode. + */ public PushConfig pushConfig() { return pushConfig; } + /** + * Returns the maximum time after a subscriber receives a message before the subscriber should + * acknowledge the message. After message delivery but before the ack deadline expires and + * before the message is acknowledged, it is an outstanding message and will not be delivered + * again during that time (on a best-effort basis). For pull subscriptions, this value is used + * as the initial value for the ack deadline. To override the ack deadline value for a given + * message, use {@link PubSub#modifyAckDeadline(String, int, TimeUnit, Iterable)}. For push + * delivery, this value is used to set the request timeout for the call to the push endpoint. If + * not specified, the default value of 10 seconds is used. + */ public long ackDeadlineSeconds() { return ackDeadlineSeconds; } @Override - public boolean equals(Object o) { - if (this == o) { + public boolean equals(Object obj) { + if (this == obj) { return true; } - if (o == null || getClass() != o.getClass()) { + if (obj == null || !obj.getClass().equals(this.getClass())) { return false; } - return Objects.equals(toPb(), ((SubscriptionInfo) o).toPb()); + SubscriptionInfo other = (SubscriptionInfo) obj; + return Objects.equals(topic, other.topic) + && Objects.equals(name, other.name) + && Objects.equals(pushConfig, other.pushConfig) + && ackDeadlineSeconds == other.ackDeadlineSeconds; } @Override @@ -150,11 +228,11 @@ public String toString() { .toString(); } - com.google.pubsub.v1.Subscription toPb() { + com.google.pubsub.v1.Subscription toPb(String projectId) { com.google.pubsub.v1.Subscription.Builder builder = com.google.pubsub.v1.Subscription.newBuilder(); - builder.setTopic(topic); - builder.setName(name); + builder.setTopic(PublisherApi.formatTopicName(projectId, topic)); + builder.setName(SubscriberApi.formatSubscriptionName(projectId, name)); builder.setAckDeadlineSeconds(ackDeadlineSeconds); if (pushConfig != null) { builder.setPushConfig(pushConfig.toPb()); @@ -163,26 +241,67 @@ com.google.pubsub.v1.Subscription toPb() { } static SubscriptionInfo fromPb(com.google.pubsub.v1.Subscription subscription) { - Builder builder = builder(subscription.getTopic(), subscription.getName()); + Builder builder = builder(PublisherApi.parseTopicFromTopicName(subscription.getTopic()), + SubscriberApi.parseSubscriptionFromSubscriptionName(subscription.getName())); builder.ackDeadLineSeconds(subscription.getAckDeadlineSeconds()); - if (subscription.hasPushConfig()) { + // A subscription with an "empty" push config is a pull subscription + if (subscription.hasPushConfig() + && !subscription.getPushConfig().getPushEndpoint().equals("")) { builder.pushConfig(PushConfig.fromPb(subscription.getPushConfig())); } return builder.build(); } + /** + * Returns a builder for the subscription object. + */ public Builder toBuilder() { return new BuilderImpl(this); } + /** + * Creates a pull {@code SubscriptionInfo} object given the name of the topic and the name of the + * subscription. + * + * @param topic the name of the topic the subscription refers to + * @param name the name of the subscription. The name must start with a letter, and contain only + * letters ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores + * ({@code _}), periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs + * ({@code %}). It must be between 3 and 255 characters in length and cannot begin with the + * string {@code goog} + */ public static SubscriptionInfo of(String topic, String name) { return builder(topic, name).build(); } + /** + * Creates a push {@code SubscriptionInfo} object given the name of the topic, the name of the + * subscription and the push endpoint. + * + * @param topic the name of the topic the subscription refers to + * @param name the name of the subscription. The name must start with a letter, and contain only + * letters ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores + * ({@code _}), periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs + * ({@code %}). It must be between 3 and 255 characters in length and cannot begin with the + * string {@code goog} + * @param endpoint a URL locating the endpoint to which messages should be pushed. For example, + * an endpoint might use {@code https://example.com/push}. + */ public static SubscriptionInfo of(String topic, String name, String endpoint) { return builder(topic, name).pushConfig(PushConfig.of(endpoint)).build(); } + /** + * Creates a builder for {@code SubscriptionInfo} objects given the name of the topic and the name + * of the subscription. + * + * @param topic the name of the topic the subscription refers to + * @param name the name of the subscription. The name must start with a letter, and contain only + * letters ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores + * ({@code _}), periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs + * ({@code %}). It must be between 3 and 255 characters in length and cannot begin with the + * string {@code goog} + */ public static Builder builder(String topic, String name) { return new BuilderImpl(topic, name); } diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicInfo.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicInfo.java index d69cb92f3244..acc5fbbd41ee 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicInfo.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicInfo.java @@ -126,6 +126,9 @@ static TopicInfo fromPb(com.google.pubsub.v1.Topic topicPb) { return builder(PublisherApi.parseTopicFromTopicName(topicPb.getName())).build(); } + /** + * Returns a builder for the topic object. + */ public Builder toBuilder() { return new BuilderImpl(this); } @@ -137,7 +140,7 @@ public Builder toBuilder() { * ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores ({@code _}), * periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs ({@code %}). * It must be between 3 and 255 characters in length and cannot begin with the string - * {@code goog}. + * {@code goog} */ public static TopicInfo of(String name) { return builder(name).build(); @@ -150,7 +153,7 @@ public static TopicInfo of(String name) { * ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores ({@code _}), * periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs ({@code %}). * It must be between 3 and 255 characters in length and cannot begin with the string - * {@code goog}. + * {@code goog} */ public static Builder builder(String name) { return new BuilderImpl(name); diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionInfoTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionInfoTest.java new file mode 100644 index 000000000000..574d40e39ce2 --- /dev/null +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionInfoTest.java @@ -0,0 +1,91 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Test; + +public class SubscriptionInfoTest { + + private static final String TOPIC = "topic"; + private static final String NAME = "subscription"; + private static final String ENDPOINT = "https://example.com/push"; + private static final PushConfig PUSH_CONFIG = PushConfig.of(ENDPOINT); + private static final int ACK_DEADLINE = 42; + private static final SubscriptionInfo SUBSCRIPTION_INFO = SubscriptionInfo.builder(TOPIC, NAME) + .pushConfig(PUSH_CONFIG) + .ackDeadLineSeconds(ACK_DEADLINE) + .build(); + + @Test + public void testToBuilder() { + compareSubscriptionInfo(SUBSCRIPTION_INFO, SUBSCRIPTION_INFO.toBuilder().build()); + SubscriptionInfo subscriptionInfo = SUBSCRIPTION_INFO.toBuilder() + .topic("newTopic") + .name("newSubscription") + .build(); + assertEquals("newTopic", subscriptionInfo.topic()); + assertEquals("newSubscription", subscriptionInfo.name()); + subscriptionInfo = subscriptionInfo.toBuilder().name(NAME).topic(TOPIC).build(); + compareSubscriptionInfo(SUBSCRIPTION_INFO, subscriptionInfo); + } + + @Test + public void testBuilder() { + assertEquals(TOPIC, SUBSCRIPTION_INFO.topic()); + assertEquals(NAME, SUBSCRIPTION_INFO.name()); + assertEquals(PUSH_CONFIG, SUBSCRIPTION_INFO.pushConfig()); + assertEquals(ACK_DEADLINE, SUBSCRIPTION_INFO.ackDeadlineSeconds()); + } + + @Test + public void testOf() { + SubscriptionInfo subscriptionInfo = SubscriptionInfo.of(TOPIC, NAME); + assertEquals(TOPIC, subscriptionInfo.topic()); + assertEquals(NAME, subscriptionInfo.name()); + assertNull(subscriptionInfo.pushConfig()); + assertEquals(0, subscriptionInfo.ackDeadlineSeconds()); + subscriptionInfo = SubscriptionInfo.of(TOPIC, NAME, ENDPOINT); + assertEquals(TOPIC, subscriptionInfo.topic()); + assertEquals(NAME, subscriptionInfo.name()); + assertEquals(PushConfig.of(ENDPOINT), subscriptionInfo.pushConfig()); + assertEquals(0, subscriptionInfo.ackDeadlineSeconds()); + } + + @Test + public void testToAndFromPb() { + compareSubscriptionInfo(SUBSCRIPTION_INFO, + SubscriptionInfo.fromPb(SUBSCRIPTION_INFO.toPb("project"))); + SubscriptionInfo subscriptionInfo = SubscriptionInfo.of(TOPIC, NAME); + compareSubscriptionInfo(subscriptionInfo, + SubscriptionInfo.fromPb(subscriptionInfo.toPb("project"))); + subscriptionInfo = SubscriptionInfo.of(TOPIC, NAME, ENDPOINT); + compareSubscriptionInfo(subscriptionInfo, + SubscriptionInfo.fromPb(subscriptionInfo.toPb("project"))); + } + + private void compareSubscriptionInfo(SubscriptionInfo expected, SubscriptionInfo value) { + assertEquals(expected, value); + assertEquals(expected.topic(), value.topic()); + assertEquals(expected.name(), value.name()); + assertEquals(expected.pushConfig(), value.pushConfig()); + assertEquals(expected.ackDeadlineSeconds(), value.ackDeadlineSeconds()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} From c339bf8460db747a5f6a6e1626557371b02c0b2f Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 6 May 2016 17:24:16 +0200 Subject: [PATCH 339/375] Re-enable ignored BigQuery integration tests (#986) --- .../test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java index 9e462a4d5142..5007c73b69ce 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java @@ -624,7 +624,6 @@ public void testInsertAllWithErrors() { assertTrue(bigquery.delete(TableId.of(DATASET, tableName))); } - @Ignore("Flaky test; see issue #836") @Test public void testListAllTableData() { Page> rows = bigquery.listTableData(TABLE_ID); @@ -908,7 +907,6 @@ public void testCancelNonExistingJob() { assertFalse(bigquery.cancel("test_cancel_non_existing_job")); } - @Ignore("Flaky test; see #836") @Test public void testInsertFromFile() throws InterruptedException { String destinationTableName = "test_insert_from_file_table"; From 6bc34ff43eca99a95472d3d4e014cc062fdef200 Mon Sep 17 00:00:00 2001 From: Shin Fan Date: Fri, 6 May 2016 15:06:30 -0700 Subject: [PATCH 340/375] Update LocalPubsubHelper to be compatible with beta emulators. (#992) --- .../com/google/cloud/pubsub/testing/LocalPubsubHelper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/testing/LocalPubsubHelper.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/testing/LocalPubsubHelper.java index 88acb46101b1..afdba1c135ed 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/testing/LocalPubsubHelper.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/testing/LocalPubsubHelper.java @@ -71,7 +71,7 @@ public class LocalPubsubHelper { public LocalPubsubHelper() { port = LocalServiceHelper.findAvailablePort(DEFAULT_PORT); List gcloudCommand = new ArrayList<>(Arrays.asList(GCLOUD_CMD_TEXT.split(" "))); - gcloudCommand.add(GCLOUD_CMD_PORT_FLAG + port); + gcloudCommand.add(GCLOUD_CMD_PORT_FLAG + "localhost:" + port); GCloudEmulatorRunner gcloudRunner = new GCloudEmulatorRunner(gcloudCommand, VERSION_PREFIX, MIN_VERSION); DownloadableEmulatorRunner downloadRunner = @@ -89,7 +89,7 @@ public LocalPubsubHelper() { * @throws IOException */ public void start() throws IOException, InterruptedException { - String blockUntilOutput = Integer.toString(port); + String blockUntilOutput = "Server started, listening on " + port; serviceHelper.start(blockUntilOutput); } From 9879a16ee47bda2df53b39d344a1eedd078193ff Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 10 May 2016 15:58:04 +0200 Subject: [PATCH 341/375] Add TopicId and SubscriptionId classes (#984) * Add TopicId class and tests. Use TopicId in SubscriptionInfo * Add SubscriptionId class and tests. Use SubscriptionId in listSubscriptions(topic) * Minor javadoc fixes * Add identity for deleted topics --- .../main/java/com/google/cloud/AsyncPage.java | 5 +- .../java/com/google/cloud/AsyncPageImpl.java | 5 +- .../java/com/google/cloud/pubsub/PubSub.java | 4 +- .../com/google/cloud/pubsub/PubSubImpl.java | 4 +- .../com/google/cloud/pubsub/Subscription.java | 16 +- .../google/cloud/pubsub/SubscriptionId.java | 89 +++++++++++ .../google/cloud/pubsub/SubscriptionInfo.java | 109 ++++++++++++-- .../java/com/google/cloud/pubsub/Topic.java | 4 +- .../java/com/google/cloud/pubsub/TopicId.java | 138 ++++++++++++++++++ .../com/google/cloud/pubsub/TopicInfo.java | 4 +- .../cloud/pubsub/SubscriptionIdTest.java | 50 +++++++ .../cloud/pubsub/SubscriptionInfoTest.java | 44 +++++- .../com/google/cloud/pubsub/TopicIdTest.java | 73 +++++++++ 13 files changed, 513 insertions(+), 32 deletions(-) create mode 100644 gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionId.java create mode 100644 gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicId.java create mode 100644 gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionIdTest.java create mode 100644 gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/TopicIdTest.java diff --git a/gcloud-java-core/src/main/java/com/google/cloud/AsyncPage.java b/gcloud-java-core/src/main/java/com/google/cloud/AsyncPage.java index d82d46f19b2d..8d7ff026e70d 100644 --- a/gcloud-java-core/src/main/java/com/google/cloud/AsyncPage.java +++ b/gcloud-java-core/src/main/java/com/google/cloud/AsyncPage.java @@ -37,7 +37,7 @@ * for (T value : page.values()) { * // do something with value * } - * page = page.nextPage().get(); + * page = page.nextPageAsync().get(); * }}

    * * @param the value type that the page holds @@ -45,7 +45,8 @@ public interface AsyncPage extends Page { /** - * Returns a {@link Future} object for the next page. + * Returns a {@link Future} object for the next page. {@link Future#get()} returns {@code null} if + * the last page has been reached. */ Future> nextPageAsync(); } diff --git a/gcloud-java-core/src/main/java/com/google/cloud/AsyncPageImpl.java b/gcloud-java-core/src/main/java/com/google/cloud/AsyncPageImpl.java index 42af7b34a943..706316e362cd 100644 --- a/gcloud-java-core/src/main/java/com/google/cloud/AsyncPageImpl.java +++ b/gcloud-java-core/src/main/java/com/google/cloud/AsyncPageImpl.java @@ -17,6 +17,7 @@ package com.google.cloud; import com.google.common.base.Throwables; +import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.Uninterruptibles; import java.io.Serializable; @@ -47,7 +48,7 @@ private static class SyncNextPageFetcher implements PageImpl.NextPageFetcher< private static final long serialVersionUID = -4124568632363525351L; - private NextPageFetcher asyncPageFetcher; + private final NextPageFetcher asyncPageFetcher; private SyncNextPageFetcher(NextPageFetcher asyncPageFetcher) { this.asyncPageFetcher = asyncPageFetcher; @@ -75,7 +76,7 @@ public AsyncPageImpl(NextPageFetcher asyncPageFetcher, String cursor, Iterabl @Override public Future> nextPageAsync() { if (nextPageCursor() == null || asyncPageFetcher == null) { - return null; + return Futures.immediateCheckedFuture(null); } return asyncPageFetcher.nextPage(); } diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java index 2695cd0064e8..3410d3f54a3e 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java @@ -194,9 +194,9 @@ public static PullOption maxConcurrentCallbacks(int maxConcurrency) { Future> listSubscriptionsAsync(ListOption... options); - Page listSubscriptions(String topic, ListOption... options); + Page listSubscriptions(String topic, ListOption... options); - Future> listSubscriptionsAsync(String topic, ListOption... options); + Future> listSubscriptionsAsync(String topic, ListOption... options); Iterator pull(String subscription, PullOption... options); diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java index df6aa283c1a3..17a99842259f 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java @@ -185,12 +185,12 @@ public Future> listSubscriptionsAsync(ListOption... opti } @Override - public Page listSubscriptions(String topic, ListOption... options) { + public Page listSubscriptions(String topic, ListOption... options) { return null; } @Override - public Future> listSubscriptionsAsync(String topic, + public Future> listSubscriptionsAsync(String topic, ListOption... options) { return null; } diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java index effa3b59ef0c..11efb5971aa2 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java @@ -50,8 +50,20 @@ private Builder(Subscription subscription) { } @Override - public Builder topic(String name) { - delegate.topic(name); + public Builder topic(TopicId topic) { + delegate.topic(topic); + return this; + } + + @Override + public Builder topic(String project, String topic) { + delegate.topic(project, topic); + return this; + } + + @Override + public Builder topic(String topic) { + delegate.topic(topic); return this; } diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionId.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionId.java new file mode 100644 index 000000000000..d083ecd04f26 --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionId.java @@ -0,0 +1,89 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static com.google.cloud.pubsub.spi.v1.SubscriberApi.parseProjectFromSubscriptionName; +import static com.google.cloud.pubsub.spi.v1.SubscriberApi.parseSubscriptionFromSubscriptionName; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; + +import java.io.Serializable; +import java.util.Objects; + +/** + * Identity for a Google PubSub subscription. {@code SubscriptionId} objects are returned by the + * {@link PubSub#listSubscriptions(String, PubSub.ListOption...)} and + * {@link PubSub#listSubscriptionsAsync(String, PubSub.ListOption...)} methods as a topic may have + * subscriptions from different projects. + */ +public class SubscriptionId implements Serializable { + + private static final long serialVersionUID = 6507142968866856283L; + + private final String project; + private final String subscription; + + SubscriptionId(String project, String subscription) { + this.project = checkNotNull(project); + this.subscription = checkNotNull(subscription); + } + + /** + * Returns the name of the project where the subscription resides. + */ + public String project() { + return project; + } + + /** + * Returns the name of the subscription. + */ + public String subscription() { + return subscription; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("project", project) + .add("subscription", subscription).toString(); + } + + @Override + public final int hashCode() { + return Objects.hash(project, subscription); + } + + @Override + public final boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof SubscriptionId)) { + return false; + } + SubscriptionId other = (SubscriptionId) obj; + return Objects.equals(project, other.project) + && Objects.equals(subscription, other.subscription); + } + + static SubscriptionId fromPb(String pb) { + return new SubscriptionId(parseProjectFromSubscriptionName(pb), + parseSubscriptionFromSubscriptionName(pb)); + } +} diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionInfo.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionInfo.java index 4ec97ca7d3f7..3c8722d6e6f9 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionInfo.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionInfo.java @@ -18,7 +18,6 @@ import static com.google.common.base.Preconditions.checkNotNull; -import com.google.cloud.pubsub.spi.v1.PublisherApi; import com.google.cloud.pubsub.spi.v1.SubscriberApi; import com.google.common.base.MoreObjects; @@ -53,7 +52,7 @@ public class SubscriptionInfo implements Serializable { private static final long serialVersionUID = 1860057426574127128L; private final String name; - private final String topic; + private final TopicId topic; private final PushConfig pushConfig; private final int ackDeadlineSeconds; @@ -72,9 +71,22 @@ public abstract static class Builder { public abstract Builder name(String name); /** - * Sets the name of the topic the subscription refers to. + * Sets the topic the subscription refers to, given the topic name. The topic is assumed to + * reside in the {@link PubSubOptions#projectId()} project. */ - public abstract Builder topic(String name); + public abstract Builder topic(String topic); + + /** + * Sets the topic the subscription refers to, given the project and topic names. + */ + public abstract Builder topic(String project, String topic); + + /** + * Sets the topic the subscription refers to, given the topic identity. If + * {@code topic.project()} is {@code null} the topic is assumed to reside in the + * {@link PubSubOptions#projectId()} project. + */ + public abstract Builder topic(TopicId topic); /** * Sets the push configuration for the subscription. If set, the subscription will be in @@ -104,11 +116,11 @@ public abstract static class Builder { static final class BuilderImpl extends Builder { private String name; - private String topic; + private TopicId topic; private PushConfig pushConfig; private int ackDeadlineSeconds; - private BuilderImpl(String topic, String name) { + private BuilderImpl(TopicId topic, String name) { this.topic = checkNotNull(topic); this.name = checkNotNull(name); } @@ -126,8 +138,18 @@ public Builder name(String name) { return this; } + @Override + public Builder topic(String project, String topic) { + return topic(TopicId.of(checkNotNull(project), topic)); + } + @Override public Builder topic(String topic) { + return topic(TopicId.of(topic)); + } + + @Override + public Builder topic(TopicId topic) { this.topic = checkNotNull(topic); return this; } @@ -158,9 +180,12 @@ public SubscriptionInfo build() { } /** - * Returns the name of the topic this subscription refers to. + * Returns the identity of the topic this subscription refers to. If {@link TopicId#project()} is + * {@code null} the topic is assumed to reside in the {@link PubSubOptions#projectId()} project. + * After a topic is deleted, existing subscriptions to that topic are not deleted, but their topic + * field is set to {@link TopicId#deletedTopic()}. */ - public String topic() { + public TopicId topic() { return topic; } @@ -231,7 +256,7 @@ public String toString() { com.google.pubsub.v1.Subscription toPb(String projectId) { com.google.pubsub.v1.Subscription.Builder builder = com.google.pubsub.v1.Subscription.newBuilder(); - builder.setTopic(PublisherApi.formatTopicName(projectId, topic)); + builder.setTopic(topic.toPb(projectId)); builder.setName(SubscriberApi.formatSubscriptionName(projectId, name)); builder.setAckDeadlineSeconds(ackDeadlineSeconds); if (pushConfig != null) { @@ -241,7 +266,7 @@ com.google.pubsub.v1.Subscription toPb(String projectId) { } static SubscriptionInfo fromPb(com.google.pubsub.v1.Subscription subscription) { - Builder builder = builder(PublisherApi.parseTopicFromTopicName(subscription.getTopic()), + Builder builder = builder(TopicId.fromPb(subscription.getTopic()), SubscriberApi.parseSubscriptionFromSubscriptionName(subscription.getName())); builder.ackDeadLineSeconds(subscription.getAckDeadlineSeconds()); // A subscription with an "empty" push config is a pull subscription @@ -261,29 +286,46 @@ public Builder toBuilder() { /** * Creates a pull {@code SubscriptionInfo} object given the name of the topic and the name of the - * subscription. + * subscription. The topic is assumed to reside in the {@link PubSubOptions#projectId()} project. * * @param topic the name of the topic the subscription refers to * @param name the name of the subscription. The name must start with a letter, and contain only * letters ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores * ({@code _}), periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs * ({@code %}). It must be between 3 and 255 characters in length and cannot begin with the - * string {@code goog} + * string {@code goog}. */ public static SubscriptionInfo of(String topic, String name) { return builder(topic, name).build(); } + /** + * Creates a pull {@code SubscriptionInfo} object given the identity of the topic and the name of + * the subscription. If {@code topic.project()} is {@code null} the topic is assumed to reside in + * the {@link PubSubOptions#projectId()} project. + * + * @param topic the identity of the topic the subscription refers to + * @param name the name of the subscription. The name must start with a letter, and contain only + * letters ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores + * ({@code _}), periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs + * ({@code %}). It must be between 3 and 255 characters in length and cannot begin with the + * string {@code goog}. + */ + public static SubscriptionInfo of(TopicId topic, String name) { + return builder(topic, name).build(); + } + /** * Creates a push {@code SubscriptionInfo} object given the name of the topic, the name of the - * subscription and the push endpoint. + * subscription and the push endpoint. The topic is assumed to reside in the + * {@link PubSubOptions#projectId()} project. * * @param topic the name of the topic the subscription refers to * @param name the name of the subscription. The name must start with a letter, and contain only * letters ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores * ({@code _}), periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs * ({@code %}). It must be between 3 and 255 characters in length and cannot begin with the - * string {@code goog} + * string {@code goog}. * @param endpoint a URL locating the endpoint to which messages should be pushed. For example, * an endpoint might use {@code https://example.com/push}. */ @@ -291,18 +333,53 @@ public static SubscriptionInfo of(String topic, String name, String endpoint) { return builder(topic, name).pushConfig(PushConfig.of(endpoint)).build(); } + /** + * Creates a push {@code SubscriptionInfo} object given the identity of the topic, the name of the + * subscription and the push endpoint. If {@code topic.project()} is {@code null} the topic is + * assumed to reside in the {@link PubSubOptions#projectId()} project. + * + * @param topic the identity of the topic the subscription refers to + * @param name the name of the subscription. The name must start with a letter, and contain only + * letters ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores + * ({@code _}), periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs + * ({@code %}). It must be between 3 and 255 characters in length and cannot begin with the + * string {@code goog}. + * @param endpoint a URL locating the endpoint to which messages should be pushed. For example, + * an endpoint might use {@code https://example.com/push}. + */ + public static SubscriptionInfo of(TopicId topic, String name, String endpoint) { + return builder(topic, name).pushConfig(PushConfig.of(endpoint)).build(); + } + /** * Creates a builder for {@code SubscriptionInfo} objects given the name of the topic and the name - * of the subscription. + * of the subscription. The topic is assumed to reside in the {@link PubSubOptions#projectId()} + * project. * * @param topic the name of the topic the subscription refers to * @param name the name of the subscription. The name must start with a letter, and contain only * letters ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores * ({@code _}), periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs * ({@code %}). It must be between 3 and 255 characters in length and cannot begin with the - * string {@code goog} + * string {@code goog}. */ public static Builder builder(String topic, String name) { + return builder(TopicId.of(topic), name); + } + + /** + * Creates a builder for {@code SubscriptionInfo} objects given the identity of the topic and the + * name of the subscription. If {@code topic.project()} is {@code null} the topic is assumed to + * reside in the {@link PubSubOptions#projectId()} project. + * + * @param topic the identity of the topic the subscription refers to + * @param name the name of the subscription. The name must start with a letter, and contain only + * letters ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores + * ({@code _}), periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs + * ({@code %}). It must be between 3 and 255 characters in length and cannot begin with the + * string {@code goog}. + */ + public static Builder builder(TopicId topic, String name) { return new BuilderImpl(topic, name); } } diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Topic.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Topic.java index f2203d3a30d9..4c08e485bb9d 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Topic.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Topic.java @@ -133,11 +133,11 @@ public Future> publishAsync(Iterable messages) { return pubsub.publishAsync(name(), messages); } - public Page listSubscriptions(ListOption... options) { + public Page listSubscriptions(ListOption... options) { return pubsub.listSubscriptions(name(), options); } - public Future> listSubscriptionsAsync(ListOption... options) { + public Future> listSubscriptionsAsync(ListOption... options) { return pubsub.listSubscriptionsAsync(name(), options); } diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicId.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicId.java new file mode 100644 index 000000000000..a86d7ad84977 --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicId.java @@ -0,0 +1,138 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static com.google.cloud.pubsub.spi.v1.PublisherApi.formatTopicName; +import static com.google.cloud.pubsub.spi.v1.PublisherApi.parseProjectFromTopicName; +import static com.google.cloud.pubsub.spi.v1.PublisherApi.parseTopicFromTopicName; +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; + +import java.io.Serializable; +import java.util.Objects; + +/** + * Identity for a Google PubSub topic. A {@code TopicId} object can be used to create subscriptions + * for topics that possibly reside in different projects. + */ +public final class TopicId implements Serializable { + + private static final long serialVersionUID = -4913169763174877777L; + private static final String DELETED_TOPIC_NAME = "_deleted_topic_"; + private static final TopicId DELETED_TOPIC = new TopicId(null, DELETED_TOPIC_NAME, true); + + private final String project; + private final String topic; + private final boolean isDeleted; + + private TopicId(String project, String topic, boolean isDeleted) { + this.project = project; + this.topic = checkNotNull(topic); + this.isDeleted = isDeleted; + } + + private TopicId(String project, String topic) { + this(project, topic, false); + } + + /** + * Returns the name of the project where the topic resides. If {@code null} the topic is assumed + * to reside in the {@link PubSubOptions#projectId()} project. + */ + public String project() { + return project; + } + + /** + * Returns the name of the topic. + */ + public String topic() { + return topic; + } + + /** + * Returns {@code true} if this object is the identity of a deleted topic, {@code false} + * otherwhise. If {@code isDeleted()} is {@code true}, {@link #topic()} returns + * "{@code _deleted_topic_}" and {@link #project()} returns {@code null}. + */ + public boolean isDeleted() { + return isDeleted; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("project", project) + .add("topic", topic) + .add("isDeleted", isDeleted) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(project, topic, isDeleted); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof TopicId)) { + return false; + } + TopicId other = (TopicId) obj; + return Objects.equals(project, other.project) + && Objects.equals(topic, other.topic) + && Objects.equals(isDeleted, other.isDeleted); + } + + String toPb(String projectId) { + return formatTopicName(project != null ? project : projectId, topic); + } + + /** + * Returns the identity of a deleted topic. The deleted topic is such that {@link #isDeleted()} + * returns {@code true}, {@link #topic()} returns "{@code _is_deleted_}" and {@link #project()} + * returns {@code null}. + */ + public static TopicId deletedTopic() { + return DELETED_TOPIC; + } + + /** + * Returns a topic identity given the topic name. + */ + public static TopicId of(String topic) { + return new TopicId(null, topic); + } + + /** + * Returns a topic identity given project and topic names. + */ + public static TopicId of(String project, String topic) { + return new TopicId(project, topic); + } + + static TopicId fromPb(String pb) { + if (Objects.equals(pb, DELETED_TOPIC_NAME)) { + return DELETED_TOPIC; + } + return TopicId.of(parseProjectFromTopicName(pb), parseTopicFromTopicName(pb)); + } +} diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicInfo.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicInfo.java index acc5fbbd41ee..8c90a0c2705d 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicInfo.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicInfo.java @@ -140,7 +140,7 @@ public Builder toBuilder() { * ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores ({@code _}), * periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs ({@code %}). * It must be between 3 and 255 characters in length and cannot begin with the string - * {@code goog} + * {@code goog}. */ public static TopicInfo of(String name) { return builder(name).build(); @@ -153,7 +153,7 @@ public static TopicInfo of(String name) { * ({@code [A-Za-z]}), numbers ({@code [0-9]}), dashes ({@code -}), underscores ({@code _}), * periods ({@code .}), tildes ({@code ~}), plus ({@code +}) or percent signs ({@code %}). * It must be between 3 and 255 characters in length and cannot begin with the string - * {@code goog} + * {@code goog}. */ public static Builder builder(String name) { return new BuilderImpl(name); diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionIdTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionIdTest.java new file mode 100644 index 000000000000..ef7e4a8cd8dd --- /dev/null +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionIdTest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +public class SubscriptionIdTest { + + private static final String PROJECT = "project"; + private static final String NAME = "subscription"; + private static final String TOPIC_PB = "projects/project/subscriptions/subscription"; + private static final SubscriptionId SUBSCRIPTION_ID = new SubscriptionId(PROJECT, NAME); + + @Test + public void testConstructor() { + assertEquals(PROJECT, SUBSCRIPTION_ID.project()); + assertEquals(NAME, SUBSCRIPTION_ID.subscription()); + } + + @Test + public void testToAndFromPb() { + SubscriptionId subscriptionId = SubscriptionId.fromPb(TOPIC_PB); + compareSubscriptionId(SUBSCRIPTION_ID, subscriptionId); + assertEquals(PROJECT, subscriptionId.project()); + assertEquals(NAME, subscriptionId.subscription()); + } + + private void compareSubscriptionId(SubscriptionId expected, SubscriptionId value) { + assertEquals(expected, value); + assertEquals(expected.project(), value.project()); + assertEquals(expected.subscription(), value.subscription()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionInfoTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionInfoTest.java index 574d40e39ce2..be832a9c8994 100644 --- a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionInfoTest.java +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionInfoTest.java @@ -23,7 +23,7 @@ public class SubscriptionInfoTest { - private static final String TOPIC = "topic"; + private static final TopicId TOPIC = TopicId.of("project", "topic"); private static final String NAME = "subscription"; private static final String ENDPOINT = "https://example.com/push"; private static final PushConfig PUSH_CONFIG = PushConfig.of(ENDPOINT); @@ -40,7 +40,7 @@ public void testToBuilder() { .topic("newTopic") .name("newSubscription") .build(); - assertEquals("newTopic", subscriptionInfo.topic()); + assertEquals(TopicId.of("newTopic"), subscriptionInfo.topic()); assertEquals("newSubscription", subscriptionInfo.name()); subscriptionInfo = subscriptionInfo.toBuilder().name(NAME).topic(TOPIC).build(); compareSubscriptionInfo(SUBSCRIPTION_INFO, subscriptionInfo); @@ -52,6 +52,23 @@ public void testBuilder() { assertEquals(NAME, SUBSCRIPTION_INFO.name()); assertEquals(PUSH_CONFIG, SUBSCRIPTION_INFO.pushConfig()); assertEquals(ACK_DEADLINE, SUBSCRIPTION_INFO.ackDeadlineSeconds()); + SubscriptionInfo subscriptionInfo = SubscriptionInfo.builder("topic", "subscription").build(); + assertEquals(TopicId.of("topic"), subscriptionInfo.topic()); + assertEquals(NAME, subscriptionInfo.name()); + assertNull(subscriptionInfo.pushConfig()); + assertEquals(0, subscriptionInfo.ackDeadlineSeconds()); + subscriptionInfo = SubscriptionInfo.builder("topic", "subscription") + .topic("project", "topic").build(); + assertEquals(TOPIC, subscriptionInfo.topic()); + assertEquals(NAME, subscriptionInfo.name()); + assertNull(subscriptionInfo.pushConfig()); + assertEquals(0, subscriptionInfo.ackDeadlineSeconds()); + subscriptionInfo = SubscriptionInfo.builder("topic", "subscription") + .topic(TOPIC).build(); + assertEquals(TOPIC, subscriptionInfo.topic()); + assertEquals(NAME, subscriptionInfo.name()); + assertNull(subscriptionInfo.pushConfig()); + assertEquals(0, subscriptionInfo.ackDeadlineSeconds()); } @Test @@ -61,11 +78,21 @@ public void testOf() { assertEquals(NAME, subscriptionInfo.name()); assertNull(subscriptionInfo.pushConfig()); assertEquals(0, subscriptionInfo.ackDeadlineSeconds()); + subscriptionInfo = SubscriptionInfo.of("topic", NAME); + assertEquals(TopicId.of("topic"), subscriptionInfo.topic()); + assertEquals(NAME, subscriptionInfo.name()); + assertNull(subscriptionInfo.pushConfig()); + assertEquals(0, subscriptionInfo.ackDeadlineSeconds()); subscriptionInfo = SubscriptionInfo.of(TOPIC, NAME, ENDPOINT); assertEquals(TOPIC, subscriptionInfo.topic()); assertEquals(NAME, subscriptionInfo.name()); assertEquals(PushConfig.of(ENDPOINT), subscriptionInfo.pushConfig()); assertEquals(0, subscriptionInfo.ackDeadlineSeconds()); + subscriptionInfo = SubscriptionInfo.of("topic", NAME, ENDPOINT); + assertEquals(TopicId.of("topic"), subscriptionInfo.topic()); + assertEquals(NAME, subscriptionInfo.name()); + assertEquals(PushConfig.of(ENDPOINT), subscriptionInfo.pushConfig()); + assertEquals(0, subscriptionInfo.ackDeadlineSeconds()); } @Test @@ -75,9 +102,22 @@ public void testToAndFromPb() { SubscriptionInfo subscriptionInfo = SubscriptionInfo.of(TOPIC, NAME); compareSubscriptionInfo(subscriptionInfo, SubscriptionInfo.fromPb(subscriptionInfo.toPb("project"))); + subscriptionInfo = SubscriptionInfo.of("topic", NAME); + compareSubscriptionInfo(SubscriptionInfo.of(TOPIC, NAME), + SubscriptionInfo.fromPb(subscriptionInfo.toPb("project"))); subscriptionInfo = SubscriptionInfo.of(TOPIC, NAME, ENDPOINT); compareSubscriptionInfo(subscriptionInfo, SubscriptionInfo.fromPb(subscriptionInfo.toPb("project"))); + subscriptionInfo = SubscriptionInfo.of("topic", NAME, ENDPOINT); + compareSubscriptionInfo(SubscriptionInfo.of(TOPIC, NAME, ENDPOINT), + SubscriptionInfo.fromPb(subscriptionInfo.toPb("project"))); + com.google.pubsub.v1.Subscription subscription = SUBSCRIPTION_INFO.toPb("project"); + subscriptionInfo = + SubscriptionInfo.fromPb(subscription.toBuilder().setTopic("_deleted_topic_").build()); + assertEquals(TopicId.deletedTopic(), subscriptionInfo.topic()); + assertEquals(NAME, subscriptionInfo.name()); + assertEquals(PUSH_CONFIG, subscriptionInfo.pushConfig()); + assertEquals(ACK_DEADLINE, subscriptionInfo.ackDeadlineSeconds()); } private void compareSubscriptionInfo(SubscriptionInfo expected, SubscriptionInfo value) { diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/TopicIdTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/TopicIdTest.java new file mode 100644 index 000000000000..a75732709be9 --- /dev/null +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/TopicIdTest.java @@ -0,0 +1,73 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class TopicIdTest { + + private static final String PROJECT = "project"; + private static final String NAME = "topic"; + private static final String TOPIC_PB = "projects/project/topics/topic"; + + @Test + public void testOf() { + TopicId topicId = TopicId.of(PROJECT, NAME); + assertEquals(PROJECT, topicId.project()); + assertEquals(NAME, topicId.topic()); + topicId = TopicId.of(NAME); + assertNull(topicId.project()); + assertEquals(NAME, topicId.topic()); + assertFalse(topicId.isDeleted()); + } + + @Test + public void testDeletedTopic() { + TopicId deletedTopic = TopicId.deletedTopic(); + assertNull(deletedTopic.project()); + assertEquals("_deleted_topic_", deletedTopic.topic()); + assertTrue(deletedTopic.isDeleted()); + assertSame(deletedTopic, TopicId.deletedTopic()); + } + + @Test + public void testToAndFromPb() { + TopicId topicId = TopicId.of(PROJECT, NAME); + String topicPb = topicId.toPb("otherProject"); + assertEquals(TOPIC_PB, topicPb); + compareTopicId(topicId, TopicId.fromPb(topicPb)); + topicId = TopicId.of(NAME); + topicPb = topicId.toPb("otherProject"); + assertEquals("projects/otherProject/topics/topic", topicPb); + compareTopicId(TopicId.of("otherProject", NAME), TopicId.fromPb(topicPb)); + } + + private void compareTopicId(TopicId expected, TopicId value) { + assertEquals(expected, value); + assertEquals(expected.project(), value.project()); + assertEquals(expected.topic(), value.topic()); + assertEquals(expected.isDeleted(), value.isDeleted()); + assertEquals(expected.toPb("project"), value.toPb("project")); + assertEquals(expected.hashCode(), value.hashCode()); + } +} From cd848c0ff6edc1da9965e853219bfb72837fd37e Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 11 May 2016 11:30:06 +0200 Subject: [PATCH 342/375] Add base class for operation options, javadoc and tests (#996) * Add base class for operation options, javadoc and tests * Refactor PullOption - Make maxMessages a method parameter rather than an optional option - Move MessageConsumer.PullOption to PubSub - Remove MessageConsumer.start/stop methods in favor of close() --- .../java/com/google/cloud/pubsub/Option.java | 77 +++++++++++ .../java/com/google/cloud/pubsub/PubSub.java | 122 ++++++++---------- .../com/google/cloud/pubsub/PubSubImpl.java | 7 +- .../com/google/cloud/pubsub/Subscription.java | 12 +- .../com/google/cloud/pubsub/OptionTest.java | 66 ++++++++++ .../com/google/cloud/pubsub/PubSubTest.java | 50 +++++++ 6 files changed, 255 insertions(+), 79 deletions(-) create mode 100644 gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Option.java create mode 100644 gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/OptionTest.java create mode 100644 gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PubSubTest.java diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Option.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Option.java new file mode 100644 index 000000000000..5359d1797f55 --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Option.java @@ -0,0 +1,77 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; + +import java.io.Serializable; +import java.util.Objects; + +/** + * Base class for Pub/Sub operation options. + */ +abstract class Option implements Serializable { + + private static final long serialVersionUID = 4956295408130172192L; + + private final OptionType optionType; + private final Object value; + + interface OptionType { + + String name(); + } + + Option(OptionType optionType, Object value) { + this.optionType = checkNotNull(optionType); + this.value = value; + } + + @SuppressWarnings("unchecked") + T optionType() { + return (T) optionType; + } + + Object value() { + return value; + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof Option)) { + return false; + } + Option other = (Option) obj; + return Objects.equals(optionType, other.optionType) + && Objects.equals(value, other.value); + } + + @Override + public int hashCode() { + return Objects.hash(optionType, value); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("name", optionType.name()) + .add("value", value) + .toString(); + } +} diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java index 3410d3f54a3e..6fde6f4425df 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java @@ -20,9 +20,9 @@ import com.google.cloud.Page; import com.google.cloud.Service; -import java.io.Serializable; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @@ -33,65 +33,79 @@ */ public interface PubSub extends Service { - final class ListOption implements Serializable { + /** + * Class for specifying options for listing topics and subscriptions. + */ + final class ListOption extends Option { private static final long serialVersionUID = 6517442127283383124L; - private final Option option; - private final Object value; + enum OptionType implements Option.OptionType { + PAGE_SIZE, PAGE_TOKEN; - enum Option { - PAGE_SIZE, PAGE_TOKEN - } + @SuppressWarnings("unchecked") + T get(Map options) { + return (T) options.get(this); + } - private ListOption(Option option, Object value) { - this.option = option; - this.value = value; - } + String getString(Map options) { + return get(options); + } - Option option() { - return option; + Integer getInteger(Map options) { + return get(options); + } } - Object value() { - return value; + private ListOption(OptionType option, Object value) { + super(option, value); } + /** + * Returns an option to specify the maximum number of resources returned per page. + */ public static ListOption pageSize(int pageSize) { - return new ListOption(Option.PAGE_SIZE, pageSize); + return new ListOption(OptionType.PAGE_SIZE, pageSize); } + /** + * Returns an option to specify the page token from which to start listing resources. + */ public static ListOption pageToken(String pageToken) { - return new ListOption(Option.PAGE_TOKEN, pageToken); + return new ListOption(OptionType.PAGE_TOKEN, pageToken); } } - final class PullOption implements Serializable { - - private static final long serialVersionUID = -5220474819637439937L; + /** + * Class for specifying options for pulling messages. + */ + final class PullOption extends Option { - private final Option option; - private final Object value; + private static final long serialVersionUID = 4792164134340316582L; - enum Option { - MAX_MESSAGES - } + enum OptionType implements Option.OptionType { + MAX_CONCURRENT_CALLBACKS; - private PullOption(Option option, Object value) { - this.option = option; - this.value = value; - } + @SuppressWarnings("unchecked") + T get(Map options) { + return (T) options.get(this); + } - Option option() { - return option; + Integer getInteger(Map options) { + return get(options); + } } - Object value() { - return value; + private PullOption(Option.OptionType option, Object value) { + super(option, value); } - public static PullOption maxMessages(int maxMessages) { - return new PullOption(Option.MAX_MESSAGES, maxMessages); + /** + * Returns an option to specify the maximum number of messages that can be executed + * concurrently at any time. + */ + public static PullOption maxConcurrentCallbacks(int maxConcurrency) { + return new PullOption(OptionType.MAX_CONCURRENT_CALLBACKS, maxConcurrency); } } @@ -108,38 +122,6 @@ interface MessageProcessor { */ interface MessageConsumer extends AutoCloseable { - final class PullOption implements Serializable { - - private static final long serialVersionUID = 4792164134340316582L; - - private final Option option; - private final Object value; - - enum Option { - MAX_CONCURRENT_CALLBACKS - } - - private PullOption(Option option, Object value) { - this.option = option; - this.value = value; - } - - Option option() { - return option; - } - - Object value() { - return value; - } - - public static PullOption maxConcurrentCallbacks(int maxConcurrency) { - return new PullOption(Option.MAX_CONCURRENT_CALLBACKS, maxConcurrency); - } - } - - void start(MessageConsumer.PullOption... options); - - void stop(); } Topic create(TopicInfo topic); @@ -198,11 +180,11 @@ public static PullOption maxConcurrentCallbacks(int maxConcurrency) { Future> listSubscriptionsAsync(String topic, ListOption... options); - Iterator pull(String subscription, PullOption... options); + Iterator pull(String subscription, int maxMessages); - Future> pullAsync(String subscription, PullOption... options); + Future> pullAsync(String subscription, int maxMessages); - MessageConsumer pullAsync(String subscription, MessageProcessor callback); + MessageConsumer pullAsync(String subscription, MessageProcessor callback, PullOption... options); void ack(String subscription, String ackId, String... ackIds); diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java index 17a99842259f..19b2e5a35fec 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java @@ -196,13 +196,13 @@ public Future> listSubscriptionsAsync(String topic, } @Override - public Iterator pull(String subscription, PullOption... options) { + public Iterator pull(String subscription, int maxMessages) { // this should set return_immediately to true return null; } @Override - public Future> pullAsync(String subscription, PullOption... options) { + public Future> pullAsync(String subscription, int maxMessages) { // though this method can set return_immediately to false (as future can be canceled) I // suggest to keep it false so sync could delegate to asyc and use the same options // this method also should use the VTKIT thread-pool to renew ack deadline for non consumed @@ -211,7 +211,8 @@ public Future> pullAsync(String subscription, PullOpti } @Override - public MessageConsumer pullAsync(String subscription, MessageProcessor callback) { + public MessageConsumer pullAsync(String subscription, MessageProcessor callback, + PullOption... options) { // this method should use the VTKIT thread-pool (maybe getting it should be part of the spi) return null; } diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java index 11efb5971aa2..7dd203a73348 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java @@ -151,16 +151,16 @@ public Future replacePushConfigAsync(PushConfig pushConfig) { return pubsub.replacePushConfigAsync(name(), pushConfig); } - public Iterator pull(PullOption... options) { - return pubsub.pull(name(), options); + public Iterator pull(int maxMessages) { + return pubsub.pull(name(), maxMessages); } - public Future> pullAsync(PullOption... options) { - return pubsub.pullAsync(name(), options); + public Future> pullAsync(int maxMessages) { + return pubsub.pullAsync(name(), maxMessages); } - public MessageConsumer pullAsync(MessageProcessor callback) { - return pubsub.pullAsync(name(), callback); + public MessageConsumer pullAsync(MessageProcessor callback, PullOption... options) { + return pubsub.pullAsync(name(), callback, options); } private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/OptionTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/OptionTest.java new file mode 100644 index 000000000000..119e64e24c3a --- /dev/null +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/OptionTest.java @@ -0,0 +1,66 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; + +import com.google.cloud.pubsub.Option.OptionType; +import com.google.cloud.pubsub.PubSub.ListOption; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class OptionTest { + + private static final OptionType OPTION_TYPE = ListOption.OptionType.PAGE_SIZE; + private static final OptionType ANOTHER_OPTION_TYPE = ListOption.OptionType.PAGE_TOKEN; + private static final String VALUE = "some value"; + private static final String OTHER_VALUE = "another value"; + private static final Option OPTION = new Option(OPTION_TYPE, VALUE) {}; + private static final Option OPTION_EQUALS = new Option(OPTION_TYPE, VALUE) {}; + private static final Option OPTION_NOT_EQUALS1 = new Option(ANOTHER_OPTION_TYPE, OTHER_VALUE) {}; + private static final Option OPTION_NOT_EQUALS2 = new Option(ANOTHER_OPTION_TYPE, VALUE) {}; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testEquals() { + assertEquals(OPTION, OPTION_EQUALS); + assertNotEquals(OPTION, OPTION_NOT_EQUALS1); + assertNotEquals(OPTION, OPTION_NOT_EQUALS2); + } + + @Test + public void testHashCode() { + assertEquals(OPTION.hashCode(), OPTION_EQUALS.hashCode()); + } + + @Test + public void testConstructor() { + assertEquals(OPTION_TYPE, OPTION.optionType()); + assertEquals(VALUE, OPTION.value()); + Option option = new Option(OPTION_TYPE, null) {}; + assertEquals(OPTION_TYPE, option.optionType()); + assertNull(option.value()); + thrown.expect(NullPointerException.class); + new Option(null, VALUE) {}; + } +} diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PubSubTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PubSubTest.java new file mode 100644 index 000000000000..620e737111f7 --- /dev/null +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PubSubTest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static org.junit.Assert.assertEquals; + +import com.google.cloud.pubsub.PubSub.ListOption; +import com.google.cloud.pubsub.PubSub.PullOption; + +import org.junit.Test; + +public class PubSubTest { + + private static final int PAGE_SIZE = 42; + private static final String PAGE_TOKEN = "page token"; + private static final int MAX_CONCURRENT_CALLBACKS = 42; + + @Test + public void testListOption() { + // page token + ListOption listOption = ListOption.pageToken(PAGE_TOKEN); + assertEquals(PAGE_TOKEN, listOption.value()); + assertEquals(ListOption.OptionType.PAGE_TOKEN, listOption.optionType()); + // page size + listOption = ListOption.pageSize(PAGE_SIZE); + assertEquals(PAGE_SIZE, listOption.value()); + assertEquals(ListOption.OptionType.PAGE_SIZE, listOption.optionType()); + } + + @Test + public void testPullOptions() { + PullOption pullOption = PullOption.maxConcurrentCallbacks(MAX_CONCURRENT_CALLBACKS); + assertEquals(MAX_CONCURRENT_CALLBACKS, pullOption.value()); + assertEquals(PullOption.OptionType.MAX_CONCURRENT_CALLBACKS, pullOption.optionType()); + } +} From 215a5dfd611a58a2a2114fae84c69515597d002e Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 11 May 2016 13:57:11 +0200 Subject: [PATCH 343/375] Add options() method and project name to LocalPubsubHelper (#999) --- .../pubsub/testing/LocalPubsubHelper.java | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/testing/LocalPubsubHelper.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/testing/LocalPubsubHelper.java index afdba1c135ed..5a6cf6574211 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/testing/LocalPubsubHelper.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/testing/LocalPubsubHelper.java @@ -19,10 +19,9 @@ import com.google.api.gax.testing.DownloadableEmulatorRunner; import com.google.api.gax.testing.GCloudEmulatorRunner; import com.google.api.gax.testing.LocalServiceHelper; - -import io.grpc.ManagedChannel; -import io.grpc.netty.NegotiationType; -import io.grpc.netty.NettyChannelBuilder; +import com.google.cloud.AuthCredentials; +import com.google.cloud.RetryParams; +import com.google.cloud.pubsub.PubSubOptions; import java.io.IOException; import java.net.MalformedURLException; @@ -30,6 +29,11 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.UUID; + +import io.grpc.ManagedChannel; +import io.grpc.netty.NegotiationType; +import io.grpc.netty.NettyChannelBuilder; /** * A class that runs a Pubsub emulator instance for use in tests. @@ -38,11 +42,13 @@ public class LocalPubsubHelper { private final int port; private final LocalServiceHelper serviceHelper; + private final String projectId; // Local server settings private static final int DEFAULT_PORT = 8080; private static final String DEFAULT_HOST = "localhost"; private static final URL EMULATOR_URL; + private static final String PROJECT_ID_PREFIX = "test-project-"; // GCloud emulator settings private static final String GCLOUD_CMD_TEXT = "gcloud beta emulators pubsub start"; @@ -77,8 +83,8 @@ public LocalPubsubHelper() { DownloadableEmulatorRunner downloadRunner = new DownloadableEmulatorRunner(Arrays.asList(BIN_NAME, BIN_CMD_PORT_FLAG + port), EMULATOR_URL, MD5_CHECKSUM); - serviceHelper = - new LocalServiceHelper(Arrays.asList(gcloudRunner, downloadRunner), port); + serviceHelper = new LocalServiceHelper(Arrays.asList(gcloudRunner, downloadRunner), port); + projectId = PROJECT_ID_PREFIX + UUID.randomUUID().toString(); } /** @@ -121,4 +127,17 @@ public ManagedChannel createChannel() { .negotiationType(NegotiationType.PLAINTEXT) .build(); } + + /** + * Returns a {@link PubSubOptions} instance that sets the host to use the PubSub emulator on + * localhost. + */ + public PubSubOptions options() { + return PubSubOptions.builder() + .projectId(projectId) + .host("localhost:" + port) + .authCredentials(AuthCredentials.noAuth()) + .retryParams(RetryParams.noRetries()) + .build(); + } } From 6e0c6c00134758cac57b2bca6eb5c818faf61093 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 12 May 2016 08:40:31 +0200 Subject: [PATCH 344/375] Add tests and javadoc for Message and ByteArray (#1000) * Add tests and javadoc for Message and ByteArray * Add final on static ByteArray methods back --- .../main/java/com/google/cloud/ByteArray.java | 61 ++++---- .../java/com/google/cloud/ServiceOptions.java | 2 +- .../java/com/google/cloud/ByteArrayTest.java | 116 +++++++++++++++ .../java/com/google/cloud/pubsub/Message.java | 124 +++++++++++++--- .../com/google/cloud/pubsub/MessageTest.java | 133 ++++++++++++++++++ 5 files changed, 387 insertions(+), 49 deletions(-) create mode 100644 gcloud-java-core/src/test/java/com/google/cloud/ByteArrayTest.java create mode 100644 gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/MessageTest.java diff --git a/gcloud-java-core/src/main/java/com/google/cloud/ByteArray.java b/gcloud-java-core/src/main/java/com/google/cloud/ByteArray.java index f23fb0876b41..6a8e3dddd0ce 100644 --- a/gcloud-java-core/src/main/java/com/google/cloud/ByteArray.java +++ b/gcloud-java-core/src/main/java/com/google/cloud/ByteArray.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 Google Inc. All Rights Reserved. + * Copyright 2016 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,8 +20,6 @@ import com.google.common.base.MoreObjects.ToStringHelper; import com.google.protobuf.ByteString; -import java.io.BufferedInputStream; -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.Serializable; @@ -35,6 +33,7 @@ public class ByteArray implements Iterable, Serializable { private static final long serialVersionUID = -1908809133893782840L; + private final ByteString byteString; protected ByteArray(ByteString byteString) { @@ -75,43 +74,38 @@ public final boolean equals(Object obj) { } /** - * Returns the size of this blob. + * Returns the number of bytes in this {@code ByteArray}. */ public final int length() { return byteString.size(); } /** - * Returns a copy as byte array. + * Returns a copy of this {@code ByteArray} as an array of bytes. */ public final byte[] toByteArray() { return byteString.toByteArray(); } /** - * Returns the content as {@code UTF-8} string. + * Returns a copy of this {@code ByteArray} as an {@code UTF-8} string. */ public final String toStringUtf8() { return byteString.toStringUtf8(); } /** - * Returns a read-only {@link ByteBuffer} for this blob content. + * Returns the content of this {@code ByteArray} as a read-only {@link ByteBuffer}. */ public final ByteBuffer asReadOnlyByteBuffer() { return byteString.asReadOnlyByteBuffer(); } /** - * Returns an {@link InputStream} for this blob content. + * Returns an {@link InputStream} for this {@code ByteArray} content. */ public final InputStream asInputStream() { - final ByteBuffer byteBuffer = asReadOnlyByteBuffer(); - return new InputStream() { - @Override public int read() { - return !byteBuffer.hasRemaining() ? -1 : byteBuffer.get() & 0xFF; - } - }; + return byteString.newInput(); } protected ByteString byteString() { @@ -119,47 +113,52 @@ protected ByteString byteString() { } /** - * Copies bytes into a ByteBuffer. + * Copies the content of this {@code ByteArray} into an existing {@code ByteBuffer}. * * @throws java.nio.ReadOnlyBufferException if the target is read-only - * @throws java.nio.BufferOverflowException if the target's remaining() space is not large - * enough to hold the data + * @throws java.nio.BufferOverflowException if the target's {@link ByteBuffer#remaining()} space + * is not large enough to hold the data */ public final void copyTo(ByteBuffer target) { byteString.copyTo(target); } /** - * Copies bytes into a buffer. + * Copies the content of this {@code ByteArray} into an array of bytes. * - * @throws IndexOutOfBoundsException if an offset or size is negative or too large + * @throws IndexOutOfBoundsException if the target is not large enough to hold the data */ public final void copyTo(byte[] target) { byteString.copyTo(target, 0, 0, length()); } - public static final ByteArray copyFrom(byte[] bytes) { + /** + * Creates a {@code ByteArray} object given an array of bytes. The bytes are copied. + */ + public final static ByteArray copyFrom(byte[] bytes) { return new ByteArray(ByteString.copyFrom(bytes)); } /** - * Copy the bytes using {@code UTF-8} decoding. + * Creates a {@code ByteArray} object given a string. The string is encoded in {@code UTF-8}. The + * bytes are copied. */ - public static final ByteArray copyFrom(String string) { + public final static ByteArray copyFrom(String string) { return new ByteArray(ByteString.copyFrom(string, StandardCharsets.UTF_8)); } - public static final ByteArray copyFrom(ByteBuffer bytes) { + /** + * Creates a {@code ByteArray} object given a {@link ByteBuffer}. The bytes are copied. + */ + public final static ByteArray copyFrom(ByteBuffer bytes) { return new ByteArray(ByteString.copyFrom(bytes)); } - public static final ByteArray copyFrom(InputStream input) throws IOException { - BufferedInputStream bufferedInput = new BufferedInputStream(input); - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - int value; - while ((value = bufferedInput.read()) != -1) { - bytes.write(value); - } - return copyFrom(bytes.toByteArray()); + /** + * Creates a {@code ByteArray} object given an {@link InputStream}. The stream is read into the + * created object. + */ + public final static ByteArray copyFrom(InputStream input) throws IOException { + return new ByteArray(ByteString.readFrom(input)); } } diff --git a/gcloud-java-core/src/main/java/com/google/cloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/cloud/ServiceOptions.java index e08d0cd9d155..194f61b45c42 100644 --- a/gcloud-java-core/src/main/java/com/google/cloud/ServiceOptions.java +++ b/gcloud-java-core/src/main/java/com/google/cloud/ServiceOptions.java @@ -26,9 +26,9 @@ import com.google.api.client.http.HttpTransport; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.auth.http.HttpCredentialsAdapter; +import com.google.cloud.spi.ServiceRpcFactory; import com.google.common.collect.Iterables; import com.google.common.io.Files; -import com.google.cloud.spi.ServiceRpcFactory; import org.json.JSONException; import org.json.JSONObject; diff --git a/gcloud-java-core/src/test/java/com/google/cloud/ByteArrayTest.java b/gcloud-java-core/src/test/java/com/google/cloud/ByteArrayTest.java new file mode 100644 index 000000000000..0adf2fe8be79 --- /dev/null +++ b/gcloud-java-core/src/test/java/com/google/cloud/ByteArrayTest.java @@ -0,0 +1,116 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +import com.google.common.io.ByteStreams; +import com.google.protobuf.ByteString; + +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; + +public class ByteArrayTest { + + private static final String STRING_CONTENT = "Hello, ByteArray!"; + private static final byte[] BYTES_CONTENT = STRING_CONTENT.getBytes(StandardCharsets.UTF_8); + private static final ByteBuffer BYTE_BUFFER_CONTENT = ByteBuffer.wrap(BYTES_CONTENT); + private static final InputStream STREAM_CONTENT = new ByteArrayInputStream(BYTES_CONTENT); + private static final ByteArray STRING_ARRAY = ByteArray.copyFrom(STRING_CONTENT); + private static final ByteArray BYTES_ARRAY = ByteArray.copyFrom(BYTES_CONTENT); + private static final ByteArray BYTE_BUFFER_ARRAY = ByteArray.copyFrom(BYTE_BUFFER_CONTENT); + private static final ByteArray ARRAY = new ByteArray(ByteString.copyFrom(BYTES_CONTENT)); + + private static ByteArray streamArray; + + @BeforeClass + public static void beforeClass() throws IOException { + streamArray = ByteArray.copyFrom(STREAM_CONTENT); + BYTE_BUFFER_CONTENT.flip(); + } + + @Test + public void testCopyFromString() throws IOException { + assertEquals(STRING_CONTENT, STRING_ARRAY.toStringUtf8()); + assertArrayEquals(BYTES_CONTENT, STRING_ARRAY.toByteArray()); + assertEquals(BYTE_BUFFER_CONTENT.asReadOnlyBuffer(), STRING_ARRAY.asReadOnlyByteBuffer()); + assertArrayEquals(BYTES_CONTENT, ByteStreams.toByteArray(STRING_ARRAY.asInputStream())); + } + + @Test + public void testCopyFromByteArray() throws IOException { + assertEquals(STRING_CONTENT, BYTES_ARRAY.toStringUtf8()); + assertArrayEquals(BYTES_CONTENT, BYTES_ARRAY.toByteArray()); + assertEquals(BYTE_BUFFER_CONTENT.asReadOnlyBuffer(), BYTES_ARRAY.asReadOnlyByteBuffer()); + assertArrayEquals(BYTES_CONTENT, ByteStreams.toByteArray(BYTES_ARRAY.asInputStream())); + } + + @Test + public void testCopyFromByteBuffer() throws IOException { + assertEquals(STRING_CONTENT, BYTE_BUFFER_ARRAY.toStringUtf8()); + assertArrayEquals(BYTES_CONTENT, BYTE_BUFFER_ARRAY.toByteArray()); + assertEquals(BYTE_BUFFER_CONTENT.asReadOnlyBuffer(), BYTE_BUFFER_ARRAY.asReadOnlyByteBuffer()); + assertArrayEquals(BYTES_CONTENT, ByteStreams.toByteArray(BYTE_BUFFER_ARRAY.asInputStream())); + } + + @Test + public void testCopyFromStream() throws IOException { + assertEquals(STRING_CONTENT, streamArray.toStringUtf8()); + assertArrayEquals(BYTES_CONTENT, streamArray.toByteArray()); + assertEquals(BYTE_BUFFER_CONTENT.asReadOnlyBuffer(), streamArray.asReadOnlyByteBuffer()); + assertArrayEquals(BYTES_CONTENT, ByteStreams.toByteArray(streamArray.asInputStream())); + } + + @Test + public void testLength() { + assertEquals(BYTES_CONTENT.length, ARRAY.length()); + } + + @Test + public void testToStringUtf8() { + assertEquals(STRING_CONTENT, ARRAY.toStringUtf8()); + } + + @Test + public void testToByteArray() { + assertArrayEquals(BYTES_CONTENT, ARRAY.toByteArray()); + } + + @Test + public void testAsReadOnlyByteBuffer() { + assertEquals(BYTE_BUFFER_CONTENT.asReadOnlyBuffer(), ARRAY.asReadOnlyByteBuffer()); + } + + @Test + public void testAsInputStream() throws IOException { + assertArrayEquals(BYTES_CONTENT, ByteStreams.toByteArray(ARRAY.asInputStream())); + } + + @Test + public void testHashCode() { + assertEquals(STRING_ARRAY.hashCode(), BYTES_ARRAY.hashCode()); + assertEquals(BYTES_ARRAY.hashCode(), BYTE_BUFFER_ARRAY.hashCode()); + assertEquals(BYTE_BUFFER_ARRAY.hashCode(), streamArray.hashCode()); + } +} diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Message.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Message.java index 830f9115a41d..c8d5ec7500da 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Message.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Message.java @@ -17,6 +17,7 @@ import static com.google.common.base.Preconditions.checkNotNull; import com.google.cloud.ByteArray; +import com.google.common.base.Function; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableMap; import com.google.protobuf.ByteString; @@ -29,10 +30,27 @@ import java.util.Objects; /** - * Pub/Sub message. + * A Google Cloud Pub/Sub message. A message is the combination of data and (optional) attributes + * that a publisher sends to a topic and is eventually delivered to subscribers. + * + *

    Message attributes are key-value pairs that a publisher can define for a message. For example, + * a key {@code iana.org/language_tag} and value {@code en} could be added to messages to mark them + * as readable by an English-speaking subscriber. + * + *

    To be published a message must have a non-empty payload, or at least one attribute. + * + * @see Pub/Sub Data Model */ public class Message implements Serializable { + static final Function TO_PB_FUNCTION = + new Function() { + @Override + public PubsubMessage apply(Message message) { + return message.toPb(); + } + }; + private static final long serialVersionUID = -1436515787233340634L; private static final long NANOS_PER_MILLISECOND = 1000000; private static final long MILLIS_PER_SECOND = 1000; @@ -61,32 +79,57 @@ protected ByteString byteString() { } /** - * Builder for Message. + * Builder for {@code Message} objects. */ public abstract static class Builder { abstract Builder id(String id); + /** + * Sets the message payload to the provided string. The string is enconded {@code UTF-8}. + */ public abstract Builder payload(String payload); + /** + * Sets the message payload to the provided {@link ByteArray}. + */ public abstract Builder payload(ByteArray payload); + /** + * Sets the message attributes to the provided map. Message attributes are key-value pairs that + * a publisher can define for a message. For example, a key {@code iana.org/language_tag} and + * value {@code en} could be added to messages to mark them as readable by an English-speaking + * subscriber. + */ public abstract Builder attributes(Map attributes); + /** + * Adds a new attribute to the message attributes. If an attribute with name {@code name} was + * already set, its value is updated. + */ public abstract Builder addAttribute(String name, String value); + /** + * Removes an attribute give its name from the message attributes. + */ public abstract Builder removeAttribute(String name); + /** + * Clears all message attributes. + */ public abstract Builder clearAttributes(); abstract Builder publishTime(long publishTime); + /** + * Creates a topic object. + */ public abstract Message build(); } static final class BuilderImpl extends Builder { - private String id = ""; + private String id; private ByteArray payload; private Map attributes = new HashMap<>(); private Long publishTime; @@ -160,35 +203,53 @@ public Message build() { publishTime = builder.publishTime; } + /** + * Returns the time in milliseconds at which the message was published. This value is set by the + * server when it receives the publish call. If not set, this method returns {@code null}. + */ public Long publishTime() { return publishTime; } + /** + * Returns the message attributes. Message attributes are key-value pairs that a publisher can + * define for a message. For example, a key {@code iana.org/language_tag} and value {@code en} + * could be added to messages to mark them as readable by an English-speaking subscriber. + */ public Map attributes() { return attributes; } + /** + * Returns the id of this message, set by the server when the message is published. The id is + * guaranteed to be unique within the topic. This value may be read by a subscriber that receives + * a Pub/Sub message via a pull call or a push delivery. If not set, this method returns + * {@code null}. + */ public String id() { return id; } + /** + * Returns the message payload as a string, decoded using {@code UTF-8}. + */ public String payloadAsString() { return payload.toStringUtf8(); } + /** + * Returns the message payload. + */ public ByteArray payload() { return payload; } @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - return Objects.equals(toPb(), ((Message) o).toPb()); + public boolean equals(Object obj) { + return obj == this + || obj != null + && obj.getClass().equals(Message.class) + && Objects.equals(toPb(), ((Message) obj).toPb()); } @Override @@ -212,10 +273,12 @@ PubsubMessage toPb() { builder.setMessageId(id); } builder.setData(payload.byteString()); - builder.getAttributes().putAll(attributes); + builder.putAllAttributes(attributes); Timestamp.Builder tsBuilder = Timestamp.newBuilder(); - tsBuilder.setSeconds(publishTime / MILLIS_PER_SECOND); - tsBuilder.setNanos((int) (publishTime % MILLIS_PER_SECOND * NANOS_PER_MILLISECOND)); + if (publishTime != null) { + tsBuilder.setSeconds(publishTime / MILLIS_PER_SECOND); + tsBuilder.setNanos((int) (publishTime % MILLIS_PER_SECOND * NANOS_PER_MILLISECOND)); + } builder.setPublishTime(tsBuilder); return builder.build(); } @@ -224,28 +287,55 @@ static Message fromPb(PubsubMessage messagePb) { Builder builder = builder(new InternalByteArray(messagePb.getData())); if (messagePb.hasPublishTime()) { Timestamp ts = messagePb.getPublishTime(); - builder.publishTime( - ts.getSeconds() * MILLIS_PER_SECOND + ts.getNanos() / NANOS_PER_MILLISECOND); + Long millis = ts.getSeconds() * MILLIS_PER_SECOND + ts.getNanos() / NANOS_PER_MILLISECOND; + if (millis != 0) { + builder.publishTime(millis); + } + } + if (!Objects.equals(messagePb.getMessageId(), "")) { + builder.id(messagePb.getMessageId()); } - builder.id(messagePb.getMessageId()); for (Map.Entry entry : messagePb.getAttributes().entrySet()) { builder.addAttribute(entry.getKey(), entry.getValue()); } return builder.build(); } + /** + * Returns a builder for the message object. + */ public Builder toBuilder() { return new BuilderImpl(this); } + /** + * Creates a {@code Message} object given the payload as a string. The string is enconded using + * {@code UTF-8}. + */ public static Message of(String payload) { return builder(payload).build(); } + /** + * Creates a {@code Message} object given the payload as a {@link ByteArray}. To be published a + * message must have a non-empty payload. + */ + public static Message of(ByteArray payload) { + return builder(payload).build(); + } + + /** + * Creates a builder for {@code Message} objects given the payload as a string. The string is + * enconded using {@code UTF-8}. To be published a message must have a non-empty payload. + */ public static Builder builder(String payload) { return new BuilderImpl().payload(payload); } + /** + * Creates a builder for {@code Message} objects given the payload as a {@link ByteArray}. To be + * published a message must have a non-empty payload, or at least one attribute. + */ public static Builder builder(ByteArray payload) { return new BuilderImpl().payload(payload); } diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/MessageTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/MessageTest.java new file mode 100644 index 000000000000..3b94bae0d958 --- /dev/null +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/MessageTest.java @@ -0,0 +1,133 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import com.google.cloud.ByteArray; +import com.google.common.collect.ImmutableMap; + +import org.junit.Test; + +import java.nio.charset.StandardCharsets; +import java.util.Map; + +public class MessageTest { + + private static final String MESSAGE_ID = "messageId"; + private static final String PAYLOAD_STRING = "payload"; + private static final ByteArray PAYLOAD = + ByteArray.copyFrom("payload".getBytes(StandardCharsets.UTF_8)); + private static final Map ATTRIBUTES = + ImmutableMap.of("key1", "value1", "key2", "value2"); + private static final Long PUBLISH_TIME = 42L; + private static final Message MESSAGE_STRING = Message.builder(PAYLOAD_STRING) + .id(MESSAGE_ID) + .attributes(ATTRIBUTES) + .publishTime(PUBLISH_TIME) + .build(); + private static final Message MESSAGE = Message.builder(PAYLOAD) + .id(MESSAGE_ID) + .attributes(ATTRIBUTES) + .publishTime(PUBLISH_TIME) + .build(); + + @Test + public void testToBuilder() { + compareMessage(MESSAGE, MESSAGE.toBuilder().build()); + Message message = MESSAGE.toBuilder() + .payload("newPayload") + .clearAttributes() + .addAttribute("key1", "value1") + .build(); + assertEquals("newPayload", message.payloadAsString()); + assertEquals(ImmutableMap.of("key1", "value1"), message.attributes()); + message = MESSAGE.toBuilder().payload(PAYLOAD_STRING).attributes(ATTRIBUTES).build(); + compareMessage(MESSAGE, message); + } + + @Test + public void testBuilder() { + assertEquals(MESSAGE_ID, MESSAGE.id()); + assertEquals(PAYLOAD, MESSAGE.payload()); + assertEquals(PAYLOAD_STRING, MESSAGE.payloadAsString()); + assertEquals(ATTRIBUTES, MESSAGE.attributes()); + assertEquals(PUBLISH_TIME, MESSAGE.publishTime()); + assertEquals(MESSAGE_ID, MESSAGE_STRING.id()); + assertEquals(PAYLOAD, MESSAGE_STRING.payload()); + assertEquals(PAYLOAD_STRING, MESSAGE_STRING.payloadAsString()); + assertEquals(ATTRIBUTES, MESSAGE_STRING.attributes()); + assertEquals(PUBLISH_TIME, MESSAGE_STRING.publishTime()); + compareMessage(MESSAGE, MESSAGE_STRING); + Message message = Message.builder(PAYLOAD) + .id(MESSAGE_ID) + .attributes(ATTRIBUTES) + .clearAttributes() + .addAttribute("key1", "value1") + .addAttribute("key2", "value2") + .publishTime(PUBLISH_TIME) + .build(); + assertEquals(MESSAGE_ID, message.id()); + assertEquals(PAYLOAD, message.payload()); + assertEquals(PAYLOAD_STRING, message.payloadAsString()); + assertEquals(ATTRIBUTES, message.attributes()); + assertEquals(PUBLISH_TIME, message.publishTime()); + compareMessage(MESSAGE, message); + } + + @Test + public void testOf() { + Message message1 = Message.of(PAYLOAD_STRING); + assertNull(message1.id()); + assertEquals(PAYLOAD, message1.payload()); + assertEquals(PAYLOAD_STRING, message1.payloadAsString()); + assertEquals(ImmutableMap.of(), message1.attributes()); + assertNull(message1.publishTime()); + Message message2 = Message.of(PAYLOAD); + assertNull(message2.id()); + assertEquals(PAYLOAD, message2.payload()); + assertEquals(PAYLOAD_STRING, message2.payloadAsString()); + assertEquals(ImmutableMap.of(), message2.attributes()); + assertNull(message2.publishTime()); + compareMessage(message1 ,message2); + } + + @Test + public void testToAndFromPb() { + compareMessage(MESSAGE, Message.fromPb(MESSAGE.toPb())); + compareMessage(MESSAGE_STRING, Message.fromPb(MESSAGE_STRING.toPb())); + } + + @Test + public void testToAndFromPbIncomplete() { + Message message = Message.of(PAYLOAD_STRING); + compareMessage(message, Message.fromPb(message.toPb())); + message = Message.of(PAYLOAD); + compareMessage(message, Message.fromPb(message.toPb())); + } + + private void compareMessage(Message expected, Message value) { + assertEquals(expected, value); + assertEquals(expected.id(), value.id()); + assertEquals(expected.payload(), value.payload()); + assertEquals(expected.payloadAsString(), value.payloadAsString()); + assertEquals(expected.attributes(), value.attributes()); + assertEquals(expected.publishTime(), value.publishTime()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} From a8a88d1b526e032a8d9b16b9d0a4824b56354139 Mon Sep 17 00:00:00 2001 From: Ajay Kannan Date: Thu, 12 May 2016 00:47:25 -0700 Subject: [PATCH 345/375] Use new datastore client that permits IP addresses for localhost (#1002) --- gcloud-java-datastore/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index 4d0e394532ce..367bbe9dc743 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -30,7 +30,7 @@ com.google.cloud.datastore datastore-v1beta3-proto-client - 1.0.0-beta + 1.0.0-beta.2 ${project.groupId} From 8fc4f7a3bad3f1e7c91eec3763b9dd92bcd4d210 Mon Sep 17 00:00:00 2001 From: Matti Pehrs Date: Thu, 12 May 2016 18:50:38 +0200 Subject: [PATCH 346/375] Make LocalDatastoreHelper use https instead of http (#942) --- .../google/cloud/datastore/testing/LocalDatastoreHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/testing/LocalDatastoreHelper.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/testing/LocalDatastoreHelper.java index 906e3ccb300e..3c831afdfbbe 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/testing/LocalDatastoreHelper.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/testing/LocalDatastoreHelper.java @@ -92,7 +92,7 @@ public class LocalDatastoreHelper { GCD_URL = null; } else { try { - GCD_URL = new URL("http://storage.googleapis.com/gcd/tools/" + GCD_FILENAME); + GCD_URL = new URL("https://storage.googleapis.com/gcd/tools/" + GCD_FILENAME); } catch (MalformedURLException e) { throw new RuntimeException(e); } From 1eded7e86fc161a504f0e6e75b33662c56c5b863 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 12 May 2016 20:41:45 +0200 Subject: [PATCH 347/375] Add javadoc and tests for PushConfig (#1004) --- .../java/com/google/cloud/pubsub/Message.java | 2 +- .../com/google/cloud/pubsub/PushConfig.java | 156 ++++++++++++++++-- .../com/google/cloud/pubsub/MessageTest.java | 6 +- .../google/cloud/pubsub/PushConfigTest.java | 96 +++++++++++ 4 files changed, 243 insertions(+), 17 deletions(-) create mode 100644 gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PushConfigTest.java diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Message.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Message.java index c8d5ec7500da..b83e5a6296f6 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Message.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Message.java @@ -122,7 +122,7 @@ public abstract static class Builder { abstract Builder publishTime(long publishTime); /** - * Creates a topic object. + * Creates a message object. */ public abstract Message build(); } diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PushConfig.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PushConfig.java index 61b64a07b36b..b8e9fae3f578 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PushConfig.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PushConfig.java @@ -27,7 +27,16 @@ import java.util.Objects; /** - * PubSub subscription push configuration. + * Google Cloud Pub/Sub configuration for a push subscription. + * + *

    In a push subscription, the Pub/Sub server sends a request to the subscriber application. A + * {@code PushConfig} object can be used to configure the application endpoint. The subscriber's + * HTTP response serves as an implicit acknowledgement: a success response indicates that the + * message has been succesfully processed and the Pub/Sub system can delete it from the + * subscription; a non-success response indicates that the Pub/Sub server should resend it + * (implicit "nack"). + * + * @see Subscriber Guide */ public final class PushConfig implements Serializable { @@ -36,34 +45,97 @@ public final class PushConfig implements Serializable { private final String endpoint; private final ImmutableMap attributes; + /** + * Builder for {@code PushConfig} objects. + */ public static final class Builder { private String endpoint; - private final Map attributes = new HashMap<>(); + private Map attributes = new HashMap<>(); private Builder() { } - public Builder endPoint(String endpoint) { + /** + * Sets the URL locating the endpoint to which messages should be pushed. For example, an + * endpoint might use {@code https://example.com/push}. + */ + public Builder endpoint(String endpoint) { this.endpoint = checkNotNull(endpoint); return this; } + /** + * Adds an API-supported attribute that can be used to control different aspects of the message + * delivery. + * + *

    The currently supported attribute is {@code x-goog-version}, which can be used to change + * the format of the push message. This attribute indicates the version of the data expected by + * the endpoint. The endpoint version is based on the version of the Pub/Sub API. Possible + * values for this attribute are: + *

      + *
    • {@code v1beta1}: uses the push format defined in the v1beta1 Pub/Sub API + *
    • {@code v1} or {@code v1beta2}: uses the push format defined in the v1 Pub/Sub API + *
    + * + *

    If the {@code x-goog-version} attribute is not present when a subscription is created (see + * {@link PubSub#create(SubscriptionInfo)} and {@link PubSub#createAsync(SubscriptionInfo)}), it + * will default to {@code v1}. If it is not present when modifying the push config (see + * {@link PubSub#replacePushConfig(String, PushConfig)} and + * {@link PubSub#replacePushConfigAsync(String, PushConfig)}), its value will not be changed. + * + * @see Message Format + */ public Builder addAttribute(String name, String value) { attributes.put(name, value); return this; } + /** + * Sets the API-supported attributes that can be used to control different aspects of the + * message delivery. + * + *

    The currently supported attribute is {@code x-goog-version}, which can be used to change + * the format of the push message. This attribute indicates the version of the data expected by + * the endpoint. The endpoint version is based on the version of the Pub/Sub API. Possible + * values for this attribute are: + *

      + *
    • {@code v1beta1}: uses the push format defined in the v1beta1 Pub/Sub API + *
    • {@code v1} or {@code v1beta2}: uses the push format defined in the v1 Pub/Sub API + *
    + * + *

    If the {@code x-goog-version} attribute is not present when a subscription is created (see + * {@link PubSub#create(SubscriptionInfo)} and {@link PubSub#createAsync(SubscriptionInfo)}), it + * will default to {@code v1}. If it is not present when modifying the push config (see + * {@link PubSub#replacePushConfig(String, PushConfig)} and + * {@link PubSub#replacePushConfigAsync(String, PushConfig)}), its value will not be changed. + * + * @see Message Format + */ + public Builder attributes(Map attributes) { + this.attributes = new HashMap<>(attributes); + return this; + } + + /** + * Removes an API-supported attribute. + */ public Builder removeAttribute(String name) { attributes.remove(name); return this; } + /** + * Clears all API-supported attributes. + */ public Builder clearAttributes() { attributes.clear(); return this; } + /** + * Creates a {@code PushConfig} object. + */ public PushConfig build() { return new PushConfig(this); } @@ -74,24 +146,49 @@ private PushConfig(Builder builder) { attributes = ImmutableMap.copyOf(builder.attributes); } + /** + * Returns the URL locating the endpoint to which messages should be pushed. For example, an + * endpoint might use {@code https://example.com/push}. + */ public String endpoint() { return endpoint; } + /** + * Returns the API-supported attributes that can be used to control different aspects of the + * message delivery. + * + *

    The currently supported attribute is {@code x-goog-version}, which can be used to change + * the format of the push message. This attribute indicates the version of the data expected by + * the endpoint. The endpoint version is based on the version of the Pub/Sub API. Possible + * values for this attribute are: + *

      + *
    • {@code v1beta1}: uses the push format defined in the v1beta1 Pub/Sub API + *
    • {@code v1} or {@code v1beta2}: uses the push format defined in the v1 Pub/Sub API + *
    + * + *

    If the {@code x-goog-version} attribute is not present when a subscription is created (see + * {@link PubSub#create(SubscriptionInfo)} and {@link PubSub#createAsync(SubscriptionInfo)}), it + * will default to {@code v1}. If it is not present when modifying the push config (see + * {@link PubSub#replacePushConfig(String, PushConfig)} and + * {@link PubSub#replacePushConfigAsync(String, PushConfig)}), its value will not be changed. + * + * @see Message Format + */ public Map attributes() { return attributes; } @Override - public boolean equals(Object o) { - if (this == o) { + public boolean equals(Object obj) { + if (this == obj) { return true; } - if (o == null || getClass() != o.getClass()) { + if (!(obj instanceof PushConfig)) { return false; } - PushConfig that = (PushConfig) o; - return Objects.equals(endpoint, that.endpoint) && Objects.equals(attributes, that.attributes); + PushConfig other = (PushConfig) obj; + return Objects.equals(endpoint, other.endpoint) && Objects.equals(attributes, other.attributes); } @Override @@ -107,28 +204,57 @@ public String toString() { .toString(); } + /** + * Returns a builder for the {@code PushConfig} object. + */ public Builder toBuilder() { return builder(endpoint, attributes); } + /** + * Creates a {@code PushConfig} object given the push endpoint. + * + * @param endpoint the URL locating the endpoint to which messages should be pushed. For example, + * an endpoint might use {@code https://example.com/push}. + */ public static PushConfig of(String endpoint) { return builder(endpoint).build(); } + /** + * Creates a {@code PushConfig} object given the push endpoint and the API-supported attributes + * that can be used to control different aspects of the message delivery. + * + * @param endpoint the URL locating the endpoint to which messages should be pushed. For example, + * an endpoint might use {@code https://example.com/push}. + * @param attributes API supported attributes used to control message delivery. See + * {@link Builder#attributes(Map)} for more details. + */ public static PushConfig of(String endpoint, Map attributes) { return builder(endpoint, attributes).build(); } - public static Builder builder(String endPoint) { - return new Builder().endPoint(endPoint); + /** + * Creates a builder for {@code PushConfig} objects given the push endpoint. + * + * @param endpoint the URL locating the endpoint to which messages should be pushed. For example, + * an endpoint might use {@code https://example.com/push}. + */ + public static Builder builder(String endpoint) { + return new Builder().endpoint(endpoint); } + /** + * Creates a builder for {@code PushConfig} objects given the push endpoint and the API-supported + * attributes that can be used to control different aspects of the message delivery. + * + * @param endpoint the URL locating the endpoint to which messages should be pushed. For example, + * an endpoint might use {@code https://example.com/push}. + * @param attributes API supported attributes used to control message delivery. See + * {@link Builder#attributes(Map)} for more details. + */ public static Builder builder(String endpoint, Map attributes) { - Builder builder = builder(endpoint); - for (Map.Entry entry : attributes.entrySet()) { - builder.addAttribute(entry.getKey(), entry.getValue()); - } - return builder; + return builder(endpoint).attributes(attributes); } com.google.pubsub.v1.PushConfig toPb() { diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/MessageTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/MessageTest.java index 3b94bae0d958..c6b177662a9b 100644 --- a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/MessageTest.java +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/MessageTest.java @@ -57,7 +57,11 @@ public void testToBuilder() { .build(); assertEquals("newPayload", message.payloadAsString()); assertEquals(ImmutableMap.of("key1", "value1"), message.attributes()); - message = MESSAGE.toBuilder().payload(PAYLOAD_STRING).attributes(ATTRIBUTES).build(); + message = message.toBuilder() + .payload(PAYLOAD_STRING) + .removeAttribute("key1") + .attributes(ATTRIBUTES) + .build(); compareMessage(MESSAGE, message); } diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PushConfigTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PushConfigTest.java new file mode 100644 index 000000000000..496c10d04938 --- /dev/null +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PushConfigTest.java @@ -0,0 +1,96 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static org.junit.Assert.assertEquals; + +import com.google.common.collect.ImmutableMap; + +import org.junit.Test; + +import java.util.Map; + +public class PushConfigTest { + + private static final String ENDPOINT = "https://example.com/push"; + private static final Map ATTRIBUTES = + ImmutableMap.of("key1", "value1", "key2", "value2"); + private static final PushConfig PUSH_CONFIG = PushConfig.builder(ENDPOINT, ATTRIBUTES).build(); + + @Test + public void testToBuilder() { + comparePushConfig(PUSH_CONFIG, PUSH_CONFIG.toBuilder().build()); + PushConfig pushConfig = PUSH_CONFIG.toBuilder() + .endpoint("https://example2.com/push") + .clearAttributes() + .addAttribute("key1", "value1") + .build(); + assertEquals("https://example2.com/push", pushConfig.endpoint()); + assertEquals(ImmutableMap.of("key1", "value1"), pushConfig.attributes()); + pushConfig = pushConfig.toBuilder() + .endpoint(ENDPOINT) + .removeAttribute("key1") + .attributes(ATTRIBUTES) + .build(); + comparePushConfig(PUSH_CONFIG, pushConfig); + } + + @Test + public void testBuilder() { + assertEquals(ENDPOINT, PUSH_CONFIG.endpoint()); + assertEquals(ATTRIBUTES, PUSH_CONFIG.attributes()); + PushConfig pushConfig = PushConfig.builder("https://example2.com/push") + .endpoint(ENDPOINT) + .attributes(ATTRIBUTES) + .clearAttributes() + .addAttribute("key1", "value1") + .addAttribute("key2", "value2") + .build(); + assertEquals(ENDPOINT, pushConfig.endpoint()); + assertEquals(ATTRIBUTES, pushConfig.attributes()); + comparePushConfig(PUSH_CONFIG, pushConfig); + } + + @Test + public void testOf() { + PushConfig pushConfig = PushConfig.of(ENDPOINT); + assertEquals(ENDPOINT, pushConfig.endpoint()); + assertEquals(ImmutableMap.of(), pushConfig.attributes()); + pushConfig = PushConfig.of(ENDPOINT, ATTRIBUTES); + assertEquals(ENDPOINT, pushConfig.endpoint()); + assertEquals(ATTRIBUTES, pushConfig.attributes()); + comparePushConfig(PUSH_CONFIG, pushConfig); + } + + @Test + public void testToAndFromPb() { + comparePushConfig(PUSH_CONFIG, PushConfig.fromPb(PUSH_CONFIG.toPb())); + } + + @Test + public void testToAndFromPbIncomplete() { + PushConfig pushConfig = PushConfig.of(ENDPOINT); + comparePushConfig(pushConfig, PushConfig.fromPb(pushConfig.toPb())); + } + + private void comparePushConfig(PushConfig expected, PushConfig value) { + assertEquals(expected, value); + assertEquals(expected.endpoint(), value.endpoint()); + assertEquals(expected.attributes(), value.attributes()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} From af79f8ffc967c66066df6ca07cc8d360ff5f0f41 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 13 May 2016 13:25:57 +0200 Subject: [PATCH 348/375] Refactor Datastore example, add example on embedded entities (#980) * Refactor Datastore example, add example on embedded entities * Minor refactoring of examples - Favor printf over println - Rename Action argument from request to arg --- gcloud-java-examples/README.md | 1 + .../examples/bigquery/BigQueryExample.java | 14 +- .../examples/compute/ComputeExample.java | 371 +++++++++--------- .../examples/datastore/DatastoreExample.java | 200 +++++++--- .../google/cloud/examples/dns/DnsExample.java | 10 +- .../ResourceManagerExample.java | 4 +- .../examples/storage/StorageExample.java | 30 +- 7 files changed, 372 insertions(+), 258 deletions(-) diff --git a/gcloud-java-examples/README.md b/gcloud-java-examples/README.md index 98af1df5f3f2..84cb6d581d8a 100644 --- a/gcloud-java-examples/README.md +++ b/gcloud-java-examples/README.md @@ -81,6 +81,7 @@ To run examples from your command line: mvn exec:java -Dexec.mainClass="com.google.cloud.examples.datastore.DatastoreExample" -Dexec.args="your-project-id my_name add my\ comment" mvn exec:java -Dexec.mainClass="com.google.cloud.examples.datastore.DatastoreExample" -Dexec.args="your-project-id my_name display" mvn exec:java -Dexec.mainClass="com.google.cloud.examples.datastore.DatastoreExample" -Dexec.args="your-project-id my_name delete" + mvn exec:java -Dexec.mainClass="com.google.cloud.examples.datastore.DatastoreExample" -Dexec.args="your-project-id my_name set myname@mydomain.com 1234" ``` * Here's an example run of `DnsExample`. diff --git a/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java index 5b15bbd6ec71..6acfb5bbef6d 100644 --- a/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java @@ -108,7 +108,7 @@ public class BigQueryExample { private abstract static class BigQueryAction { - abstract void run(BigQuery bigquery, T request) throws Exception; + abstract void run(BigQuery bigquery, T arg) throws Exception; abstract T parse(String... args) throws Exception; @@ -775,18 +775,18 @@ public static void main(String... args) throws Exception { return; } BigQuery bigquery = optionsBuilder.build().service(); - Object request; + Object arg; try { - request = action.parse(args); + arg = action.parse(args); } catch (IllegalArgumentException ex) { - System.out.println("Invalid input for action '" + actionName + "'. " + ex.getMessage()); - System.out.println("Expected: " + action.params()); + System.out.printf("Invalid input for action '%s'. %s%n", actionName, ex.getMessage()); + System.out.printf("Expected: %s%n", action.params()); return; } catch (Exception ex) { - System.out.println("Failed to parse request."); + System.out.println("Failed to parse arguments."); ex.printStackTrace(); return; } - action.run(bigquery, request); + action.run(bigquery, arg); } } diff --git a/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/ComputeExample.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/ComputeExample.java index d7f8e671cb72..23421e197f58 100644 --- a/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/ComputeExample.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/ComputeExample.java @@ -199,7 +199,7 @@ Z z() { private abstract static class ComputeAction { - abstract void run(Compute compute, T request) throws Exception; + abstract void run(Compute compute, T arg) throws Exception; abstract T parse(String... args) throws Exception; @@ -332,7 +332,7 @@ public void run(Compute compute, ZoneId zone) { private static class DiskTypeInfoAction extends ComputeAction { @Override public void run(Compute compute, DiskTypeId diskType) { - System.out.println("Disk type info: " + compute.getDiskType(diskType)); + System.out.printf("Disk type info: %s%n", compute.getDiskType(diskType)); } @Override @@ -387,7 +387,7 @@ public void run(Compute compute, ZoneId zone) { private static class MachineTypeInfoAction extends ComputeAction { @Override public void run(Compute compute, MachineTypeId machineType) { - System.out.println("Machine type info: " + compute.getMachineType(machineType)); + System.out.printf("Machine type info: %s%n", compute.getMachineType(machineType)); } @Override @@ -434,7 +434,7 @@ public void run(Compute compute, Void arg) { private static class RegionInfoAction extends ComputeAction { @Override public void run(Compute compute, RegionId region) { - System.out.println("Region info: " + compute.getRegion(region.region())); + System.out.printf("Region info: %s%n", compute.getRegion(region.region())); } @Override @@ -480,7 +480,7 @@ public void run(Compute compute, Void arg) { private static class ZoneInfoAction extends ComputeAction { @Override public void run(Compute compute, ZoneId zone) { - System.out.println("Zone info: " + compute.getZone(zone.zone())); + System.out.printf("Zone info: %s%n", compute.getZone(zone.zone())); } @Override @@ -511,7 +511,7 @@ public String params() { private static class LicenseInfoAction extends ComputeAction { @Override public void run(Compute compute, LicenseId license) { - System.out.println("License info: " + compute.getLicense(license.license())); + System.out.printf("License info: %s%n", compute.getLicense(license.license())); } @Override @@ -687,7 +687,7 @@ public String params() { private static class GlobalOperationInfoAction extends GlobalOperationAction { @Override public void run(Compute compute, GlobalOperationId operation) { - System.out.println("Operation info: " + compute.getOperation(operation)); + System.out.printf("Operation info: %s%n", compute.getOperation(operation)); } } @@ -700,7 +700,7 @@ public void run(Compute compute, GlobalOperationId operation) { private static class ZoneOperationInfoAction extends ZoneOperationAction { @Override public void run(Compute compute, ZoneOperationId operation) { - System.out.println("Operation info: " + compute.getOperation(operation)); + System.out.printf("Operation info: %s%n", compute.getOperation(operation)); } } @@ -713,7 +713,7 @@ public void run(Compute compute, ZoneOperationId operation) { private static class RegionOperationInfoAction extends RegionOperationAction { @Override public void run(Compute compute, RegionOperationId operation) { - System.out.println("Operation info: " + compute.getOperation(operation)); + System.out.printf("Operation info: %s%n", compute.getOperation(operation)); } } @@ -727,9 +727,9 @@ private static class DeleteGlobalOperationAction extends GlobalOperationAction { @Override public void run(Compute compute, GlobalOperationId operation) { if (compute.deleteOperation(operation)) { - System.out.println("Operation " + operation + " was deleted"); + System.out.printf("Operation %s was deleted%n", operation); } else { - System.out.println("Operation " + operation + " not found"); + System.out.printf("Operation %s not found%n", operation); } } } @@ -744,9 +744,9 @@ private static class DeleteZoneOperationAction extends ZoneOperationAction { @Override public void run(Compute compute, ZoneOperationId operation) { if (compute.deleteOperation(operation)) { - System.out.println("Operation " + operation + " was deleted"); + System.out.printf("Operation %s was deleted%n", operation); } else { - System.out.println("Operation " + operation + " not found"); + System.out.printf("Operation %s not found%n", operation); } } } @@ -761,9 +761,9 @@ private static class DeleteRegionOperationAction extends RegionOperationAction { @Override public void run(Compute compute, RegionOperationId operation) { if (compute.deleteOperation(operation)) { - System.out.println("Operation " + operation + " was deleted"); + System.out.printf("Operation %s was deleted%n", operation); } else { - System.out.println("Operation " + operation + " not found"); + System.out.printf("Operation %s not found%n", operation); } } } @@ -824,7 +824,7 @@ public String params() { private static class AddressInfoAction extends AddressAction { @Override public void run(Compute compute, AddressId address) { - System.out.println("Address info: " + compute.getAddress(address)); + System.out.printf("Address info: %s%n", compute.getAddress(address)); } } @@ -841,20 +841,20 @@ private static class DeleteAddressAction extends AddressAction { public void run(Compute compute, AddressId address) throws InterruptedException { Operation operation = compute.deleteAddress(address); if (operation == null) { - System.out.println("Address " + address + " does not exist"); + System.out.printf("Address %s does not exist%n", address); return; } while (!operation.isDone()) { - System.out.println( - "Waiting for operation " + operation.operationId().operation() + " to complete"); + System.out.printf( + "Waiting for operation %s to complete%n", operation.operationId().operation()); Thread.sleep(1000L); } operation = operation.reload(); if (operation.errors() == null) { - System.out.println("Address " + address + " was deleted"); + System.out.printf("Address %s was deleted%n", address); } else { - System.out.println("Deletion of address " + address + " failed"); - System.out.println("Error: " + operation.errors()); + System.out.printf("Deletion of address %s failed%n", address); + System.out.printf("Error: %s%n", operation.errors()); } } } @@ -872,16 +872,16 @@ private static class CreateAddressAction extends AddressAction { public void run(Compute compute, AddressId address) throws InterruptedException { Operation operation = compute.create(AddressInfo.of(address)); while (!operation.isDone()) { - System.out.println( - "Waiting for operation " + operation.operationId().operation() + " to complete"); + System.out.printf( + "Waiting for operation %s to complete%n", operation.operationId().operation()); Thread.sleep(1000L); } operation = operation.reload(); if (operation.errors() == null) { - System.out.println("Address " + address + " was created"); + System.out.printf("Address %s was created%n", address); } else { - System.out.println("Creation of address " + address + " failed"); - System.out.println("Error: " + operation.errors()); + System.out.printf("Creation of address %s failed%n", address); + System.out.printf("Error: %s%n", operation.errors()); } } } @@ -931,7 +931,7 @@ public String params() { private static class SnapshotInfoAction extends SnapshotAction { @Override public void run(Compute compute, SnapshotId snapshot) { - System.out.println("Snapshot info: " + compute.getSnapshot(snapshot.snapshot())); + System.out.printf("Snapshot info: %s%n", compute.getSnapshot(snapshot.snapshot())); } } @@ -946,20 +946,20 @@ private static class DeleteSnapshotAction extends SnapshotAction { public void run(Compute compute, SnapshotId snapshot) throws InterruptedException { Operation operation = compute.deleteSnapshot(snapshot.snapshot()); if (operation == null) { - System.out.println("Snapshot " + snapshot + " does not exist"); + System.out.printf("Snapshot %s does not exist%n", snapshot); return; } while (!operation.isDone()) { - System.out.println( - "Waiting for operation " + operation.operationId().operation() + " to complete"); + System.out.printf( + "Waiting for operation %s to complete%n", operation.operationId().operation()); Thread.sleep(1000L); } operation = operation.reload(); if (operation.errors() == null) { - System.out.println("Snapshot " + snapshot + " was deleted"); + System.out.printf("Snapshot %s was deleted%n", snapshot); } else { - System.out.println("Deletion of snapshot " + snapshot + " failed"); - System.out.println("Error: " + operation.errors()); + System.out.printf("Deletion of snapshot %s failed%n", snapshot); + System.out.printf("Error: %s%n", operation.errors()); } } } @@ -975,16 +975,16 @@ private static class CreateSnapshotAction extends ComputeAction { public void run(Compute compute, SnapshotInfo snapshot) throws InterruptedException { Operation operation = compute.create(snapshot); while (!operation.isDone()) { - System.out.println( - "Waiting for operation " + operation.operationId().operation() + " to complete"); + System.out.printf( + "Waiting for operation %s to complete%n", operation.operationId().operation()); Thread.sleep(1000L); } operation = operation.reload(); if (operation.errors() == null) { - System.out.println("Snapshot " + snapshot.snapshotId() + " was created"); + System.out.printf("Snapshot %s was created%n", snapshot.snapshotId()); } else { - System.out.println("Creation of snapshot " + snapshot.snapshotId() + " failed"); - System.out.println("Error: " + operation.errors()); + System.out.printf("Creation of snapshot %s failed%n", snapshot.snapshotId()); + System.out.printf("Error: %s%n", operation.errors()); } } @@ -1055,7 +1055,7 @@ public String params() { private static class ImageInfoAction extends ImageAction { @Override public void run(Compute compute, ImageId image) { - System.out.println("Image info: " + compute.getImage(image)); + System.out.printf("Image info: %s%n", compute.getImage(image)); } } @@ -1070,20 +1070,20 @@ private static class DeleteImageAction extends ImageAction { public void run(Compute compute, ImageId image) throws InterruptedException { Operation operation = compute.deleteImage(image); if (operation == null) { - System.out.println("Image " + image + " does not exist"); + System.out.printf("Image %s does not exist%n", image); return; } while (!operation.isDone()) { - System.out.println( - "Waiting for operation " + operation.operationId().operation() + " to complete"); + System.out.printf( + "Waiting for operation %s to complete%n", operation.operationId().operation()); Thread.sleep(1000L); } operation = operation.reload(); if (operation.errors() == null) { - System.out.println("Image " + image + " was deleted"); + System.out.printf("Image %s was deleted%n", image); } else { - System.out.println("Deletion of image " + image + " failed"); - System.out.println("Error: " + operation.errors()); + System.out.printf("Deletion of image %s failed%n", image); + System.out.printf("Error: %s%n", operation.errors()); } } } @@ -1099,16 +1099,16 @@ private static class CreateImageAction extends ComputeAction { public void run(Compute compute, ImageInfo image) throws InterruptedException { Operation operation = compute.create(image); while (!operation.isDone()) { - System.out.println( - "Waiting for operation " + operation.operationId().operation() + " to complete"); + System.out.printf( + "Waiting for operation %s to complete%n", operation.operationId().operation()); Thread.sleep(1000L); } operation = operation.reload(); if (operation.errors() == null) { - System.out.println("Image " + image.imageId() + " was created"); + System.out.printf("Image %s was created%n", image.imageId()); } else { - System.out.println("Creation of image " + image.imageId() + " failed"); - System.out.println("Error: " + operation.errors()); + System.out.printf("Creation of image %s failed%n", image.imageId()); + System.out.printf("Error: %s%n", operation.errors()); } } @@ -1163,7 +1163,7 @@ public String params() { private static class DiskInfoAction extends DiskAction { @Override public void run(Compute compute, DiskId disk) { - System.out.println("Disk info: " + compute.getDisk(disk)); + System.out.printf("Disk info: %s%n", compute.getDisk(disk)); } } @@ -1178,20 +1178,20 @@ private static class DeleteDiskAction extends DiskAction { public void run(Compute compute, DiskId disk) throws InterruptedException { Operation operation = compute.deleteDisk(disk); if (operation == null) { - System.out.println("Disk " + disk + " does not exist"); + System.out.printf("Disk %s does not exist%n", disk); return; } while (!operation.isDone()) { - System.out.println( - "Waiting for operation " + operation.operationId().operation() + " to complete"); + System.out.printf( + "Waiting for operation %s to complete%n", operation.operationId().operation()); Thread.sleep(1000L); } operation = operation.reload(); if (operation.errors() == null) { - System.out.println("Disk " + disk + " was deleted"); + System.out.printf("Disk %s was deleted%n", disk); } else { - System.out.println("Deletion of disk " + disk + " failed"); - System.out.println("Error: " + operation.errors()); + System.out.printf("Deletion of disk %s failed%n", disk); + System.out.printf("Error: %s%n", operation.errors()); } } } @@ -1217,16 +1217,16 @@ private abstract static class CreateDiskAction extends ComputeAction { public void run(Compute compute, DiskInfo disk) throws InterruptedException { Operation operation = compute.create(disk); while (!operation.isDone()) { - System.out.println( - "Waiting for operation " + operation.operationId().operation() + " to complete"); + System.out.printf( + "Waiting for operation %s to complete%n", operation.operationId().operation()); Thread.sleep(1000L); } operation = operation.reload(); if (operation.errors() == null) { - System.out.println("Disk " + disk.diskId() + " was created"); + System.out.printf("Disk %s was created%n", disk.diskId()); } else { - System.out.println("Creation of disk " + disk.diskId() + " failed"); - System.out.println("Error: " + operation.errors()); + System.out.printf("Creation of disk %s failed%n", disk.diskId()); + System.out.printf("Error: %s%n", operation.errors()); } } @@ -1370,7 +1370,7 @@ public String params() { private static class NetworkInfoAction extends NetworkAction { @Override public void run(Compute compute, NetworkId network) { - System.out.println("Network info: " + compute.getNetwork(network.network())); + System.out.printf("Network info: %s%n", compute.getNetwork(network.network())); } } @@ -1385,20 +1385,20 @@ private static class DeleteNetworkAction extends NetworkAction { public void run(Compute compute, NetworkId network) throws InterruptedException { Operation operation = compute.deleteNetwork(network.network()); if (operation == null) { - System.out.println("Network " + network + " does not exist"); + System.out.printf("Network %s does not exist%n", network); return; } while (!operation.isDone()) { - System.out.println( - "Waiting for operation " + operation.operationId().operation() + " to complete"); + System.out.printf( + "Waiting for operation %s to complete%n", operation.operationId().operation()); Thread.sleep(1000L); } operation = operation.reload(); if (operation.errors() == null) { - System.out.println("Network " + network + " was deleted"); + System.out.printf("Network %s was deleted%n", network); } else { - System.out.println("Deletion of network " + network + " failed"); - System.out.println("Error: " + operation.errors()); + System.out.printf("Deletion of network %s failed%n", network); + System.out.printf("Error: %s%n", operation.errors()); } } } @@ -1408,16 +1408,16 @@ private abstract static class CreateNetworkAction extends ComputeAction { public void run(Compute compute, InstanceInfo instance) throws InterruptedException { Operation operation = compute.create(instance); while (!operation.isDone()) { - System.out.println( - "Waiting for operation " + operation.operationId().operation() + " to complete"); + System.out.printf( + "Waiting for operation %s to complete%n", operation.operationId().operation()); Thread.sleep(1000L); } operation = operation.reload(); if (operation.errors() == null) { - System.out.println("Instance " + instance.instanceId() + " was created"); + System.out.printf("Instance %s was created%n", instance.instanceId()); } else { - System.out.println("Creation of instance " + instance.instanceId() + " failed"); - System.out.println("Error: " + operation.errors()); + System.out.printf("Creation of instance %s failed%n", instance.instanceId()); + System.out.printf("Error: %s%n", operation.errors()); } } @@ -1760,10 +1760,10 @@ public void run(Compute compute, Tuple instanceAndPort) Integer port = instanceAndPort.y(); String serialPortOutput; if (port != null) { - System.out.println("Getting serial port " + port + " output for instance " + instance); + System.out.printf("Getting serial port %d output for instance %s%n", port, instance); serialPortOutput = compute.getSerialPortOutput(instance, port); } else { - System.out.println("Getting serial port output for instance " + instance); + System.out.printf("Getting serial port output for instance %s%n", instance); serialPortOutput = compute.getSerialPortOutput(instance); } System.out.println(serialPortOutput); @@ -1813,22 +1813,22 @@ public void run(Compute compute, Triple interf AccessConfig accessConfig = interfaceAndConfig.z(); Operation operation = compute.addAccessConfig(instance, networkInterface, accessConfig); if (operation == null) { - System.out.println("Instance " + instance + " does not exist"); + System.out.printf("Instance %s does not exist%n", instance); return; } while (!operation.isDone()) { - System.out.println( - "Waiting for operation " + operation.operationId().operation() + " to complete"); + System.out.printf( + "Waiting for operation %s to complete%n", operation.operationId().operation()); Thread.sleep(1000L); } operation = operation.reload(); if (operation.errors() == null) { - System.out.println("Access config added to network interface " + networkInterface - + " of instance " + instance); + System.out.printf("Access config added to network interface %s of instance %s%n", + networkInterface, instance); } else { - System.out.println("Attempt to add access config to network interface " + networkInterface - + " of instance " + instance + " failed"); - System.out.println("Error: " + operation.errors()); + System.out.printf("Attempt to add access config to network interface %s of instance %s%n", + networkInterface, instance); + System.out.printf("Error: %s%n", operation.errors()); } } @@ -1877,22 +1877,23 @@ public void run(Compute compute, Triple interfaceAnd String accessConfig = interfaceAndConfig.z(); Operation operation = compute.deleteAccessConfig(instance, networkInterface, accessConfig); if (operation == null) { - System.out.println("Instance " + instance + " does not exist"); + System.out.printf("Instance %s does not exist%n", instance); return; } while (!operation.isDone()) { - System.out.println( - "Waiting for operation " + operation.operationId().operation() + " to complete"); + System.out.printf( + "Waiting for operation %s to complete%n", operation.operationId().operation()); Thread.sleep(1000L); } operation = operation.reload(); if (operation.errors() == null) { - System.out.println("Access config deleted from network interface " + networkInterface - + " of instance " + instance); + System.out.printf("Access config deleted from network interface %s of instance %s%n", + networkInterface, instance); } else { - System.out.println("Attempt to delete access config from network interface " - + networkInterface + " of instance " + instance + " failed"); - System.out.println("Error: " + operation.errors()); + System.out.printf( + "Attempt to delete access config from network interface %s of instance %s failed%n", + networkInterface, instance); + System.out.printf("Error: %s%n", operation.errors()); } } @@ -1934,20 +1935,20 @@ public void run(Compute compute, Triple instanceAndDevice) String deviceName = instanceAndDevice.y(); Operation operation = compute.detachDisk(instance, deviceName); if (operation == null) { - System.out.println("Instance " + instance + " does not exist"); + System.out.printf("Instance %s does not exist%n", instance); return; } while (!operation.isDone()) { - System.out.println( - "Waiting for operation " + operation.operationId().operation() + " to complete"); + System.out.printf( + "Waiting for operation %s to complete%n", operation.operationId().operation()); Thread.sleep(1000L); } operation = operation.reload(); if (operation.errors() == null) { - System.out.println("Disk detached from instance " + instance); + System.out.printf("Disk detached from instance %s%n", instance); } else { - System.out.println("Attempt to detach disk from instance " + instance + " failed"); - System.out.println("Error: " + operation.errors()); + System.out.printf("Attempt to detach disk from instance %s failed%n", instance); + System.out.printf("Error: %s%n", operation.errors()); } } @@ -2045,21 +2046,21 @@ public void run(Compute compute, Triple deviceAndAu Boolean autoDelete = deviceAndAutoDelete.z(); Operation operation = compute.setDiskAutoDelete(instance, deviceName, autoDelete); if (operation == null) { - System.out.println("Instance " + instance + " does not exist"); + System.out.printf("Instance %s does not exist%n", instance); return; } while (!operation.isDone()) { - System.out.println( - "Waiting for operation " + operation.operationId().operation() + " to complete"); + System.out.printf( + "Waiting for operation %s to complete%n", operation.operationId().operation()); Thread.sleep(1000L); } operation = operation.reload(); if (operation.errors() == null) { - System.out.println("Auto-delete set for device " + deviceName + " of instance " + instance); + System.out.printf("Auto-delete set for device %s of instance %s%n", deviceName, instance); } else { - System.out.println("Attempt to set auto-delete for device " + deviceName + " of instance " - + instance + " failed"); - System.out.println("Error: " + operation.errors()); + System.out.printf("Attempt to set auto-delete for device %s of instance %s failed%n", + deviceName, instance); + System.out.printf("Error: %s%n", operation.errors()); } } @@ -2111,20 +2112,20 @@ public void run(Compute compute, Tuple instanceAndTyp MachineTypeId machineType = instanceAndType.y(); Operation operation = compute.setMachineType(instance, machineType); if (operation == null) { - System.out.println("Instance " + instance + " does not exist"); + System.out.printf("Instance %s does not exist%n", instance); return; } while (!operation.isDone()) { - System.out.println( - "Waiting for operation " + operation.operationId().operation() + " to complete"); + System.out.printf( + "Waiting for operation %s to complete%n", operation.operationId().operation()); Thread.sleep(1000L); } operation = operation.reload(); if (operation.errors() == null) { - System.out.println("Machine type set for instance " + instance); + System.out.printf("Machine type set for instance %s%n", instance); } else { - System.out.println("Attempt to set machine type for instance " + instance + " failed"); - System.out.println("Error: " + operation.errors()); + System.out.printf("Attempt to set machine type for instance %s failed%n", instance); + System.out.printf("Error: %s%n", operation.errors()); } } @@ -2164,21 +2165,21 @@ public void run(Compute compute, Tuple> instanceAndTags List tags = instanceAndTags.y(); Instance instance = compute.getInstance(instanceId); if (instance == null) { - System.out.println("Instance " + instance + " does not exist"); + System.out.printf("Instance %s does not exist%n", instanceId); return; } Operation operation = instance.setTags(tags); while (!operation.isDone()) { - System.out.println( - "Waiting for operation " + operation.operationId().operation() + " to complete"); + System.out.printf( + "Waiting for operation %s to complete%n", operation.operationId().operation()); Thread.sleep(1000L); } operation = operation.reload(); if (operation.errors() == null) { - System.out.println("Tags set for instance " + instanceId); + System.out.printf("Tags set for instance %s%n", instanceId); } else { - System.out.println("Attempt to set tags for instance " + instanceId + " failed"); - System.out.println("Error: " + operation.errors()); + System.out.printf("Attempt to set tags for instance %s failed%n", instanceId); + System.out.printf("Error: %s%n", operation.errors()); } } @@ -2215,21 +2216,21 @@ public void run(Compute compute, Tuple> instance Map metadata = instanceAndMetadata.y(); Instance instance = compute.getInstance(instanceId); if (instance == null) { - System.out.println("Instance " + instance + " does not exist"); + System.out.printf("Instance %s does not exist%n", instanceId); return; } Operation operation = instance.setMetadata(metadata); while (!operation.isDone()) { - System.out.println( - "Waiting for operation " + operation.operationId().operation() + " to complete"); + System.out.printf( + "Waiting for operation %s to complete%n", operation.operationId().operation()); Thread.sleep(1000L); } operation = operation.reload(); if (operation.errors() == null) { - System.out.println("Metadata set for instance " + instanceId); + System.out.printf("Metadata set for instance %s%n", instanceId); } else { - System.out.println("Attempt to set metadata for instance " + instanceId + " failed"); - System.out.println("Error: " + operation.errors()); + System.out.printf("Attempt to set metadata for instance %s failed%n", instanceId); + System.out.printf("Error: %s%n", operation.errors()); } } @@ -2271,21 +2272,21 @@ public void run(Compute compute, Tuple instanceAn SchedulingOptions schedulingOptions = instanceAndScheduling.y(); Operation operation = compute.setSchedulingOptions(instanceId, schedulingOptions); if (operation == null) { - System.out.println("Instance " + instanceId + " does not exist"); + System.out.printf("Instance %s does not exist%n", instanceId); return; } while (!operation.isDone()) { - System.out.println( - "Waiting for operation " + operation.operationId().operation() + " to complete"); + System.out.printf( + "Waiting for operation %s to complete%n", operation.operationId().operation()); Thread.sleep(1000L); } operation = operation.reload(); if (operation.errors() == null) { - System.out.println("Scheduling options set for instance " + instanceId); + System.out.printf("Scheduling options set for instance %s%n", instanceId); } else { - System.out.println( - "Attempt to set scheduling options for instance " + instanceId + " failed"); - System.out.println("Error: " + operation.errors()); + System.out.printf( + "Attempt to set scheduling options for instance %s failed%n", instanceId); + System.out.printf("Error: %s%n", operation.errors()); } } @@ -2337,20 +2338,20 @@ private static class ResetInstanceAction extends InstanceAction { public void run(Compute compute, InstanceId instance) throws InterruptedException { Operation operation = compute.reset(instance); if (operation == null) { - System.out.println("Instance " + instance + " does not exist"); + System.out.printf("Instance %s does not exist%n", instance); return; } while (!operation.isDone()) { - System.out.println( - "Waiting for operation " + operation.operationId().operation() + " to complete"); + System.out.printf( + "Waiting for operation %s to complete%n", operation.operationId().operation()); Thread.sleep(1000L); } operation = operation.reload(); if (operation.errors() == null) { - System.out.println("Instance " + instance + " was reset"); + System.out.printf("Instance %s was reset%n", instance); } else { - System.out.println("Attempt to reset instance " + instance + " failed"); - System.out.println("Error: " + operation.errors()); + System.out.printf("Attempt to reset instance %s failed%n", instance); + System.out.printf("Error: %s%n", operation.errors()); } } } @@ -2366,20 +2367,20 @@ private static class StopInstanceAction extends InstanceAction { public void run(Compute compute, InstanceId instance) throws InterruptedException { Operation operation = compute.stop(instance); if (operation == null) { - System.out.println("Instance " + instance + " does not exist"); + System.out.printf("Instance %s does not exist%n", instance); return; } while (!operation.isDone()) { - System.out.println( - "Waiting for operation " + operation.operationId().operation() + " to complete"); + System.out.printf( + "Waiting for operation %s to complete%n", operation.operationId().operation()); Thread.sleep(1000L); } operation = operation.reload(); if (operation.errors() == null) { - System.out.println("Instance " + instance + " was stopped"); + System.out.printf("Instance %s was stopped%n", instance); } else { - System.out.println("Attempt to stop instance " + instance + " failed"); - System.out.println("Error: " + operation.errors()); + System.out.printf("Attempt to stop instance %s failed%n", instance); + System.out.printf("Error: %s%n", operation.errors()); } } } @@ -2395,20 +2396,20 @@ private static class StartInstanceAction extends InstanceAction { public void run(Compute compute, InstanceId instance) throws InterruptedException { Operation operation = compute.start(instance); if (operation == null) { - System.out.println("Instance " + instance + " does not exist"); + System.out.printf("Instance %s does not exist%n", instance); return; } while (!operation.isDone()) { - System.out.println( - "Waiting for operation " + operation.operationId().operation() + " to complete"); + System.out.printf( + "Waiting for operation %s to complete%n", operation.operationId().operation()); Thread.sleep(1000L); } operation = operation.reload(); if (operation.errors() == null) { - System.out.println("Instance " + instance + " was started"); + System.out.printf("Instance %s was started%n", instance); } else { - System.out.println("Attempt to start instance " + instance + " failed"); - System.out.println("Error: " + operation.errors()); + System.out.printf("Attempt to start instance %s failed%n", instance); + System.out.printf("Error: %s%n", operation.errors()); } } } @@ -2522,18 +2523,18 @@ public static void main(String... args) throws Exception { return; } Compute compute = optionsBuilder.build().service(); - Object request; + Object arg; try { - request = action.parse(args); + arg = action.parse(args); } catch (IllegalArgumentException ex) { - System.out.println("Invalid input for action '" + actionName + "'. " + ex.getMessage()); - System.out.println("Expected: " + action.params()); + System.out.printf("Invalid input for action '%s'. %s%n", actionName, ex.getMessage()); + System.out.printf("Expected: %s%n", action.params()); return; } catch (Exception ex) { - System.out.println("Failed to parse request."); + System.out.println("Failed to parse arguments."); ex.printStackTrace(); return; } - action.run(compute, request); + action.run(compute, arg); } } diff --git a/gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/DatastoreExample.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/DatastoreExample.java index cf0fee504bf8..4b83f04e7165 100644 --- a/gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/DatastoreExample.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/datastore/DatastoreExample.java @@ -38,15 +38,23 @@ /** * An example of using Google Cloud Datastore. * - *

    This example adds, display or clear comments for a given user. + *

    This example adds, displays or clears comments for a given user. This example also sets + * contact information for a user. * *

    Steps needed for running the example:

      *
    1. login using gcloud SDK - {@code gcloud auth login}.
    2. *
    3. compile using maven - {@code mvn compile}
    4. - *
    5. run using maven - {@code mvn exec:java - * -Dexec.mainClass="com.google.cloud.examples.datastore.DatastoreExample" - * -Dexec.args="[projectId] [user] [delete|display|add comment]"}
    6. + *
    7. run using maven - + *
      {@code mvn exec:java -Dexec.mainClass="com.google.cloud.examples.datastore.DatastoreExample"
      + *  -Dexec.args=" 
      + *  delete |
      + *  display |
      + *  add  |
      + *  set  }
      + *
    8. *
    + * + *

    If no action is provided {@code display} is executed. */ public class DatastoreExample { @@ -56,15 +64,24 @@ public class DatastoreExample { private static final String DEFAULT_ACTION = "display"; private static final Map ACTIONS = new HashMap<>(); - private interface DatastoreAction { - void run(Transaction tx, Key userKey, String... args); + private abstract static class DatastoreAction { + + abstract void run(Transaction tx, Key userKey, T arg) throws Exception; - String getRequiredParams(); + abstract T parse(String... args) throws Exception; + + protected String params() { + return ""; + } } - private static class DeleteAction implements DatastoreAction { + /** + * This class demonstrates how to delete a user. This action also queries the keys of all comments + * associated with the user and uses them to delete comments. + */ + private static class DeleteAction extends DatastoreAction { @Override - public void run(Transaction tx, Key userKey, String... args) { + public void run(Transaction tx, Key userKey, Void arg) { Entity user = tx.get(userKey); if (user == null) { System.out.println("Nothing to delete, user does not exist."); @@ -86,19 +103,30 @@ public void run(Transaction tx, Key userKey, String... args) { } @Override - public String getRequiredParams() { - return ""; + Void parse(String... args) throws Exception { + return null; } } - private static class DisplayAction implements DatastoreAction { + /** + * This class demonstrates how to get a user. The action also queries all comments associated + * with the user. + */ + private static class DisplayAction extends DatastoreAction { @Override - public void run(Transaction tx, Key userKey, String... args) { + public void run(Transaction tx, Key userKey, Void arg) { Entity user = tx.get(userKey); if (user == null) { - System.out.println("No comments for '" + userKey.name() + "'."); + System.out.printf("User '%s' does not exist.%n", userKey.name()); return; } + if (user.contains("contact")) { + FullEntity contact = user.getEntity("contact"); + String email = contact.getString("email"); + String phone = contact.getString("phone"); + System.out.printf("User '%s' email is '%s', phone is '%s'.%n", + userKey.name(), email, phone); + } System.out.printf("User '%s' has %d comment[s].%n", userKey.name(), user.getLong("count")); int limit = 200; Map sortedComments = new TreeMap<>(); @@ -131,25 +159,37 @@ public void run(Transaction tx, Key userKey, String... args) { } @Override - public String getRequiredParams() { - return ""; + Void parse(String... args) throws Exception { + return null; } } - private static class AddAction implements DatastoreAction { + /** + * This class adds a comment for a user. If the user does not exist its entity is created. + */ + private static class AddCommentAction extends DatastoreAction { @Override - public void run(Transaction tx, Key userKey, String... args) { + public void run(Transaction tx, Key userKey, String content) { Entity user = tx.get(userKey); if (user == null) { System.out.println("Adding a new user."); - user = Entity.builder(userKey) - .set("count", 1L) - .build(); + user = Entity.builder(userKey).set("count", 1).build(); tx.add(user); } else { user = Entity.builder(user).set("count", user.getLong("count") + 1L).build(); tx.update(user); } + IncompleteKey commentKey = IncompleteKey.builder(userKey, COMMENT_KIND).build(); + FullEntity comment = FullEntity.builder(commentKey) + .set("content", content) + .set("timestamp", DateTime.now()) + .build(); + tx.addWithDeferredIdAllocation(comment); + System.out.printf("Adding a comment to user '%s'.%n", userKey.name()); + } + + @Override + String parse(String... args) throws Exception { String content = "No comment."; if (args.length > 0) { StringBuilder stBuilder = new StringBuilder(); @@ -159,28 +199,98 @@ public void run(Transaction tx, Key userKey, String... args) { stBuilder.setLength(stBuilder.length() - 1); content = stBuilder.toString(); } - IncompleteKey commentKey = IncompleteKey.builder(userKey, COMMENT_KIND).build(); - FullEntity comment = FullEntity.builder(commentKey) - .set("content", content) - .set("timestamp", DateTime.now()) + return content; + } + + @Override + protected String params() { + return ""; + } + } + + /** + * This class sets contact information (email and phone) for a user. If the user does not exist + * its entity is created. Contact information is saved as an entity embedded in the user entity. + */ + private static class SetContactAction extends DatastoreAction { + + static final class Contact { + + private final String email; + private final String phone; + + Contact(String email, String phone) { + this.email = email; + this.phone = phone; + } + + String email() { + return email; + } + + String phone() { + return phone; + } + } + + @Override + public void run(Transaction tx, Key userKey, Contact contact) { + Entity user = tx.get(userKey); + if (user == null) { + System.out.println("Adding a new user."); + user = Entity.builder(userKey).set("count", 0L).build(); + tx.add(user); + } + FullEntity contactEntity = FullEntity.builder() + .set("email", contact.email()) + .set("phone", contact.phone()) .build(); - tx.addWithDeferredIdAllocation(comment); - System.out.println("Adding a comment to user '" + userKey.name() + "'."); + tx.update(Entity.builder(user).set("contact", contactEntity).build()); + System.out.printf("Setting contact for user '%s'.%n", userKey.name()); + } + + @Override + Contact parse(String... args) throws Exception { + String message; + if (args.length == 2) { + return new Contact(args[0], args[1]); + } else if (args.length > 2) { + message = "Too many arguments."; + } else { + message = "Missing required email and phone."; + } + throw new IllegalArgumentException(message); } @Override - public String getRequiredParams() { - return "comment"; + protected String params() { + return " "; } } static { ACTIONS.put("delete", new DeleteAction()); - ACTIONS.put("add", new AddAction()); + ACTIONS.put("add", new AddCommentAction()); + ACTIONS.put("set", new SetContactAction()); ACTIONS.put("display", new DisplayAction()); } - public static void main(String... args) { + private static void printUsage() { + StringBuilder actionAndParams = new StringBuilder(); + for (Map.Entry entry : ACTIONS.entrySet()) { + actionAndParams.append("\n\t").append(entry.getKey()); + + String param = entry.getValue().params(); + if (param != null && !param.isEmpty()) { + actionAndParams.append(' ').append(param); + } + } + System.out.printf("Usage: %s operation *%s%n", + DatastoreExample.class.getSimpleName(), actionAndParams); + } + + @SuppressWarnings("unchecked") + public static void main(String... args) throws Exception { String projectId = args.length > 0 ? args[0] : null; // If you want to access a local Datastore running via the Google Cloud SDK, do // DatastoreOptions options = DatastoreOptions.builder() @@ -197,24 +307,26 @@ public static void main(String... args) { String actionName = args.length > 2 ? args[2].toLowerCase() : DEFAULT_ACTION; DatastoreAction action = ACTIONS.get(actionName); if (action == null) { - StringBuilder actionAndParams = new StringBuilder(); - for (Map.Entry entry : ACTIONS.entrySet()) { - actionAndParams.append(entry.getKey()); - String param = entry.getValue().getRequiredParams(); - if (param != null && !param.isEmpty()) { - actionAndParams.append(' ').append(param); - } - actionAndParams.append('|'); - } - actionAndParams.setLength(actionAndParams.length() - 1); - System.out.printf("Usage: %s [projectId] [user] [%s]%n", - DatastoreExample.class.getSimpleName(), actionAndParams); + System.out.println("Unrecognized action."); + printUsage(); return; } args = args.length > 3 ? Arrays.copyOfRange(args, 3, args.length) : new String []{}; Transaction tx = datastore.newTransaction(); + Object request; + try { + request = action.parse(args); + } catch (IllegalArgumentException ex) { + System.out.printf("Invalid input for action '%s'. %s%n", actionName, ex.getMessage()); + System.out.printf("Expected: %s%n", action.params()); + return; + } catch (Exception ex) { + System.out.println("Failed to parse request."); + ex.printStackTrace(); + return; + } try { - action.run(tx, key, args); + action.run(tx, key, request); tx.commit(); } finally { if (tx.active()) { diff --git a/gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/DnsExample.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/DnsExample.java index 88b4b984e4c5..8b3c91cbd664 100644 --- a/gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/DnsExample.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/dns/DnsExample.java @@ -501,13 +501,13 @@ public static void main(String... args) throws Exception { try { valid = action.check(args); } catch (NumberFormatException ex) { - System.out.println("Invalid input for action '" + actionName + "'."); + System.out.printf("Invalid input for action '%s'.%n", actionName); System.out.println("Ttl must be an integer."); - System.out.println("Expected: " + action.params()); + System.out.printf("Expected: %s%n", action.params()); return; } catch (Exception ex) { System.out.println("Failed to parse request."); - System.out.println("Expected: " + action.params()); + System.out.printf("Expected: %s%n", action.params()); ex.printStackTrace(); return; } @@ -519,8 +519,8 @@ public static void main(String... args) throws Exception { Dns dns = optionsBuilder.build().service(); action.run(dns, args); } else { - System.out.println("Invalid input for action '" + actionName + "'"); - System.out.println("Expected: " + action.params()); + System.out.printf("Invalid input for action '%s'%n", actionName); + System.out.printf("Expected: %s%n", action.params()); } } } diff --git a/gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/ResourceManagerExample.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/ResourceManagerExample.java index 1d688c414575..fd2eb3ed6d91 100644 --- a/gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/ResourceManagerExample.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/resourcemanager/ResourceManagerExample.java @@ -90,9 +90,9 @@ public void run(ResourceManager resourceManager, String... args) { Scanner scanner = new Scanner(System.in); if (scanner.nextLine().toLowerCase().equals("y")) { resourceManager.delete(projectId); - System.out.println("Successfully deleted project " + projectId + "."); + System.out.printf("Successfully deleted project %s.%n", projectId); } else { - System.out.println("Will not delete project " + projectId + "."); + System.out.printf("Will not delete project %s.%n", projectId); } scanner.close(); } diff --git a/gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/StorageExample.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/StorageExample.java index 01b864e7c8b8..1a6aafa60e9d 100644 --- a/gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/StorageExample.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/StorageExample.java @@ -90,7 +90,7 @@ public class StorageExample { private abstract static class StorageAction { - abstract void run(Storage storage, T request) throws Exception; + abstract void run(Storage storage, T arg) throws Exception; abstract T parse(String... args) throws Exception; @@ -137,7 +137,7 @@ public void run(Storage storage, BlobId... blobIds) { System.out.println("No such bucket"); return; } - System.out.println("Bucket info: " + bucket); + System.out.printf("Bucket info: %s%n", bucket); } else { // get Blob Blob blob = storage.get(blobIds[0]); @@ -145,7 +145,7 @@ public void run(Storage storage, BlobId... blobIds) { System.out.println("No such object"); return; } - System.out.println("Blob info: " + blob); + System.out.printf("Blob info: %s%n", blob); } } else { // use batch to get multiple blobs. @@ -188,7 +188,7 @@ public void run(Storage storage, BlobId... blobIds) { for (Boolean deleted : deleteResults) { if (deleted) { // request order is maintained - System.out.println("Blob " + blobIds[index] + " was deleted"); + System.out.printf("Blob %s was deleted%n", blobIds[index]); } index++; } @@ -373,7 +373,7 @@ private static class CopyAction extends StorageAction { @Override public void run(Storage storage, CopyRequest request) { CopyWriter copyWriter = storage.copy(request); - System.out.println("Copied " + copyWriter.result()); + System.out.printf("Copied %s%n", copyWriter.result()); } @Override @@ -399,7 +399,7 @@ private static class ComposeAction extends StorageAction { @Override public void run(Storage storage, ComposeRequest request) { BlobInfo composedBlobInfo = storage.compose(request); - System.out.println("Composed " + composedBlobInfo); + System.out.printf("Composed %s%n", composedBlobInfo); } @Override @@ -442,7 +442,7 @@ private void run(Storage storage, BlobId blobId, Map metadata) { return; } Blob updateBlob = blob.toBuilder().metadata(metadata).build().update(); - System.out.println("Updated " + updateBlob); + System.out.printf("Updated %s%n", updateBlob); } @Override @@ -488,8 +488,8 @@ public void run(Storage storage, Tuple private void run(Storage storage, ServiceAccountAuthCredentials cred, BlobInfo blobInfo) { Blob blob = storage.get(blobInfo.blobId()); - System.out.println("Signed URL: " - + blob.signUrl(1, TimeUnit.DAYS, SignUrlOption.signWith(cred))); + System.out.printf("Signed URL: %s%n", + blob.signUrl(1, TimeUnit.DAYS, SignUrlOption.signWith(cred))); } @Override @@ -564,18 +564,18 @@ public static void main(String... args) throws Exception { return; } Storage storage = optionsBuilder.build().service(); - Object request; + Object arg; try { - request = action.parse(args); + arg = action.parse(args); } catch (IllegalArgumentException ex) { - System.out.println("Invalid input for action '" + actionName + "'"); - System.out.println("Expected: " + action.params()); + System.out.printf("Invalid input for action '%s'. %s%n", actionName, ex.getMessage()); + System.out.printf("Expected: %s%n", action.params()); return; } catch (Exception ex) { - System.out.println("Failed to parse request."); + System.out.println("Failed to parse arguments."); ex.printStackTrace(); return; } - action.run(storage, request); + action.run(storage, arg); } } From fd387a561662f35d0202027060a3d4b826e983ea Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 16 May 2016 20:26:09 +0200 Subject: [PATCH 349/375] Add base service option classes for gRPC and HTTP services (#1011) * Add base service option classes for gRPC and HTTP services * Rename ExecutorProvider to ExecutorFactory, refactor shutdown and serialization --- .../cloud/bigquery/BigQueryOptions.java | 8 +- .../com/google/cloud/GrpcServiceOptions.java | 256 ++++++++++++++++++ .../com/google/cloud/HttpServiceOptions.java | 227 ++++++++++++++++ .../java/com/google/cloud/ServiceOptions.java | 146 +--------- .../google/cloud/GrpcServiceOptionsTest.java | 218 +++++++++++++++ .../google/cloud/HttpServiceOptionsTest.java | 163 +++++++++++ .../com/google/cloud/ServiceOptionsTest.java | 18 -- .../cloud/datastore/DatastoreOptions.java | 9 +- .../java/com/google/cloud/dns/DnsOptions.java | 8 +- .../java/com/google/cloud/pubsub/PubSub.java | 2 +- .../com/google/cloud/pubsub/PubSubImpl.java | 5 + .../google/cloud/pubsub/PubSubOptions.java | 10 +- .../cloud/pubsub/spi/DefaultPubSubRpc.java | 79 ++++-- .../google/cloud/pubsub/spi/PubSubRpc.java | 2 +- .../ResourceManagerOptions.java | 10 +- .../google/cloud/storage/StorageOptions.java | 8 +- 16 files changed, 964 insertions(+), 205 deletions(-) create mode 100644 gcloud-java-core/src/main/java/com/google/cloud/GrpcServiceOptions.java create mode 100644 gcloud-java-core/src/main/java/com/google/cloud/HttpServiceOptions.java create mode 100644 gcloud-java-core/src/test/java/com/google/cloud/GrpcServiceOptionsTest.java create mode 100644 gcloud-java-core/src/test/java/com/google/cloud/HttpServiceOptionsTest.java diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryOptions.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryOptions.java index b0cc56fa0298..bf7fa65bcf0f 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryOptions.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryOptions.java @@ -16,19 +16,19 @@ package com.google.cloud.bigquery; +import com.google.cloud.HttpServiceOptions; import com.google.common.collect.ImmutableSet; -import com.google.cloud.ServiceOptions; import com.google.cloud.bigquery.spi.BigQueryRpc; import com.google.cloud.bigquery.spi.BigQueryRpcFactory; import com.google.cloud.bigquery.spi.DefaultBigQueryRpc; import java.util.Set; -public class BigQueryOptions extends ServiceOptions { +public class BigQueryOptions extends HttpServiceOptions { private static final String BIGQUERY_SCOPE = "https://www.googleapis.com/auth/bigquery"; private static final Set SCOPES = ImmutableSet.of(BIGQUERY_SCOPE); - private static final long serialVersionUID = -215981591481708043L; + private static final long serialVersionUID = -8592198255032667206L; public static class DefaultBigqueryFactory implements BigQueryFactory { @@ -51,7 +51,7 @@ public BigQueryRpc create(BigQueryOptions options) { } public static class Builder extends - ServiceOptions.Builder { + HttpServiceOptions.Builder { private Builder() { } diff --git a/gcloud-java-core/src/main/java/com/google/cloud/GrpcServiceOptions.java b/gcloud-java-core/src/main/java/com/google/cloud/GrpcServiceOptions.java new file mode 100644 index 000000000000..2a1110c9362e --- /dev/null +++ b/gcloud-java-core/src/main/java/com/google/cloud/GrpcServiceOptions.java @@ -0,0 +1,256 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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; + +import static com.google.common.base.MoreObjects.firstNonNull; + +import com.google.cloud.spi.ServiceRpcFactory; +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Preconditions; + +import io.grpc.internal.SharedResourceHolder; +import io.grpc.internal.SharedResourceHolder.Resource; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.util.Objects; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + * Abstract class representing service options for those services that use gRPC as the transport + * layer. + * + * @param the service subclass + * @param the spi-layer class corresponding to the service + * @param the {@code ServiceOptions} subclass corresponding to the service + */ +public abstract class GrpcServiceOptions, ServiceRpcT, + OptionsT extends GrpcServiceOptions> + extends ServiceOptions { + + private static final long serialVersionUID = 6415982522610509549L; + private final String executorFactoryClassName; + private final int initialTimeout; + private final double timeoutMultiplier; + private final int maxTimeout; + + private transient ExecutorFactory executorFactory; + + /** + * Shared thread pool executor. + */ + private static final Resource EXECUTOR = + new Resource() { + @Override + public ScheduledExecutorService create() { + ScheduledThreadPoolExecutor service = new ScheduledThreadPoolExecutor(8); + service.setKeepAliveTime(5, TimeUnit.SECONDS); + service.allowCoreThreadTimeOut(true); + service.setRemoveOnCancelPolicy(true); + return service; + } + + @Override + public void close(ScheduledExecutorService instance) { + instance.shutdown(); + } + }; + + /** + * An interface for {@link ScheduledExecutorService} factories. Implementations of this interface + * can be used to provide an user-defined scheduled executor to execute requests. Any + * implementation of this interface must override the {@code get()} method to return the desired + * executor. The {@code release(executor)} method should be overriden to free resources used by + * the executor (if needed) according to application's logic. + * + *

    Implementation must provide a public no-arg constructor. Loading of a factory implementation + * is done via {@link java.util.ServiceLoader}. + */ + public interface ExecutorFactory { + + /** + * Gets a scheduled executor service instance. + */ + ScheduledExecutorService get(); + + /** + * Releases resources used by the executor and possibly shuts it down. + */ + void release(ScheduledExecutorService executor); + } + + @VisibleForTesting + static class DefaultExecutorFactory implements ExecutorFactory { + + private static final DefaultExecutorFactory INSTANCE = new DefaultExecutorFactory(); + + @Override + public ScheduledExecutorService get() { + return SharedResourceHolder.get(EXECUTOR); + } + + @Override + public synchronized void release(ScheduledExecutorService executor) { + SharedResourceHolder.release(EXECUTOR, executor); + } + } + + /** + * Builder for {@code GrpcServiceOptions}. + * + * @param the service subclass + * @param the spi-layer class corresponding to the service + * @param the {@code GrpcServiceOptions} subclass corresponding to the service + * @param the {@code ServiceOptions} builder + */ + protected abstract static class Builder, ServiceRpcT, + OptionsT extends GrpcServiceOptions, + B extends Builder> + extends ServiceOptions.Builder { + + private ExecutorFactory executorFactory; + private int initialTimeout = 20_000; + private double timeoutMultiplier = 1.5; + private int maxTimeout = 100_000; + + protected Builder() {} + + protected Builder(GrpcServiceOptions options) { + super(options); + executorFactory = options.executorFactory; + initialTimeout = options.initialTimeout; + timeoutMultiplier = options.timeoutMultiplier; + maxTimeout = options.maxTimeout; + } + + @Override + protected abstract GrpcServiceOptions build(); + + /** + * Sets the scheduled executor factory. This method can be used to provide an user-defined + * scheduled executor to execute requests. + * + * @return the builder + */ + public B executorFactory(ExecutorFactory executorFactory) { + this.executorFactory = executorFactory; + return self(); + } + + /** + * Sets the timeout for the initial RPC, in milliseconds. Subsequent calls will use this value + * adjusted according to {@link #timeoutMultiplier(double)}. Default value is 20000. + * + * @throws IllegalArgumentException if the provided timeout is < 0 + * @return the builder + */ + public B initialTimeout(int initialTimeout) { + Preconditions.checkArgument(initialTimeout > 0, "Initial timeout must be > 0"); + this.initialTimeout = initialTimeout; + return self(); + } + + /** + * Sets the timeout multiplier. This value is used to compute the timeout for a retried RPC. + * Timeout is computed as {@code timeoutMultiplier * previousTimeout}. Default value is 1.5. + * + * @throws IllegalArgumentException if the provided timeout multiplier is < 0 + * @return the builder + */ + public B timeoutMultiplier(double timeoutMultiplier) { + Preconditions.checkArgument(timeoutMultiplier >= 1.0, "Timeout multiplier must be >= 1"); + this.timeoutMultiplier = timeoutMultiplier; + return self(); + } + + /** + * Sets the maximum timeout for a RPC call, in milliseconds. Default value is 100000. If + * {@code maxTimeout} is lower than the initial timeout the {@link #initialTimeout(int)} value + * is used instead. + * + * @return the builder + */ + public B maxTimeout(int maxTimeout) { + this.maxTimeout = maxTimeout; + return self(); + } + } + + protected GrpcServiceOptions( + Class> serviceFactoryClass, + Class> rpcFactoryClass, Builder builder) { + super(serviceFactoryClass, rpcFactoryClass, builder); + executorFactory = firstNonNull(builder.executorFactory, + getFromServiceLoader(ExecutorFactory.class, DefaultExecutorFactory.INSTANCE)); + executorFactoryClassName = executorFactory.getClass().getName(); + initialTimeout = builder.initialTimeout; + timeoutMultiplier = builder.timeoutMultiplier; + maxTimeout = builder.maxTimeout <= initialTimeout ? initialTimeout : builder.maxTimeout; + } + + /** + * Returns a scheduled executor service provider. + */ + protected ExecutorFactory executorFactory() { + return executorFactory; + } + + /** + * Returns the timeout for the initial RPC, in milliseconds. Subsequent calls will use this value + * adjusted according to {@link #timeoutMultiplier()}. Default value is 20000. + */ + public int initialTimeout() { + return initialTimeout; + } + + /** + * Returns the timeout multiplier. This values is used to compute the timeout for a RPC. Timeout + * is computed as {@code timeoutMultiplier * previousTimeout}. Default value is 1.5. + */ + public double timeoutMultiplier() { + return timeoutMultiplier; + } + + /** + * Returns the maximum timeout for a RPC call, in milliseconds. Default value is 100000. + */ + public int maxTimeout() { + return maxTimeout; + } + + @Override + protected int baseHashCode() { + return Objects.hash(super.baseHashCode(), executorFactoryClassName, initialTimeout, + timeoutMultiplier, maxTimeout); + } + + protected boolean baseEquals(GrpcServiceOptions other) { + return super.baseEquals(other) + && Objects.equals(executorFactoryClassName, other.executorFactoryClassName) + && Objects.equals(initialTimeout, other.initialTimeout) + && Objects.equals(timeoutMultiplier, other.timeoutMultiplier) + && Objects.equals(maxTimeout, other.maxTimeout); + } + + private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { + input.defaultReadObject(); + executorFactory = newInstance(executorFactoryClassName); + } +} diff --git a/gcloud-java-core/src/main/java/com/google/cloud/HttpServiceOptions.java b/gcloud-java-core/src/main/java/com/google/cloud/HttpServiceOptions.java new file mode 100644 index 000000000000..eca411849eaf --- /dev/null +++ b/gcloud-java-core/src/main/java/com/google/cloud/HttpServiceOptions.java @@ -0,0 +1,227 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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; + +import static com.google.common.base.MoreObjects.firstNonNull; + +import com.google.api.client.extensions.appengine.http.UrlFetchTransport; +import com.google.api.client.http.HttpRequest; +import com.google.api.client.http.HttpRequestInitializer; +import com.google.api.client.http.HttpTransport; +import com.google.api.client.http.javanet.NetHttpTransport; +import com.google.auth.http.HttpCredentialsAdapter; +import com.google.cloud.spi.ServiceRpcFactory; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.util.Objects; + +/** + * Abstract class representing service options for those services that use HTTP as the transport + * layer. + * + * @param the service subclass + * @param the spi-layer class corresponding to the service + * @param the {@code ServiceOptions} subclass corresponding to the service + */ +public abstract class HttpServiceOptions, ServiceRpcT, + OptionsT extends HttpServiceOptions> + extends ServiceOptions { + + private static final long serialVersionUID = 3652819407083815771L; + private final int connectTimeout; + private final int readTimeout; + private final String httpTransportFactoryClassName; + + private transient HttpTransportFactory httpTransportFactory; + + /** + * A base interface for all {@link HttpTransport} factories. + * + *

    Implementation must provide a public no-arg constructor. Loading of a factory implementation + * is done via {@link java.util.ServiceLoader}. + */ + public interface HttpTransportFactory { + HttpTransport create(); + } + + public static class DefaultHttpTransportFactory implements HttpTransportFactory { + + private static final HttpTransportFactory INSTANCE = new DefaultHttpTransportFactory(); + + @Override + public HttpTransport create() { + // Consider App Engine + if (appEngineAppId() != null) { + try { + return new UrlFetchTransport(); + } catch (Exception ignore) { + // Maybe not on App Engine + } + } + return new NetHttpTransport(); + } + } + + /** + * Builder for {@code HttpServiceOptions}. + * + * @param the service subclass + * @param the spi-layer class corresponding to the service + * @param the {@code HttpServiceOptions} subclass corresponding to the service + * @param the {@code ServiceOptions} builder + */ + protected abstract static class Builder, ServiceRpcT, + OptionsT extends HttpServiceOptions, + B extends Builder> + extends ServiceOptions.Builder { + + private HttpTransportFactory httpTransportFactory; + private int connectTimeout = -1; + private int readTimeout = -1; + + protected Builder() {} + + protected Builder(HttpServiceOptions options) { + super(options); + httpTransportFactory = options.httpTransportFactory; + connectTimeout = options.connectTimeout; + readTimeout = options.readTimeout; + } + + @Override + protected abstract HttpServiceOptions build(); + + @SuppressWarnings("unchecked") + protected B self() { + return (B) this; + } + + /** + * Sets the HTTP transport factory. + * + * @return the builder + */ + public B httpTransportFactory(HttpTransportFactory httpTransportFactory) { + this.httpTransportFactory = httpTransportFactory; + return self(); + } + + /** + * Sets the timeout in milliseconds to establish a connection. + * + * @param connectTimeout connection timeout in milliseconds. 0 for an infinite timeout, a + * negative number for the default value (20000). + * @return the builder + */ + public B connectTimeout(int connectTimeout) { + this.connectTimeout = connectTimeout; + return self(); + } + + /** + * Sets the timeout in milliseconds to read data from an established connection. + * + * @param readTimeout read timeout in milliseconds. 0 for an infinite timeout, a negative number + * for the default value (20000). + * @return the builder + */ + public B readTimeout(int readTimeout) { + this.readTimeout = readTimeout; + return self(); + } + } + + protected HttpServiceOptions( + Class> serviceFactoryClass, + Class> rpcFactoryClass, Builder builder) { + super(serviceFactoryClass, rpcFactoryClass, builder); + httpTransportFactory = firstNonNull(builder.httpTransportFactory, + getFromServiceLoader(HttpTransportFactory.class, DefaultHttpTransportFactory.INSTANCE)); + httpTransportFactoryClassName = httpTransportFactory.getClass().getName(); + connectTimeout = builder.connectTimeout; + readTimeout = builder.readTimeout; + } + + /** + * Returns the HTTP transport factory. + */ + public HttpTransportFactory httpTransportFactory() { + return httpTransportFactory; + } + + + /** + * Returns a request initializer responsible for initializing requests according to service + * options. + */ + public HttpRequestInitializer httpRequestInitializer() { + final HttpRequestInitializer delegate = + authCredentials() != null && authCredentials().credentials() != null + ? new HttpCredentialsAdapter(authCredentials().credentials().createScoped(scopes())) + : null; + return new HttpRequestInitializer() { + @Override + public void initialize(HttpRequest httpRequest) throws IOException { + if (delegate != null) { + delegate.initialize(httpRequest); + } + if (connectTimeout >= 0) { + httpRequest.setConnectTimeout(connectTimeout); + } + if (readTimeout >= 0) { + httpRequest.setReadTimeout(readTimeout); + } + } + }; + } + + /** + * Returns the timeout in milliseconds to establish a connection. 0 is an infinite timeout, a + * negative number is the default value (20000). + */ + public int connectTimeout() { + return connectTimeout; + } + + /** + * Returns the timeout in milliseconds to read from an established connection. 0 is an infinite + * timeout, a negative number is the default value (20000). + */ + public int readTimeout() { + return readTimeout; + } + + @Override + protected int baseHashCode() { + return Objects.hash(super.baseHashCode(), httpTransportFactoryClassName, connectTimeout, + readTimeout); + } + + protected boolean baseEquals(HttpServiceOptions other) { + return super.baseEquals(other) + && Objects.equals(httpTransportFactoryClassName, other.httpTransportFactoryClassName) + && Objects.equals(connectTimeout, other.connectTimeout) + && Objects.equals(readTimeout, other.readTimeout); + } + + private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { + input.defaultReadObject(); + httpTransportFactory = newInstance(httpTransportFactoryClassName); + } +} diff --git a/gcloud-java-core/src/main/java/com/google/cloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/cloud/ServiceOptions.java index 194f61b45c42..a4f27994a39f 100644 --- a/gcloud-java-core/src/main/java/com/google/cloud/ServiceOptions.java +++ b/gcloud-java-core/src/main/java/com/google/cloud/ServiceOptions.java @@ -20,12 +20,6 @@ import static com.google.common.base.Preconditions.checkArgument; import static java.nio.charset.StandardCharsets.UTF_8; -import com.google.api.client.extensions.appengine.http.UrlFetchTransport; -import com.google.api.client.http.HttpRequest; -import com.google.api.client.http.HttpRequestInitializer; -import com.google.api.client.http.HttpTransport; -import com.google.api.client.http.javanet.NetHttpTransport; -import com.google.auth.http.HttpCredentialsAdapter; import com.google.cloud.spi.ServiceRpcFactory; import com.google.common.collect.Iterables; import com.google.common.io.Files; @@ -71,60 +65,28 @@ public abstract class ServiceOptions, Service OptionsT extends ServiceOptions> implements Serializable { private static final String DEFAULT_HOST = "https://www.googleapis.com"; - private static final long serialVersionUID = 1203687993961393350L; private static final String PROJECT_ENV_NAME = "GCLOUD_PROJECT"; private static final String MANIFEST_ARTIFACT_ID_KEY = "artifactId"; private static final String MANIFEST_VERSION_KEY = "Implementation-Version"; private static final String ARTIFACT_ID = "gcloud-java-core"; private static final String APPLICATION_BASE_NAME = "gcloud-java"; private static final String APPLICATION_NAME = getApplicationName(); + private static final long serialVersionUID = -6410263550484023006L; private final String projectId; private final String host; - private final String httpTransportFactoryClassName; private final RestorableState authCredentialsState; private final RetryParams retryParams; private final String serviceRpcFactoryClassName; private final String serviceFactoryClassName; - private final int connectTimeout; - private final int readTimeout; private final Clock clock; - private transient HttpTransportFactory httpTransportFactory; private transient AuthCredentials authCredentials; private transient ServiceRpcFactory serviceRpcFactory; private transient ServiceFactory serviceFactory; private transient ServiceT service; private transient ServiceRpcT rpc; - /** - * A base interface for all {@link HttpTransport} factories. - * - *

    Implementation must provide a public no-arg constructor. Loading of a factory implementation - * is done via {@link java.util.ServiceLoader}. - */ - public interface HttpTransportFactory { - HttpTransport create(); - } - - public static class DefaultHttpTransportFactory implements HttpTransportFactory { - - private static final HttpTransportFactory INSTANCE = new DefaultHttpTransportFactory(); - - @Override - public HttpTransport create() { - // Consider App Engine - if (appEngineAppId() != null) { - try { - return new UrlFetchTransport(); - } catch (Exception ignore) { - // Maybe not on App Engine - } - } - return new NetHttpTransport(); - } - } - /** * A class providing access to the current time in milliseconds. This class is mainly used for * testing and will be replaced by Java8's {@code java.time.Clock}. @@ -178,13 +140,10 @@ protected abstract static class Builder, Serv private String projectId; private String host; - private HttpTransportFactory httpTransportFactory; private AuthCredentials authCredentials; private RetryParams retryParams; private ServiceFactory serviceFactory; private ServiceRpcFactory serviceRpcFactory; - private int connectTimeout = -1; - private int readTimeout = -1; private Clock clock; protected Builder() {} @@ -192,13 +151,10 @@ protected Builder() {} protected Builder(ServiceOptions options) { projectId = options.projectId; host = options.host; - httpTransportFactory = options.httpTransportFactory; authCredentials = options.authCredentials; retryParams = options.retryParams; serviceFactory = options.serviceFactory; serviceRpcFactory = options.serviceRpcFactory; - connectTimeout = options.connectTimeout; - readTimeout = options.readTimeout; clock = options.clock; } @@ -249,16 +205,6 @@ public B host(String host) { return self(); } - /** - * Sets the transport factory. - * - * @return the builder - */ - public B httpTransportFactory(HttpTransportFactory httpTransportFactory) { - this.httpTransportFactory = httpTransportFactory; - return self(); - } - /** * Sets the service authentication credentials. * @@ -290,30 +236,6 @@ public B serviceRpcFactory(ServiceRpcFactory serviceRpcFa this.serviceRpcFactory = serviceRpcFactory; return self(); } - - /** - * Sets the timeout in milliseconds to establish a connection. - * - * @param connectTimeout connection timeout in milliseconds. 0 for an infinite timeout, a - * negative number for the default value (20000). - * @return the builder - */ - public B connectTimeout(int connectTimeout) { - this.connectTimeout = connectTimeout; - return self(); - } - - /** - * Sets the timeout in milliseconds to read data from an established connection. - * - * @param readTimeout read timeout in milliseconds. 0 for an infinite timeout, a negative number - * for the default value (20000). - * @return the builder - */ - public B readTimeout(int readTimeout) { - this.readTimeout = readTimeout; - return self(); - } } protected ServiceOptions(Class> serviceFactoryClass, @@ -327,9 +249,6 @@ protected ServiceOptions(Class> ser + "or the environment. Please set a project ID using the builder."); } host = firstNonNull(builder.host, defaultHost()); - httpTransportFactory = firstNonNull(builder.httpTransportFactory, - getFromServiceLoader(HttpTransportFactory.class, DefaultHttpTransportFactory.INSTANCE)); - httpTransportFactoryClassName = httpTransportFactory.getClass().getName(); authCredentials = builder.authCredentials != null ? builder.authCredentials : defaultAuthCredentials(); authCredentialsState = authCredentials != null ? authCredentials.capture() : null; @@ -340,8 +259,6 @@ protected ServiceOptions(Class> ser serviceRpcFactory = firstNonNull(builder.serviceRpcFactory, getFromServiceLoader(rpcFactoryClass, defaultRpcFactory())); serviceRpcFactoryClassName = serviceRpcFactory.getClass().getName(); - connectTimeout = builder.connectTimeout; - readTimeout = builder.readTimeout; clock = firstNonNull(builder.clock, Clock.defaultClock()); } @@ -532,13 +449,6 @@ public String host() { return host; } - /** - * Returns the transport factory. - */ - public HttpTransportFactory httpTransportFactory() { - return httpTransportFactory; - } - /** * Returns the authentication credentials. */ @@ -554,47 +464,6 @@ public RetryParams retryParams() { return retryParams; } - /** - * Returns a request initializer responsible for initializing requests according to service - * options. - */ - public HttpRequestInitializer httpRequestInitializer() { - final HttpRequestInitializer delegate = - authCredentials() != null && authCredentials.credentials() != null - ? new HttpCredentialsAdapter(authCredentials().credentials().createScoped(scopes())) - : null; - return new HttpRequestInitializer() { - @Override - public void initialize(HttpRequest httpRequest) throws IOException { - if (delegate != null) { - delegate.initialize(httpRequest); - } - if (connectTimeout >= 0) { - httpRequest.setConnectTimeout(connectTimeout); - } - if (readTimeout >= 0) { - httpRequest.setReadTimeout(readTimeout); - } - } - }; - } - - /** - * Returns the timeout in milliseconds to establish a connection. 0 is an infinite timeout, a - * negative number is the default value (20000). - */ - public int connectTimeout() { - return connectTimeout; - } - - /** - * Returns the timeout in milliseconds to read from an established connection. 0 is an infinite - * timeout, a negative number is the default value (20000). - */ - public int readTimeout() { - return readTimeout; - } - /** * Returns the service's clock. Default time source uses {@link System#currentTimeMillis()} to get * current time. @@ -611,34 +480,29 @@ public String applicationName() { } protected int baseHashCode() { - return Objects.hash(projectId, host, httpTransportFactoryClassName, authCredentialsState, - retryParams, serviceFactoryClassName, serviceRpcFactoryClassName, connectTimeout, - readTimeout, clock); + return Objects.hash(projectId, host, authCredentialsState, retryParams, serviceFactoryClassName, + serviceRpcFactoryClassName, clock); } protected boolean baseEquals(ServiceOptions other) { return Objects.equals(projectId, other.projectId) && Objects.equals(host, other.host) - && Objects.equals(httpTransportFactoryClassName, other.httpTransportFactoryClassName) && Objects.equals(authCredentialsState, other.authCredentialsState) && Objects.equals(retryParams, other.retryParams) && Objects.equals(serviceFactoryClassName, other.serviceFactoryClassName) && Objects.equals(serviceRpcFactoryClassName, other.serviceRpcFactoryClassName) - && Objects.equals(connectTimeout, other.connectTimeout) - && Objects.equals(readTimeout, other.readTimeout) && Objects.equals(clock, clock); } private void readObject(ObjectInputStream input) throws IOException, ClassNotFoundException { input.defaultReadObject(); - httpTransportFactory = newInstance(httpTransportFactoryClassName); serviceFactory = newInstance(serviceFactoryClassName); serviceRpcFactory = newInstance(serviceRpcFactoryClassName); authCredentials = authCredentialsState != null ? authCredentialsState.restore() : null; } @SuppressWarnings("unchecked") - private static T newInstance(String className) throws IOException, ClassNotFoundException { + static T newInstance(String className) throws IOException, ClassNotFoundException { try { return (T) Class.forName(className).newInstance(); } catch (InstantiationException | IllegalAccessException e) { @@ -663,7 +527,7 @@ protected RetryParams defaultRetryParams() { return RetryParams.defaultInstance(); } - private static T getFromServiceLoader(Class clazz, T defaultInstance) { + static T getFromServiceLoader(Class clazz, T defaultInstance) { return Iterables.getFirst(ServiceLoader.load(clazz), defaultInstance); } diff --git a/gcloud-java-core/src/test/java/com/google/cloud/GrpcServiceOptionsTest.java b/gcloud-java-core/src/test/java/com/google/cloud/GrpcServiceOptionsTest.java new file mode 100644 index 000000000000..0a3c34f87916 --- /dev/null +++ b/gcloud-java-core/src/test/java/com/google/cloud/GrpcServiceOptionsTest.java @@ -0,0 +1,218 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.google.cloud.GrpcServiceOptions.DefaultExecutorFactory; +import com.google.cloud.GrpcServiceOptions.ExecutorFactory; +import com.google.cloud.spi.ServiceRpcFactory; + +import org.easymock.EasyMock; +import org.junit.Test; + +import java.util.Set; +import java.util.concurrent.ScheduledExecutorService; + +public class GrpcServiceOptionsTest { + + private static final ExecutorFactory MOCK_EXECUTOR_FACTORY = + EasyMock.createMock(ExecutorFactory.class); + private static final TestGrpcServiceOptions OPTIONS = TestGrpcServiceOptions.builder() + .projectId("project-id") + .initialTimeout(1234) + .timeoutMultiplier(1.6) + .maxTimeout(5678) + .executorFactory(MOCK_EXECUTOR_FACTORY) + .build(); + private static final TestGrpcServiceOptions DEFAULT_OPTIONS = + TestGrpcServiceOptions.builder().projectId("project-id").build(); + private static final TestGrpcServiceOptions OPTIONS_COPY = OPTIONS.toBuilder().build(); + + private interface TestService extends Service {} + + private static class TestServiceImpl + extends BaseService implements TestService { + private TestServiceImpl(TestGrpcServiceOptions options) { + super(options); + } + } + + private interface TestServiceFactory extends ServiceFactory { + } + + private static class DefaultTestServiceFactory implements TestServiceFactory { + private static final TestServiceFactory INSTANCE = new DefaultTestServiceFactory(); + + @Override + public TestService create(TestGrpcServiceOptions options) { + return new TestServiceImpl(options); + } + } + + private interface TestServiceRpcFactory + extends ServiceRpcFactory {} + + private static class DefaultTestServiceRpcFactory implements TestServiceRpcFactory { + private static final TestServiceRpcFactory INSTANCE = new DefaultTestServiceRpcFactory(); + + @Override + public TestServiceRpc create(TestGrpcServiceOptions options) { + return new DefaultTestServiceRpc(options); + } + } + + private interface TestServiceRpc {} + + private static class DefaultTestServiceRpc implements TestServiceRpc { + DefaultTestServiceRpc(TestGrpcServiceOptions options) {} + } + + private static class TestGrpcServiceOptions + extends GrpcServiceOptions { + private static class Builder + extends GrpcServiceOptions.Builder { + private Builder() {} + + private Builder(TestGrpcServiceOptions options) { + super(options); + } + + @Override + protected TestGrpcServiceOptions build() { + return new TestGrpcServiceOptions(this); + } + } + + private TestGrpcServiceOptions(Builder builder) { + super(TestServiceFactory.class, TestServiceRpcFactory.class, builder); + } + + @Override + protected TestServiceFactory defaultServiceFactory() { + return DefaultTestServiceFactory.INSTANCE; + } + + @Override + protected TestServiceRpcFactory defaultRpcFactory() { + return DefaultTestServiceRpcFactory.INSTANCE; + } + + @Override + protected Set scopes() { + return null; + } + + @Override + public Builder toBuilder() { + return new Builder(this); + } + + private static Builder builder() { + return new Builder(); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof TestGrpcServiceOptions && baseEquals((TestGrpcServiceOptions) obj); + } + + @Override + public int hashCode() { + return baseHashCode(); + } + } + + @Test + public void testBuilder() { + assertEquals(1234, OPTIONS.initialTimeout()); + assertEquals(1.6, OPTIONS.timeoutMultiplier(), 0.0); + assertEquals(5678, OPTIONS.maxTimeout()); + assertSame(MOCK_EXECUTOR_FACTORY, OPTIONS.executorFactory()); + assertEquals(20000, DEFAULT_OPTIONS.initialTimeout()); + assertEquals(1.5, DEFAULT_OPTIONS.timeoutMultiplier(), 0.0); + assertEquals(100000, DEFAULT_OPTIONS.maxTimeout()); + assertTrue(DEFAULT_OPTIONS.executorFactory() instanceof DefaultExecutorFactory); + } + + @Test + public void testBuilderError() { + try { + TestGrpcServiceOptions.builder().initialTimeout(0); + fail("IllegalArgumentException expected"); + } catch (IllegalArgumentException ex) { + assertEquals("Initial timeout must be > 0", ex.getMessage()); + } + try { + TestGrpcServiceOptions.builder().initialTimeout(-1); + fail("IllegalArgumentException expected"); + } catch (IllegalArgumentException ex) { + assertEquals("Initial timeout must be > 0", ex.getMessage()); + } + try { + TestGrpcServiceOptions.builder().timeoutMultiplier(0.9); + fail("IllegalArgumentException expected"); + } catch (IllegalArgumentException ex) { + assertEquals("Timeout multiplier must be >= 1", ex.getMessage()); + } + } + + @Test + public void testBuilderInvalidMaxTimeout() { + TestGrpcServiceOptions options = TestGrpcServiceOptions.builder() + .projectId("project-id") + .initialTimeout(1234) + .timeoutMultiplier(1.6) + .maxTimeout(123) + .build(); + assertEquals(1234, options.initialTimeout()); + assertEquals(1.6, options.timeoutMultiplier(), 0.0); + assertEquals(1234, options.maxTimeout()); + } + + @Test + public void testBaseEquals() { + assertEquals(OPTIONS, OPTIONS_COPY); + assertNotEquals(DEFAULT_OPTIONS, OPTIONS); + TestGrpcServiceOptions options = OPTIONS.toBuilder() + .executorFactory(new DefaultExecutorFactory()) + .build(); + assertNotEquals(OPTIONS, options); + } + + @Test + public void testBaseHashCode() { + assertEquals(OPTIONS.hashCode(), OPTIONS_COPY.hashCode()); + assertNotEquals(DEFAULT_OPTIONS.hashCode(), OPTIONS.hashCode()); + TestGrpcServiceOptions options = OPTIONS.toBuilder() + .executorFactory(new DefaultExecutorFactory()) + .build(); + assertNotEquals(OPTIONS.hashCode(), options.hashCode()); + } + + @Test + public void testDefaultExecutorFactory() { + ExecutorFactory executorFactory = new DefaultExecutorFactory(); + ScheduledExecutorService executorService = executorFactory.get(); + assertSame(executorService, executorFactory.get()); + } +} diff --git a/gcloud-java-core/src/test/java/com/google/cloud/HttpServiceOptionsTest.java b/gcloud-java-core/src/test/java/com/google/cloud/HttpServiceOptionsTest.java new file mode 100644 index 000000000000..de8dc8592eeb --- /dev/null +++ b/gcloud-java-core/src/test/java/com/google/cloud/HttpServiceOptionsTest.java @@ -0,0 +1,163 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import com.google.cloud.HttpServiceOptions.DefaultHttpTransportFactory; +import com.google.cloud.HttpServiceOptions.HttpTransportFactory; +import com.google.cloud.spi.ServiceRpcFactory; + +import org.easymock.EasyMock; +import org.junit.Test; + +import java.util.Set; + +public class HttpServiceOptionsTest { + + private static final HttpTransportFactory MOCK_HTTP_TRANSPORT_FACTORY = + EasyMock.createMock(HttpTransportFactory.class); + private static final TestHttpServiceOptions OPTIONS = TestHttpServiceOptions.builder() + .projectId("project-id") + .connectTimeout(1234) + .httpTransportFactory(MOCK_HTTP_TRANSPORT_FACTORY) + .readTimeout(5678) + .build(); + private static final TestHttpServiceOptions DEFAULT_OPTIONS = + TestHttpServiceOptions.builder().projectId("project-id").build(); + private static final TestHttpServiceOptions OPTIONS_COPY = OPTIONS.toBuilder().build(); + + private interface TestService extends Service {} + + private static class TestServiceImpl + extends BaseService implements TestService { + private TestServiceImpl(TestHttpServiceOptions options) { + super(options); + } + } + + private interface TestServiceFactory extends ServiceFactory { + } + + private static class DefaultTestServiceFactory implements TestServiceFactory { + private static final TestServiceFactory INSTANCE = new DefaultTestServiceFactory(); + + @Override + public TestService create(TestHttpServiceOptions options) { + return new TestServiceImpl(options); + } + } + + private interface TestServiceRpcFactory + extends ServiceRpcFactory {} + + private static class DefaultTestServiceRpcFactory implements TestServiceRpcFactory { + private static final TestServiceRpcFactory INSTANCE = new DefaultTestServiceRpcFactory(); + + @Override + public TestServiceRpc create(TestHttpServiceOptions options) { + return new DefaultTestServiceRpc(options); + } + } + + private interface TestServiceRpc {} + + private static class DefaultTestServiceRpc implements TestServiceRpc { + DefaultTestServiceRpc(TestHttpServiceOptions options) {} + } + + private static class TestHttpServiceOptions + extends HttpServiceOptions { + private static class Builder + extends HttpServiceOptions.Builder { + private Builder() {} + + private Builder(TestHttpServiceOptions options) { + super(options); + } + + @Override + protected TestHttpServiceOptions build() { + return new TestHttpServiceOptions(this); + } + } + + private TestHttpServiceOptions(Builder builder) { + super(TestServiceFactory.class, TestServiceRpcFactory.class, builder); + } + + @Override + protected TestServiceFactory defaultServiceFactory() { + return DefaultTestServiceFactory.INSTANCE; + } + + @Override + protected TestServiceRpcFactory defaultRpcFactory() { + return DefaultTestServiceRpcFactory.INSTANCE; + } + + @Override + protected Set scopes() { + return null; + } + + @Override + public Builder toBuilder() { + return new Builder(this); + } + + private static Builder builder() { + return new Builder(); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof TestHttpServiceOptions && baseEquals((TestHttpServiceOptions) obj); + } + + @Override + public int hashCode() { + return baseHashCode(); + } + } + + @Test + public void testBuilder() { + assertEquals(1234, OPTIONS.connectTimeout()); + assertSame(MOCK_HTTP_TRANSPORT_FACTORY, OPTIONS.httpTransportFactory()); + assertEquals(5678, OPTIONS.readTimeout()); + assertEquals(-1, DEFAULT_OPTIONS.connectTimeout()); + assertTrue(DEFAULT_OPTIONS.httpTransportFactory() instanceof DefaultHttpTransportFactory); + assertEquals(-1, DEFAULT_OPTIONS.readTimeout()); + } + + @Test + public void testBaseEquals() { + assertEquals(OPTIONS, OPTIONS_COPY); + assertNotEquals(DEFAULT_OPTIONS, OPTIONS); + } + + @Test + public void testBaseHashCode() { + assertEquals(OPTIONS.hashCode(), OPTIONS_COPY.hashCode()); + assertNotEquals(DEFAULT_OPTIONS.hashCode(), OPTIONS.hashCode()); + } +} diff --git a/gcloud-java-core/src/test/java/com/google/cloud/ServiceOptionsTest.java b/gcloud-java-core/src/test/java/com/google/cloud/ServiceOptionsTest.java index b6f7a5453ddc..1f0abc0ece11 100644 --- a/gcloud-java-core/src/test/java/com/google/cloud/ServiceOptionsTest.java +++ b/gcloud-java-core/src/test/java/com/google/cloud/ServiceOptionsTest.java @@ -23,21 +23,15 @@ import static org.junit.Assert.fail; import com.google.cloud.ServiceOptions.Clock; -import com.google.cloud.ServiceOptions.DefaultHttpTransportFactory; -import com.google.cloud.ServiceOptions.HttpTransportFactory; import com.google.cloud.spi.ServiceRpcFactory; -import org.easymock.EasyMock; import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Set; -@RunWith(JUnit4.class) public class ServiceOptionsTest { private static final String JSON_KEY = "{\n" @@ -75,18 +69,13 @@ public class ServiceOptionsTest { fail("Couldn't create fake JSON credentials."); } } - private static final HttpTransportFactory MOCK_HTTP_TRANSPORT_FACTORY = - EasyMock.createMock(HttpTransportFactory.class); private static final Clock TEST_CLOCK = new TestClock(); private static final TestServiceOptions OPTIONS = TestServiceOptions.builder() .authCredentials(authCredentials) .clock(TEST_CLOCK) - .connectTimeout(1234) .host("host") - .httpTransportFactory(MOCK_HTTP_TRANSPORT_FACTORY) .projectId("project-id") - .readTimeout(5678) .retryParams(RetryParams.noRetries()) .build(); private static final TestServiceOptions DEFAULT_OPTIONS = @@ -197,18 +186,11 @@ public int hashCode() { public void testBuilder() { assertSame(authCredentials, OPTIONS.authCredentials()); assertSame(TEST_CLOCK, OPTIONS.clock()); - assertEquals(1234, OPTIONS.connectTimeout()); assertEquals("host", OPTIONS.host()); - assertSame(MOCK_HTTP_TRANSPORT_FACTORY, OPTIONS.httpTransportFactory()); assertEquals("project-id", OPTIONS.projectId()); - assertEquals(5678, OPTIONS.readTimeout()); assertSame(RetryParams.noRetries(), OPTIONS.retryParams()); - assertSame(Clock.defaultClock(), DEFAULT_OPTIONS.clock()); - assertEquals(-1, DEFAULT_OPTIONS.connectTimeout()); assertEquals("https://www.googleapis.com", DEFAULT_OPTIONS.host()); - assertTrue(DEFAULT_OPTIONS.httpTransportFactory() instanceof DefaultHttpTransportFactory); - assertEquals(-1, DEFAULT_OPTIONS.readTimeout()); assertSame(RetryParams.defaultInstance(), DEFAULT_OPTIONS.retryParams()); } diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java index a9466939060a..0f29fefd9815 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreOptions.java @@ -18,9 +18,9 @@ import static com.google.cloud.datastore.Validator.validateNamespace; +import com.google.cloud.HttpServiceOptions; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableSet; -import com.google.cloud.ServiceOptions; import com.google.cloud.datastore.spi.DatastoreRpc; import com.google.cloud.datastore.spi.DatastoreRpcFactory; import com.google.cloud.datastore.spi.DefaultDatastoreRpc; @@ -29,9 +29,10 @@ import java.util.Objects; import java.util.Set; -public class DatastoreOptions extends ServiceOptions { +public class DatastoreOptions + extends HttpServiceOptions { - private static final long serialVersionUID = 5056049000758143852L; + private static final long serialVersionUID = -7859275434360052450L; private static final String DATASTORE_SCOPE = "https://www.googleapis.com/auth/datastore"; private static final Set SCOPES = ImmutableSet.of(DATASTORE_SCOPE); @@ -58,7 +59,7 @@ public DatastoreRpc create(DatastoreOptions options) { } public static class Builder extends - ServiceOptions.Builder { + HttpServiceOptions.Builder { private String namespace; diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsOptions.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsOptions.java index 059f7b212044..a213a855fff2 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsOptions.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsOptions.java @@ -16,17 +16,17 @@ package com.google.cloud.dns; +import com.google.cloud.HttpServiceOptions; import com.google.common.collect.ImmutableSet; -import com.google.cloud.ServiceOptions; import com.google.cloud.dns.spi.DefaultDnsRpc; import com.google.cloud.dns.spi.DnsRpc; import com.google.cloud.dns.spi.DnsRpcFactory; import java.util.Set; -public class DnsOptions extends ServiceOptions { +public class DnsOptions extends HttpServiceOptions { - private static final long serialVersionUID = -519128051411747771L; + private static final long serialVersionUID = -8639966476950724880L; private static final String GC_DNS_RW = "https://www.googleapis.com/auth/ndev.clouddns.readwrite"; private static final Set SCOPES = ImmutableSet.of(GC_DNS_RW); @@ -49,7 +49,7 @@ public DnsRpc create(DnsOptions options) { } } - public static class Builder extends ServiceOptions.Builder { private Builder() { diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java index 6fde6f4425df..48de7002d54f 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java @@ -31,7 +31,7 @@ * * @see Google Cloud Pub/Sub */ -public interface PubSub extends Service { +public interface PubSub extends AutoCloseable, Service { /** * Class for specifying options for listing topics and subscriptions. diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java index 19b2e5a35fec..bd69103b9819 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java @@ -278,4 +278,9 @@ public Future modifyAckDeadlineAsync(String subscription, int deadline, Ti Iterable ackIds) { return null; } + + @Override + public void close() throws Exception { + rpc.close(); + } } diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubOptions.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubOptions.java index 73482ccef25f..420b0d50148b 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubOptions.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubOptions.java @@ -16,7 +16,7 @@ package com.google.cloud.pubsub; -import com.google.cloud.ServiceOptions; +import com.google.cloud.GrpcServiceOptions; import com.google.cloud.pubsub.spi.DefaultPubSubRpc; import com.google.cloud.pubsub.spi.PubSubRpc; import com.google.cloud.pubsub.spi.PubSubRpcFactory; @@ -25,9 +25,9 @@ import java.io.IOException; import java.util.Set; -public class PubSubOptions extends ServiceOptions { +public class PubSubOptions extends GrpcServiceOptions { - private static final long serialVersionUID = 6740347843343421456L; + private static final long serialVersionUID = 5640180400046623305L; private static final String PUBSUB_SCOPE = "https://www.googleapis.com/auth/pubsub"; private static final Set SCOPES = ImmutableSet.of(PUBSUB_SCOPE); private static final String DEFAULT_HOST = "https://pubsub.googleapis.com"; @@ -67,7 +67,7 @@ protected String defaultHost() { } public static class Builder extends - ServiceOptions.Builder { + GrpcServiceOptions.Builder { private Builder() {} @@ -81,7 +81,7 @@ public PubSubOptions build() { } } - private PubSubOptions(Builder builder) { + protected PubSubOptions(Builder builder) { super(PubSubFactory.class, PubSubRpcFactory.class, builder); } diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java index d4f00fd7cf37..7878a6d83835 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java @@ -19,6 +19,9 @@ import com.google.api.gax.core.RetrySettings; import com.google.api.gax.grpc.ApiCallSettings; import com.google.api.gax.grpc.ApiException; +import com.google.auth.oauth2.GoogleCredentials; +import com.google.cloud.AuthCredentials; +import com.google.cloud.GrpcServiceOptions.ExecutorFactory; import com.google.cloud.RetryParams; import com.google.cloud.pubsub.PubSubException; import com.google.cloud.pubsub.PubSubOptions; @@ -27,6 +30,7 @@ import com.google.cloud.pubsub.spi.v1.SubscriberApi; import com.google.cloud.pubsub.spi.v1.SubscriberSettings; import com.google.common.base.Function; +import com.google.common.collect.Sets; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.protobuf.Empty; @@ -52,32 +56,64 @@ import org.joda.time.Duration; +import io.grpc.ManagedChannel; +import io.grpc.Status.Code; +import io.grpc.netty.NegotiationType; +import io.grpc.netty.NettyChannelBuilder; + import java.io.IOException; import java.util.Set; import java.util.concurrent.Future; - -import autovalue.shaded.com.google.common.common.collect.Sets; -import io.grpc.Status.Code; +import java.util.concurrent.ScheduledExecutorService; public class DefaultPubSubRpc implements PubSubRpc { private final PublisherApi publisherApi; private final SubscriberApi subscriberApi; + private final ScheduledExecutorService executor; + private final ExecutorFactory executorFactory; + + private static final class InternalPubSubOptions extends PubSubOptions { + + private static final long serialVersionUID = -7997372049256706185L; + + private InternalPubSubOptions(PubSubOptions options) { + super(options.toBuilder()); + } + + @Override + protected ExecutorFactory executorFactory() { + return super.executorFactory(); + } + } public DefaultPubSubRpc(PubSubOptions options) throws IOException { + executorFactory = new InternalPubSubOptions(options).executorFactory(); + executor = executorFactory.get(); try { - // Provide (and use a common thread-pool). - // This depends on https://github.com/googleapis/gax-java/issues/73 - PublisherSettings.Builder pbuilder = - PublisherSettings.defaultBuilder() - .provideChannelWith(options.authCredentials().credentials()) - .applyToAllApiMethods(apiCallSettings(options)); - publisherApi = PublisherApi.create(pbuilder.build()); - SubscriberSettings.Builder sBuilder = - SubscriberSettings.defaultBuilder() - .provideChannelWith(options.authCredentials().credentials()) - .applyToAllApiMethods(apiCallSettings(options)); - subscriberApi = SubscriberApi.create(sBuilder.build()); + PublisherSettings.Builder pubBuilder = + PublisherSettings.defaultBuilder().provideExecutorWith(executor, false); + SubscriberSettings.Builder subBuilder = + SubscriberSettings.defaultBuilder().provideExecutorWith(executor, false); + // todo(mziccard): PublisherSettings should support null/absent credentials for testing + if (options.host().contains("localhost") + || options.authCredentials().equals(AuthCredentials.noAuth())) { + ManagedChannel channel = NettyChannelBuilder.forTarget(options.host()) + .negotiationType(NegotiationType.PLAINTEXT) + .build(); + pubBuilder.provideChannelWith(channel, true); + subBuilder.provideChannelWith(channel, true); + } else { + GoogleCredentials credentials = options.authCredentials().credentials(); + pubBuilder.provideChannelWith( + credentials.createScoped(PublisherSettings.DEFAULT_SERVICE_SCOPES)); + subBuilder.provideChannelWith( + credentials.createScoped(SubscriberSettings.DEFAULT_SERVICE_SCOPES)); + } + pubBuilder.applyToAllApiMethods(apiCallSettings(options)); + subBuilder.applyToAllApiMethods(apiCallSettings(options)); + publisherApi = PublisherApi.create(pubBuilder.build()); + subscriberApi = SubscriberApi.create(subBuilder.build()); } catch (Exception ex) { throw new IOException(ex); } @@ -89,9 +125,9 @@ private static ApiCallSettings.Builder apiCallSettings(PubSubOptions options) { RetryParams retryParams = options.retryParams(); final RetrySettings.Builder builder = RetrySettings.newBuilder() .setTotalTimeout(Duration.millis(retryParams.totalRetryPeriodMillis())) - .setInitialRpcTimeout(Duration.millis(options.connectTimeout())) - .setRpcTimeoutMultiplier(1.5) - .setMaxRpcTimeout(Duration.millis(options.connectTimeout() + options.readTimeout())) + .setInitialRpcTimeout(Duration.millis(options.initialTimeout())) + .setRpcTimeoutMultiplier(options.timeoutMultiplier()) + .setMaxRpcTimeout(Duration.millis(options.maxTimeout())) .setInitialRetryDelay(Duration.millis(retryParams.initialRetryDelayMillis())) .setRetryDelayMultiplier(retryParams.retryDelayBackoffFactor()) .setMaxRetryDelay(Duration.millis(retryParams.maxRetryDelayMillis())); @@ -195,4 +231,11 @@ public Future pull(PullRequest request) { public Future modify(ModifyPushConfigRequest request) { return translate(subscriberApi.modifyPushConfigCallable().futureCall(request), false); } + + @Override + public void close() throws Exception { + subscriberApi.close(); + publisherApi.close(); + executorFactory.release(executor); + } } diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/PubSubRpc.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/PubSubRpc.java index 8474ba042234..6d738cd554c4 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/PubSubRpc.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/PubSubRpc.java @@ -39,7 +39,7 @@ import java.util.concurrent.Future; -public interface PubSubRpc { +public interface PubSubRpc extends AutoCloseable { // in all cases root cause of ExecutionException is PubSubException Future create(Topic topic); diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerOptions.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerOptions.java index 8f5c79e8bc3f..afc0514ea643 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerOptions.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerOptions.java @@ -16,8 +16,8 @@ package com.google.cloud.resourcemanager; +import com.google.cloud.HttpServiceOptions; import com.google.common.collect.ImmutableSet; -import com.google.cloud.ServiceOptions; import com.google.cloud.resourcemanager.spi.DefaultResourceManagerRpc; import com.google.cloud.resourcemanager.spi.ResourceManagerRpc; import com.google.cloud.resourcemanager.spi.ResourceManagerRpcFactory; @@ -25,9 +25,9 @@ import java.util.Set; public class ResourceManagerOptions - extends ServiceOptions { + extends HttpServiceOptions { - private static final long serialVersionUID = 538303101192527452L; + private static final long serialVersionUID = -109855112863688882L; private static final String GCRM_SCOPE = "https://www.googleapis.com/auth/cloud-platform"; private static final Set SCOPES = ImmutableSet.of(GCRM_SCOPE); private static final String DEFAULT_HOST = "https://cloudresourcemanager.googleapis.com"; @@ -63,8 +63,8 @@ protected String defaultHost() { return DEFAULT_HOST; } - public static class Builder extends ServiceOptions.Builder { + public static class Builder extends HttpServiceOptions.Builder { private Builder() {} diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageOptions.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageOptions.java index 15e5791a6b91..45b393c5e171 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageOptions.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageOptions.java @@ -16,17 +16,17 @@ package com.google.cloud.storage; +import com.google.cloud.HttpServiceOptions; import com.google.common.collect.ImmutableSet; -import com.google.cloud.ServiceOptions; import com.google.cloud.storage.spi.DefaultStorageRpc; import com.google.cloud.storage.spi.StorageRpc; import com.google.cloud.storage.spi.StorageRpcFactory; import java.util.Set; -public class StorageOptions extends ServiceOptions { +public class StorageOptions extends HttpServiceOptions { - private static final long serialVersionUID = -7804860602287801084L; + private static final long serialVersionUID = -7456495262640805964L; private static final String GCS_SCOPE = "https://www.googleapis.com/auth/devstorage.full_control"; private static final Set SCOPES = ImmutableSet.of(GCS_SCOPE); @@ -51,7 +51,7 @@ public StorageRpc create(StorageOptions options) { } public static class Builder extends - ServiceOptions.Builder { + HttpServiceOptions.Builder { private Builder() {} From 554b03ed1a5bfe1baba5528559c60b83eb9fd0f8 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 17 May 2016 09:21:25 +0200 Subject: [PATCH 350/375] Fix StorageImpl.signUrl with object names starting with / (#1013) * Fix StorageImpl.signUrl with object names starting with / * Add test for Storage.signUrl with object names starting with / --- .../com/google/cloud/storage/StorageImpl.java | 2 +- .../google/cloud/storage/StorageImplTest.java | 57 +++++++++++++------ 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageImpl.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageImpl.java index f4769905d8bc..8a33f2bc4203 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageImpl.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageImpl.java @@ -571,7 +571,7 @@ public URL signUrl(BlobInfo blobInfo, long duration, TimeUnit unit, SignUrlOptio path.append('/'); } if (blobInfo.name().startsWith("/")) { - path.setLength(stBuilder.length() - 1); + path.setLength(path.length() - 1); } path.append(blobInfo.name()); stBuilder.append(path); diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java index 47f776458876..9df971721906 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java @@ -1136,17 +1136,42 @@ public void testSignUrl() throws NoSuchAlgorithmException, InvalidKeyException, storage = options.toBuilder().authCredentials(authCredentials).build().service(); URL url = storage.signUrl(BLOB_INFO1, 14, TimeUnit.DAYS); String stringUrl = url.toString(); - String expectedUrl = - new StringBuilder("https://storage.googleapis.com/").append(BUCKET_NAME1).append("/") - .append(BLOB_NAME1).append("?GoogleAccessId=").append(ACCOUNT).append("&Expires=") - .append(42L + 1209600).append("&Signature=").toString(); + String expectedUrl = new StringBuilder("https://storage.googleapis.com/").append(BUCKET_NAME1) + .append('/').append(BLOB_NAME1).append("?GoogleAccessId=").append(ACCOUNT) + .append("&Expires=").append(42L + 1209600).append("&Signature=").toString(); assertTrue(stringUrl.startsWith(expectedUrl)); String signature = stringUrl.substring(expectedUrl.length()); StringBuilder signedMessageBuilder = new StringBuilder(); - signedMessageBuilder.append(HttpMethod.GET).append('\n').append('\n').append('\n') - .append(42L + 1209600).append('\n').append("/").append(BUCKET_NAME1).append("/") - .append(BLOB_NAME1); + signedMessageBuilder.append(HttpMethod.GET).append("\n\n\n").append(42L + 1209600).append("\n/") + .append(BUCKET_NAME1).append('/').append(BLOB_NAME1); + + Signature signer = Signature.getInstance("SHA256withRSA"); + signer.initVerify(publicKey); + signer.update(signedMessageBuilder.toString().getBytes(UTF_8)); + assertTrue(signer.verify(BaseEncoding.base64().decode( + URLDecoder.decode(signature, UTF_8.name())))); + } + + @Test + public void testSignUrlLeadingSlash() throws NoSuchAlgorithmException, InvalidKeyException, + SignatureException, UnsupportedEncodingException { + String blobName = "/b1"; + EasyMock.replay(storageRpcMock); + ServiceAccountAuthCredentials authCredentials = + ServiceAccountAuthCredentials.createFor(ACCOUNT, privateKey); + storage = options.toBuilder().authCredentials(authCredentials).build().service(); + URL url = storage.signUrl(BlobInfo.builder(BUCKET_NAME1, blobName).build(), 14, TimeUnit.DAYS); + String stringUrl = url.toString(); + String expectedUrl = new StringBuilder("https://storage.googleapis.com/").append(BUCKET_NAME1) + .append(blobName).append("?GoogleAccessId=").append(ACCOUNT).append("&Expires=") + .append(42L + 1209600).append("&Signature=").toString(); + assertTrue(stringUrl.startsWith(expectedUrl)); + String signature = stringUrl.substring(expectedUrl.length()); + + StringBuilder signedMessageBuilder = new StringBuilder(); + signedMessageBuilder.append(HttpMethod.GET).append("\n\n\n").append(42L + 1209600).append("\n/") + .append(BUCKET_NAME1).append(blobName); Signature signer = Signature.getInstance("SHA256withRSA"); signer.initVerify(publicKey); @@ -1162,22 +1187,20 @@ public void testSignUrlWithOptions() throws NoSuchAlgorithmException, InvalidKey ServiceAccountAuthCredentials authCredentials = ServiceAccountAuthCredentials.createFor(ACCOUNT, privateKey); storage = options.toBuilder().authCredentials(authCredentials).build().service(); - URL url = - storage.signUrl(BLOB_INFO1, 14, TimeUnit.DAYS, - Storage.SignUrlOption.httpMethod(HttpMethod.POST), - Storage.SignUrlOption.withContentType(), Storage.SignUrlOption.withMd5()); + URL url = storage.signUrl(BLOB_INFO1, 14, TimeUnit.DAYS, + Storage.SignUrlOption.httpMethod(HttpMethod.POST), Storage.SignUrlOption.withContentType(), + Storage.SignUrlOption.withMd5()); String stringUrl = url.toString(); - String expectedUrl = - new StringBuilder("https://storage.googleapis.com/").append(BUCKET_NAME1).append("/") - .append(BLOB_NAME1).append("?GoogleAccessId=").append(ACCOUNT).append("&Expires=") - .append(42L + 1209600).append("&Signature=").toString(); + String expectedUrl = new StringBuilder("https://storage.googleapis.com/").append(BUCKET_NAME1) + .append('/').append(BLOB_NAME1).append("?GoogleAccessId=").append(ACCOUNT) + .append("&Expires=").append(42L + 1209600).append("&Signature=").toString(); assertTrue(stringUrl.startsWith(expectedUrl)); String signature = stringUrl.substring(expectedUrl.length()); StringBuilder signedMessageBuilder = new StringBuilder(); signedMessageBuilder.append(HttpMethod.POST).append('\n').append(BLOB_INFO1.md5()).append('\n') - .append(BLOB_INFO1.contentType()).append('\n').append(42L + 1209600).append('\n') - .append("/").append(BUCKET_NAME1).append("/").append(BLOB_NAME1); + .append(BLOB_INFO1.contentType()).append('\n').append(42L + 1209600).append("\n/") + .append(BUCKET_NAME1).append('/').append(BLOB_NAME1); Signature signer = Signature.getInstance("SHA256withRSA"); signer.initVerify(publicKey); From 2656eb953bd700004f1d3f4159e806996f76c9e5 Mon Sep 17 00:00:00 2001 From: michaelbausor Date: Tue, 17 May 2016 08:02:17 -0700 Subject: [PATCH 351/375] Regenerated pubsub surface (#1009) * Regenerated pubsub surface Improved code samples Client side validation of resource names Updated GAX * Removed formatted prefix from parameters --- .../cloud/pubsub/spi/v1/PublisherApi.java | 268 +++++++++++++- .../cloud/pubsub/spi/v1/SubscriberApi.java | 344 +++++++++++++++++- gcloud-java-pubsub/pom.xml | 2 +- .../cloud/pubsub/spi/v1/PublisherApi.java | 268 +++++++++++++- .../cloud/pubsub/spi/v1/SubscriberApi.java | 344 +++++++++++++++++- 5 files changed, 1193 insertions(+), 33 deletions(-) diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java index 36d576767efb..7d8eb0f15e79 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java @@ -67,8 +67,8 @@ *

      * 
      * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    - *   String name = "";
    - *   Topic callResult = publisherApi.createTopic(name);
    + *   String formattedName = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    + *   Topic response = publisherApi.createTopic(formattedName);
      * }
      * 
      * 
    @@ -277,6 +277,14 @@ public void close() throws IOException { /** * Creates the given topic with the given name. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedName = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   Topic response = publisherApi.createTopic(formattedName);
    +   * }
    +   * 
    + * * * * @@ -289,8 +297,8 @@ public void close() throws IOException { * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final Topic createTopic(String name) { + TOPIC_PATH_TEMPLATE.validate(name); Topic request = Topic.newBuilder().setName(name).build(); - return createTopic(request); } @@ -298,6 +306,17 @@ public final Topic createTopic(String name) { /** * Creates the given topic with the given name. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedName = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   Topic request = Topic.newBuilder()
    +   *     .setName(formattedName)
    +   *     .build();
    +   *   Topic response = publisherApi.createTopic(request);
    +   * }
    +   * 
    + * * * * @@ -312,6 +331,19 @@ private Topic createTopic(Topic request) { /** * Creates the given topic with the given name. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedName = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   Topic request = Topic.newBuilder()
    +   *     .setName(formattedName)
    +   *     .build();
    +   *   ListenableFuture<Topic> future = publisherApi.createTopicCallable().futureCall(request);
    +   *   // Do something
    +   *   Topic response = future.get();
    +   * }
    +   * 
    + * * * */ @@ -327,6 +359,15 @@ public final ApiCallable createTopicCallable() { * does not exist. The message payload must not be empty; it must contain * either a non-empty data field, or at least one attribute. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   List<PubsubMessage> messages = new ArrayList<>();
    +   *   PublishResponse response = publisherApi.publish(formattedTopic, messages);
    +   * }
    +   * 
    + * * * * @@ -335,9 +376,10 @@ public final ApiCallable createTopicCallable() { * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final PublishResponse publish(String topic, List messages) { + TOPIC_PATH_TEMPLATE.validate(topic); + PublishRequest request = PublishRequest.newBuilder().setTopic(topic).addAllMessages(messages).build(); - return publish(request); } @@ -347,6 +389,19 @@ public final PublishResponse publish(String topic, List messages) * does not exist. The message payload must not be empty; it must contain * either a non-empty data field, or at least one attribute. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   List<PubsubMessage> messages = new ArrayList<>();
    +   *   PublishRequest request = PublishRequest.newBuilder()
    +   *     .setTopic(formattedTopic)
    +   *     .addAllMessages(messages)
    +   *     .build();
    +   *   PublishResponse response = publisherApi.publish(request);
    +   * }
    +   * 
    + * * * * @@ -363,6 +418,21 @@ public PublishResponse publish(PublishRequest request) { * does not exist. The message payload must not be empty; it must contain * either a non-empty data field, or at least one attribute. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   List<PubsubMessage> messages = new ArrayList<>();
    +   *   PublishRequest request = PublishRequest.newBuilder()
    +   *     .setTopic(formattedTopic)
    +   *     .addAllMessages(messages)
    +   *     .build();
    +   *   ListenableFuture<PublishResponse> future = publisherApi.publishCallable().futureCall(request);
    +   *   // Do something
    +   *   PublishResponse response = future.get();
    +   * }
    +   * 
    + * * * */ @@ -376,6 +446,14 @@ public final ApiCallable publishCallable() { /** * Gets the configuration of a topic. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   Topic response = publisherApi.getTopic(formattedTopic);
    +   * }
    +   * 
    + * * * * @@ -383,8 +461,8 @@ public final ApiCallable publishCallable() { * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final Topic getTopic(String topic) { + TOPIC_PATH_TEMPLATE.validate(topic); GetTopicRequest request = GetTopicRequest.newBuilder().setTopic(topic).build(); - return getTopic(request); } @@ -392,6 +470,17 @@ public final Topic getTopic(String topic) { /** * Gets the configuration of a topic. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   GetTopicRequest request = GetTopicRequest.newBuilder()
    +   *     .setTopic(formattedTopic)
    +   *     .build();
    +   *   Topic response = publisherApi.getTopic(request);
    +   * }
    +   * 
    + * * * * @@ -406,6 +495,19 @@ private Topic getTopic(GetTopicRequest request) { /** * Gets the configuration of a topic. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   GetTopicRequest request = GetTopicRequest.newBuilder()
    +   *     .setTopic(formattedTopic)
    +   *     .build();
    +   *   ListenableFuture<Topic> future = publisherApi.getTopicCallable().futureCall(request);
    +   *   // Do something
    +   *   Topic response = future.get();
    +   * }
    +   * 
    + * * * */ @@ -419,6 +521,16 @@ public final ApiCallable getTopicCallable() { /** * Lists matching topics. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedProject = PublisherApi.formatProjectName("[PROJECT]");
    +   *   for (Topic elements : publisherApi.listTopics(formattedProject)) {
    +   *     // doThingsWith(elements);
    +   *   }
    +   * }
    +   * 
    + * * * * @@ -426,6 +538,7 @@ public final ApiCallable getTopicCallable() { * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final PageAccessor listTopics(String project) { + PROJECT_PATH_TEMPLATE.validate(project); ListTopicsRequest request = ListTopicsRequest.newBuilder().setProject(project).build(); return listTopics(request); } @@ -434,6 +547,19 @@ public final PageAccessor listTopics(String project) { /** * Lists matching topics. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedProject = PublisherApi.formatProjectName("[PROJECT]");
    +   *   ListTopicsRequest request = ListTopicsRequest.newBuilder()
    +   *     .setProject(formattedProject)
    +   *     .build();
    +   *   for (Topic elements : publisherApi.listTopics(request)) {
    +   *     // doThingsWith(elements);
    +   *   }
    +   * }
    +   * 
    + * * * * @@ -448,6 +574,21 @@ public final PageAccessor listTopics(ListTopicsRequest request) { /** * Lists matching topics. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedProject = PublisherApi.formatProjectName("[PROJECT]");
    +   *   ListTopicsRequest request = ListTopicsRequest.newBuilder()
    +   *     .setProject(formattedProject)
    +   *     .build();
    +   *   ListenableFuture<PageAccessor<Topic>> future = publisherApi.listTopicsPagedCallable().futureCall(request);
    +   *   // Do something
    +   *   for (Topic elements : future.get()) {
    +   *     // doThingsWith(elements);
    +   *   }
    +   * }
    +   * 
    + * * * */ @@ -459,6 +600,28 @@ public final ApiCallable> listTopicsPaged /** * Lists matching topics. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedProject = PublisherApi.formatProjectName("[PROJECT]");
    +   *   ListTopicsRequest request = ListTopicsRequest.newBuilder()
    +   *     .setProject(formattedProject)
    +   *     .build();
    +   *   while (true) {
    +   *     ListTopicsResponse response = publisherApi.listTopicsCallable().call(request);
    +   *     for (Topic elements : response.getTopicsList()) {
    +   *       // doThingsWith(elements);
    +   *     }
    +   *     String nextPageToken = response.getNextPageToken();
    +   *     if (!Strings.isNullOrEmpty(nextPageToken)) {
    +   *       request = request.toBuilder().setPageToken(nextPageToken).build();
    +   *     } else {
    +   *       break;
    +   *     }
    +   *   }
    +   * }
    +   * 
    + * * * */ @@ -472,6 +635,16 @@ public final ApiCallable listTopicsCallab /** * Lists the name of the subscriptions for this topic. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   for (String elements : publisherApi.listTopicSubscriptions(formattedTopic)) {
    +   *     // doThingsWith(elements);
    +   *   }
    +   * }
    +   * 
    + * * * * @@ -479,6 +652,7 @@ public final ApiCallable listTopicsCallab * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final PageAccessor listTopicSubscriptions(String topic) { + TOPIC_PATH_TEMPLATE.validate(topic); ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder().setTopic(topic).build(); return listTopicSubscriptions(request); @@ -488,6 +662,19 @@ public final PageAccessor listTopicSubscriptions(String topic) { /** * Lists the name of the subscriptions for this topic. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder()
    +   *     .setTopic(formattedTopic)
    +   *     .build();
    +   *   for (String elements : publisherApi.listTopicSubscriptions(request)) {
    +   *     // doThingsWith(elements);
    +   *   }
    +   * }
    +   * 
    + * * * * @@ -502,6 +689,21 @@ public final PageAccessor listTopicSubscriptions(ListTopicSubscriptionsR /** * Lists the name of the subscriptions for this topic. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder()
    +   *     .setTopic(formattedTopic)
    +   *     .build();
    +   *   ListenableFuture<PageAccessor<String>> future = publisherApi.listTopicSubscriptionsPagedCallable().futureCall(request);
    +   *   // Do something
    +   *   for (String elements : future.get()) {
    +   *     // doThingsWith(elements);
    +   *   }
    +   * }
    +   * 
    + * * * */ @@ -514,6 +716,28 @@ public final PageAccessor listTopicSubscriptions(ListTopicSubscriptionsR /** * Lists the name of the subscriptions for this topic. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder()
    +   *     .setTopic(formattedTopic)
    +   *     .build();
    +   *   while (true) {
    +   *     ListTopicSubscriptionsResponse response = publisherApi.listTopicSubscriptionsCallable().call(request);
    +   *     for (String elements : response.getSubscriptionsList()) {
    +   *       // doThingsWith(elements);
    +   *     }
    +   *     String nextPageToken = response.getNextPageToken();
    +   *     if (!Strings.isNullOrEmpty(nextPageToken)) {
    +   *       request = request.toBuilder().setPageToken(nextPageToken).build();
    +   *     } else {
    +   *       break;
    +   *     }
    +   *   }
    +   * }
    +   * 
    + * * * */ @@ -532,6 +756,14 @@ public final PageAccessor listTopicSubscriptions(ListTopicSubscriptionsR * configuration or subscriptions. Existing subscriptions to this topic are * not deleted, but their `topic` field is set to `_deleted-topic_`. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   publisherApi.deleteTopic(formattedTopic);
    +   * }
    +   * 
    + * * * * @@ -539,8 +771,8 @@ public final PageAccessor listTopicSubscriptions(ListTopicSubscriptionsR * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final void deleteTopic(String topic) { + TOPIC_PATH_TEMPLATE.validate(topic); DeleteTopicRequest request = DeleteTopicRequest.newBuilder().setTopic(topic).build(); - deleteTopic(request); } @@ -552,6 +784,17 @@ public final void deleteTopic(String topic) { * configuration or subscriptions. Existing subscriptions to this topic are * not deleted, but their `topic` field is set to `_deleted-topic_`. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   DeleteTopicRequest request = DeleteTopicRequest.newBuilder()
    +   *     .setTopic(formattedTopic)
    +   *     .build();
    +   *   publisherApi.deleteTopic(request);
    +   * }
    +   * 
    + * * * * @@ -570,6 +813,19 @@ private void deleteTopic(DeleteTopicRequest request) { * configuration or subscriptions. Existing subscriptions to this topic are * not deleted, but their `topic` field is set to `_deleted-topic_`. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   DeleteTopicRequest request = DeleteTopicRequest.newBuilder()
    +   *     .setTopic(formattedTopic)
    +   *     .build();
    +   *   ListenableFuture<Void> future = publisherApi.deleteTopicCallable().futureCall(request);
    +   *   // Do something
    +   *   future.get();
    +   * }
    +   * 
    + * * * */ diff --git a/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java index dd6275bcd9d0..bbb1bf629f8f 100644 --- a/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java +++ b/gcloud-java-pubsub/baseline/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java @@ -68,11 +68,11 @@ *
      * 
      * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    - *   String name = "";
    - *   String topic = "";
    + *   String formattedName = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    + *   String formattedTopic = SubscriberApi.formatTopicName("[PROJECT]", "[TOPIC]");
      *   PushConfig pushConfig = PushConfig.newBuilder().build();
      *   int ackDeadlineSeconds = 0;
    - *   Subscription callResult = subscriberApi.createSubscription(name, topic, pushConfig, ackDeadlineSeconds);
    + *   Subscription response = subscriberApi.createSubscription(formattedName, formattedTopic, pushConfig, ackDeadlineSeconds);
      * }
      * 
      * 
    @@ -321,6 +321,17 @@ public void close() throws IOException { * If the name is not provided in the request, the server will assign a random * name for this subscription on the same project as the topic. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedName = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   String formattedTopic = SubscriberApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   PushConfig pushConfig = PushConfig.newBuilder().build();
    +   *   int ackDeadlineSeconds = 0;
    +   *   Subscription response = subscriberApi.createSubscription(formattedName, formattedTopic, pushConfig, ackDeadlineSeconds);
    +   * }
    +   * 
    + * * * * @@ -356,6 +367,9 @@ public void close() throws IOException { */ public final Subscription createSubscription( String name, String topic, PushConfig pushConfig, int ackDeadlineSeconds) { + SUBSCRIPTION_PATH_TEMPLATE.validate(name); + TOPIC_PATH_TEMPLATE.validate(topic); + Subscription request = Subscription.newBuilder() .setName(name) @@ -363,7 +377,6 @@ public final Subscription createSubscription( .setPushConfig(pushConfig) .setAckDeadlineSeconds(ackDeadlineSeconds) .build(); - return createSubscription(request); } @@ -376,6 +389,19 @@ public final Subscription createSubscription( * If the name is not provided in the request, the server will assign a random * name for this subscription on the same project as the topic. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedName = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   String formattedTopic = SubscriberApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   Subscription request = Subscription.newBuilder()
    +   *     .setName(formattedName)
    +   *     .setTopic(formattedTopic)
    +   *     .build();
    +   *   Subscription response = subscriberApi.createSubscription(request);
    +   * }
    +   * 
    + * * * * @@ -395,6 +421,21 @@ public Subscription createSubscription(Subscription request) { * If the name is not provided in the request, the server will assign a random * name for this subscription on the same project as the topic. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedName = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   String formattedTopic = SubscriberApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   Subscription request = Subscription.newBuilder()
    +   *     .setName(formattedName)
    +   *     .setTopic(formattedTopic)
    +   *     .build();
    +   *   ListenableFuture<Subscription> future = subscriberApi.createSubscriptionCallable().futureCall(request);
    +   *   // Do something
    +   *   Subscription response = future.get();
    +   * }
    +   * 
    + * * * */ @@ -411,6 +452,14 @@ public final ApiCallable createSubscriptionCallable( * If the topic of a subscription has been deleted, the subscription itself is * not deleted, but the value of the `topic` field is set to `_deleted-topic_`. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   Subscription response = subscriberApi.getSubscription(formattedSubscription);
    +   * }
    +   * 
    + * * * * @@ -418,9 +467,9 @@ public final ApiCallable createSubscriptionCallable( * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final Subscription getSubscription(String subscription) { + SUBSCRIPTION_PATH_TEMPLATE.validate(subscription); GetSubscriptionRequest request = GetSubscriptionRequest.newBuilder().setSubscription(subscription).build(); - return getSubscription(request); } @@ -431,6 +480,17 @@ public final Subscription getSubscription(String subscription) { * If the topic of a subscription has been deleted, the subscription itself is * not deleted, but the value of the `topic` field is set to `_deleted-topic_`. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   GetSubscriptionRequest request = GetSubscriptionRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .build();
    +   *   Subscription response = subscriberApi.getSubscription(request);
    +   * }
    +   * 
    + * * * * @@ -448,6 +508,19 @@ private Subscription getSubscription(GetSubscriptionRequest request) { * If the topic of a subscription has been deleted, the subscription itself is * not deleted, but the value of the `topic` field is set to `_deleted-topic_`. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   GetSubscriptionRequest request = GetSubscriptionRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .build();
    +   *   ListenableFuture<Subscription> future = subscriberApi.getSubscriptionCallable().futureCall(request);
    +   *   // Do something
    +   *   Subscription response = future.get();
    +   * }
    +   * 
    + * * * */ @@ -464,6 +537,16 @@ public final ApiCallable getSubscriptionCa * If the topic of a subscription has been deleted, the subscription itself is * not deleted, but the value of the `topic` field is set to `_deleted-topic_`. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedProject = SubscriberApi.formatProjectName("[PROJECT]");
    +   *   for (Subscription elements : subscriberApi.listSubscriptions(formattedProject)) {
    +   *     // doThingsWith(elements);
    +   *   }
    +   * }
    +   * 
    + * * * * @@ -471,6 +554,7 @@ public final ApiCallable getSubscriptionCa * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final PageAccessor listSubscriptions(String project) { + PROJECT_PATH_TEMPLATE.validate(project); ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder().setProject(project).build(); return listSubscriptions(request); @@ -483,6 +567,19 @@ public final PageAccessor listSubscriptions(String project) { * If the topic of a subscription has been deleted, the subscription itself is * not deleted, but the value of the `topic` field is set to `_deleted-topic_`. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedProject = SubscriberApi.formatProjectName("[PROJECT]");
    +   *   ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder()
    +   *     .setProject(formattedProject)
    +   *     .build();
    +   *   for (Subscription elements : subscriberApi.listSubscriptions(request)) {
    +   *     // doThingsWith(elements);
    +   *   }
    +   * }
    +   * 
    + * * * * @@ -500,6 +597,21 @@ public final PageAccessor listSubscriptions(ListSubscriptionsReque * If the topic of a subscription has been deleted, the subscription itself is * not deleted, but the value of the `topic` field is set to `_deleted-topic_`. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedProject = SubscriberApi.formatProjectName("[PROJECT]");
    +   *   ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder()
    +   *     .setProject(formattedProject)
    +   *     .build();
    +   *   ListenableFuture<PageAccessor<Subscription>> future = subscriberApi.listSubscriptionsPagedCallable().futureCall(request);
    +   *   // Do something
    +   *   for (Subscription elements : future.get()) {
    +   *     // doThingsWith(elements);
    +   *   }
    +   * }
    +   * 
    + * * * */ @@ -515,6 +627,28 @@ public final PageAccessor listSubscriptions(ListSubscriptionsReque * If the topic of a subscription has been deleted, the subscription itself is * not deleted, but the value of the `topic` field is set to `_deleted-topic_`. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedProject = SubscriberApi.formatProjectName("[PROJECT]");
    +   *   ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder()
    +   *     .setProject(formattedProject)
    +   *     .build();
    +   *   while (true) {
    +   *     ListSubscriptionsResponse response = subscriberApi.listSubscriptionsCallable().call(request);
    +   *     for (Subscription elements : response.getSubscriptionsList()) {
    +   *       // doThingsWith(elements);
    +   *     }
    +   *     String nextPageToken = response.getNextPageToken();
    +   *     if (!Strings.isNullOrEmpty(nextPageToken)) {
    +   *       request = request.toBuilder().setPageToken(nextPageToken).build();
    +   *     } else {
    +   *       break;
    +   *     }
    +   *   }
    +   * }
    +   * 
    + * * * */ @@ -533,6 +667,14 @@ public final PageAccessor listSubscriptions(ListSubscriptionsReque * the same name, but the new one has no association with the old * subscription, or its topic unless the same topic is specified. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   subscriberApi.deleteSubscription(formattedSubscription);
    +   * }
    +   * 
    + * * * * @@ -540,9 +682,9 @@ public final PageAccessor listSubscriptions(ListSubscriptionsReque * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final void deleteSubscription(String subscription) { + SUBSCRIPTION_PATH_TEMPLATE.validate(subscription); DeleteSubscriptionRequest request = DeleteSubscriptionRequest.newBuilder().setSubscription(subscription).build(); - deleteSubscription(request); } @@ -554,6 +696,17 @@ public final void deleteSubscription(String subscription) { * the same name, but the new one has no association with the old * subscription, or its topic unless the same topic is specified. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   DeleteSubscriptionRequest request = DeleteSubscriptionRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .build();
    +   *   subscriberApi.deleteSubscription(request);
    +   * }
    +   * 
    + * * * * @@ -572,6 +725,19 @@ private void deleteSubscription(DeleteSubscriptionRequest request) { * the same name, but the new one has no association with the old * subscription, or its topic unless the same topic is specified. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   DeleteSubscriptionRequest request = DeleteSubscriptionRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .build();
    +   *   ListenableFuture<Void> future = subscriberApi.deleteSubscriptionCallable().futureCall(request);
    +   *   // Do something
    +   *   future.get();
    +   * }
    +   * 
    + * * * */ @@ -588,6 +754,16 @@ public final ApiCallable deleteSubscriptionCal * subscriber, or to make the message available for redelivery if the * processing was interrupted. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   List<String> ackIds = new ArrayList<>();
    +   *   int ackDeadlineSeconds = 0;
    +   *   subscriberApi.modifyAckDeadline(formattedSubscription, ackIds, ackDeadlineSeconds);
    +   * }
    +   * 
    + * * * * @@ -602,13 +778,14 @@ public final ApiCallable deleteSubscriptionCal */ public final void modifyAckDeadline( String subscription, List ackIds, int ackDeadlineSeconds) { + SUBSCRIPTION_PATH_TEMPLATE.validate(subscription); + ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() .setSubscription(subscription) .addAllAckIds(ackIds) .setAckDeadlineSeconds(ackDeadlineSeconds) .build(); - modifyAckDeadline(request); } @@ -619,6 +796,21 @@ public final void modifyAckDeadline( * subscriber, or to make the message available for redelivery if the * processing was interrupted. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   List<String> ackIds = new ArrayList<>();
    +   *   int ackDeadlineSeconds = 0;
    +   *   ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .addAllAckIds(ackIds)
    +   *     .setAckDeadlineSeconds(ackDeadlineSeconds)
    +   *     .build();
    +   *   subscriberApi.modifyAckDeadline(request);
    +   * }
    +   * 
    + * * * * @@ -636,6 +828,23 @@ public void modifyAckDeadline(ModifyAckDeadlineRequest request) { * subscriber, or to make the message available for redelivery if the * processing was interrupted. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   List<String> ackIds = new ArrayList<>();
    +   *   int ackDeadlineSeconds = 0;
    +   *   ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .addAllAckIds(ackIds)
    +   *     .setAckDeadlineSeconds(ackDeadlineSeconds)
    +   *     .build();
    +   *   ListenableFuture<Void> future = subscriberApi.modifyAckDeadlineCallable().futureCall(request);
    +   *   // Do something
    +   *   future.get();
    +   * }
    +   * 
    + * * * */ @@ -655,6 +864,15 @@ public final ApiCallable modifyAckDeadlineCalla * but such a message may be redelivered later. Acknowledging a message more * than once will not result in an error. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   List<String> ackIds = new ArrayList<>();
    +   *   subscriberApi.acknowledge(formattedSubscription, ackIds);
    +   * }
    +   * 
    + * * * * @@ -664,9 +882,10 @@ public final ApiCallable modifyAckDeadlineCalla * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final void acknowledge(String subscription, List ackIds) { + SUBSCRIPTION_PATH_TEMPLATE.validate(subscription); + AcknowledgeRequest request = AcknowledgeRequest.newBuilder().setSubscription(subscription).addAllAckIds(ackIds).build(); - acknowledge(request); } @@ -680,6 +899,19 @@ public final void acknowledge(String subscription, List ackIds) { * but such a message may be redelivered later. Acknowledging a message more * than once will not result in an error. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   List<String> ackIds = new ArrayList<>();
    +   *   AcknowledgeRequest request = AcknowledgeRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .addAllAckIds(ackIds)
    +   *     .build();
    +   *   subscriberApi.acknowledge(request);
    +   * }
    +   * 
    + * * * * @@ -700,6 +932,21 @@ public void acknowledge(AcknowledgeRequest request) { * but such a message may be redelivered later. Acknowledging a message more * than once will not result in an error. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   List<String> ackIds = new ArrayList<>();
    +   *   AcknowledgeRequest request = AcknowledgeRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .addAllAckIds(ackIds)
    +   *     .build();
    +   *   ListenableFuture<Void> future = subscriberApi.acknowledgeCallable().futureCall(request);
    +   *   // Do something
    +   *   future.get();
    +   * }
    +   * 
    + * * * */ @@ -716,6 +963,16 @@ public final ApiCallable acknowledgeCallable() { * there are too many concurrent pull requests pending for the given * subscription. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   boolean returnImmediately = false;
    +   *   int maxMessages = 0;
    +   *   PullResponse response = subscriberApi.pull(formattedSubscription, returnImmediately, maxMessages);
    +   * }
    +   * 
    + * * * * @@ -729,13 +986,14 @@ public final ApiCallable acknowledgeCallable() { * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final PullResponse pull(String subscription, boolean returnImmediately, int maxMessages) { + SUBSCRIPTION_PATH_TEMPLATE.validate(subscription); + PullRequest request = PullRequest.newBuilder() .setSubscription(subscription) .setReturnImmediately(returnImmediately) .setMaxMessages(maxMessages) .build(); - return pull(request); } @@ -746,6 +1004,19 @@ public final PullResponse pull(String subscription, boolean returnImmediately, i * there are too many concurrent pull requests pending for the given * subscription. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   int maxMessages = 0;
    +   *   PullRequest request = PullRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .setMaxMessages(maxMessages)
    +   *     .build();
    +   *   PullResponse response = subscriberApi.pull(request);
    +   * }
    +   * 
    + * * * * @@ -763,6 +1034,21 @@ public PullResponse pull(PullRequest request) { * there are too many concurrent pull requests pending for the given * subscription. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   int maxMessages = 0;
    +   *   PullRequest request = PullRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .setMaxMessages(maxMessages)
    +   *     .build();
    +   *   ListenableFuture<PullResponse> future = subscriberApi.pullCallable().futureCall(request);
    +   *   // Do something
    +   *   PullResponse response = future.get();
    +   * }
    +   * 
    + * * * */ @@ -781,6 +1067,15 @@ public final ApiCallable pullCallable() { * attributes of a push subscription. Messages will accumulate for delivery * continuously through the call regardless of changes to the `PushConfig`. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   PushConfig pushConfig = PushConfig.newBuilder().build();
    +   *   subscriberApi.modifyPushConfig(formattedSubscription, pushConfig);
    +   * }
    +   * 
    + * * * * @@ -794,12 +1089,13 @@ public final ApiCallable pullCallable() { * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final void modifyPushConfig(String subscription, PushConfig pushConfig) { + SUBSCRIPTION_PATH_TEMPLATE.validate(subscription); + ModifyPushConfigRequest request = ModifyPushConfigRequest.newBuilder() .setSubscription(subscription) .setPushConfig(pushConfig) .build(); - modifyPushConfig(request); } @@ -812,6 +1108,19 @@ public final void modifyPushConfig(String subscription, PushConfig pushConfig) { * attributes of a push subscription. Messages will accumulate for delivery * continuously through the call regardless of changes to the `PushConfig`. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   PushConfig pushConfig = PushConfig.newBuilder().build();
    +   *   ModifyPushConfigRequest request = ModifyPushConfigRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .setPushConfig(pushConfig)
    +   *     .build();
    +   *   subscriberApi.modifyPushConfig(request);
    +   * }
    +   * 
    + * * * * @@ -831,6 +1140,21 @@ public void modifyPushConfig(ModifyPushConfigRequest request) { * attributes of a push subscription. Messages will accumulate for delivery * continuously through the call regardless of changes to the `PushConfig`. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   PushConfig pushConfig = PushConfig.newBuilder().build();
    +   *   ModifyPushConfigRequest request = ModifyPushConfigRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .setPushConfig(pushConfig)
    +   *     .build();
    +   *   ListenableFuture<Void> future = subscriberApi.modifyPushConfigCallable().futureCall(request);
    +   *   // Do something
    +   *   future.get();
    +   * }
    +   * 
    + * * * */ diff --git a/gcloud-java-pubsub/pom.xml b/gcloud-java-pubsub/pom.xml index f9b9b6533f78..77902a588260 100644 --- a/gcloud-java-pubsub/pom.xml +++ b/gcloud-java-pubsub/pom.xml @@ -25,7 +25,7 @@ com.google.api gax - 0.0.12 + 0.0.13 com.google.api.grpc diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java index 36d576767efb..7d8eb0f15e79 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/PublisherApi.java @@ -67,8 +67,8 @@ *
      * 
      * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    - *   String name = "";
    - *   Topic callResult = publisherApi.createTopic(name);
    + *   String formattedName = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    + *   Topic response = publisherApi.createTopic(formattedName);
      * }
      * 
      * 
    @@ -277,6 +277,14 @@ public void close() throws IOException { /** * Creates the given topic with the given name. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedName = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   Topic response = publisherApi.createTopic(formattedName);
    +   * }
    +   * 
    + * * * * @@ -289,8 +297,8 @@ public void close() throws IOException { * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final Topic createTopic(String name) { + TOPIC_PATH_TEMPLATE.validate(name); Topic request = Topic.newBuilder().setName(name).build(); - return createTopic(request); } @@ -298,6 +306,17 @@ public final Topic createTopic(String name) { /** * Creates the given topic with the given name. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedName = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   Topic request = Topic.newBuilder()
    +   *     .setName(formattedName)
    +   *     .build();
    +   *   Topic response = publisherApi.createTopic(request);
    +   * }
    +   * 
    + * * * * @@ -312,6 +331,19 @@ private Topic createTopic(Topic request) { /** * Creates the given topic with the given name. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedName = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   Topic request = Topic.newBuilder()
    +   *     .setName(formattedName)
    +   *     .build();
    +   *   ListenableFuture<Topic> future = publisherApi.createTopicCallable().futureCall(request);
    +   *   // Do something
    +   *   Topic response = future.get();
    +   * }
    +   * 
    + * * * */ @@ -327,6 +359,15 @@ public final ApiCallable createTopicCallable() { * does not exist. The message payload must not be empty; it must contain * either a non-empty data field, or at least one attribute. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   List<PubsubMessage> messages = new ArrayList<>();
    +   *   PublishResponse response = publisherApi.publish(formattedTopic, messages);
    +   * }
    +   * 
    + * * * * @@ -335,9 +376,10 @@ public final ApiCallable createTopicCallable() { * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final PublishResponse publish(String topic, List messages) { + TOPIC_PATH_TEMPLATE.validate(topic); + PublishRequest request = PublishRequest.newBuilder().setTopic(topic).addAllMessages(messages).build(); - return publish(request); } @@ -347,6 +389,19 @@ public final PublishResponse publish(String topic, List messages) * does not exist. The message payload must not be empty; it must contain * either a non-empty data field, or at least one attribute. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   List<PubsubMessage> messages = new ArrayList<>();
    +   *   PublishRequest request = PublishRequest.newBuilder()
    +   *     .setTopic(formattedTopic)
    +   *     .addAllMessages(messages)
    +   *     .build();
    +   *   PublishResponse response = publisherApi.publish(request);
    +   * }
    +   * 
    + * * * * @@ -363,6 +418,21 @@ public PublishResponse publish(PublishRequest request) { * does not exist. The message payload must not be empty; it must contain * either a non-empty data field, or at least one attribute. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   List<PubsubMessage> messages = new ArrayList<>();
    +   *   PublishRequest request = PublishRequest.newBuilder()
    +   *     .setTopic(formattedTopic)
    +   *     .addAllMessages(messages)
    +   *     .build();
    +   *   ListenableFuture<PublishResponse> future = publisherApi.publishCallable().futureCall(request);
    +   *   // Do something
    +   *   PublishResponse response = future.get();
    +   * }
    +   * 
    + * * * */ @@ -376,6 +446,14 @@ public final ApiCallable publishCallable() { /** * Gets the configuration of a topic. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   Topic response = publisherApi.getTopic(formattedTopic);
    +   * }
    +   * 
    + * * * * @@ -383,8 +461,8 @@ public final ApiCallable publishCallable() { * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final Topic getTopic(String topic) { + TOPIC_PATH_TEMPLATE.validate(topic); GetTopicRequest request = GetTopicRequest.newBuilder().setTopic(topic).build(); - return getTopic(request); } @@ -392,6 +470,17 @@ public final Topic getTopic(String topic) { /** * Gets the configuration of a topic. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   GetTopicRequest request = GetTopicRequest.newBuilder()
    +   *     .setTopic(formattedTopic)
    +   *     .build();
    +   *   Topic response = publisherApi.getTopic(request);
    +   * }
    +   * 
    + * * * * @@ -406,6 +495,19 @@ private Topic getTopic(GetTopicRequest request) { /** * Gets the configuration of a topic. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   GetTopicRequest request = GetTopicRequest.newBuilder()
    +   *     .setTopic(formattedTopic)
    +   *     .build();
    +   *   ListenableFuture<Topic> future = publisherApi.getTopicCallable().futureCall(request);
    +   *   // Do something
    +   *   Topic response = future.get();
    +   * }
    +   * 
    + * * * */ @@ -419,6 +521,16 @@ public final ApiCallable getTopicCallable() { /** * Lists matching topics. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedProject = PublisherApi.formatProjectName("[PROJECT]");
    +   *   for (Topic elements : publisherApi.listTopics(formattedProject)) {
    +   *     // doThingsWith(elements);
    +   *   }
    +   * }
    +   * 
    + * * * * @@ -426,6 +538,7 @@ public final ApiCallable getTopicCallable() { * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final PageAccessor listTopics(String project) { + PROJECT_PATH_TEMPLATE.validate(project); ListTopicsRequest request = ListTopicsRequest.newBuilder().setProject(project).build(); return listTopics(request); } @@ -434,6 +547,19 @@ public final PageAccessor listTopics(String project) { /** * Lists matching topics. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedProject = PublisherApi.formatProjectName("[PROJECT]");
    +   *   ListTopicsRequest request = ListTopicsRequest.newBuilder()
    +   *     .setProject(formattedProject)
    +   *     .build();
    +   *   for (Topic elements : publisherApi.listTopics(request)) {
    +   *     // doThingsWith(elements);
    +   *   }
    +   * }
    +   * 
    + * * * * @@ -448,6 +574,21 @@ public final PageAccessor listTopics(ListTopicsRequest request) { /** * Lists matching topics. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedProject = PublisherApi.formatProjectName("[PROJECT]");
    +   *   ListTopicsRequest request = ListTopicsRequest.newBuilder()
    +   *     .setProject(formattedProject)
    +   *     .build();
    +   *   ListenableFuture<PageAccessor<Topic>> future = publisherApi.listTopicsPagedCallable().futureCall(request);
    +   *   // Do something
    +   *   for (Topic elements : future.get()) {
    +   *     // doThingsWith(elements);
    +   *   }
    +   * }
    +   * 
    + * * * */ @@ -459,6 +600,28 @@ public final ApiCallable> listTopicsPaged /** * Lists matching topics. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedProject = PublisherApi.formatProjectName("[PROJECT]");
    +   *   ListTopicsRequest request = ListTopicsRequest.newBuilder()
    +   *     .setProject(formattedProject)
    +   *     .build();
    +   *   while (true) {
    +   *     ListTopicsResponse response = publisherApi.listTopicsCallable().call(request);
    +   *     for (Topic elements : response.getTopicsList()) {
    +   *       // doThingsWith(elements);
    +   *     }
    +   *     String nextPageToken = response.getNextPageToken();
    +   *     if (!Strings.isNullOrEmpty(nextPageToken)) {
    +   *       request = request.toBuilder().setPageToken(nextPageToken).build();
    +   *     } else {
    +   *       break;
    +   *     }
    +   *   }
    +   * }
    +   * 
    + * * * */ @@ -472,6 +635,16 @@ public final ApiCallable listTopicsCallab /** * Lists the name of the subscriptions for this topic. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   for (String elements : publisherApi.listTopicSubscriptions(formattedTopic)) {
    +   *     // doThingsWith(elements);
    +   *   }
    +   * }
    +   * 
    + * * * * @@ -479,6 +652,7 @@ public final ApiCallable listTopicsCallab * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final PageAccessor listTopicSubscriptions(String topic) { + TOPIC_PATH_TEMPLATE.validate(topic); ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder().setTopic(topic).build(); return listTopicSubscriptions(request); @@ -488,6 +662,19 @@ public final PageAccessor listTopicSubscriptions(String topic) { /** * Lists the name of the subscriptions for this topic. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder()
    +   *     .setTopic(formattedTopic)
    +   *     .build();
    +   *   for (String elements : publisherApi.listTopicSubscriptions(request)) {
    +   *     // doThingsWith(elements);
    +   *   }
    +   * }
    +   * 
    + * * * * @@ -502,6 +689,21 @@ public final PageAccessor listTopicSubscriptions(ListTopicSubscriptionsR /** * Lists the name of the subscriptions for this topic. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder()
    +   *     .setTopic(formattedTopic)
    +   *     .build();
    +   *   ListenableFuture<PageAccessor<String>> future = publisherApi.listTopicSubscriptionsPagedCallable().futureCall(request);
    +   *   // Do something
    +   *   for (String elements : future.get()) {
    +   *     // doThingsWith(elements);
    +   *   }
    +   * }
    +   * 
    + * * * */ @@ -514,6 +716,28 @@ public final PageAccessor listTopicSubscriptions(ListTopicSubscriptionsR /** * Lists the name of the subscriptions for this topic. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder()
    +   *     .setTopic(formattedTopic)
    +   *     .build();
    +   *   while (true) {
    +   *     ListTopicSubscriptionsResponse response = publisherApi.listTopicSubscriptionsCallable().call(request);
    +   *     for (String elements : response.getSubscriptionsList()) {
    +   *       // doThingsWith(elements);
    +   *     }
    +   *     String nextPageToken = response.getNextPageToken();
    +   *     if (!Strings.isNullOrEmpty(nextPageToken)) {
    +   *       request = request.toBuilder().setPageToken(nextPageToken).build();
    +   *     } else {
    +   *       break;
    +   *     }
    +   *   }
    +   * }
    +   * 
    + * * * */ @@ -532,6 +756,14 @@ public final PageAccessor listTopicSubscriptions(ListTopicSubscriptionsR * configuration or subscriptions. Existing subscriptions to this topic are * not deleted, but their `topic` field is set to `_deleted-topic_`. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   publisherApi.deleteTopic(formattedTopic);
    +   * }
    +   * 
    + * * * * @@ -539,8 +771,8 @@ public final PageAccessor listTopicSubscriptions(ListTopicSubscriptionsR * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final void deleteTopic(String topic) { + TOPIC_PATH_TEMPLATE.validate(topic); DeleteTopicRequest request = DeleteTopicRequest.newBuilder().setTopic(topic).build(); - deleteTopic(request); } @@ -552,6 +784,17 @@ public final void deleteTopic(String topic) { * configuration or subscriptions. Existing subscriptions to this topic are * not deleted, but their `topic` field is set to `_deleted-topic_`. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   DeleteTopicRequest request = DeleteTopicRequest.newBuilder()
    +   *     .setTopic(formattedTopic)
    +   *     .build();
    +   *   publisherApi.deleteTopic(request);
    +   * }
    +   * 
    + * * * * @@ -570,6 +813,19 @@ private void deleteTopic(DeleteTopicRequest request) { * configuration or subscriptions. Existing subscriptions to this topic are * not deleted, but their `topic` field is set to `_deleted-topic_`. * + * Sample code: + *
    
    +   * try (PublisherApi publisherApi = PublisherApi.createWithDefaults()) {
    +   *   String formattedTopic = PublisherApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   DeleteTopicRequest request = DeleteTopicRequest.newBuilder()
    +   *     .setTopic(formattedTopic)
    +   *     .build();
    +   *   ListenableFuture<Void> future = publisherApi.deleteTopicCallable().futureCall(request);
    +   *   // Do something
    +   *   future.get();
    +   * }
    +   * 
    + * * * */ diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java index dd6275bcd9d0..bbb1bf629f8f 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/v1/SubscriberApi.java @@ -68,11 +68,11 @@ *
      * 
      * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    - *   String name = "";
    - *   String topic = "";
    + *   String formattedName = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    + *   String formattedTopic = SubscriberApi.formatTopicName("[PROJECT]", "[TOPIC]");
      *   PushConfig pushConfig = PushConfig.newBuilder().build();
      *   int ackDeadlineSeconds = 0;
    - *   Subscription callResult = subscriberApi.createSubscription(name, topic, pushConfig, ackDeadlineSeconds);
    + *   Subscription response = subscriberApi.createSubscription(formattedName, formattedTopic, pushConfig, ackDeadlineSeconds);
      * }
      * 
      * 
    @@ -321,6 +321,17 @@ public void close() throws IOException { * If the name is not provided in the request, the server will assign a random * name for this subscription on the same project as the topic. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedName = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   String formattedTopic = SubscriberApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   PushConfig pushConfig = PushConfig.newBuilder().build();
    +   *   int ackDeadlineSeconds = 0;
    +   *   Subscription response = subscriberApi.createSubscription(formattedName, formattedTopic, pushConfig, ackDeadlineSeconds);
    +   * }
    +   * 
    + * * * * @@ -356,6 +367,9 @@ public void close() throws IOException { */ public final Subscription createSubscription( String name, String topic, PushConfig pushConfig, int ackDeadlineSeconds) { + SUBSCRIPTION_PATH_TEMPLATE.validate(name); + TOPIC_PATH_TEMPLATE.validate(topic); + Subscription request = Subscription.newBuilder() .setName(name) @@ -363,7 +377,6 @@ public final Subscription createSubscription( .setPushConfig(pushConfig) .setAckDeadlineSeconds(ackDeadlineSeconds) .build(); - return createSubscription(request); } @@ -376,6 +389,19 @@ public final Subscription createSubscription( * If the name is not provided in the request, the server will assign a random * name for this subscription on the same project as the topic. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedName = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   String formattedTopic = SubscriberApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   Subscription request = Subscription.newBuilder()
    +   *     .setName(formattedName)
    +   *     .setTopic(formattedTopic)
    +   *     .build();
    +   *   Subscription response = subscriberApi.createSubscription(request);
    +   * }
    +   * 
    + * * * * @@ -395,6 +421,21 @@ public Subscription createSubscription(Subscription request) { * If the name is not provided in the request, the server will assign a random * name for this subscription on the same project as the topic. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedName = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   String formattedTopic = SubscriberApi.formatTopicName("[PROJECT]", "[TOPIC]");
    +   *   Subscription request = Subscription.newBuilder()
    +   *     .setName(formattedName)
    +   *     .setTopic(formattedTopic)
    +   *     .build();
    +   *   ListenableFuture<Subscription> future = subscriberApi.createSubscriptionCallable().futureCall(request);
    +   *   // Do something
    +   *   Subscription response = future.get();
    +   * }
    +   * 
    + * * * */ @@ -411,6 +452,14 @@ public final ApiCallable createSubscriptionCallable( * If the topic of a subscription has been deleted, the subscription itself is * not deleted, but the value of the `topic` field is set to `_deleted-topic_`. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   Subscription response = subscriberApi.getSubscription(formattedSubscription);
    +   * }
    +   * 
    + * * * * @@ -418,9 +467,9 @@ public final ApiCallable createSubscriptionCallable( * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final Subscription getSubscription(String subscription) { + SUBSCRIPTION_PATH_TEMPLATE.validate(subscription); GetSubscriptionRequest request = GetSubscriptionRequest.newBuilder().setSubscription(subscription).build(); - return getSubscription(request); } @@ -431,6 +480,17 @@ public final Subscription getSubscription(String subscription) { * If the topic of a subscription has been deleted, the subscription itself is * not deleted, but the value of the `topic` field is set to `_deleted-topic_`. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   GetSubscriptionRequest request = GetSubscriptionRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .build();
    +   *   Subscription response = subscriberApi.getSubscription(request);
    +   * }
    +   * 
    + * * * * @@ -448,6 +508,19 @@ private Subscription getSubscription(GetSubscriptionRequest request) { * If the topic of a subscription has been deleted, the subscription itself is * not deleted, but the value of the `topic` field is set to `_deleted-topic_`. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   GetSubscriptionRequest request = GetSubscriptionRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .build();
    +   *   ListenableFuture<Subscription> future = subscriberApi.getSubscriptionCallable().futureCall(request);
    +   *   // Do something
    +   *   Subscription response = future.get();
    +   * }
    +   * 
    + * * * */ @@ -464,6 +537,16 @@ public final ApiCallable getSubscriptionCa * If the topic of a subscription has been deleted, the subscription itself is * not deleted, but the value of the `topic` field is set to `_deleted-topic_`. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedProject = SubscriberApi.formatProjectName("[PROJECT]");
    +   *   for (Subscription elements : subscriberApi.listSubscriptions(formattedProject)) {
    +   *     // doThingsWith(elements);
    +   *   }
    +   * }
    +   * 
    + * * * * @@ -471,6 +554,7 @@ public final ApiCallable getSubscriptionCa * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final PageAccessor listSubscriptions(String project) { + PROJECT_PATH_TEMPLATE.validate(project); ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder().setProject(project).build(); return listSubscriptions(request); @@ -483,6 +567,19 @@ public final PageAccessor listSubscriptions(String project) { * If the topic of a subscription has been deleted, the subscription itself is * not deleted, but the value of the `topic` field is set to `_deleted-topic_`. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedProject = SubscriberApi.formatProjectName("[PROJECT]");
    +   *   ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder()
    +   *     .setProject(formattedProject)
    +   *     .build();
    +   *   for (Subscription elements : subscriberApi.listSubscriptions(request)) {
    +   *     // doThingsWith(elements);
    +   *   }
    +   * }
    +   * 
    + * * * * @@ -500,6 +597,21 @@ public final PageAccessor listSubscriptions(ListSubscriptionsReque * If the topic of a subscription has been deleted, the subscription itself is * not deleted, but the value of the `topic` field is set to `_deleted-topic_`. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedProject = SubscriberApi.formatProjectName("[PROJECT]");
    +   *   ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder()
    +   *     .setProject(formattedProject)
    +   *     .build();
    +   *   ListenableFuture<PageAccessor<Subscription>> future = subscriberApi.listSubscriptionsPagedCallable().futureCall(request);
    +   *   // Do something
    +   *   for (Subscription elements : future.get()) {
    +   *     // doThingsWith(elements);
    +   *   }
    +   * }
    +   * 
    + * * * */ @@ -515,6 +627,28 @@ public final PageAccessor listSubscriptions(ListSubscriptionsReque * If the topic of a subscription has been deleted, the subscription itself is * not deleted, but the value of the `topic` field is set to `_deleted-topic_`. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedProject = SubscriberApi.formatProjectName("[PROJECT]");
    +   *   ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder()
    +   *     .setProject(formattedProject)
    +   *     .build();
    +   *   while (true) {
    +   *     ListSubscriptionsResponse response = subscriberApi.listSubscriptionsCallable().call(request);
    +   *     for (Subscription elements : response.getSubscriptionsList()) {
    +   *       // doThingsWith(elements);
    +   *     }
    +   *     String nextPageToken = response.getNextPageToken();
    +   *     if (!Strings.isNullOrEmpty(nextPageToken)) {
    +   *       request = request.toBuilder().setPageToken(nextPageToken).build();
    +   *     } else {
    +   *       break;
    +   *     }
    +   *   }
    +   * }
    +   * 
    + * * * */ @@ -533,6 +667,14 @@ public final PageAccessor listSubscriptions(ListSubscriptionsReque * the same name, but the new one has no association with the old * subscription, or its topic unless the same topic is specified. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   subscriberApi.deleteSubscription(formattedSubscription);
    +   * }
    +   * 
    + * * * * @@ -540,9 +682,9 @@ public final PageAccessor listSubscriptions(ListSubscriptionsReque * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final void deleteSubscription(String subscription) { + SUBSCRIPTION_PATH_TEMPLATE.validate(subscription); DeleteSubscriptionRequest request = DeleteSubscriptionRequest.newBuilder().setSubscription(subscription).build(); - deleteSubscription(request); } @@ -554,6 +696,17 @@ public final void deleteSubscription(String subscription) { * the same name, but the new one has no association with the old * subscription, or its topic unless the same topic is specified. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   DeleteSubscriptionRequest request = DeleteSubscriptionRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .build();
    +   *   subscriberApi.deleteSubscription(request);
    +   * }
    +   * 
    + * * * * @@ -572,6 +725,19 @@ private void deleteSubscription(DeleteSubscriptionRequest request) { * the same name, but the new one has no association with the old * subscription, or its topic unless the same topic is specified. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   DeleteSubscriptionRequest request = DeleteSubscriptionRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .build();
    +   *   ListenableFuture<Void> future = subscriberApi.deleteSubscriptionCallable().futureCall(request);
    +   *   // Do something
    +   *   future.get();
    +   * }
    +   * 
    + * * * */ @@ -588,6 +754,16 @@ public final ApiCallable deleteSubscriptionCal * subscriber, or to make the message available for redelivery if the * processing was interrupted. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   List<String> ackIds = new ArrayList<>();
    +   *   int ackDeadlineSeconds = 0;
    +   *   subscriberApi.modifyAckDeadline(formattedSubscription, ackIds, ackDeadlineSeconds);
    +   * }
    +   * 
    + * * * * @@ -602,13 +778,14 @@ public final ApiCallable deleteSubscriptionCal */ public final void modifyAckDeadline( String subscription, List ackIds, int ackDeadlineSeconds) { + SUBSCRIPTION_PATH_TEMPLATE.validate(subscription); + ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() .setSubscription(subscription) .addAllAckIds(ackIds) .setAckDeadlineSeconds(ackDeadlineSeconds) .build(); - modifyAckDeadline(request); } @@ -619,6 +796,21 @@ public final void modifyAckDeadline( * subscriber, or to make the message available for redelivery if the * processing was interrupted. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   List<String> ackIds = new ArrayList<>();
    +   *   int ackDeadlineSeconds = 0;
    +   *   ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .addAllAckIds(ackIds)
    +   *     .setAckDeadlineSeconds(ackDeadlineSeconds)
    +   *     .build();
    +   *   subscriberApi.modifyAckDeadline(request);
    +   * }
    +   * 
    + * * * * @@ -636,6 +828,23 @@ public void modifyAckDeadline(ModifyAckDeadlineRequest request) { * subscriber, or to make the message available for redelivery if the * processing was interrupted. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   List<String> ackIds = new ArrayList<>();
    +   *   int ackDeadlineSeconds = 0;
    +   *   ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .addAllAckIds(ackIds)
    +   *     .setAckDeadlineSeconds(ackDeadlineSeconds)
    +   *     .build();
    +   *   ListenableFuture<Void> future = subscriberApi.modifyAckDeadlineCallable().futureCall(request);
    +   *   // Do something
    +   *   future.get();
    +   * }
    +   * 
    + * * * */ @@ -655,6 +864,15 @@ public final ApiCallable modifyAckDeadlineCalla * but such a message may be redelivered later. Acknowledging a message more * than once will not result in an error. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   List<String> ackIds = new ArrayList<>();
    +   *   subscriberApi.acknowledge(formattedSubscription, ackIds);
    +   * }
    +   * 
    + * * * * @@ -664,9 +882,10 @@ public final ApiCallable modifyAckDeadlineCalla * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final void acknowledge(String subscription, List ackIds) { + SUBSCRIPTION_PATH_TEMPLATE.validate(subscription); + AcknowledgeRequest request = AcknowledgeRequest.newBuilder().setSubscription(subscription).addAllAckIds(ackIds).build(); - acknowledge(request); } @@ -680,6 +899,19 @@ public final void acknowledge(String subscription, List ackIds) { * but such a message may be redelivered later. Acknowledging a message more * than once will not result in an error. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   List<String> ackIds = new ArrayList<>();
    +   *   AcknowledgeRequest request = AcknowledgeRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .addAllAckIds(ackIds)
    +   *     .build();
    +   *   subscriberApi.acknowledge(request);
    +   * }
    +   * 
    + * * * * @@ -700,6 +932,21 @@ public void acknowledge(AcknowledgeRequest request) { * but such a message may be redelivered later. Acknowledging a message more * than once will not result in an error. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   List<String> ackIds = new ArrayList<>();
    +   *   AcknowledgeRequest request = AcknowledgeRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .addAllAckIds(ackIds)
    +   *     .build();
    +   *   ListenableFuture<Void> future = subscriberApi.acknowledgeCallable().futureCall(request);
    +   *   // Do something
    +   *   future.get();
    +   * }
    +   * 
    + * * * */ @@ -716,6 +963,16 @@ public final ApiCallable acknowledgeCallable() { * there are too many concurrent pull requests pending for the given * subscription. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   boolean returnImmediately = false;
    +   *   int maxMessages = 0;
    +   *   PullResponse response = subscriberApi.pull(formattedSubscription, returnImmediately, maxMessages);
    +   * }
    +   * 
    + * * * * @@ -729,13 +986,14 @@ public final ApiCallable acknowledgeCallable() { * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final PullResponse pull(String subscription, boolean returnImmediately, int maxMessages) { + SUBSCRIPTION_PATH_TEMPLATE.validate(subscription); + PullRequest request = PullRequest.newBuilder() .setSubscription(subscription) .setReturnImmediately(returnImmediately) .setMaxMessages(maxMessages) .build(); - return pull(request); } @@ -746,6 +1004,19 @@ public final PullResponse pull(String subscription, boolean returnImmediately, i * there are too many concurrent pull requests pending for the given * subscription. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   int maxMessages = 0;
    +   *   PullRequest request = PullRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .setMaxMessages(maxMessages)
    +   *     .build();
    +   *   PullResponse response = subscriberApi.pull(request);
    +   * }
    +   * 
    + * * * * @@ -763,6 +1034,21 @@ public PullResponse pull(PullRequest request) { * there are too many concurrent pull requests pending for the given * subscription. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   int maxMessages = 0;
    +   *   PullRequest request = PullRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .setMaxMessages(maxMessages)
    +   *     .build();
    +   *   ListenableFuture<PullResponse> future = subscriberApi.pullCallable().futureCall(request);
    +   *   // Do something
    +   *   PullResponse response = future.get();
    +   * }
    +   * 
    + * * * */ @@ -781,6 +1067,15 @@ public final ApiCallable pullCallable() { * attributes of a push subscription. Messages will accumulate for delivery * continuously through the call regardless of changes to the `PushConfig`. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   PushConfig pushConfig = PushConfig.newBuilder().build();
    +   *   subscriberApi.modifyPushConfig(formattedSubscription, pushConfig);
    +   * }
    +   * 
    + * * * * @@ -794,12 +1089,13 @@ public final ApiCallable pullCallable() { * @throws com.google.api.gax.grpc.ApiException if the remote call fails */ public final void modifyPushConfig(String subscription, PushConfig pushConfig) { + SUBSCRIPTION_PATH_TEMPLATE.validate(subscription); + ModifyPushConfigRequest request = ModifyPushConfigRequest.newBuilder() .setSubscription(subscription) .setPushConfig(pushConfig) .build(); - modifyPushConfig(request); } @@ -812,6 +1108,19 @@ public final void modifyPushConfig(String subscription, PushConfig pushConfig) { * attributes of a push subscription. Messages will accumulate for delivery * continuously through the call regardless of changes to the `PushConfig`. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   PushConfig pushConfig = PushConfig.newBuilder().build();
    +   *   ModifyPushConfigRequest request = ModifyPushConfigRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .setPushConfig(pushConfig)
    +   *     .build();
    +   *   subscriberApi.modifyPushConfig(request);
    +   * }
    +   * 
    + * * * * @@ -831,6 +1140,21 @@ public void modifyPushConfig(ModifyPushConfigRequest request) { * attributes of a push subscription. Messages will accumulate for delivery * continuously through the call regardless of changes to the `PushConfig`. * + * Sample code: + *
    
    +   * try (SubscriberApi subscriberApi = SubscriberApi.createWithDefaults()) {
    +   *   String formattedSubscription = SubscriberApi.formatSubscriptionName("[PROJECT]", "[SUBSCRIPTION]");
    +   *   PushConfig pushConfig = PushConfig.newBuilder().build();
    +   *   ModifyPushConfigRequest request = ModifyPushConfigRequest.newBuilder()
    +   *     .setSubscription(formattedSubscription)
    +   *     .setPushConfig(pushConfig)
    +   *     .build();
    +   *   ListenableFuture<Void> future = subscriberApi.modifyPushConfigCallable().futureCall(request);
    +   *   // Do something
    +   *   future.get();
    +   * }
    +   * 
    + * * * */ From d5cf72639e67e133bfb9f491a74aa786c009d856 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 18 May 2016 14:59:37 +0200 Subject: [PATCH 352/375] Fix readAllBytes permission error on GAE (#1010) --- .../java/com/google/cloud/storage/spi/DefaultStorageRpc.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/DefaultStorageRpc.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/DefaultStorageRpc.java index 4ef9afc45e4c..1a9589aa40cf 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/DefaultStorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/DefaultStorageRpc.java @@ -355,8 +355,7 @@ public byte[] load(StorageObject from, Map options) { .setIfGenerationMatch(IF_GENERATION_MATCH.getLong(options)) .setIfGenerationNotMatch(IF_GENERATION_NOT_MATCH.getLong(options)); ByteArrayOutputStream out = new ByteArrayOutputStream(); - getRequest.getMediaHttpDownloader().setDirectDownloadEnabled(true); - getRequest.executeMediaAndDownloadTo(out); + getRequest.executeMedia().download(out); return out.toByteArray(); } catch (IOException ex) { throw translate(ex); From 4c0332ec55ba99c39572ef608ea508e55547ccf7 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 20 May 2016 15:30:26 +0200 Subject: [PATCH 353/375] Move Clock out of ServiceOptions, use it in RetryHelper (#954) * Move Clock out of ServiceOptions, use it in RetryHelper * Always pass options.clock() to RetryHelper.runWithRetries --- .../google/cloud/bigquery/BigQueryImpl.java | 34 ++--- .../cloud/bigquery/TableDataWriteChannel.java | 2 +- .../com/google/cloud/compute/ComputeImpl.java | 130 +++++++++--------- .../src/main/java/com/google/cloud/Clock.java | 59 ++++++++ .../java/com/google/cloud/RetryHelper.java | 23 ++-- .../java/com/google/cloud/ServiceOptions.java | 40 ------ .../com/google/cloud/RetryHelperTest.java | 22 ++- .../com/google/cloud/ServiceOptionsTest.java | 1 - .../google/cloud/datastore/DatastoreImpl.java | 12 +- .../java/com/google/cloud/dns/DnsImpl.java | 18 +-- .../com/google/cloud/dns/DnsImplTest.java | 4 +- .../resourcemanager/ResourceManagerImpl.java | 18 +-- .../google/cloud/storage/BlobReadChannel.java | 2 +- .../cloud/storage/BlobWriteChannel.java | 2 +- .../com/google/cloud/storage/CopyWriter.java | 2 +- .../com/google/cloud/storage/StorageImpl.java | 26 ++-- .../google/cloud/storage/StorageImplTest.java | 4 +- 17 files changed, 206 insertions(+), 193 deletions(-) create mode 100644 gcloud-java-core/src/main/java/com/google/cloud/Clock.java diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryImpl.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryImpl.java index 62a72647beff..d8dfcaea445d 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryImpl.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryImpl.java @@ -164,7 +164,7 @@ public Dataset create(DatasetInfo dataset, DatasetOption... options) { public com.google.api.services.bigquery.model.Dataset call() { return bigQueryRpc.create(datasetPb, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER)); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock())); } catch (RetryHelper.RetryHelperException e) { throw BigQueryException.translateAndThrow(e); } @@ -182,7 +182,7 @@ public Table create(TableInfo table, TableOption... options) { public com.google.api.services.bigquery.model.Table call() { return bigQueryRpc.create(tablePb, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER)); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock())); } catch (RetryHelper.RetryHelperException e) { throw BigQueryException.translateAndThrow(e); } @@ -200,7 +200,7 @@ public Job create(JobInfo job, JobOption... options) { public com.google.api.services.bigquery.model.Job call() { return bigQueryRpc.create(jobPb, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER)); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock())); } catch (RetryHelper.RetryHelperException e) { throw BigQueryException.translateAndThrow(e); } @@ -221,7 +221,7 @@ public Dataset getDataset(final DatasetId datasetId, DatasetOption... options) { public com.google.api.services.bigquery.model.Dataset call() { return bigQueryRpc.getDataset(datasetId.dataset(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Dataset.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw BigQueryException.translateAndThrow(e); @@ -244,7 +244,7 @@ private static Page listDatasets(final BigQueryOptions serviceOptions, Iterable> call() { return serviceOptions.rpc().listDatasets(optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); return new PageImpl<>(new DatasetPageFetcher(serviceOptions, cursor, optionsMap), cursor, Iterables.transform(result.y(), @@ -273,7 +273,7 @@ public boolean delete(final DatasetId datasetId, DatasetDeleteOption... options) public Boolean call() { return bigQueryRpc.deleteDataset(datasetId.dataset(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); } catch (RetryHelper.RetryHelperException e) { throw BigQueryException.translateAndThrow(e); } @@ -292,7 +292,7 @@ public boolean delete(final TableId tableId) { public Boolean call() { return bigQueryRpc.deleteTable(tableId.dataset(), tableId.table()); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); } catch (RetryHelper.RetryHelperException e) { throw BigQueryException.translateAndThrow(e); } @@ -310,7 +310,7 @@ public Dataset update(DatasetInfo dataset, DatasetOption... options) { public com.google.api.services.bigquery.model.Dataset call() { return bigQueryRpc.patch(datasetPb, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER)); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock())); } catch (RetryHelper.RetryHelperException e) { throw BigQueryException.translateAndThrow(e); } @@ -328,7 +328,7 @@ public Table update(TableInfo table, TableOption... options) { public com.google.api.services.bigquery.model.Table call() { return bigQueryRpc.patch(tablePb, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER)); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock())); } catch (RetryHelper.RetryHelperException e) { throw BigQueryException.translateAndThrow(e); } @@ -349,7 +349,7 @@ public Table getTable(final TableId tableId, TableOption... options) { public com.google.api.services.bigquery.model.Table call() { return bigQueryRpc.getTable(tableId.dataset(), tableId.table(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Table.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw BigQueryException.translateAndThrow(e); @@ -377,7 +377,7 @@ private static Page
  • listTables(final String datasetId, final BigQueryOpti call() { return serviceOptions.rpc().listTables(datasetId, optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable
    tables = Iterables.transform(result.y(), new Function() { @@ -432,7 +432,7 @@ public BigQueryRpc.Tuple> call() { return serviceOptions.rpc() .listTableData(tableId.dataset(), tableId.table(), optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); return new PageImpl<>(new TableDataPageFetcher(tableId, serviceOptions, cursor, optionsMap), cursor, transformTableData(result.y())); @@ -467,7 +467,7 @@ public Job getJob(final JobId jobId, JobOption... options) { public com.google.api.services.bigquery.model.Job call() { return bigQueryRpc.getJob(jobId.job(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Job.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw BigQueryException.translateAndThrow(e); @@ -489,7 +489,7 @@ private static Page listJobs(final BigQueryOptions serviceOptions, call() { return serviceOptions.rpc().listJobs(optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable jobs = Iterables.transform(result.y(), new Function() { @@ -514,7 +514,7 @@ public boolean cancel(final JobId jobId) { public Boolean call() { return bigQueryRpc.cancel(jobId.job()); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); } catch (RetryHelper.RetryHelperException e) { throw BigQueryException.translateAndThrow(e); } @@ -529,7 +529,7 @@ public QueryResponse query(final QueryRequest request) { public com.google.api.services.bigquery.model.QueryResponse call() { return bigQueryRpc.query(request.setProjectId(options().projectId()).toPb()); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); QueryResponse.Builder builder = QueryResponse.builder(); JobId completeJobId = JobId.fromPb(results.getJobReference()); builder.jobId(completeJobId); @@ -574,7 +574,7 @@ private static QueryResponse getQueryResults(final JobId jobId, public GetQueryResultsResponse call() { return serviceOptions.rpc().getQueryResults(jobId.job(), optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); QueryResponse.Builder builder = QueryResponse.builder(); JobId completeJobId = JobId.fromPb(results.getJobReference()); builder.jobId(completeJobId); diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableDataWriteChannel.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableDataWriteChannel.java index 9319b59cfea3..d56358f86e98 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableDataWriteChannel.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/TableDataWriteChannel.java @@ -47,7 +47,7 @@ protected void flushBuffer(final int length, final boolean last) { public void run() { options().rpc().write(uploadId(), buffer(), 0, position(), length, last); } - }), options().retryParams(), BigQueryImpl.EXCEPTION_HANDLER); + }), options().retryParams(), BigQueryImpl.EXCEPTION_HANDLER, options().clock()); } catch (RetryHelper.RetryHelperException e) { throw BigQueryException.translateAndThrow(e); } diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeImpl.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeImpl.java index c0846749d326..23501f93bcc6 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeImpl.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/ComputeImpl.java @@ -471,7 +471,7 @@ public DiskType getDiskType(final DiskTypeId diskTypeId, DiskTypeOption... optio public com.google.api.services.compute.model.DiskType call() { return computeRpc.getDiskType(diskTypeId.zone(), diskTypeId.type(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : DiskType.fromPb(answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -499,7 +499,7 @@ private static Page listDiskTypes(final String zone, Iterable> call() { return serviceOptions.rpc().listDiskTypes(zone, optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable diskTypes = Iterables.transform( result.y() == null ? ImmutableList.of() @@ -533,7 +533,7 @@ private static Page listDiskTypes(final ComputeOptions serviceOptions, Iterable> call() { return serviceOptions.rpc().listDiskTypes(optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable diskTypes = Iterables.transform(result.y(), new Function() { @@ -559,7 +559,7 @@ public MachineType getMachineType(final MachineTypeId machineType, MachineTypeOp public com.google.api.services.compute.model.MachineType call() { return computeRpc.getMachineType(machineType.zone(), machineType.type(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : MachineType.fromPb(answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -587,7 +587,7 @@ private static Page listMachineTypes(final String zone, Iterable> call() { return serviceOptions.rpc().listMachineTypes(zone, optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable machineTypes = Iterables.transform( result.y() == null ? ImmutableList.of() @@ -622,7 +622,7 @@ private static Page listMachineTypes(final ComputeOptions serviceOp Iterable> call() { return serviceOptions.rpc().listMachineTypes(optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable machineTypes = Iterables.transform(result.y(), new Function() { @@ -650,7 +650,7 @@ public Region getRegion(final String region, RegionOption... options) { public com.google.api.services.compute.model.Region call() { return computeRpc.getRegion(region, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Region.fromPb(answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -673,7 +673,7 @@ private static Page listRegions(final ComputeOptions serviceOptions, Iterable> call() { return serviceOptions.rpc().listRegions(optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable regions = Iterables.transform( result.y() == null ? ImmutableList.of() @@ -701,7 +701,7 @@ public Zone getZone(final String zone, ZoneOption... options) { public com.google.api.services.compute.model.Zone call() { return computeRpc.getZone(zone, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Zone.fromPb(answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -724,7 +724,7 @@ private static Page listZones(final ComputeOptions serviceOptions, Iterable> call() { return serviceOptions.rpc().listZones(optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable zones = Iterables.transform( result.y() == null ? ImmutableList.of() @@ -757,7 +757,7 @@ public License getLicense(LicenseId license, LicenseOption... options) { public com.google.api.services.compute.model.License call() { return computeRpc.getLicense(completeId.project(), completeId.license(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : License.fromPb(answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -787,7 +787,7 @@ public com.google.api.services.compute.model.Operation call() { throw new IllegalArgumentException("Unexpected operation identity type"); } } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -820,7 +820,7 @@ private static Page listGlobalOperations(final ComputeOptions service Iterable> call() { return serviceOptions.rpc().listGlobalOperations(optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable operations = Iterables.transform( result.y() == null ? ImmutableList.of() @@ -848,7 +848,7 @@ private static Page listRegionOperations(final String region, Iterable> call() { return serviceOptions.rpc().listRegionOperations(region, optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable operations = Iterables.transform( result.y() == null ? ImmutableList.of() @@ -876,7 +876,7 @@ private static Page listZoneOperations(final String zone, Iterable> call() { return serviceOptions.rpc().listZoneOperations(zone, optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable operations = Iterables.transform( result.y() == null ? ImmutableList.of() @@ -909,7 +909,7 @@ public Boolean call() { throw new IllegalArgumentException("Unexpected operation identity type"); } } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); } @@ -934,7 +934,7 @@ public com.google.api.services.compute.model.Address call() { throw new IllegalArgumentException("Unexpected address identity type"); } } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Address.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -962,7 +962,7 @@ public com.google.api.services.compute.model.Operation call() { throw new IllegalArgumentException("Unexpected address identity type"); } } - }, options().retryParams(), EXCEPTION_HANDLER)); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock())); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); } @@ -994,7 +994,7 @@ private static Page
    listGlobalAddresses(final ComputeOptions serviceOpt Iterable> call() { return serviceOptions.rpc().listGlobalAddresses(optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable
    operations = Iterables.transform( result.y() == null ? ImmutableList.of() @@ -1022,7 +1022,7 @@ private static Page
    listRegionAddresses(final String region, Iterable> call() { return serviceOptions.rpc().listRegionAddresses(region, optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable
    operations = Iterables.transform( result.y() == null ? ImmutableList.of() @@ -1050,7 +1050,7 @@ private static Page
    listAddresses(final ComputeOptions serviceOptions, Iterable> call() { return serviceOptions.rpc().listAddresses(optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable
    operations = Iterables.transform( result.y() == null ? ImmutableList.of() @@ -1087,7 +1087,7 @@ public com.google.api.services.compute.model.Operation call() { throw new IllegalArgumentException("Unexpected address identity type"); } } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1107,7 +1107,7 @@ public com.google.api.services.compute.model.Operation call() { completeSnapshot.sourceDisk().disk(), completeSnapshot.snapshotId().snapshot(), completeSnapshot.description(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1124,7 +1124,7 @@ public Snapshot getSnapshot(final String snapshot, SnapshotOption... options) { public com.google.api.services.compute.model.Snapshot call() { return computeRpc.getSnapshot(snapshot, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Snapshot.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1147,7 +1147,7 @@ private static Page listSnapshots(final ComputeOptions serviceOptions, Iterable> call() { return serviceOptions.rpc().listSnapshots(optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable snapshots = Iterables.transform( result.y() == null ? ImmutableList.of() @@ -1180,7 +1180,7 @@ public Operation deleteSnapshot(final String snapshot, OperationOption... option public com.google.api.services.compute.model.Operation call() { return computeRpc.deleteSnapshot(snapshot, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1198,7 +1198,7 @@ public Operation create(ImageInfo image, OperationOption... options) { public com.google.api.services.compute.model.Operation call() { return computeRpc.createImage(completeImage.toPb(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1217,7 +1217,7 @@ public com.google.api.services.compute.model.Image call() { return computeRpc.getImage(completeImageId.project(), completeImageId.image(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Image.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1245,7 +1245,7 @@ private static Page listImages(final String project, final ComputeOptions Iterable> call() { return serviceOptions.rpc().listImages(project, optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable images = Iterables.transform( result.y() == null ? ImmutableList.of() @@ -1274,7 +1274,7 @@ public Operation deleteImage(ImageId image, OperationOption... options) { public com.google.api.services.compute.model.Operation call() { return computeRpc.deleteImage(completeId.project(), completeId.image(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1294,7 +1294,7 @@ public com.google.api.services.compute.model.Operation call() { return computeRpc.deprecateImage(completeId.project(), completeId.image(), deprecationStatus.toPb(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1311,7 +1311,7 @@ public Disk getDisk(final DiskId diskId, DiskOption... options) { public com.google.api.services.compute.model.Disk call() { return computeRpc.getDisk(diskId.zone(), diskId.disk(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Disk.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1330,7 +1330,7 @@ public Operation create(final DiskInfo disk, OperationOption... options) { public com.google.api.services.compute.model.Operation call() { return computeRpc.createDisk(disk.diskId().zone(), diskPb, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER)); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock())); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); } @@ -1362,7 +1362,7 @@ private static Page listDisks(final String zone, final ComputeOptions serv Iterable> call() { return serviceOptions.rpc().listDisks(zone, optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable disks = Iterables.transform( result.y() == null ? ImmutableList.of() @@ -1390,7 +1390,7 @@ private static Page listDisks(final ComputeOptions serviceOptions, Iterable> call() { return serviceOptions.rpc().listDisks(optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable disks = Iterables.transform( result.y() == null ? ImmutableList.of() @@ -1412,7 +1412,7 @@ public Operation deleteDisk(final DiskId disk, OperationOption... options) { public com.google.api.services.compute.model.Operation call() { return computeRpc.deleteDisk(disk.zone(), disk.disk(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1429,7 +1429,7 @@ public Operation resize(final DiskId disk, final long sizeGb, OperationOption... public com.google.api.services.compute.model.Operation call() { return computeRpc.resizeDisk(disk.zone(), disk.disk(), sizeGb, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1447,7 +1447,7 @@ public com.google.api.services.compute.model.Operation call() { return computeRpc.createSubnetwork(completeSubnetwork.subnetworkId().region(), completeSubnetwork.toPb(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1465,7 +1465,7 @@ public com.google.api.services.compute.model.Subnetwork call() { return computeRpc.getSubnetwork(subnetworkId.region(), subnetworkId.subnetwork(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Subnetwork.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1498,7 +1498,7 @@ private static Page listSubnetworks(final String region, Iterable> call() { return serviceOptions.rpc().listSubnetworks(region, optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable subnetworks = Iterables.transform( result.y() == null ? ImmutableList.of() @@ -1526,7 +1526,7 @@ private static Page listSubnetworks(final ComputeOptions serviceOpti Iterable> call() { return serviceOptions.rpc().listSubnetworks(optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable subnetworks = Iterables.transform( result.y() == null ? ImmutableList.of() @@ -1549,7 +1549,7 @@ public com.google.api.services.compute.model.Operation call() { return computeRpc.deleteSubnetwork(subnetwork.region(), subnetwork.subnetwork(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1567,7 +1567,7 @@ public Operation create(NetworkInfo network, OperationOption... options) { public com.google.api.services.compute.model.Operation call() { return computeRpc.createNetwork(completeNetwork.toPb(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1584,7 +1584,7 @@ public Network getNetwork(final String network, NetworkOption... options) { public com.google.api.services.compute.model.Network call() { return computeRpc.getNetwork(network, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Network.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1607,7 +1607,7 @@ private static Page listNetworks(final ComputeOptions serviceOptions, Iterable> call() { return serviceOptions.rpc().listNetworks(optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable networks = Iterables.transform( result.y() == null ? ImmutableList.of() @@ -1635,7 +1635,7 @@ public Operation deleteNetwork(final NetworkId network, OperationOption... optio public com.google.api.services.compute.model.Operation call() { return computeRpc.deleteNetwork(network.network(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1659,7 +1659,7 @@ public com.google.api.services.compute.model.Operation call() { return computeRpc.createInstance(completeInstance.instanceId().zone(), completeInstance.toPb(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1676,7 +1676,7 @@ public Instance getInstance(final InstanceId instance, InstanceOption... options public com.google.api.services.compute.model.Instance call() { return computeRpc.getInstance(instance.zone(), instance.instance(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Instance.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1709,7 +1709,7 @@ private static Page listInstances(final String zone, Iterable> call() { return serviceOptions.rpc().listInstances(zone, optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable instances = Iterables.transform( result.y() == null ? ImmutableList.of() @@ -1737,7 +1737,7 @@ private static Page listInstances(final ComputeOptions serviceOptions, Iterable> call() { return serviceOptions.rpc().listInstances(optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable instances = Iterables.transform( result.y() == null ? ImmutableList.of() @@ -1759,7 +1759,7 @@ public Operation deleteInstance(final InstanceId instance, OperationOption... op public com.google.api.services.compute.model.Operation call() { return computeRpc.deleteInstance(instance.zone(), instance.instance(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1778,7 +1778,7 @@ public com.google.api.services.compute.model.Operation call() { return computeRpc.addAccessConfig(instance.zone(), instance.instance(), networkInterface, accessConfig.toPb(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1797,7 +1797,7 @@ public com.google.api.services.compute.model.Operation call() { return computeRpc.attachDisk(instance.zone(), instance.instance(), completeDisk.toPb(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1838,7 +1838,7 @@ public com.google.api.services.compute.model.Operation call() { return computeRpc.deleteAccessConfig(instance.zone(), instance.instance(), networkInterface, accessConfig, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1857,7 +1857,7 @@ public com.google.api.services.compute.model.Operation call() { return computeRpc.detachDisk(instance.zone(), instance.instance(), deviceName, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1873,7 +1873,7 @@ public String call() { return computeRpc.getSerialPortOutput(instance.zone(), instance.instance(), port, optionMap()); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); } @@ -1888,7 +1888,7 @@ public String call() { return computeRpc.getSerialPortOutput(instance.zone(), instance.instance(), null, optionMap()); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); } @@ -1904,7 +1904,7 @@ public Operation reset(final InstanceId instance, OperationOption... options) { public com.google.api.services.compute.model.Operation call() { return computeRpc.reset(instance.zone(), instance.instance(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1923,7 +1923,7 @@ public com.google.api.services.compute.model.Operation call() { return computeRpc.setDiskAutoDelete(instance.zone(), instance.instance(), deviceName, autoDelete, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1943,7 +1943,7 @@ public com.google.api.services.compute.model.Operation call() { return computeRpc.setMachineType(instance.zone(), instance.instance(), machineTypeUrl, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1962,7 +1962,7 @@ public com.google.api.services.compute.model.Operation call() { return computeRpc.setMetadata(instance.zone(), instance.instance(), metadata.toPb(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1981,7 +1981,7 @@ public com.google.api.services.compute.model.Operation call() { return computeRpc.setScheduling(instance.zone(), instance.instance(), schedulingOptions.toPb(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -1999,7 +1999,7 @@ public com.google.api.services.compute.model.Operation call() { return computeRpc.setTags(instance.zone(), instance.instance(), tags.toPb(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -2016,7 +2016,7 @@ public Operation start(final InstanceId instance, OperationOption... options) { public com.google.api.services.compute.model.Operation call() { return computeRpc.start(instance.zone(), instance.instance(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); @@ -2033,7 +2033,7 @@ public Operation stop(final InstanceId instance, OperationOption... options) { public com.google.api.services.compute.model.Operation call() { return computeRpc.stop(instance.zone(), instance.instance(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Operation.fromPb(this, answer); } catch (RetryHelper.RetryHelperException e) { throw ComputeException.translateAndThrow(e); diff --git a/gcloud-java-core/src/main/java/com/google/cloud/Clock.java b/gcloud-java-core/src/main/java/com/google/cloud/Clock.java new file mode 100644 index 000000000000..447200b03bf4 --- /dev/null +++ b/gcloud-java-core/src/main/java/com/google/cloud/Clock.java @@ -0,0 +1,59 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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; + +import java.io.ObjectStreamException; +import java.io.Serializable; + +/** + * A class providing access to the current time in milliseconds. This class is mainly used for + * testing and will be replaced by Java8's {@code java.time.Clock}. + * + *

    Implementations should implement {@code Serializable} wherever possible and must document + * whether or not they do support serialization. + */ +public abstract class Clock { + + private static final Clock DEFAULT_TIME_SOURCE = new DefaultClock(); + + /** + * Returns current time in milliseconds according to this clock. + */ + public abstract long millis(); + + /** + * Returns the default clock. Default clock uses {@link System#currentTimeMillis()} to get time + * in milliseconds. + */ + public static Clock defaultClock() { + return DEFAULT_TIME_SOURCE; + } + + private static class DefaultClock extends Clock implements Serializable { + + private static final long serialVersionUID = -5077300394286703864L; + + @Override + public long millis() { + return System.currentTimeMillis(); + } + + private Object readResolve() throws ObjectStreamException { + return DEFAULT_TIME_SOURCE; + } + } +} diff --git a/gcloud-java-core/src/main/java/com/google/cloud/RetryHelper.java b/gcloud-java-core/src/main/java/com/google/cloud/RetryHelper.java index 48bd5fcf9324..bd59070d4754 100644 --- a/gcloud-java-core/src/main/java/com/google/cloud/RetryHelper.java +++ b/gcloud-java-core/src/main/java/com/google/cloud/RetryHelper.java @@ -21,12 +21,10 @@ import static java.lang.StrictMath.min; import static java.lang.StrictMath.pow; import static java.lang.StrictMath.random; -import static java.util.concurrent.TimeUnit.MILLISECONDS; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects.ToStringHelper; -import com.google.common.base.Stopwatch; import java.io.InterruptedIOException; import java.nio.channels.ClosedByInterruptException; @@ -45,7 +43,7 @@ public class RetryHelper { private static final Logger log = Logger.getLogger(RetryHelper.class.getName()); - private final Stopwatch stopwatch; + private final Clock clock; private final Callable callable; private final RetryParams params; private final ExceptionHandler exceptionHandler; @@ -153,10 +151,10 @@ static Context getContext() { @VisibleForTesting RetryHelper(Callable callable, RetryParams params, ExceptionHandler exceptionHandler, - Stopwatch stopwatch) { + Clock clock) { this.callable = checkNotNull(callable); this.params = checkNotNull(params); - this.stopwatch = checkNotNull(stopwatch); + this.clock = checkNotNull(clock); this.exceptionHandler = checkNotNull(exceptionHandler); exceptionHandler.verifyCaller(callable); } @@ -165,7 +163,7 @@ static Context getContext() { public String toString() { ToStringHelper toStringHelper = MoreObjects.toStringHelper(this); toStringHelper.add("params", params); - toStringHelper.add("stopwatch", stopwatch); + toStringHelper.add("clock", clock); toStringHelper.add("attemptNumber", attemptNumber); toStringHelper.add("callable", callable); toStringHelper.add("exceptionHandler", exceptionHandler); @@ -173,7 +171,7 @@ public String toString() { } private V doRetry() throws RetryHelperException { - stopwatch.start(); + long start = clock.millis(); while (true) { attemptNumber++; Exception exception; @@ -196,7 +194,7 @@ private V doRetry() throws RetryHelperException { } if (attemptNumber >= params.retryMaxAttempts() || attemptNumber >= params.retryMinAttempts() - && stopwatch.elapsed(MILLISECONDS) >= params.totalRetryPeriodMillis()) { + && clock.millis() - start >= params.totalRetryPeriodMillis()) { throw new RetriesExhaustedException(this + ": Too many failures, giving up", exception); } long sleepDurationMillis = getSleepDuration(params, attemptNumber); @@ -234,13 +232,12 @@ public static V runWithRetries(Callable callable) throws RetryHelperExcep public static V runWithRetries(Callable callable, RetryParams params, ExceptionHandler exceptionHandler) throws RetryHelperException { - return runWithRetries(callable, params, exceptionHandler, Stopwatch.createUnstarted()); + return runWithRetries(callable, params, exceptionHandler, Clock.defaultClock()); } - @VisibleForTesting - static V runWithRetries(Callable callable, RetryParams params, - ExceptionHandler exceptionHandler, Stopwatch stopwatch) throws RetryHelperException { - RetryHelper retryHelper = new RetryHelper<>(callable, params, exceptionHandler, stopwatch); + public static V runWithRetries(Callable callable, RetryParams params, + ExceptionHandler exceptionHandler, Clock clock) throws RetryHelperException { + RetryHelper retryHelper = new RetryHelper<>(callable, params, exceptionHandler, clock); Context previousContext = getContext(); setContext(new Context(retryHelper)); try { diff --git a/gcloud-java-core/src/main/java/com/google/cloud/ServiceOptions.java b/gcloud-java-core/src/main/java/com/google/cloud/ServiceOptions.java index 194f61b45c42..d2f648b01fe5 100644 --- a/gcloud-java-core/src/main/java/com/google/cloud/ServiceOptions.java +++ b/gcloud-java-core/src/main/java/com/google/cloud/ServiceOptions.java @@ -43,7 +43,6 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.ObjectInputStream; -import java.io.ObjectStreamException; import java.io.Serializable; import java.lang.reflect.Method; import java.net.HttpURLConnection; @@ -125,45 +124,6 @@ public HttpTransport create() { } } - /** - * A class providing access to the current time in milliseconds. This class is mainly used for - * testing and will be replaced by Java8's {@code java.time.Clock}. - * - *

    Implementations should implement {@code Serializable} wherever possible and must document - * whether or not they do support serialization. - */ - public abstract static class Clock { - - private static final ServiceOptions.Clock DEFAULT_TIME_SOURCE = new DefaultClock(); - - /** - * Returns current time in milliseconds according to this clock. - */ - public abstract long millis(); - - /** - * Returns the default clock. Default clock uses {@link System#currentTimeMillis()} to get time - * in milliseconds. - */ - public static ServiceOptions.Clock defaultClock() { - return DEFAULT_TIME_SOURCE; - } - - private static class DefaultClock extends ServiceOptions.Clock implements Serializable { - - private static final long serialVersionUID = -5077300394286703864L; - - @Override - public long millis() { - return System.currentTimeMillis(); - } - - private Object readResolve() throws ObjectStreamException { - return DEFAULT_TIME_SOURCE; - } - } - } - /** * Builder for {@code ServiceOptions}. * diff --git a/gcloud-java-core/src/test/java/com/google/cloud/RetryHelperTest.java b/gcloud-java-core/src/test/java/com/google/cloud/RetryHelperTest.java index 3887cecd6a83..fcb404a4624f 100644 --- a/gcloud-java-core/src/test/java/com/google/cloud/RetryHelperTest.java +++ b/gcloud-java-core/src/test/java/com/google/cloud/RetryHelperTest.java @@ -24,8 +24,6 @@ import com.google.cloud.RetryHelper.NonRetriableException; import com.google.cloud.RetryHelper.RetriesExhaustedException; -import com.google.common.base.Stopwatch; -import com.google.common.base.Ticker; import org.junit.Test; @@ -157,24 +155,24 @@ public void testTriesNoMoreThanMaxTimes() { } } - private static class FakeTicker extends Ticker { - private final AtomicLong nanos = new AtomicLong(); + private static class FakeClock extends Clock { - // Advances the ticker value by {@code time} in {@code timeUnit}. + private final AtomicLong millis = new AtomicLong(); + + // Advances the clock value by {@code time} in {@code timeUnit}. void advance(long time, TimeUnit timeUnit) { - nanos.addAndGet(timeUnit.toNanos(time)); + millis.addAndGet(timeUnit.toMillis(time)); } @Override - public long read() { - return nanos.get(); + public long millis() { + return millis.get(); } } @Test public void testTriesNoMoreLongerThanTotalRetryPeriod() { - final FakeTicker ticker = new FakeTicker(); - Stopwatch stopwatch = Stopwatch.createUnstarted(ticker); + final FakeClock fakeClock = new FakeClock(); // The 8th attempt (after min and before max) will trigger a 1 second (virtual) delay exceeding // total retry period which is set just under 1 second. Test occurs faster than realtime. RetryParams params = RetryParams.builder().initialRetryDelayMillis(0) @@ -190,11 +188,11 @@ public void testTriesNoMoreLongerThanTotalRetryPeriod() { @Override public void run() { timesCalled.incrementAndGet(); if (timesCalled.get() == sleepOnAttempt) { - ticker.advance(1000, TimeUnit.MILLISECONDS); + fakeClock.advance(1000, TimeUnit.MILLISECONDS); } throw new RuntimeException(); } - }), params, handler, stopwatch); + }), params, handler, fakeClock); fail(); } catch (RetriesExhaustedException expected) { // verify timesCalled diff --git a/gcloud-java-core/src/test/java/com/google/cloud/ServiceOptionsTest.java b/gcloud-java-core/src/test/java/com/google/cloud/ServiceOptionsTest.java index b6f7a5453ddc..bcbecbe3c6cb 100644 --- a/gcloud-java-core/src/test/java/com/google/cloud/ServiceOptionsTest.java +++ b/gcloud-java-core/src/test/java/com/google/cloud/ServiceOptionsTest.java @@ -22,7 +22,6 @@ import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import com.google.cloud.ServiceOptions.Clock; import com.google.cloud.ServiceOptions.DefaultHttpTransportFactory; import com.google.cloud.ServiceOptions.HttpTransportFactory; import com.google.cloud.spi.ServiceRpcFactory; diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java index 2aa0638bfa7c..07ca76d2118f 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java @@ -91,7 +91,7 @@ com.google.datastore.v1beta3.RunQueryResponse runQuery( throws DatastoreException { return datastoreRpc.runQuery(requestPb); } - }, retryParams, EXCEPTION_HANDLER); + }, retryParams, EXCEPTION_HANDLER, options().clock()); } catch (RetryHelperException e) { throw DatastoreException.translateAndThrow(e); } @@ -129,7 +129,7 @@ com.google.datastore.v1beta3.AllocateIdsResponse allocateIds( throws DatastoreException { return datastoreRpc.allocateIds(requestPb); } - }, retryParams, EXCEPTION_HANDLER); + }, retryParams, EXCEPTION_HANDLER, options().clock()); } catch (RetryHelperException e) { throw DatastoreException.translateAndThrow(e); } @@ -285,7 +285,7 @@ com.google.datastore.v1beta3.LookupResponse lookup( throws DatastoreException { return datastoreRpc.lookup(requestPb); } - }, retryParams, EXCEPTION_HANDLER); + }, retryParams, EXCEPTION_HANDLER, options().clock()); } catch (RetryHelperException e) { throw DatastoreException.translateAndThrow(e); } @@ -365,7 +365,7 @@ public com.google.datastore.v1beta3.CommitResponse call() throws DatastoreExcept } }, retryParams, - EXCEPTION_HANDLER); + EXCEPTION_HANDLER, options().clock()); } catch (RetryHelperException e) { throw DatastoreException.translateAndThrow(e); } @@ -388,7 +388,7 @@ public com.google.datastore.v1beta3.BeginTransactionResponse call() } }, retryParams, - EXCEPTION_HANDLER); + EXCEPTION_HANDLER, options().clock()); } catch (RetryHelperException e) { throw DatastoreException.translateAndThrow(e); } @@ -408,7 +408,7 @@ void rollback(final com.google.datastore.v1beta3.RollbackRequest requestPb) { datastoreRpc.rollback(requestPb); return null; } - }, retryParams, EXCEPTION_HANDLER); + }, retryParams, EXCEPTION_HANDLER, options().clock()); } catch (RetryHelperException e) { throw DatastoreException.translateAndThrow(e); } diff --git a/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsImpl.java b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsImpl.java index be0e8621cf41..1bf2a0c1d8cb 100644 --- a/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsImpl.java +++ b/gcloud-java-dns/src/main/java/com/google/cloud/dns/DnsImpl.java @@ -135,7 +135,7 @@ private static Page listZones(final DnsOptions serviceOptions, public DnsRpc.ListResult call() { return rpc.listZones(optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.pageToken(); // transform that list into zone objects Iterable zones = result.results() == null ? ImmutableList.of() @@ -163,7 +163,7 @@ private static Page listChangeRequests(final String zoneName, public DnsRpc.ListResult call() { return rpc.listChangeRequests(zoneName, optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.pageToken(); // transform that list into change request objects Iterable changes = result.results() == null @@ -193,7 +193,7 @@ private static Page listRecordSets(final String zoneName, public DnsRpc.ListResult call() { return rpc.listRecordSets(zoneName, optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.pageToken(); // transform that list into record sets Iterable recordSets = result.results() == null @@ -216,7 +216,7 @@ public Zone create(final ZoneInfo zoneInfo, Dns.ZoneOption... options) { public ManagedZone call() { return dnsRpc.create(zoneInfo.toPb(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Zone.fromPb(this, answer); } catch (RetryHelper.RetryHelperException ex) { throw DnsException.translateAndThrow(ex); @@ -233,7 +233,7 @@ public Zone getZone(final String zoneName, Dns.ZoneOption... options) { public ManagedZone call() { return dnsRpc.getZone(zoneName, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Zone.fromPb(this, answer); } catch (RetryHelper.RetryHelperException ex) { throw DnsException.translateAndThrow(ex); @@ -248,7 +248,7 @@ public boolean delete(final String zoneName) { public Boolean call() { return dnsRpc.deleteZone(zoneName); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); } catch (RetryHelper.RetryHelperException ex) { throw DnsException.translateAndThrow(ex); } @@ -264,7 +264,7 @@ public ProjectInfo getProject(Dns.ProjectOption... fields) { public Project call() { return dnsRpc.getProject(optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : ProjectInfo.fromPb(answer); // should never be null } catch (RetryHelper.RetryHelperException ex) { throw DnsException.translateAndThrow(ex); @@ -282,7 +282,7 @@ public ChangeRequest applyChangeRequest(final String zoneName, public Change call() { return dnsRpc.applyChangeRequest(zoneName, changeRequest.toPb(), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : ChangeRequest.fromPb(this, zoneName, answer); // not null } catch (RetryHelper.RetryHelperException ex) { throw DnsException.translateAndThrow(ex); @@ -300,7 +300,7 @@ public ChangeRequest getChangeRequest(final String zoneName, final String change public Change call() { return dnsRpc.getChangeRequest(zoneName, changeRequestId, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : ChangeRequest.fromPb(this, zoneName, answer); } catch (RetryHelper.RetryHelperException ex) { throw DnsException.translateAndThrow(ex); diff --git a/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsImplTest.java b/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsImplTest.java index d34cb340e6e3..deefe21f36aa 100644 --- a/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsImplTest.java +++ b/gcloud-java-dns/src/test/java/com/google/cloud/dns/DnsImplTest.java @@ -22,9 +22,9 @@ import com.google.api.services.dns.model.Change; import com.google.api.services.dns.model.ManagedZone; import com.google.api.services.dns.model.ResourceRecordSet; +import com.google.cloud.Clock; import com.google.cloud.Page; import com.google.cloud.RetryParams; -import com.google.cloud.ServiceOptions; import com.google.cloud.dns.spi.DnsRpc; import com.google.cloud.dns.spi.DnsRpcFactory; import com.google.common.collect.ImmutableList; @@ -100,7 +100,7 @@ public class DnsImplTest { // Other private static final Map EMPTY_RPC_OPTIONS = ImmutableMap.of(); - private static final ServiceOptions.Clock TIME_SOURCE = new ServiceOptions.Clock() { + private static final Clock TIME_SOURCE = new Clock() { @Override public long millis() { return 42000L; diff --git a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerImpl.java b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerImpl.java index 4054a4b2443a..81bcb563cd93 100644 --- a/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerImpl.java +++ b/gcloud-java-resourcemanager/src/main/java/com/google/cloud/resourcemanager/ResourceManagerImpl.java @@ -55,7 +55,7 @@ public Project create(final ProjectInfo project) { public com.google.api.services.cloudresourcemanager.model.Project call() { return resourceManagerRpc.create(project.toPb()); } - }, options().retryParams(), EXCEPTION_HANDLER)); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock())); } catch (RetryHelperException ex) { throw ResourceManagerException.translateAndThrow(ex); } @@ -70,7 +70,7 @@ public Void call() { resourceManagerRpc.delete(projectId); return null; } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); } catch (RetryHelperException ex) { throw ResourceManagerException.translateAndThrow(ex); } @@ -86,7 +86,7 @@ public Project get(final String projectId, ProjectGetOption... options) { public com.google.api.services.cloudresourcemanager.model.Project call() { return resourceManagerRpc.get(projectId, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Project.fromPb(this, answer); } catch (RetryHelperException ex) { throw ResourceManagerException.translateAndThrow(ex); @@ -129,7 +129,7 @@ Iterable> call() { return serviceOptions.rpc().list(optionsMap); } }, - serviceOptions.retryParams(), EXCEPTION_HANDLER); + serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable projects = result.y() == null @@ -161,7 +161,7 @@ public Project replace(final ProjectInfo newProject) { public com.google.api.services.cloudresourcemanager.model.Project call() { return resourceManagerRpc.replace(newProject.toPb()); } - }, options().retryParams(), EXCEPTION_HANDLER)); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock())); } catch (RetryHelperException ex) { throw ResourceManagerException.translateAndThrow(ex); } @@ -176,7 +176,7 @@ public Void call() { resourceManagerRpc.undelete(projectId); return null; } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); } catch (RetryHelperException ex) { throw ResourceManagerException.translateAndThrow(ex); } @@ -192,7 +192,7 @@ public Policy getPolicy(final String projectId) { public com.google.api.services.cloudresourcemanager.model.Policy call() { return resourceManagerRpc.getPolicy(projectId); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Policy.fromPb(answer); } catch (RetryHelperException ex) { throw ResourceManagerException.translateAndThrow(ex); @@ -208,7 +208,7 @@ public Policy replacePolicy(final String projectId, final Policy newPolicy) { public com.google.api.services.cloudresourcemanager.model.Policy call() { return resourceManagerRpc.replacePolicy(projectId, newPolicy.toPb()); } - }, options().retryParams(), EXCEPTION_HANDLER)); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock())); } catch (RetryHelperException ex) { throw ResourceManagerException.translateAndThrow(ex); } @@ -223,7 +223,7 @@ public List testPermissions(final String projectId, final List public List call() { return resourceManagerRpc.testPermissions(projectId, permissions); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); } catch (RetryHelperException ex) { throw ResourceManagerException.translateAndThrow(ex); } diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobReadChannel.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobReadChannel.java index 49ceb99a5792..0352e8a9d550 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobReadChannel.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobReadChannel.java @@ -126,7 +126,7 @@ public int read(ByteBuffer byteBuffer) throws IOException { public Tuple call() { return storageRpc.read(storageObject, requestOptions, position, toRead); } - }, serviceOptions.retryParams(), StorageImpl.EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), StorageImpl.EXCEPTION_HANDLER, serviceOptions.clock()); if (result.y().length > 0 && lastEtag != null && !Objects.equals(result.x(), lastEtag)) { StringBuilder messageBuilder = new StringBuilder(); messageBuilder.append("Blob ").append(blob).append(" was updated while reading"); diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobWriteChannel.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobWriteChannel.java index 0076b3cbaac4..9765b8fa1bb7 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobWriteChannel.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobWriteChannel.java @@ -48,7 +48,7 @@ protected void flushBuffer(final int length, final boolean last) { public void run() { options().rpc().write(uploadId(), buffer(), 0, position(), length, last); } - }), options().retryParams(), StorageImpl.EXCEPTION_HANDLER); + }), options().retryParams(), StorageImpl.EXCEPTION_HANDLER, options().clock()); } catch (RetryHelper.RetryHelperException e) { throw StorageException.translateAndThrow(e); } diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/CopyWriter.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/CopyWriter.java index 9e674052f877..2cf309d7c5ca 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/CopyWriter.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/CopyWriter.java @@ -113,7 +113,7 @@ public void copyChunk() { public RewriteResponse call() { return storageRpc.continueRewrite(rewriteResponse); } - }, serviceOptions.retryParams(), StorageImpl.EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), StorageImpl.EXCEPTION_HANDLER, serviceOptions.clock()); } catch (RetryHelper.RetryHelperException e) { throw StorageException.translateAndThrow(e); } diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageImpl.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageImpl.java index 8a33f2bc4203..50a1076fc84a 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageImpl.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageImpl.java @@ -100,7 +100,7 @@ public Bucket create(BucketInfo bucketInfo, BucketTargetOption... options) { public com.google.api.services.storage.model.Bucket call() { return storageRpc.create(bucketPb, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER)); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock())); } catch (RetryHelperException e) { throw StorageException.translateAndThrow(e); } @@ -142,7 +142,7 @@ public StorageObject call() { return storageRpc.create(blobPb, firstNonNull(content, new ByteArrayInputStream(EMPTY_BYTE_ARRAY)), optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER)); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock())); } catch (RetryHelperException e) { throw StorageException.translateAndThrow(e); } @@ -159,7 +159,7 @@ public Bucket get(String bucket, BucketGetOption... options) { public com.google.api.services.storage.model.Bucket call() { return storageRpc.get(bucketPb, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return answer == null ? null : Bucket.fromPb(this, answer); } catch (RetryHelperException e) { throw StorageException.translateAndThrow(e); @@ -181,7 +181,7 @@ public Blob get(BlobId blob, BlobGetOption... options) { public StorageObject call() { return storageRpc.get(storedObject, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return storageObject == null ? null : Blob.fromPb(this, storageObject); } catch (RetryHelperException e) { throw StorageException.translateAndThrow(e); @@ -253,7 +253,7 @@ private static Page listBuckets(final StorageOptions serviceOptions, public Tuple> call() { return serviceOptions.rpc().list(optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable buckets = result.y() == null ? ImmutableList.of() : Iterables.transform(result.y(), @@ -280,7 +280,7 @@ private static Page listBlobs(final String bucket, public Tuple> call() { return serviceOptions.rpc().list(bucket, optionsMap); } - }, serviceOptions.retryParams(), EXCEPTION_HANDLER); + }, serviceOptions.retryParams(), EXCEPTION_HANDLER, serviceOptions.clock()); String cursor = result.x(); Iterable blobs = result.y() == null @@ -311,7 +311,7 @@ public Bucket update(BucketInfo bucketInfo, BucketTargetOption... options) { public com.google.api.services.storage.model.Bucket call() { return storageRpc.patch(bucketPb, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER)); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock())); } catch (RetryHelperException e) { throw StorageException.translateAndThrow(e); } @@ -327,7 +327,7 @@ public Blob update(BlobInfo blobInfo, BlobTargetOption... options) { public StorageObject call() { return storageRpc.patch(storageObject, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER)); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock())); } catch (RetryHelperException e) { throw StorageException.translateAndThrow(e); } @@ -348,7 +348,7 @@ public boolean delete(String bucket, BucketSourceOption... options) { public Boolean call() { return storageRpc.delete(bucketPb, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); } catch (RetryHelperException e) { throw StorageException.translateAndThrow(e); } @@ -369,7 +369,7 @@ public boolean delete(BlobId blob, BlobSourceOption... options) { public Boolean call() { return storageRpc.delete(storageObject, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); } catch (RetryHelperException e) { throw StorageException.translateAndThrow(e); } @@ -398,7 +398,7 @@ public Blob compose(final ComposeRequest composeRequest) { public StorageObject call() { return storageRpc.compose(sources, target, targetOptions); } - }, options().retryParams(), EXCEPTION_HANDLER)); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock())); } catch (RetryHelperException e) { throw StorageException.translateAndThrow(e); } @@ -420,7 +420,7 @@ public RewriteResponse call() { copyRequest.overrideInfo(), targetObject, targetOptions, copyRequest.megabytesCopiedPerChunk())); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); return new CopyWriter(options(), rewriteResponse); } catch (RetryHelperException e) { throw StorageException.translateAndThrow(e); @@ -442,7 +442,7 @@ public byte[] readAllBytes(BlobId blob, BlobSourceOption... options) { public byte[] call() { return storageRpc.load(storageObject, optionsMap); } - }, options().retryParams(), EXCEPTION_HANDLER); + }, options().retryParams(), EXCEPTION_HANDLER, options().clock()); } catch (RetryHelperException e) { throw StorageException.translateAndThrow(e); } diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java index 9df971721906..b6188df3b3c5 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java @@ -26,10 +26,10 @@ import com.google.api.services.storage.model.StorageObject; import com.google.cloud.AuthCredentials.ServiceAccountAuthCredentials; +import com.google.cloud.Clock; import com.google.cloud.Page; import com.google.cloud.ReadChannel; import com.google.cloud.RetryParams; -import com.google.cloud.ServiceOptions; import com.google.cloud.WriteChannel; import com.google.cloud.storage.Storage.CopyRequest; import com.google.cloud.storage.spi.StorageRpc; @@ -225,7 +225,7 @@ public class StorageImplTest { + "EkPPhszldvQTY486uPxyD/D7HdfnGW/Nbw5JUhfvecAdudDEhNAQ3PNabyDMI+TpiHy4NTWOrgdcWrzj6VXcdc" + "+uuABnPwRCdcyJ1xl2kOrPksRnp1auNGMLOe4IpEBjGY7baX9UG8+A45MbG0aHmkR59Op/aR9XowIDAQAB"; - private static final ServiceOptions.Clock TIME_SOURCE = new ServiceOptions.Clock() { + private static final Clock TIME_SOURCE = new Clock() { @Override public long millis() { return 42000L; From e921bbe3a44c90039574245f4a4dce5c4fdbd669 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 20 May 2016 20:25:54 +0200 Subject: [PATCH 354/375] Refactor storage batches to use StorageBatchRequest and BatchResult (#952) * Refactor storage batches to use StorageBatchRequest and BatchResult * Limit batch size (storage performs better if the batches are split) --- .../google/cloud/storage/BatchRequest.java | 131 ------- .../google/cloud/storage/BatchResponse.java | 162 --------- .../java/com/google/cloud/storage/Bucket.java | 38 ++- .../com/google/cloud/storage/Storage.java | 60 +++- .../google/cloud/storage/StorageBatch.java | 207 ++++++++++++ .../cloud/storage/StorageBatchResult.java | 39 +++ .../com/google/cloud/storage/StorageImpl.java | 154 ++++----- .../cloud/storage/spi/DefaultStorageRpc.java | 255 +++++++------- .../google/cloud/storage/spi/RpcBatch.java | 70 ++++ .../google/cloud/storage/spi/StorageRpc.java | 44 +-- .../cloud/storage/BatchRequestTest.java | 142 -------- .../cloud/storage/BatchResponseTest.java | 84 ----- .../com/google/cloud/storage/BucketTest.java | 57 ++-- .../cloud/storage/SerializationTest.java | 12 +- .../cloud/storage/StorageBatchResultTest.java | 109 ++++++ .../cloud/storage/StorageBatchTest.java | 224 ++++++++++++ .../google/cloud/storage/StorageImplTest.java | 319 ++++++++---------- .../cloud/storage/it/ITStorageTest.java | 175 +++++----- 18 files changed, 1192 insertions(+), 1090 deletions(-) delete mode 100644 gcloud-java-storage/src/main/java/com/google/cloud/storage/BatchRequest.java delete mode 100644 gcloud-java-storage/src/main/java/com/google/cloud/storage/BatchResponse.java create mode 100644 gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageBatch.java create mode 100644 gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageBatchResult.java create mode 100644 gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/RpcBatch.java delete mode 100644 gcloud-java-storage/src/test/java/com/google/cloud/storage/BatchRequestTest.java delete mode 100644 gcloud-java-storage/src/test/java/com/google/cloud/storage/BatchResponseTest.java create mode 100644 gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageBatchResultTest.java create mode 100644 gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageBatchTest.java diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BatchRequest.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BatchRequest.java deleted file mode 100644 index 05dfe8e2a1dc..000000000000 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BatchRequest.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * 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 com.google.cloud.storage.Storage.BlobGetOption; -import com.google.cloud.storage.Storage.BlobSourceOption; -import com.google.cloud.storage.Storage.BlobTargetOption; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; - -import java.io.Serializable; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Objects; - -/** - * Google storage batch request. - */ -public final class BatchRequest implements Serializable { - - private static final long serialVersionUID = -1527992265939800345L; - - private final Map> toDelete; - private final Map> toUpdate; - private final Map> toGet; - - public static class Builder { - - private Map> toDelete = new LinkedHashMap<>(); - private Map> toUpdate = new LinkedHashMap<>(); - private Map> toGet = new LinkedHashMap<>(); - - private Builder() {} - - /** - * Delete the given blob. - */ - public Builder delete(String bucket, String blob, BlobSourceOption... options) { - toDelete.put(BlobId.of(bucket, blob), Lists.newArrayList(options)); - return this; - } - - /** - * Delete the given blob. - */ - public Builder delete(BlobId blob, BlobSourceOption... options) { - toDelete.put(blob, Lists.newArrayList(options)); - return this; - } - - /** - * Update the given blob. - */ - public Builder update(BlobInfo blobInfo, BlobTargetOption... options) { - toUpdate.put(blobInfo, Lists.newArrayList(options)); - return this; - } - - /** - * Retrieve metadata for the given blob. - */ - public Builder get(String bucket, String blob, BlobGetOption... options) { - toGet.put(BlobId.of(bucket, blob), Lists.newArrayList(options)); - return this; - } - - /** - * Retrieve metadata for the given blob. - */ - public Builder get(BlobId blob, BlobGetOption... options) { - toGet.put(blob, Lists.newArrayList(options)); - return this; - } - - public BatchRequest build() { - return new BatchRequest(this); - } - } - - private BatchRequest(Builder builder) { - toDelete = ImmutableMap.copyOf(builder.toDelete); - toUpdate = ImmutableMap.copyOf(builder.toUpdate); - toGet = ImmutableMap.copyOf(builder.toGet); - } - - @Override - public int hashCode() { - return Objects.hash(toDelete, toUpdate, toGet); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof BatchRequest)) { - return false; - } - BatchRequest other = (BatchRequest) obj; - return Objects.equals(toDelete, other.toDelete) - && Objects.equals(toUpdate, other.toUpdate) - && Objects.equals(toGet, other.toGet); - } - - public Map> toDelete() { - return toDelete; - } - - public Map> toUpdate() { - return toUpdate; - } - - public Map> toGet() { - return toGet; - } - - public static Builder builder() { - return new Builder(); - } -} diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BatchResponse.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BatchResponse.java deleted file mode 100644 index d1e56758b9d2..000000000000 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BatchResponse.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * 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 com.google.common.base.MoreObjects; -import com.google.common.collect.ImmutableList; - -import java.io.Serializable; -import java.util.List; -import java.util.Objects; - -/** - * Google Storage batch response. - */ -public class BatchResponse implements Serializable { - - private static final long serialVersionUID = 1057416839397037706L; - - private final List> deleteResult; - private final List> updateResult; - private final List> getResult; - - public static class Result implements Serializable { - - private static final long serialVersionUID = -1946539570170529094L; - private static final Result EMPTY = Result.of(null); - - private final T value; - private final StorageException exception; - - - public Result(T value) { - this.value = value; - this.exception = null; - } - - public Result(StorageException exception) { - this.exception = exception; - this.value = null; - } - - static Result of(T value) { - return new Result<>(value); - } - - /** - * Returns the result. - * - * @throws StorageException if failed - */ - public T get() throws StorageException { - if (failed()) { - throw failure(); - } - return value; - } - - /** - * Returns the failure or {@code null} if was successful. - */ - public StorageException failure() { - return exception; - } - - /** - * Returns {@code true} if failed, {@code false} otherwise. - */ - public boolean failed() { - return exception != null; - } - - @Override - public int hashCode() { - return Objects.hash(value, exception); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof Result)) { - return false; - } - Result other = (Result) obj; - return Objects.equals(value, other.value) - && Objects.equals(exception, other.exception); - } - - @Override - public String toString() { - return MoreObjects.toStringHelper(this) - .add("value", value) - .add("exception", exception) - .toString(); - } - - static Result empty() { - @SuppressWarnings("unchecked") - Result result = (Result) EMPTY; - return result; - } - } - - BatchResponse(List> deleteResult, List> updateResult, - List> getResult) { - this.deleteResult = ImmutableList.copyOf(deleteResult); - this.updateResult = ImmutableList.copyOf(updateResult); - this.getResult = ImmutableList.copyOf(getResult); - } - - @Override - public final int hashCode() { - return Objects.hash(deleteResult, updateResult, getResult); - } - - @Override - public final boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (obj == null || !obj.getClass().equals(BatchResponse.class)) { - return false; - } - BatchResponse other = (BatchResponse) obj; - return Objects.equals(deleteResult, other.deleteResult) - && Objects.equals(updateResult, other.updateResult) - && Objects.equals(getResult, other.getResult); - } - - /** - * Returns the results for the delete operations using the request order. - */ - public List> deletes() { - return deleteResult; - } - - /** - * Returns the results for the update operations using the request order. - */ - public List> updates() { - return updateResult; - } - - /** - * Returns the results for the get operations using the request order. - */ - public List> gets() { - return getResult; - } -} diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/Bucket.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Bucket.java index 9f5a2e2499a0..ebb6835eba4b 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/Bucket.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Bucket.java @@ -26,6 +26,7 @@ import com.google.cloud.storage.Storage.BucketTargetOption; import com.google.cloud.storage.spi.StorageRpc; import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.collect.Sets; @@ -33,9 +34,7 @@ import java.io.InputStream; import java.io.ObjectInputStream; import java.io.Serializable; -import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Set; @@ -609,19 +608,28 @@ public Blob get(String blob, BlobGetOption... options) { * @throws StorageException upon failure */ public List get(String blobName1, String blobName2, String... blobNames) { - BatchRequest.Builder batch = BatchRequest.builder(); - batch.get(name(), blobName1); - batch.get(name(), blobName2); - for (String name : blobNames) { - batch.get(name(), name); - } - List blobs = new ArrayList<>(blobNames.length); - BatchResponse response = storage.submit(batch.build()); - for (BatchResponse.Result result : response.gets()) { - BlobInfo blobInfo = result.get(); - blobs.add(blobInfo != null ? new Blob(storage, new BlobInfo.BuilderImpl(blobInfo)) : null); - } - return Collections.unmodifiableList(blobs); + List blobIds = Lists.newArrayListWithCapacity(blobNames.length + 2); + blobIds.add(BlobId.of(name(), blobName1)); + blobIds.add(BlobId.of(name(), blobName2)); + for (String blobName : blobNames) { + blobIds.add(BlobId.of(name(), blobName)); + } + return storage.get(blobIds); + } + + /** + * Returns a list of requested blobs in this bucket. Blobs that do not exist are null. + * + * @param blobNames blobs to get + * @return an immutable list of {@code Blob} objects + * @throws StorageException upon failure + */ + public List get(Iterable blobNames) { + ImmutableList.Builder builder = ImmutableList.builder(); + for (String blobName : blobNames) { + builder.add(BlobId.of(name(), blobName)); + } + return storage.get(builder.build()); } /** diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/Storage.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Storage.java index 4c32aea1a428..b1087f72bce1 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/Storage.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Storage.java @@ -1425,12 +1425,29 @@ public static Builder builder() { byte[] readAllBytes(BlobId blob, BlobSourceOption... options); /** - * Sends a batch request. + * Creates a new empty batch for grouping multiple service calls in one underlying RPC call. * - * @return the batch response - * @throws StorageException upon failure + *

    Example of using a batch request to delete, update and get a blob: + *

    {@code
    +   * StorageBatch batch = storage.batch();
    +   * BlobId firstBlob = BlobId.of("bucket", "blob1"));
    +   * BlobId secondBlob = BlobId.of("bucket", "blob2"));
    +   * batch.delete(firstBlob).notify(new BatchResult.Callback() {
    +   *   public void success(Boolean result) {
    +   *     // deleted successfully
    +   *   }
    +   *
    +   *   public void error(StorageException exception) {
    +   *     // delete failed
    +   *   }
    +   * });
    +   * batch.update(BlobInfo.builder(secondBlob).contentType("text/plain").build());
    +   * StorageBatchResult result = batch.get(secondBlob);
    +   * batch.submit();
    +   * Blob blob = result.get(); // returns get result or throws StorageException
    +   * }
    */ - BatchResponse submit(BatchRequest batchRequest); + StorageBatch batch(); /** * Returns a channel for reading the blob's content. The blob's latest generation is read. If the @@ -1534,6 +1551,16 @@ public static Builder builder() { */ List get(BlobId... blobIds); + /** + * Gets the requested blobs. A batch request is used to perform this call. + * + * @param blobIds blobs to get + * @return an immutable list of {@code Blob} objects. If a blob does not exist or access to it + * has been denied the corresponding item in the list is {@code null}. + * @throws StorageException upon failure + */ + List get(Iterable blobIds); + /** * Updates the requested blobs. A batch request is used to perform this call. Original metadata * are merged with metadata in the provided {@code BlobInfo} objects. To replace metadata instead @@ -1548,6 +1575,20 @@ public static Builder builder() { */ List update(BlobInfo... blobInfos); + /** + * Updates the requested blobs. A batch request is used to perform this call. Original metadata + * are merged with metadata in the provided {@code BlobInfo} objects. To replace metadata instead + * you first have to unset them. Unsetting metadata can be done by setting the provided + * {@code BlobInfo} objects metadata to {@code null}. See + * {@link #update(BlobInfo)} for a code example. + * + * @param blobInfos blobs to update + * @return an immutable list of {@code Blob} objects. If a blob does not exist or access to it + * has been denied the corresponding item in the list is {@code null}. + * @throws StorageException upon failure + */ + List update(Iterable blobInfos); + /** * Deletes the requested blobs. A batch request is used to perform this call. * @@ -1558,4 +1599,15 @@ public static Builder builder() { * @throws StorageException upon failure */ List delete(BlobId... blobIds); + + /** + * Deletes the requested blobs. A batch request is used to perform this call. + * + * @param blobIds blobs to delete + * @return an immutable list of booleans. If a blob has been deleted the corresponding item in the + * list is {@code true}. If a blob was not found, deletion failed or access to the resource + * was denied the corresponding item is {@code false}. + * @throws StorageException upon failure + */ + List delete(Iterable blobIds); } diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageBatch.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageBatch.java new file mode 100644 index 000000000000..1153d8015453 --- /dev/null +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageBatch.java @@ -0,0 +1,207 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 java.net.HttpURLConnection.HTTP_NOT_FOUND; + +import com.google.api.client.googleapis.json.GoogleJsonError; +import com.google.api.services.storage.model.StorageObject; +import com.google.cloud.storage.Storage.BlobGetOption; +import com.google.cloud.storage.Storage.BlobSourceOption; +import com.google.cloud.storage.Storage.BlobTargetOption; +import com.google.cloud.storage.spi.RpcBatch; +import com.google.cloud.storage.spi.StorageRpc; +import com.google.common.annotations.VisibleForTesting; + +import java.util.Map; + +/** + * A batch of operations to be submitted to Google Cloud Storage using a single RPC request. + * + *

    Example of using a batch request to delete, update and get a blob: + *

    {@code
    + * StorageBatch batch = storage.batch();
    + * BlobId firstBlob = BlobId.of("bucket", "blob1"));
    + * BlobId secondBlob = BlobId.of("bucket", "blob2"));
    + * batch.delete(firstBlob).notify(new BatchResult.Callback() {
    + *   public void success(Boolean result) {
    + *     // deleted successfully
    + *   }
    + *
    + *   public void error(StorageException exception) {
    + *     // delete failed
    + *   }
    + * });
    + * batch.update(BlobInfo.builder(secondBlob).contentType("text/plain").build());
    + * StorageBatchResult result = batch.get(secondBlob);
    + * batch.submit();
    + * Blob blob = result.get(); // returns get result or throws StorageException
    + * }
    + */ +public class StorageBatch { + + private final RpcBatch batch; + private final StorageRpc storageRpc; + private final StorageOptions options; + + StorageBatch(StorageOptions options) { + this.options = options; + this.storageRpc = options.rpc(); + this.batch = storageRpc.createBatch(); + } + + @VisibleForTesting + Object batch() { + return batch; + } + + @VisibleForTesting + StorageRpc storageRpc() { + return storageRpc; + } + + @VisibleForTesting + StorageOptions options() { + return options; + } + + /** + * Adds a request representing the "delete blob" operation to this batch. Calling {@link + * StorageBatchResult#get()} on the return value yields {@code true} upon successful deletion, + * {@code false} if the blob was not found, or throws a {@link StorageException} if the operation + * failed. + */ + public StorageBatchResult delete(String bucket, String blob, + BlobSourceOption... options) { + return delete(BlobId.of(bucket, blob), options); + } + + /** + * Adds a request representing the "delete blob" operation to this batch. Calling {@link + * StorageBatchResult#get()} on the return value yields {@code true} upon successful deletion, + * {@code false} if the blob was not found, or throws a {@link StorageException} if the operation + * failed. + */ + public StorageBatchResult delete(BlobId blob, BlobSourceOption... options) { + StorageBatchResult result = new StorageBatchResult<>(); + RpcBatch.Callback callback = createDeleteCallback(result); + Map optionMap = StorageImpl.optionMap(blob, options); + batch.addDelete(blob.toPb(), callback, optionMap); + return result; + } + + /** + * Adds a request representing the "update blob" operation to this batch. The {@code options} can + * be used in the same way as for {@link Storage#update(BlobInfo, BlobTargetOption...)}. Calling + * {@link StorageBatchResult#get()} on the return value yields the updated {@link Blob} if + * successful, or throws a {@link StorageException} if the operation failed. + */ + public StorageBatchResult update(BlobInfo blobInfo, BlobTargetOption... options) { + StorageBatchResult result = new StorageBatchResult<>(); + RpcBatch.Callback callback = createUpdateCallback(this.options, result); + Map optionMap = StorageImpl.optionMap(blobInfo, options); + batch.addPatch(blobInfo.toPb(), callback, optionMap); + return result; + } + + /** + * Adds a request representing the "get blob" operation to this batch. The {@code options} can be + * used in the same way as for {@link Storage#get(BlobId, BlobGetOption...)}. Calling + * {@link StorageBatchResult#get()} on the return value yields the requested {@link Blob} if + * successful, {@code null} if no such blob exists, or throws a {@link StorageException} if the + * operation failed. + */ + public StorageBatchResult get(String bucket, String blob, BlobGetOption... options) { + return get(BlobId.of(bucket, blob), options); + } + + /** + * Adds a request representing the "get blob" operation to this batch. The {@code options} can be + * used in the same way as for {@link Storage#get(BlobId, BlobGetOption...)}. Calling + * {@link StorageBatchResult#get()} on the return value yields the requested {@link Blob} if + * successful, {@code null} if no such blob exists, or throws a {@link StorageException} if the + * operation failed. + */ + public StorageBatchResult get(BlobId blob, BlobGetOption... options) { + StorageBatchResult result = new StorageBatchResult<>(); + RpcBatch.Callback callback = createGetCallback(this.options, result); + Map optionMap = StorageImpl.optionMap(blob, options); + batch.addGet(blob.toPb(), callback, optionMap); + return result; + } + + /** + * Submits this batch for processing using a single RPC request. + */ + public void submit() { + batch.submit(); + } + + private RpcBatch.Callback createDeleteCallback(final StorageBatchResult result) { + return new RpcBatch.Callback() { + @Override + public void onSuccess(Void response) { + result.success(true); + } + + @Override + public void onFailure(GoogleJsonError googleJsonError) { + StorageException serviceException = new StorageException(googleJsonError); + if (serviceException.code() == HTTP_NOT_FOUND) { + result.success(false); + } else { + result.error(serviceException); + } + } + }; + } + + private RpcBatch.Callback createGetCallback(final StorageOptions serviceOptions, + final StorageBatchResult result) { + return new RpcBatch.Callback() { + @Override + public void onSuccess(StorageObject response) { + result.success(response == null ? null : Blob.fromPb(serviceOptions.service(), response)); + } + + @Override + public void onFailure(GoogleJsonError googleJsonError) { + StorageException serviceException = new StorageException(googleJsonError); + if (serviceException.code() == HTTP_NOT_FOUND) { + result.success(null); + } else { + result.error(serviceException); + } + } + }; + } + + private RpcBatch.Callback createUpdateCallback(final StorageOptions serviceOptions, + final StorageBatchResult result) { + return new RpcBatch.Callback() { + @Override + public void onSuccess(StorageObject response) { + result.success(response == null ? null : Blob.fromPb(serviceOptions.service(), response)); + } + + @Override + public void onFailure(GoogleJsonError googleJsonError) { + result.error(new StorageException(googleJsonError)); + } + }; + } +} diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageBatchResult.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageBatchResult.java new file mode 100644 index 000000000000..2311436ab2d2 --- /dev/null +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageBatchResult.java @@ -0,0 +1,39 @@ + +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 com.google.cloud.BatchResult; + +/** + * This class holds a single result of a batch call to Cloud Storage. + */ +public class StorageBatchResult extends BatchResult { + + StorageBatchResult() { + } + + @Override + protected void error(StorageException error) { + super.error(error); + } + + @Override + protected void success(T result) { + super.success(result); + } +} diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageImpl.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageImpl.java index 50a1076fc84a..8d8ccb753d5f 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageImpl.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/StorageImpl.java @@ -33,6 +33,7 @@ import com.google.api.services.storage.model.StorageObject; import com.google.cloud.BaseService; +import com.google.cloud.BatchResult; import com.google.cloud.Page; import com.google.cloud.PageImpl; import com.google.cloud.PageImpl.NextPageFetcher; @@ -54,7 +55,6 @@ import java.io.ByteArrayInputStream; import java.io.InputStream; -import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; @@ -449,60 +449,8 @@ public byte[] call() { } @Override - public BatchResponse submit(BatchRequest batchRequest) { - List>> toDelete = - Lists.newArrayListWithCapacity(batchRequest.toDelete().size()); - for (Map.Entry> entry : batchRequest.toDelete().entrySet()) { - BlobId blob = entry.getKey(); - Map optionsMap = optionMap(blob.generation(), null, entry.getValue()); - StorageObject storageObject = blob.toPb(); - toDelete.add(Tuple.>of(storageObject, optionsMap)); - } - List>> toUpdate = - Lists.newArrayListWithCapacity(batchRequest.toUpdate().size()); - for (Map.Entry> entry : - batchRequest.toUpdate().entrySet()) { - BlobInfo blobInfo = entry.getKey(); - Map optionsMap = - optionMap(blobInfo.generation(), blobInfo.metageneration(), entry.getValue()); - toUpdate.add(Tuple.>of(blobInfo.toPb(), optionsMap)); - } - List>> toGet = - Lists.newArrayListWithCapacity(batchRequest.toGet().size()); - for (Map.Entry> entry : batchRequest.toGet().entrySet()) { - BlobId blob = entry.getKey(); - Map optionsMap = optionMap(blob.generation(), null, entry.getValue()); - toGet.add(Tuple.>of(blob.toPb(), optionsMap)); - } - StorageRpc.BatchResponse response = - storageRpc.batch(new StorageRpc.BatchRequest(toDelete, toUpdate, toGet)); - List> deletes = - transformBatchResult(toDelete, response.deletes, DELETE_FUNCTION); - List> updates = - transformBatchResult(toUpdate, response.updates, Blob.BLOB_FROM_PB_FUNCTION); - List> gets = - transformBatchResult(toGet, response.gets, Blob.BLOB_FROM_PB_FUNCTION); - return new BatchResponse(deletes, updates, gets); - } - - private List> transformBatchResult( - Iterable>> request, - Map> results, - Function, O> transform) { - List> response = Lists.newArrayListWithCapacity(results.size()); - for (Tuple tuple : request) { - Tuple result = results.get(tuple.x()); - I object = result.x(); - StorageException exception = result.y(); - if (exception != null) { - response.add(new BatchResponse.Result(exception)); - } else { - response.add(object != null - ? BatchResponse.Result.of(transform.apply(Tuple.of((Storage) this, object))) - : BatchResponse.Result.empty()); - } - } - return response; + public StorageBatch batch() { + return new StorageBatch(this.options()); } @Override @@ -591,42 +539,80 @@ public URL signUrl(BlobInfo blobInfo, long duration, TimeUnit unit, SignUrlOptio @Override public List get(BlobId... blobIds) { - BatchRequest.Builder requestBuilder = BatchRequest.builder(); + return get(Arrays.asList(blobIds)); + } + + @Override + public List get(Iterable blobIds) { + StorageBatch batch = batch(); + final List results = Lists.newArrayList(); for (BlobId blob : blobIds) { - requestBuilder.get(blob); + batch.get(blob).notify(new BatchResult.Callback() { + @Override + public void success(Blob result) { + results.add(result); + } + + @Override + public void error(StorageException exception) { + results.add(null); + } + }); } - BatchResponse response = submit(requestBuilder.build()); - return Collections.unmodifiableList(transformResultList(response.gets(), null)); + batch.submit(); + return Collections.unmodifiableList(results); } @Override public List update(BlobInfo... blobInfos) { - BatchRequest.Builder requestBuilder = BatchRequest.builder(); + return update(Arrays.asList(blobInfos)); + } + + @Override + public List update(Iterable blobInfos) { + StorageBatch batch = batch(); + final List results = Lists.newArrayList(); for (BlobInfo blobInfo : blobInfos) { - requestBuilder.update(blobInfo); + batch.update(blobInfo).notify(new BatchResult.Callback() { + @Override + public void success(Blob result) { + results.add(result); + } + + @Override + public void error(StorageException exception) { + results.add(null); + } + }); } - BatchResponse response = submit(requestBuilder.build()); - return Collections.unmodifiableList(transformResultList(response.updates(), null)); + batch.submit(); + return Collections.unmodifiableList(results); } @Override public List delete(BlobId... blobIds) { - BatchRequest.Builder requestBuilder = BatchRequest.builder(); - for (BlobId blob : blobIds) { - requestBuilder.delete(blob); - } - BatchResponse response = submit(requestBuilder.build()); - return Collections.unmodifiableList(transformResultList(response.deletes(), Boolean.FALSE)); + return delete(Arrays.asList(blobIds)); } - private static List transformResultList( - List> results, final T errorValue) { - return Lists.transform(results, new Function, T>() { - @Override - public T apply(BatchResponse.Result result) { - return result.failed() ? errorValue : result.get(); - } - }); + @Override + public List delete(Iterable blobIds) { + StorageBatch batch = batch(); + final List results = Lists.newArrayList(); + for (BlobId blob : blobIds) { + batch.delete(blob).notify(new BatchResult.Callback() { + @Override + public void success(Boolean result) { + results.add(result); + } + + @Override + public void error(StorageException exception) { + results.add(Boolean.FALSE); + } + }); + } + batch.submit(); + return Collections.unmodifiableList(results); } private static void addToOptionMap(StorageRpc.Option option, T defaultValue, @@ -646,12 +632,12 @@ private static void addToOptionMap(StorageRpc.Option getOption, StorageRpc.O } } - private Map optionMap(Long generation, Long metaGeneration, + private static Map optionMap(Long generation, Long metaGeneration, Iterable options) { return optionMap(generation, metaGeneration, options, false); } - private Map optionMap(Long generation, Long metaGeneration, + private static Map optionMap(Long generation, Long metaGeneration, Iterable options, boolean useAsSource) { Map temp = Maps.newEnumMap(StorageRpc.Option.class); for (Option option : options) { @@ -677,24 +663,24 @@ private static void addToOptionMap(StorageRpc.Option getOption, StorageRpc.O return ImmutableMap.copyOf(temp); } - private Map optionMap(Option... options) { + private static Map optionMap(Option... options) { return optionMap(null, null, Arrays.asList(options)); } - private Map optionMap(Long generation, Long metaGeneration, + private static Map optionMap(Long generation, Long metaGeneration, Option... options) { return optionMap(generation, metaGeneration, Arrays.asList(options)); } - private Map optionMap(BucketInfo bucketInfo, Option... options) { + private static Map optionMap(BucketInfo bucketInfo, Option... options) { return optionMap(null, bucketInfo.metageneration(), options); } - private Map optionMap(BlobInfo blobInfo, Option... options) { + static Map optionMap(BlobInfo blobInfo, Option... options) { return optionMap(blobInfo.generation(), blobInfo.metageneration(), options); } - private Map optionMap(BlobId blobId, Option... options) { + static Map optionMap(BlobId blobId, Option... options) { return optionMap(blobId.generation(), null, options); } } diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/DefaultStorageRpc.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/DefaultStorageRpc.java index 1a9589aa40cf..65d540458c7c 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/DefaultStorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/DefaultStorageRpc.java @@ -34,6 +34,7 @@ import static java.net.HttpURLConnection.HTTP_NOT_FOUND; import static javax.servlet.http.HttpServletResponse.SC_REQUESTED_RANGE_NOT_SATISFIABLE; +import com.google.api.client.googleapis.batch.BatchRequest; import com.google.api.client.googleapis.batch.json.JsonBatchCallback; import com.google.api.client.googleapis.json.GoogleJsonError; import com.google.api.client.http.ByteArrayContent; @@ -64,14 +65,13 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; -import com.google.common.collect.Maps; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.util.ArrayList; -import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -82,7 +82,6 @@ public class DefaultStorageRpc implements StorageRpc { private final Storage storage; private static final long MEGABYTE = 1024L * 1024L; - private static final int MAX_BATCH_DELETES = 100; public DefaultStorageRpc(StorageOptions options) { HttpTransport transport = options.httpTransportFactory().create(); @@ -94,6 +93,96 @@ public DefaultStorageRpc(StorageOptions options) { .build(); } + private class DefaultRpcBatch implements RpcBatch { + + // Batch size is limited as, due to some current service implementation details, the service + // performs better if the batches are split for better distribution. See + // https://github.com/GoogleCloudPlatform/gcloud-java/pull/952#issuecomment-213466772 for + // background. + private static final int MAX_BATCH_SIZE = 100; + + private final Storage storage; + private final LinkedList batches; + private int currentBatchSize; + + private DefaultRpcBatch(Storage storage) { + this.storage = storage; + batches = new LinkedList<>(); + batches.add(storage.batch()); + } + + @Override + public void addDelete(StorageObject storageObject, RpcBatch.Callback callback, + Map options) { + try { + if (currentBatchSize == MAX_BATCH_SIZE) { + batches.add(storage.batch()); + currentBatchSize = 0; + } + deleteCall(storageObject, options).queue(batches.getLast(), toJsonCallback(callback)); + currentBatchSize++; + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public void addPatch(StorageObject storageObject, RpcBatch.Callback callback, + Map options) { + try { + if (currentBatchSize == MAX_BATCH_SIZE) { + batches.add(storage.batch()); + currentBatchSize = 0; + } + patchCall(storageObject, options).queue(batches.getLast(), toJsonCallback(callback)); + currentBatchSize++; + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public void addGet(StorageObject storageObject, RpcBatch.Callback callback, + Map options) { + try { + if (currentBatchSize == MAX_BATCH_SIZE) { + batches.add(storage.batch()); + currentBatchSize = 0; + } + getCall(storageObject, options).queue(batches.getLast(), toJsonCallback(callback)); + currentBatchSize++; + } catch (IOException ex) { + throw translate(ex); + } + } + + @Override + public void submit() { + try { + for (BatchRequest batch : batches) { + batch.execute(); + } + } catch (IOException ex) { + throw translate(ex); + } + } + } + + private static JsonBatchCallback toJsonCallback(final RpcBatch.Callback callback) { + return new JsonBatchCallback() { + @Override + public void onSuccess(T response, HttpHeaders httpHeaders) throws IOException { + callback.onSuccess(response); + } + + @Override + public void onFailure(GoogleJsonError googleJsonError, HttpHeaders httpHeaders) + throws IOException { + callback.onFailure(googleJsonError); + } + }; + } + private static StorageException translate(IOException exception) { return new StorageException(exception); } @@ -209,20 +298,7 @@ public Bucket get(Bucket bucket, Map options) { } } - @Override - public StorageObject get(StorageObject object, Map options) { - try { - return getRequest(object, options).execute(); - } catch (IOException ex) { - StorageException serviceException = translate(ex); - if (serviceException.code() == HTTP_NOT_FOUND) { - return null; - } - throw serviceException; - } - } - - private Storage.Objects.Get getRequest(StorageObject object, Map options) + private Storage.Objects.Get getCall(StorageObject object, Map options) throws IOException { return storage.objects() .get(object.getBucket(), object.getName()) @@ -235,6 +311,19 @@ private Storage.Objects.Get getRequest(StorageObject object, Map opti .setFields(FIELDS.getString(options)); } + @Override + public StorageObject get(StorageObject object, Map options) { + try { + return getCall(object, options).execute(); + } catch (IOException ex) { + StorageException serviceException = translate(ex); + if (serviceException.code() == HTTP_NOT_FOUND) { + return null; + } + throw serviceException; + } + } + @Override public Bucket patch(Bucket bucket, Map options) { try { @@ -251,16 +340,7 @@ public Bucket patch(Bucket bucket, Map options) { } } - @Override - public StorageObject patch(StorageObject storageObject, Map options) { - try { - return patchRequest(storageObject, options).execute(); - } catch (IOException ex) { - throw translate(ex); - } - } - - private Storage.Objects.Patch patchRequest(StorageObject storageObject, Map options) + private Storage.Objects.Patch patchCall(StorageObject storageObject, Map options) throws IOException { return storage.objects() .patch(storageObject.getBucket(), storageObject.getName(), storageObject) @@ -272,6 +352,15 @@ private Storage.Objects.Patch patchRequest(StorageObject storageObject, Map options) { + try { + return patchCall(storageObject, options).execute(); + } catch (IOException ex) { + throw translate(ex); + } + } + @Override public boolean delete(Bucket bucket, Map options) { try { @@ -290,10 +379,21 @@ public boolean delete(Bucket bucket, Map options) { } } + private Storage.Objects.Delete deleteCall(StorageObject blob, Map options) + throws IOException { + return storage.objects() + .delete(blob.getBucket(), blob.getName()) + .setGeneration(blob.getGeneration()) + .setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options)) + .setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options)) + .setIfGenerationMatch(IF_GENERATION_MATCH.getLong(options)) + .setIfGenerationNotMatch(IF_GENERATION_NOT_MATCH.getLong(options)); + } + @Override public boolean delete(StorageObject blob, Map options) { try { - deleteRequest(blob, options).execute(); + deleteCall(blob, options).execute(); return true; } catch (IOException ex) { StorageException serviceException = translate(ex); @@ -304,17 +404,6 @@ public boolean delete(StorageObject blob, Map options) { } } - private Storage.Objects.Delete deleteRequest(StorageObject blob, Map options) - throws IOException { - return storage.objects() - .delete(blob.getBucket(), blob.getName()) - .setGeneration(blob.getGeneration()) - .setIfMetagenerationMatch(IF_METAGENERATION_MATCH.getLong(options)) - .setIfMetagenerationNotMatch(IF_METAGENERATION_NOT_MATCH.getLong(options)) - .setIfGenerationMatch(IF_GENERATION_MATCH.getLong(options)) - .setIfGenerationNotMatch(IF_GENERATION_NOT_MATCH.getLong(options)); - } - @Override public StorageObject compose(Iterable sources, StorageObject target, Map targetOptions) { @@ -363,92 +452,8 @@ public byte[] load(StorageObject from, Map options) { } @Override - public BatchResponse batch(BatchRequest request) { - List>>> partitionedToDelete = - Lists.partition(request.toDelete, MAX_BATCH_DELETES); - Iterator>>> iterator = partitionedToDelete.iterator(); - BatchRequest chunkRequest = new BatchRequest( - iterator.hasNext() - ? iterator.next() : ImmutableList.>>of(), - request.toUpdate, request.toGet); - BatchResponse response = batchChunk(chunkRequest); - Map> deletes = - Maps.newHashMapWithExpectedSize(request.toDelete.size()); - deletes.putAll(response.deletes); - while (iterator.hasNext()) { - chunkRequest = new BatchRequest(iterator.next(), null, null); - BatchResponse deleteBatchResponse = batchChunk(chunkRequest); - deletes.putAll(deleteBatchResponse.deletes); - } - return new BatchResponse(deletes, response.updates, response.gets); - } - - private BatchResponse batchChunk(BatchRequest request) { - com.google.api.client.googleapis.batch.BatchRequest batch = storage.batch(); - final Map> deletes = - Maps.newConcurrentMap(); - final Map> updates = - Maps.newConcurrentMap(); - final Map> gets = - Maps.newConcurrentMap(); - try { - for (final Tuple> tuple : request.toDelete) { - deleteRequest(tuple.x(), tuple.y()).queue(batch, new JsonBatchCallback() { - @Override - public void onSuccess(Void ignore, HttpHeaders responseHeaders) { - deletes.put(tuple.x(), Tuple.of(Boolean.TRUE, null)); - } - - @Override - public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) { - if (e.getCode() == HTTP_NOT_FOUND) { - deletes.put(tuple.x(), Tuple.of(Boolean.FALSE, null)); - } else { - deletes.put(tuple.x(), Tuple.of(null, translate(e))); - } - } - }); - } - for (final Tuple> tuple : request.toUpdate) { - patchRequest(tuple.x(), tuple.y()).queue(batch, new JsonBatchCallback() { - @Override - public void onSuccess(StorageObject storageObject, HttpHeaders responseHeaders) { - updates.put(tuple.x(), - Tuple.of(storageObject, null)); - } - - @Override - public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) { - updates.put(tuple.x(), - Tuple.of(null, translate(e))); - } - }); - } - for (final Tuple> tuple : request.toGet) { - getRequest(tuple.x(), tuple.y()).queue(batch, new JsonBatchCallback() { - @Override - public void onSuccess(StorageObject storageObject, HttpHeaders responseHeaders) { - gets.put(tuple.x(), - Tuple.of(storageObject, null)); - } - - @Override - public void onFailure(GoogleJsonError e, HttpHeaders responseHeaders) { - if (e.getCode() == HTTP_NOT_FOUND) { - gets.put(tuple.x(), - Tuple.of(null, null)); - } else { - gets.put(tuple.x(), - Tuple.of(null, translate(e))); - } - } - }); - } - batch.execute(); - } catch (IOException ex) { - throw translate(ex); - } - return new BatchResponse(deletes, updates, gets); + public RpcBatch createBatch() { + return new DefaultRpcBatch(storage); } @Override diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/RpcBatch.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/RpcBatch.java new file mode 100644 index 000000000000..54b15fe45654 --- /dev/null +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/RpcBatch.java @@ -0,0 +1,70 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.spi; + +import com.google.api.client.googleapis.json.GoogleJsonError; +import com.google.api.services.storage.model.StorageObject; + +import java.util.Map; + +/** + * An interface for the collection of batch operations. + */ +public interface RpcBatch { + + /** + * An interface for batch callbacks. + */ + interface Callback { + + /** + * This method will be called upon success of the batch operation. + */ + void onSuccess(T response); + + /** + * This method will be called upon failure of the batch operation. + */ + void onFailure(GoogleJsonError googleJsonError); + } + + /** + * Adds a call to "delete storage object" to the batch, with the provided {@code callback} and + * {@code options}. + */ + void addDelete(StorageObject storageObject, Callback callback, + Map options); + + /** + * Adds a call to "patch storage object" to the batch, with the provided {@code callback} and + * {@code options}. + */ + void addPatch(StorageObject storageObject, Callback callback, + Map options); + + /** + * Adds a call to "get storage object" to the batch, with the provided {@code callback} and + * {@code options}. + */ + void addGet(StorageObject storageObject, Callback callback, + Map options); + + /** + * Submits a batch of requests for processing using a single RPC request to Cloud Storage. + */ + void submit(); +} diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/StorageRpc.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/StorageRpc.java index 13dddb7d6737..6beeeed11f9f 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/StorageRpc.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/spi/StorageRpc.java @@ -16,16 +16,11 @@ package com.google.cloud.storage.spi; -import static com.google.common.base.MoreObjects.firstNonNull; - import com.google.api.services.storage.model.Bucket; import com.google.api.services.storage.model.StorageObject; import com.google.cloud.storage.StorageException; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; import java.io.InputStream; -import java.util.List; import java.util.Map; import java.util.Objects; @@ -101,39 +96,6 @@ public Y y() { } } - class BatchRequest { - - public final List>> toDelete; - public final List>> toUpdate; - public final List>> toGet; - - public BatchRequest(Iterable>> toDelete, - Iterable>> toUpdate, - Iterable>> toGet) { - this.toDelete = ImmutableList.copyOf( - firstNonNull(toDelete, ImmutableList.>>of())); - this.toUpdate = ImmutableList.copyOf( - firstNonNull(toUpdate, ImmutableList.>>of())); - this.toGet = ImmutableList.copyOf( - firstNonNull(toGet, ImmutableList.>>of())); - } - } - - class BatchResponse { - - public final Map> deletes; - public final Map> updates; - public final Map> gets; - - public BatchResponse(Map> deletes, - Map> updates, - Map> gets) { - this.deletes = ImmutableMap.copyOf(deletes); - this.updates = ImmutableMap.copyOf(updates); - this.gets = ImmutableMap.copyOf(gets); - } - } - class RewriteRequest { public final StorageObject source; @@ -295,11 +257,9 @@ public int hashCode() { boolean delete(StorageObject object, Map options); /** - * Sends a batch request. - * - * @throws StorageException upon failure + * Creates an empty batch. */ - BatchResponse batch(BatchRequest request); + RpcBatch createBatch(); /** * Sends a compose request. diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BatchRequestTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BatchRequestTest.java deleted file mode 100644 index a47c7c140216..000000000000 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BatchRequestTest.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * 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.cloud.storage.Storage.PredefinedAcl.PUBLIC_READ; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertTrue; - -import com.google.cloud.storage.Storage.BlobGetOption; -import com.google.cloud.storage.Storage.BlobSourceOption; -import com.google.cloud.storage.Storage.BlobTargetOption; -import com.google.common.collect.Iterables; - -import org.junit.Test; - -import java.util.Iterator; -import java.util.Map.Entry; - -public class BatchRequestTest { - - @Test - public void testBatchRequest() { - BatchRequest request = BatchRequest.builder() - .delete(BlobId.of("b1", "o1", 1L), BlobSourceOption.generationMatch()) - .delete("b1", "o2", BlobSourceOption.generationMatch(1), - BlobSourceOption.metagenerationMatch(2)) - .update(BlobInfo.builder("b2", "o1").build(), BlobTargetOption.predefinedAcl(PUBLIC_READ)) - .update(BlobInfo.builder("b2", "o2").build()) - .get(BlobId.of("b3", "o1", 1L), BlobGetOption.generationMatch()) - .get("b3", "o2", BlobGetOption.generationMatch(1)) - .get("b3", "o3") - .build(); - - Iterator>> deletes = request - .toDelete().entrySet().iterator(); - Entry> delete = deletes.next(); - assertEquals(BlobId.of("b1", "o1", 1L), delete.getKey()); - assertEquals(1, Iterables.size(delete.getValue())); - assertEquals(BlobSourceOption.generationMatch(), Iterables.getFirst(delete.getValue(), null)); - delete = deletes.next(); - assertEquals(BlobId.of("b1", "o2"), delete.getKey()); - assertEquals(2, Iterables.size(delete.getValue())); - assertEquals(BlobSourceOption.generationMatch(1L), Iterables.getFirst(delete.getValue(), null)); - assertEquals(BlobSourceOption.metagenerationMatch(2L), - Iterables.get(delete.getValue(), 1, null)); - assertFalse(deletes.hasNext()); - - Iterator>> updates = request - .toUpdate().entrySet().iterator(); - Entry> update = updates.next(); - assertEquals(BlobInfo.builder("b2", "o1").build(), update.getKey()); - assertEquals(1, Iterables.size(update.getValue())); - assertEquals(BlobTargetOption.predefinedAcl(PUBLIC_READ), - Iterables.getFirst(update.getValue(), null)); - update = updates.next(); - assertEquals(BlobInfo.builder("b2", "o2").build(), update.getKey()); - assertTrue(Iterables.isEmpty(update.getValue())); - assertFalse(updates.hasNext()); - - Iterator>> gets = request.toGet().entrySet().iterator(); - Entry> get = gets.next(); - assertEquals(BlobId.of("b3", "o1", 1L), get.getKey()); - assertEquals(1, Iterables.size(get.getValue())); - assertEquals(BlobGetOption.generationMatch(), Iterables.getFirst(get.getValue(), null)); - get = gets.next(); - assertEquals(BlobId.of("b3", "o2"), get.getKey()); - assertEquals(1, Iterables.size(get.getValue())); - assertEquals(BlobGetOption.generationMatch(1), Iterables.getFirst(get.getValue(), null)); - get = gets.next(); - assertEquals(BlobId.of("b3", "o3"), get.getKey()); - assertTrue(Iterables.isEmpty(get.getValue())); - assertFalse(gets.hasNext()); - } - - @Test - public void testEquals() { - BatchRequest request = BatchRequest.builder() - .delete("b1", "o1") - .delete("b1", "o2") - .update(BlobInfo.builder("b2", "o1").build()) - .update(BlobInfo.builder("b2", "o2").build()) - .get("b3", "o1") - .get("b3", "o2") - .build(); - BatchRequest requestEquals = BatchRequest.builder() - .delete("b1", "o1") - .delete("b1", "o2") - .update(BlobInfo.builder("b2", "o1").build()) - .update(BlobInfo.builder("b2", "o2").build()) - .get("b3", "o1") - .get("b3", "o2") - .build(); - BatchRequest requestNotEquals1 = BatchRequest.builder() - .delete("b1", "o1") - .delete("b1", "o3") - .update(BlobInfo.builder("b2", "o1").build()) - .update(BlobInfo.builder("b2", "o2").build()) - .get("b3", "o1") - .get("b3", "o2") - .build(); - BatchRequest requestNotEquals2 = BatchRequest.builder() - .delete("b1", "o1") - .delete("b1", "o2") - .update(BlobInfo.builder("b2", "o1").build()) - .update(BlobInfo.builder("b2", "o3").build()) - .get("b3", "o1") - .get("b3", "o2") - .build(); - BatchRequest requestNotEquals3 = BatchRequest.builder() - .delete("b1", "o1") - .delete("b1", "o2") - .update(BlobInfo.builder("b2", "o1").build()) - .update(BlobInfo.builder("b2", "o2").build()) - .get("b3", "o1") - .get("b3", "o3") - .build(); - assertEquals(request, requestEquals); - assertEquals(request.hashCode(), requestEquals.hashCode()); - assertNotEquals(request, requestNotEquals1); - assertNotEquals(request.hashCode(), requestNotEquals1.hashCode()); - assertNotEquals(request, requestNotEquals2); - assertNotEquals(request.hashCode(), requestNotEquals2.hashCode()); - assertNotEquals(request, requestNotEquals3); - assertNotEquals(request.hashCode(), requestNotEquals3.hashCode()); - } -} diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BatchResponseTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BatchResponseTest.java deleted file mode 100644 index a9177489c2fd..000000000000 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BatchResponseTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2015 Google Inc. All Rights Reserved. - * - * 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 org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotEquals; - -import com.google.cloud.storage.BatchResponse.Result; -import com.google.common.collect.ImmutableList; - -import org.easymock.EasyMock; -import org.junit.Before; -import org.junit.Test; - -import java.util.List; - -public class BatchResponseTest { - - private Storage mockStorage; - private Blob blob1; - private Blob blob2; - private Blob blob3; - - @Before - public void setUp() { - mockStorage = EasyMock.createMock(Storage.class); - EasyMock.expect(mockStorage.options()).andReturn(null).times(3); - EasyMock.replay(mockStorage); - blob1 = new Blob(mockStorage, new BlobInfo.BuilderImpl(BlobInfo.builder("b", "o1").build())); - blob2 = new Blob(mockStorage, new BlobInfo.BuilderImpl(BlobInfo.builder("b", "o2").build())); - blob3 = new Blob(mockStorage, new BlobInfo.BuilderImpl(BlobInfo.builder("b", "o3").build())); - } - - @Test - public void testBatchResponse() { - List> deletes = ImmutableList.of(Result.of(true), Result.of(false)); - List> updates = - ImmutableList.of(Result.of(blob1), Result.of(blob2)); - List> gets = ImmutableList.of(Result.of(blob2), Result.of(blob3)); - BatchResponse response = new BatchResponse(deletes, updates, gets); - assertEquals(deletes, response.deletes()); - assertEquals(updates, response.updates()); - assertEquals(gets, response.gets()); - } - - @Test - public void testEquals() { - List> deletes = ImmutableList.of(Result.of(true), Result.of(false)); - List> updates = - ImmutableList.of(Result.of(blob1), Result.of(blob2)); - List> gets = ImmutableList.of(Result.of(blob2), Result.of(blob3)); - List> otherDeletes = ImmutableList.of(Result.of(false), Result.of(true)); - List> otherUpdates = ImmutableList.of(Result.of(blob2), Result.of(blob3)); - List> otherGets = - ImmutableList.of(Result.of(blob1), Result.of(blob2)); - BatchResponse response = new BatchResponse(deletes, updates, gets); - BatchResponse responseEquals = new BatchResponse(deletes, updates, gets); - BatchResponse responseNotEquals1 = new BatchResponse(otherDeletes, updates, gets); - BatchResponse responseNotEquals2 = new BatchResponse(deletes, otherUpdates, gets); - BatchResponse responseNotEquals3 = new BatchResponse(deletes, updates, otherGets); - assertEquals(response, responseEquals); - assertEquals(response.hashCode(), responseEquals.hashCode()); - assertNotEquals(response, responseNotEquals1); - assertNotEquals(response.hashCode(), responseNotEquals1.hashCode()); - assertNotEquals(response, responseNotEquals2); - assertNotEquals(response.hashCode(), responseNotEquals2.hashCode()); - assertNotEquals(response, responseNotEquals3); - assertNotEquals(response.hashCode(), responseNotEquals3.hashCode()); - } -} diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BucketTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BucketTest.java index 0494dfcdf506..1b9a29f03676 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BucketTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BucketTest.java @@ -19,7 +19,6 @@ import static com.google.cloud.storage.Acl.Project.ProjectRole.VIEWERS; import static com.google.cloud.storage.Acl.Role.READER; import static com.google.cloud.storage.Acl.Role.WRITER; -import static org.easymock.EasyMock.capture; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createStrictMock; import static org.easymock.EasyMock.expect; @@ -34,12 +33,12 @@ import com.google.cloud.PageImpl; import com.google.cloud.storage.Acl.Project; import com.google.cloud.storage.Acl.User; -import com.google.cloud.storage.BatchResponse.Result; import com.google.cloud.storage.BucketInfo.AgeDeleteRule; import com.google.cloud.storage.BucketInfo.DeleteRule; +import com.google.common.base.Function; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; -import org.easymock.Capture; import org.junit.After; import org.junit.Before; import org.junit.Rule; @@ -50,9 +49,7 @@ import java.io.InputStream; import java.util.Collections; import java.util.Iterator; -import java.util.LinkedList; import java.util.List; -import java.util.Set; public class BucketTest { @@ -99,7 +96,7 @@ public class BucketTest { private StorageOptions mockOptions = createMock(StorageOptions.class); private Bucket bucket; private Bucket expectedBucket; - private Iterable blobResults; + private List blobResults; @Rule public ExpectedException thrown = ExpectedException.none(); @@ -249,33 +246,35 @@ public void testGet() throws Exception { } @Test - public void testGetAll() throws Exception { + public void testGetAllArray() throws Exception { initializeExpectedBucket(4); - Capture capturedBatchRequest = Capture.newInstance(); - List> batchResultList = new LinkedList<>(); - for (Blob info : blobResults) { - batchResultList.add(new Result<>(info)); - } - BatchResponse response = new BatchResponse(Collections.>emptyList(), - Collections.>emptyList(), batchResultList); expect(storage.options()).andReturn(mockOptions); - expect(storage.submit(capture(capturedBatchRequest))).andReturn(response); - expect(storage.options()).andReturn(mockOptions).times(3); + List blobIds = Lists.transform(blobResults, new Function() { + @Override + public BlobId apply(Blob blob) { + return blob.blobId(); + } + }); + expect(storage.get(blobIds)).andReturn(blobResults); replay(storage); initializeBucket(); - List blobs = bucket.get("n1", "n2", "n3"); - Set blobInfoSet = capturedBatchRequest.getValue().toGet().keySet(); - assertEquals(batchResultList.size(), blobInfoSet.size()); - for (BlobInfo info : blobResults) { - assertTrue(blobInfoSet.contains(info.blobId())); - } - Iterator blobIterator = blobs.iterator(); - Iterator> batchResultIterator = response.gets().iterator(); - while (batchResultIterator.hasNext() && blobIterator.hasNext()) { - assertEquals(batchResultIterator.next().get(), blobIterator.next()); - } - assertFalse(batchResultIterator.hasNext()); - assertFalse(blobIterator.hasNext()); + assertEquals(blobResults, bucket.get("n1", "n2", "n3")); + } + + @Test + public void testGetAllIterable() throws Exception { + initializeExpectedBucket(4); + expect(storage.options()).andReturn(mockOptions); + List blobIds = Lists.transform(blobResults, new Function() { + @Override + public BlobId apply(Blob blob) { + return blob.blobId(); + } + }); + expect(storage.get(blobIds)).andReturn(blobResults); + replay(storage); + initializeBucket(); + assertEquals(blobResults, bucket.get(ImmutableList.of("n1", "n2", "n3"))); } @Test diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/SerializationTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/SerializationTest.java index a8d399e1b1e4..a816415ddc02 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/SerializationTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/SerializationTest.java @@ -45,11 +45,6 @@ public class SerializationTest extends BaseSerializationTest { private static final Cors.Origin ORIGIN = Cors.Origin.any(); private static final Cors CORS = Cors.builder().maxAgeSeconds(1).origins(Collections.singleton(ORIGIN)).build(); - private static final BatchRequest BATCH_REQUEST = BatchRequest.builder().delete("B", "N").build(); - private static final BatchResponse BATCH_RESPONSE = new BatchResponse( - Collections.singletonList(BatchResponse.Result.of(true)), - Collections.>emptyList(), - Collections.>emptyList()); private static final PageImpl PAGE_RESULT = new PageImpl<>(null, "c", Collections.singletonList(BLOB)); private static final StorageException STORAGE_EXCEPTION = new StorageException(42, "message"); @@ -78,10 +73,9 @@ protected Serializable[] serializableObjects() { .authCredentials(null) .build(); return new Serializable[]{ACL_DOMAIN, ACL_GROUP, ACL_PROJECT_, ACL_USER, ACL_RAW, ACL, - BLOB_INFO, BLOB, BUCKET_INFO, BUCKET, ORIGIN, CORS, BATCH_REQUEST, BATCH_RESPONSE, - PAGE_RESULT, BLOB_LIST_OPTIONS, BLOB_SOURCE_OPTIONS, BLOB_TARGET_OPTIONS, - BUCKET_LIST_OPTIONS, BUCKET_SOURCE_OPTIONS, BUCKET_TARGET_OPTIONS, STORAGE_EXCEPTION, - options, otherOptions}; + BLOB_INFO, BLOB, BUCKET_INFO, BUCKET, ORIGIN, CORS, PAGE_RESULT, BLOB_LIST_OPTIONS, + BLOB_SOURCE_OPTIONS, BLOB_TARGET_OPTIONS, BUCKET_LIST_OPTIONS, BUCKET_SOURCE_OPTIONS, + BUCKET_TARGET_OPTIONS, STORAGE_EXCEPTION, options, otherOptions}; } @Override diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageBatchResultTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageBatchResultTest.java new file mode 100644 index 000000000000..cfa5f6fb9fc6 --- /dev/null +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageBatchResultTest.java @@ -0,0 +1,109 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 org.junit.Assert.assertFalse; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.google.cloud.BatchResult; + +import org.easymock.EasyMock; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; + +public class StorageBatchResultTest { + + private StorageBatchResult result; + + @Before + public void setUp() { + result = new StorageBatchResult<>(); + } + + @Test + public void testSuccess() { + assertFalse(result.completed()); + try { + result.get(); + fail("This was not completed yet."); + } catch (IllegalStateException ex) { + // expected + } + result.success(true); + assertTrue(result.get()); + } + + @Test + public void testError() { + assertFalse(result.completed()); + try { + result.get(); + fail("This was not completed yet."); + } catch (IllegalStateException ex) { + // expected + } + StorageException ex = new StorageException(new IOException("some error")); + result.error(ex); + try { + result.get(); + fail("This is a failed operation and should have thrown a StorageException."); + } catch (StorageException real) { + assertSame(ex, real); + } + } + + @Test + public void testNotifyError() { + StorageException ex = new StorageException(new IOException("some error")); + assertFalse(result.completed()); + BatchResult.Callback callback = + EasyMock.createStrictMock(BatchResult.Callback.class); + callback.error(ex); + EasyMock.replay(callback); + result.notify(callback); + result.error(ex); + try { + result.notify(callback); + fail("The batch has been completed."); + } catch (IllegalStateException exception) { + // expected + } + EasyMock.verify(callback); + } + + @Test + public void testNotifySuccess() { + assertFalse(result.completed()); + BatchResult.Callback callback = + EasyMock.createStrictMock(BatchResult.Callback.class); + callback.success(true); + EasyMock.replay(callback); + result.notify(callback); + result.success(true); + try { + result.notify(callback); + fail("The batch has been completed."); + } catch (IllegalStateException exception) { + // expected + } + EasyMock.verify(callback); + } +} diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageBatchTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageBatchTest.java new file mode 100644 index 000000000000..02f14fd457ed --- /dev/null +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageBatchTest.java @@ -0,0 +1,224 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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 org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.google.api.client.googleapis.json.GoogleJsonError; +import com.google.api.services.storage.model.StorageObject; +import com.google.cloud.storage.Storage.BlobGetOption; +import com.google.cloud.storage.Storage.BlobSourceOption; +import com.google.cloud.storage.Storage.BlobTargetOption; +import com.google.cloud.storage.spi.RpcBatch; +import com.google.cloud.storage.spi.StorageRpc; +import com.google.common.collect.ImmutableMap; + +import org.easymock.Capture; +import org.easymock.EasyMock; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.Map; + +public class StorageBatchTest { + + private static final BlobId BLOB_ID = BlobId.of("b1", "n1"); + private static final BlobId BLOB_ID_COMPLETE = BlobId.of("b1", "n1", 42L); + private static final BlobInfo BLOB_INFO = BlobInfo.builder(BLOB_ID).build(); + private static final BlobInfo BLOB_INFO_COMPLETE = BlobInfo.builder(BLOB_ID_COMPLETE) + .metageneration(42L) + .build(); + private static final BlobGetOption[] BLOB_GET_OPTIONS = { + BlobGetOption.generationMatch(42L), BlobGetOption.metagenerationMatch(42L)}; + private static final BlobSourceOption[] BLOB_SOURCE_OPTIONS = { + BlobSourceOption.generationMatch(42L), BlobSourceOption.metagenerationMatch(42L)}; + private static final BlobTargetOption[] BLOB_TARGET_OPTIONS = { + BlobTargetOption.generationMatch(), BlobTargetOption.metagenerationMatch()}; + private static final GoogleJsonError GOOGLE_JSON_ERROR = new GoogleJsonError(); + + private StorageOptions optionsMock; + private StorageRpc dnsRpcMock; + private RpcBatch batchMock; + private StorageBatch dnsBatch; + private final Storage storage = EasyMock.createStrictMock(Storage.class); + + @Before + public void setUp() { + optionsMock = EasyMock.createMock(StorageOptions.class); + dnsRpcMock = EasyMock.createMock(StorageRpc.class); + batchMock = EasyMock.createMock(RpcBatch.class); + EasyMock.expect(optionsMock.rpc()).andReturn(dnsRpcMock); + EasyMock.expect(dnsRpcMock.createBatch()).andReturn(batchMock); + EasyMock.replay(optionsMock, dnsRpcMock, batchMock, storage); + dnsBatch = new StorageBatch(optionsMock); + } + + @After + public void tearDown() { + EasyMock.verify(batchMock, dnsRpcMock, optionsMock, storage); + } + + @Test + public void testConstructor() { + assertSame(batchMock, dnsBatch.batch()); + assertSame(optionsMock, dnsBatch.options()); + assertSame(dnsRpcMock, dnsBatch.storageRpc()); + } + + @Test + public void testDelete() { + EasyMock.reset(batchMock); + Capture> callback = Capture.newInstance(); + batchMock.addDelete(EasyMock.eq(BLOB_INFO.toPb()), EasyMock.capture(callback), + EasyMock.eq(ImmutableMap.of())); + EasyMock.replay(batchMock); + StorageBatchResult batchResult = dnsBatch.delete(BLOB_ID.bucket(), BLOB_ID.name()); + assertNotNull(callback.getValue()); + try { + batchResult.get(); + fail("No result available yet."); + } catch (IllegalStateException ex) { + // expected + } + // testing error here, success is tested with options + RpcBatch.Callback capturedCallback = callback.getValue(); + capturedCallback.onFailure(GOOGLE_JSON_ERROR); + try { + batchResult.get(); + fail("Should throw a StorageExcetion on error."); + } catch (StorageException ex) { + // expected + } + } + + @Test + public void testDeleteWithOptions() { + EasyMock.reset(batchMock); + Capture> callback = Capture.newInstance(); + Capture> capturedOptions = Capture.newInstance(); + batchMock.addDelete(EasyMock.eq(BLOB_INFO.toPb()), EasyMock.capture(callback), + EasyMock.capture(capturedOptions)); + EasyMock.replay(batchMock); + StorageBatchResult batchResult = dnsBatch.delete(BLOB_ID, BLOB_SOURCE_OPTIONS); + assertNotNull(callback.getValue()); + assertEquals(2, capturedOptions.getValue().size()); + for (BlobSourceOption option : BLOB_SOURCE_OPTIONS) { + assertEquals(option.value(), capturedOptions.getValue().get(option.rpcOption())); + } + RpcBatch.Callback capturedCallback = callback.getValue(); + capturedCallback.onSuccess(null); + assertTrue(batchResult.get()); + } + + @Test + public void testUpdate() { + EasyMock.reset(batchMock); + Capture> callback = Capture.newInstance(); + batchMock.addPatch(EasyMock.eq(BLOB_INFO.toPb()), EasyMock.capture(callback), + EasyMock.eq(ImmutableMap.of())); + EasyMock.replay(batchMock); + StorageBatchResult batchResult = dnsBatch.update(BLOB_INFO); + assertNotNull(callback.getValue()); + try { + batchResult.get(); + fail("No result available yet."); + } catch (IllegalStateException ex) { + // expected + } + // testing error here, success is tested with options + RpcBatch.Callback capturedCallback = callback.getValue(); + capturedCallback.onFailure(GOOGLE_JSON_ERROR); + try { + batchResult.get(); + fail("Should throw a StorageExcetion on error."); + } catch (StorageException ex) { + // expected + } + } + + @Test + public void testUpdateWithOptions() { + EasyMock.reset(storage, batchMock, optionsMock); + EasyMock.expect(storage.options()).andReturn(optionsMock).times(2); + EasyMock.expect(optionsMock.service()).andReturn(storage); + Capture> callback = Capture.newInstance(); + Capture> capturedOptions = Capture.newInstance(); + batchMock.addPatch(EasyMock.eq(BLOB_INFO_COMPLETE.toPb()), EasyMock.capture(callback), + EasyMock.capture(capturedOptions)); + EasyMock.replay(batchMock, storage, optionsMock); + StorageBatchResult batchResult = dnsBatch.update(BLOB_INFO_COMPLETE, BLOB_TARGET_OPTIONS); + assertNotNull(callback.getValue()); + assertEquals(2, capturedOptions.getValue().size()); + assertEquals(42L, capturedOptions.getValue().get(BLOB_TARGET_OPTIONS[0].rpcOption())); + assertEquals(42L, capturedOptions.getValue().get(BLOB_TARGET_OPTIONS[1].rpcOption())); + RpcBatch.Callback capturedCallback = callback.getValue(); + capturedCallback.onSuccess(BLOB_INFO.toPb()); + assertEquals(new Blob(storage, new Blob.BuilderImpl(BLOB_INFO)), batchResult.get()); + } + + @Test + public void testGet() { + EasyMock.reset(batchMock); + Capture> callback = Capture.newInstance(); + batchMock.addGet(EasyMock.eq(BLOB_INFO.toPb()), EasyMock.capture(callback), + EasyMock.eq(ImmutableMap.of())); + EasyMock.replay(batchMock); + StorageBatchResult batchResult = dnsBatch.get(BLOB_ID.bucket(), BLOB_ID.name()); + assertNotNull(callback.getValue()); + try { + batchResult.get(); + fail("No result available yet."); + } catch (IllegalStateException ex) { + // expected + } + // testing error here, success is tested with options + RpcBatch.Callback capturedCallback = callback.getValue(); + capturedCallback.onFailure(GOOGLE_JSON_ERROR); + try { + batchResult.get(); + fail("Should throw a StorageExcetion on error."); + } catch (StorageException ex) { + // expected + } + } + + @Test + public void testGetWithOptions() { + EasyMock.reset(storage, batchMock, optionsMock); + EasyMock.expect(storage.options()).andReturn(optionsMock).times(2); + EasyMock.expect(optionsMock.service()).andReturn(storage); + Capture> callback = Capture.newInstance(); + Capture> capturedOptions = Capture.newInstance(); + batchMock.addGet(EasyMock.eq(BLOB_INFO.toPb()), EasyMock.capture(callback), + EasyMock.capture(capturedOptions)); + EasyMock.replay(storage, batchMock, optionsMock); + StorageBatchResult batchResult = dnsBatch.get(BLOB_ID, BLOB_GET_OPTIONS); + assertNotNull(callback.getValue()); + assertEquals(2, capturedOptions.getValue().size()); + for (BlobGetOption option : BLOB_GET_OPTIONS) { + assertEquals(option.value(), capturedOptions.getValue().get(option.rpcOption())); + } + RpcBatch.Callback capturedCallback = callback.getValue(); + capturedCallback.onSuccess(BLOB_INFO.toPb()); + assertEquals(new Blob(storage, new Blob.BuilderImpl(BLOB_INFO)), batchResult.get()); + } +} diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java index b6188df3b3c5..332450bd4b28 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java @@ -19,11 +19,13 @@ import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import com.google.api.client.googleapis.json.GoogleJsonError; import com.google.api.services.storage.model.StorageObject; import com.google.cloud.AuthCredentials.ServiceAccountAuthCredentials; import com.google.cloud.Clock; @@ -32,14 +34,13 @@ import com.google.cloud.RetryParams; import com.google.cloud.WriteChannel; import com.google.cloud.storage.Storage.CopyRequest; +import com.google.cloud.storage.spi.RpcBatch; import com.google.cloud.storage.spi.StorageRpc; import com.google.cloud.storage.spi.StorageRpc.Tuple; import com.google.cloud.storage.spi.StorageRpcFactory; -import com.google.common.base.Function; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Iterables; -import com.google.common.collect.Maps; import com.google.common.io.BaseEncoding; import org.easymock.Capture; @@ -983,82 +984,16 @@ public void testReadAllBytesWithOptionsFromBlobId() { } @Test - public void testApply() { - BatchRequest req = BatchRequest.builder() - .delete(BUCKET_NAME1, BLOB_NAME1) - .update(BLOB_INFO2) - .get(BUCKET_NAME1, BLOB_NAME3) - .build(); - List toDelete = ImmutableList.of(BlobId.of(BUCKET_NAME1, BLOB_NAME1).toPb()); - List toUpdate = ImmutableList.of(BlobId.of(BUCKET_NAME1, BLOB_NAME2).toPb()); - List toGet = ImmutableList.of(BlobId.of(BUCKET_NAME1, BLOB_NAME3).toPb()); - List> deleteOptions = - ImmutableList.>of(EMPTY_RPC_OPTIONS); - List> updateOptions = - ImmutableList.>of(EMPTY_RPC_OPTIONS); - List> getOptions = - ImmutableList.>of(EMPTY_RPC_OPTIONS); - - Map> deleteResult = Maps.toMap(toDelete, - new Function>() { - @Override - public Tuple apply(StorageObject f) { - return Tuple.of(true, null); - } - }); - Map> updateResult = Maps.toMap(toUpdate, - new Function>() { - @Override - public Tuple apply(StorageObject f) { - return Tuple.of(f, null); - } - }); - Map> getResult = Maps.toMap(toGet, - new Function>() { - @Override - public Tuple apply(StorageObject f) { - return Tuple.of(f, null); - } - }); - StorageRpc.BatchResponse res = - new StorageRpc.BatchResponse(deleteResult, updateResult, getResult); - - Capture capturedBatchRequest = Capture.newInstance(); - EasyMock.expect(storageRpcMock.batch(EasyMock.capture(capturedBatchRequest))).andReturn(res); - EasyMock.replay(storageRpcMock); + public void testBatch() { + RpcBatch batchMock = EasyMock.mock(RpcBatch.class); + EasyMock.expect(storageRpcMock.createBatch()).andReturn(batchMock); + EasyMock.replay(batchMock, storageRpcMock); initializeService(); - BatchResponse batchResponse = storage.submit(req); - - // Verify captured StorageRpc.BatchRequest - List>> capturedToDelete = - capturedBatchRequest.getValue().toDelete; - List>> capturedToUpdate = - capturedBatchRequest.getValue().toUpdate; - List>> capturedToGet = - capturedBatchRequest.getValue().toGet; - for (int i = 0; i < capturedToDelete.size(); i++) { - assertEquals(toDelete.get(i), capturedToDelete.get(i).x()); - assertEquals(deleteOptions.get(i), capturedToDelete.get(i).y()); - } - for (int i = 0; i < capturedToUpdate.size(); i++) { - assertEquals(toUpdate.get(i), capturedToUpdate.get(i).x()); - assertEquals(updateOptions.get(i), capturedToUpdate.get(i).y()); - } - for (int i = 0; i < capturedToGet.size(); i++) { - assertEquals(toGet.get(i), capturedToGet.get(i).x()); - assertEquals(getOptions.get(i), capturedToGet.get(i).y()); - } - - // Verify BatchResponse - for (BatchResponse.Result result : batchResponse.deletes()) { - assertTrue(result.get()); - } - for (int i = 0; i < batchResponse.updates().size(); i++) { - assertEquals(toUpdate.get(i), batchResponse.updates().get(i).get().toPb()); - } - for (int i = 0; i < batchResponse.gets().size(); i++) { - assertEquals(toGet.get(i), batchResponse.gets().get(i).get().toPb()); - } + StorageBatch batch = storage.batch(); + assertSame(options, batch.options()); + assertSame(storageRpcMock, batch.storageRpc()); + assertSame(batchMock, batch.batch()); + EasyMock.verify(batchMock); } @Test @@ -1210,129 +1145,143 @@ public void testSignUrlWithOptions() throws NoSuchAlgorithmException, InvalidKey } @Test - public void testGetAll() { + public void testGetAllArray() { BlobId blobId1 = BlobId.of(BUCKET_NAME1, BLOB_NAME1); BlobId blobId2 = BlobId.of(BUCKET_NAME1, BLOB_NAME2); - StorageObject storageObject1 = blobId1.toPb(); - StorageObject storageObject2 = blobId2.toPb(); - List toGet = ImmutableList.of(storageObject1, storageObject2); - - Map> deleteResult = ImmutableMap.of(); - Map> updateResult = ImmutableMap.of(); - Map> getResult = Maps.toMap(toGet, - new Function>() { - @Override - public Tuple apply(StorageObject f) { - return Tuple.of(f, null); - } - }); - StorageRpc.BatchResponse res = - new StorageRpc.BatchResponse(deleteResult, updateResult, getResult); - - Capture capturedBatchRequest = Capture.newInstance(); - EasyMock.expect(storageRpcMock.batch(EasyMock.capture(capturedBatchRequest))).andReturn(res); - EasyMock.replay(storageRpcMock); + RpcBatch batchMock = EasyMock.createMock(RpcBatch.class); + Capture> callback1 = Capture.newInstance(); + Capture> callback2 = Capture.newInstance(); + batchMock.addGet(EasyMock.eq(blobId1.toPb()), EasyMock.capture(callback1), + EasyMock.eq(ImmutableMap.of())); + batchMock.addGet(EasyMock.eq(blobId2.toPb()), EasyMock.capture(callback2), + EasyMock.eq(ImmutableMap.of())); + EasyMock.expect(storageRpcMock.createBatch()).andReturn(batchMock); + batchMock.submit(); + EasyMock.replay(storageRpcMock, batchMock); initializeService(); List resultBlobs = storage.get(blobId1, blobId2); + callback1.getValue().onSuccess(BLOB_INFO1.toPb()); + callback2.getValue().onFailure(new GoogleJsonError()); + assertEquals(2, resultBlobs.size()); + assertEquals(new Blob(storage, new BlobInfo.BuilderImpl(BLOB_INFO1)), resultBlobs.get(0)); + assertNull(resultBlobs.get(1)); + EasyMock.verify(batchMock); + } - // Verify captured StorageRpc.BatchRequest - List>> capturedToGet = - capturedBatchRequest.getValue().toGet; - assertTrue(capturedBatchRequest.getValue().toDelete.isEmpty()); - assertTrue(capturedBatchRequest.getValue().toUpdate.isEmpty()); - for (int i = 0; i < capturedToGet.size(); i++) { - assertEquals(toGet.get(i), capturedToGet.get(i).x()); - assertTrue(capturedToGet.get(i).y().isEmpty()); - } - - // Verify result - for (int i = 0; i < resultBlobs.size(); i++) { - assertEquals(toGet.get(i), resultBlobs.get(i).toPb()); - } + @Test + public void testGetAllArrayIterable() { + BlobId blobId1 = BlobId.of(BUCKET_NAME1, BLOB_NAME1); + BlobId blobId2 = BlobId.of(BUCKET_NAME1, BLOB_NAME2); + RpcBatch batchMock = EasyMock.createMock(RpcBatch.class); + Capture> callback1 = Capture.newInstance(); + Capture> callback2 = Capture.newInstance(); + batchMock.addGet(EasyMock.eq(blobId1.toPb()), EasyMock.capture(callback1), + EasyMock.eq(ImmutableMap.of())); + batchMock.addGet(EasyMock.eq(blobId2.toPb()), EasyMock.capture(callback2), + EasyMock.eq(ImmutableMap.of())); + EasyMock.expect(storageRpcMock.createBatch()).andReturn(batchMock); + batchMock.submit(); + EasyMock.replay(storageRpcMock, batchMock); + initializeService(); + List resultBlobs = storage.get(ImmutableList.of(blobId1, blobId2)); + callback1.getValue().onSuccess(BLOB_INFO1.toPb()); + callback2.getValue().onFailure(new GoogleJsonError()); + assertEquals(2, resultBlobs.size()); + assertEquals(new Blob(storage, new BlobInfo.BuilderImpl(BLOB_INFO1)), resultBlobs.get(0)); + assertNull(resultBlobs.get(1)); + EasyMock.verify(batchMock); } @Test - public void testUpdateAll() { - BlobInfo blobInfo1 = BlobInfo.builder(BUCKET_NAME1, BLOB_NAME1).contentType("type").build(); - BlobInfo blobInfo2 = BlobInfo.builder(BUCKET_NAME1, BLOB_NAME2).contentType("type").build(); - StorageObject storageObject1 = blobInfo1.toPb(); - StorageObject storageObject2 = blobInfo2.toPb(); - List toUpdate = ImmutableList.of(storageObject1, storageObject2); - - Map> deleteResult = ImmutableMap.of(); - Map> getResult = ImmutableMap.of(); - Map> updateResult = Maps.toMap(toUpdate, - new Function>() { - @Override - public Tuple apply(StorageObject f) { - return Tuple.of(f, null); - } - }); - StorageRpc.BatchResponse res = - new StorageRpc.BatchResponse(deleteResult, updateResult, getResult); - - Capture capturedBatchRequest = Capture.newInstance(); - EasyMock.expect(storageRpcMock.batch(EasyMock.capture(capturedBatchRequest))).andReturn(res); - EasyMock.replay(storageRpcMock); + public void testDeleteAllArray() { + BlobId blobId1 = BlobId.of(BUCKET_NAME1, BLOB_NAME1); + BlobId blobId2 = BlobId.of(BUCKET_NAME1, BLOB_NAME2); + RpcBatch batchMock = EasyMock.createMock(RpcBatch.class); + Capture> callback1 = Capture.newInstance(); + Capture> callback2 = Capture.newInstance(); + batchMock.addDelete(EasyMock.eq(blobId1.toPb()), EasyMock.capture(callback1), + EasyMock.eq(ImmutableMap.of())); + batchMock.addDelete(EasyMock.eq(blobId2.toPb()), EasyMock.capture(callback2), + EasyMock.eq(ImmutableMap.of())); + EasyMock.expect(storageRpcMock.createBatch()).andReturn(batchMock); + batchMock.submit(); + EasyMock.replay(storageRpcMock, batchMock); initializeService(); - List resultBlobs = storage.update(blobInfo1, blobInfo2); - - // Verify captured StorageRpc.BatchRequest - List>> capturedToUpdate = - capturedBatchRequest.getValue().toUpdate; - assertTrue(capturedBatchRequest.getValue().toDelete.isEmpty()); - assertTrue(capturedBatchRequest.getValue().toGet.isEmpty()); - for (int i = 0; i < capturedToUpdate.size(); i++) { - assertEquals(toUpdate.get(i), capturedToUpdate.get(i).x()); - assertTrue(capturedToUpdate.get(i).y().isEmpty()); - } + List result = storage.delete(blobId1, blobId2); + callback1.getValue().onSuccess(null); + callback2.getValue().onFailure(new GoogleJsonError()); + assertEquals(2, result.size()); + assertTrue(result.get(0)); + assertFalse(result.get(1)); + EasyMock.verify(batchMock); + } - // Verify result - for (int i = 0; i < resultBlobs.size(); i++) { - assertEquals(toUpdate.get(i), resultBlobs.get(i).toPb()); - } + @Test + public void testDeleteAllIterable() { + BlobId blobId1 = BlobId.of(BUCKET_NAME1, BLOB_NAME1); + BlobId blobId2 = BlobId.of(BUCKET_NAME1, BLOB_NAME2); + RpcBatch batchMock = EasyMock.createMock(RpcBatch.class); + Capture> callback1 = Capture.newInstance(); + Capture> callback2 = Capture.newInstance(); + batchMock.addDelete(EasyMock.eq(blobId1.toPb()), EasyMock.capture(callback1), + EasyMock.eq(ImmutableMap.of())); + batchMock.addDelete(EasyMock.eq(blobId2.toPb()), EasyMock.capture(callback2), + EasyMock.eq(ImmutableMap.of())); + EasyMock.expect(storageRpcMock.createBatch()).andReturn(batchMock); + batchMock.submit(); + EasyMock.replay(storageRpcMock, batchMock); + initializeService(); + List result = storage.delete(blobId1, blobId2); + callback1.getValue().onSuccess(null); + callback2.getValue().onFailure(new GoogleJsonError()); + assertEquals(2, result.size()); + assertTrue(result.get(0)); + assertFalse(result.get(1)); + EasyMock.verify(batchMock); } @Test - public void testDeleteAll() { - BlobInfo blobInfo1 = BlobInfo.builder(BUCKET_NAME1, BLOB_NAME1).build(); - BlobInfo blobInfo2 = BlobInfo.builder(BUCKET_NAME1, BLOB_NAME2).build(); - StorageObject storageObject1 = blobInfo1.toPb(); - StorageObject storageObject2 = blobInfo2.toPb(); - List toUpdate = ImmutableList.of(storageObject1, storageObject2); - - Map> updateResult = ImmutableMap.of(); - Map> getResult = ImmutableMap.of(); - Map> deleteResult = Maps.toMap(toUpdate, - new Function>() { - @Override - public Tuple apply(StorageObject f) { - return Tuple.of(true, null); - } - }); - StorageRpc.BatchResponse res = - new StorageRpc.BatchResponse(deleteResult, updateResult, getResult); - - Capture capturedBatchRequest = Capture.newInstance(); - EasyMock.expect(storageRpcMock.batch(EasyMock.capture(capturedBatchRequest))).andReturn(res); - EasyMock.replay(storageRpcMock); + public void testUpdateAllArray() { + RpcBatch batchMock = EasyMock.createMock(RpcBatch.class); + Capture> callback1 = Capture.newInstance(); + Capture> callback2 = Capture.newInstance(); + batchMock.addPatch(EasyMock.eq(BLOB_INFO1.toPb()), EasyMock.capture(callback1), + EasyMock.eq(ImmutableMap.of())); + batchMock.addPatch(EasyMock.eq(BLOB_INFO2.toPb()), EasyMock.capture(callback2), + EasyMock.eq(ImmutableMap.of())); + EasyMock.expect(storageRpcMock.createBatch()).andReturn(batchMock); + batchMock.submit(); + EasyMock.replay(storageRpcMock, batchMock); initializeService(); - List deleteResults = storage.delete(blobInfo1.blobId(), blobInfo2.blobId()); - - // Verify captured StorageRpc.BatchRequest - List>> capturedToDelete = - capturedBatchRequest.getValue().toDelete; - assertTrue(capturedBatchRequest.getValue().toUpdate.isEmpty()); - assertTrue(capturedBatchRequest.getValue().toGet.isEmpty()); - for (int i = 0; i < capturedToDelete.size(); i++) { - assertEquals(toUpdate.get(i), capturedToDelete.get(i).x()); - assertTrue(capturedToDelete.get(i).y().isEmpty()); - } + List resultBlobs = storage.update(BLOB_INFO1, BLOB_INFO2); + callback1.getValue().onSuccess(BLOB_INFO1.toPb()); + callback2.getValue().onFailure(new GoogleJsonError()); + assertEquals(2, resultBlobs.size()); + assertEquals(new Blob(storage, new BlobInfo.BuilderImpl(BLOB_INFO1)), resultBlobs.get(0)); + assertNull(resultBlobs.get(1)); + EasyMock.verify(batchMock); + } - // Verify result - for (Boolean deleteStatus : deleteResults) { - assertTrue(deleteStatus); - } + @Test + public void testUpdateAllIterable() { + RpcBatch batchMock = EasyMock.createMock(RpcBatch.class); + Capture> callback1 = Capture.newInstance(); + Capture> callback2 = Capture.newInstance(); + batchMock.addPatch(EasyMock.eq(BLOB_INFO1.toPb()), EasyMock.capture(callback1), + EasyMock.eq(ImmutableMap.of())); + batchMock.addPatch(EasyMock.eq(BLOB_INFO2.toPb()), EasyMock.capture(callback2), + EasyMock.eq(ImmutableMap.of())); + EasyMock.expect(storageRpcMock.createBatch()).andReturn(batchMock); + batchMock.submit(); + EasyMock.replay(storageRpcMock, batchMock); + initializeService(); + List resultBlobs = storage.update(ImmutableList.of(BLOB_INFO1, BLOB_INFO2)); + callback1.getValue().onSuccess(BLOB_INFO1.toPb()); + callback2.getValue().onFailure(new GoogleJsonError()); + assertEquals(2, resultBlobs.size()); + assertEquals(new Blob(storage, new BlobInfo.BuilderImpl(BLOB_INFO1)), resultBlobs.get(0)); + assertNull(resultBlobs.get(1)); + EasyMock.verify(batchMock); } @Test diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java index 684653390d1b..5b7fa3a84e63 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java @@ -29,8 +29,6 @@ import com.google.cloud.ReadChannel; import com.google.cloud.RestorableState; import com.google.cloud.WriteChannel; -import com.google.cloud.storage.BatchRequest; -import com.google.cloud.storage.BatchResponse; import com.google.cloud.storage.Blob; import com.google.cloud.storage.BlobId; import com.google.cloud.storage.BlobInfo; @@ -41,6 +39,8 @@ import com.google.cloud.storage.Storage; import com.google.cloud.storage.Storage.BlobField; import com.google.cloud.storage.Storage.BucketField; +import com.google.cloud.storage.StorageBatch; +import com.google.cloud.storage.StorageBatchResult; import com.google.cloud.storage.StorageException; import com.google.cloud.storage.testing.RemoteStorageHelper; import com.google.common.collect.ImmutableList; @@ -81,7 +81,7 @@ public class ITStorageTest { private static final String CONTENT_TYPE = "text/plain"; private static final byte[] BLOB_BYTE_CONTENT = {0xD, 0xE, 0xA, 0xD}; private static final String BLOB_STRING_CONTENT = "Hello Google Cloud Storage!"; - private static final int MAX_BATCH_DELETES = 100; + private static final int MAX_BATCH_SIZE = 100; @BeforeClass public static void beforeClass() { @@ -778,16 +778,12 @@ public void testBatchRequest() { // Batch update request BlobInfo updatedBlob1 = sourceBlob1.toBuilder().contentType(CONTENT_TYPE).build(); BlobInfo updatedBlob2 = sourceBlob2.toBuilder().contentType(CONTENT_TYPE).build(); - BatchRequest updateRequest = BatchRequest.builder() - .update(updatedBlob1) - .update(updatedBlob2) - .build(); - BatchResponse updateResponse = storage.submit(updateRequest); - assertEquals(2, updateResponse.updates().size()); - assertEquals(0, updateResponse.deletes().size()); - assertEquals(0, updateResponse.gets().size()); - BlobInfo remoteUpdatedBlob1 = updateResponse.updates().get(0).get(); - BlobInfo remoteUpdatedBlob2 = updateResponse.updates().get(1).get(); + StorageBatch updateBatch = storage.batch(); + StorageBatchResult updateResult1 = updateBatch.update(updatedBlob1); + StorageBatchResult updateResult2 = updateBatch.update(updatedBlob2); + updateBatch.submit(); + Blob remoteUpdatedBlob1 = updateResult1.get(); + Blob remoteUpdatedBlob2 = updateResult2.get(); assertEquals(sourceBlob1.bucket(), remoteUpdatedBlob1.bucket()); assertEquals(sourceBlob1.name(), remoteUpdatedBlob1.name()); assertEquals(sourceBlob2.bucket(), remoteUpdatedBlob2.bucket()); @@ -796,76 +792,88 @@ public void testBatchRequest() { assertEquals(updatedBlob2.contentType(), remoteUpdatedBlob2.contentType()); // Batch get request - BatchRequest getRequest = BatchRequest.builder() - .get(BUCKET, sourceBlobName1) - .get(BUCKET, sourceBlobName2) - .build(); - BatchResponse getResponse = storage.submit(getRequest); - assertEquals(2, getResponse.gets().size()); - assertEquals(0, getResponse.deletes().size()); - assertEquals(0, getResponse.updates().size()); - BlobInfo remoteBlob1 = getResponse.gets().get(0).get(); - BlobInfo remoteBlob2 = getResponse.gets().get(1).get(); + StorageBatch getBatch = storage.batch(); + StorageBatchResult getResult1 = getBatch.get(BUCKET, sourceBlobName1); + StorageBatchResult getResult2 = getBatch.get(BUCKET, sourceBlobName2); + getBatch.submit(); + Blob remoteBlob1 = getResult1.get(); + Blob remoteBlob2 = getResult2.get(); assertEquals(remoteUpdatedBlob1, remoteBlob1); assertEquals(remoteUpdatedBlob2, remoteBlob2); // Batch delete request - BatchRequest deleteRequest = BatchRequest.builder() - .delete(BUCKET, sourceBlobName1) - .delete(BUCKET, sourceBlobName2) - .build(); - BatchResponse deleteResponse = storage.submit(deleteRequest); - assertEquals(2, deleteResponse.deletes().size()); - assertEquals(0, deleteResponse.gets().size()); - assertEquals(0, deleteResponse.updates().size()); - assertTrue(deleteResponse.deletes().get(0).get()); - assertTrue(deleteResponse.deletes().get(1).get()); + StorageBatch deleteBatch = storage.batch(); + StorageBatchResult deleteResult1 = deleteBatch.delete(BUCKET, sourceBlobName1); + StorageBatchResult deleteResult2 = deleteBatch.delete(BUCKET, sourceBlobName2); + deleteBatch.submit(); + assertTrue(deleteResult1.get()); + assertTrue(deleteResult2.get()); } @Test - public void testBatchRequestManyDeletes() { - List blobsToDelete = Lists.newArrayListWithCapacity(2 * MAX_BATCH_DELETES); - for (int i = 0; i < 2 * MAX_BATCH_DELETES; i++) { - blobsToDelete.add(BlobId.of(BUCKET, "test-batch-request-many-deletes-blob-" + i)); + public void testBatchRequestManyOperations() { + List> deleteResults = + Lists.newArrayListWithCapacity(MAX_BATCH_SIZE); + List> getResults = + Lists.newArrayListWithCapacity(MAX_BATCH_SIZE / 2); + List> updateResults = + Lists.newArrayListWithCapacity(MAX_BATCH_SIZE / 2); + StorageBatch batch = storage.batch(); + for (int i = 0; i < MAX_BATCH_SIZE; i++) { + BlobId blobId = BlobId.of(BUCKET, "test-batch-request-many-operations-blob-" + i); + deleteResults.add(batch.delete(blobId)); + } + for (int i = 0; i < MAX_BATCH_SIZE / 2; i++) { + BlobId blobId = BlobId.of(BUCKET, "test-batch-request-many-operations-blob-" + i); + getResults.add(batch.get(blobId)); } - BatchRequest.Builder builder = BatchRequest.builder(); - for (BlobId blob : blobsToDelete) { - builder.delete(blob); + for (int i = 0; i < MAX_BATCH_SIZE / 2; i++) { + BlobInfo blob = + BlobInfo.builder(BlobId.of(BUCKET, "test-batch-request-many-operations-blob-" + i)) + .build(); + updateResults.add(batch.update(blob)); } - String sourceBlobName1 = "test-batch-request-many-deletes-source-blob-1"; - String sourceBlobName2 = "test-batch-request-many-deletes-source-blob-2"; + + String sourceBlobName1 = "test-batch-request-many-operations-source-blob-1"; + String sourceBlobName2 = "test-batch-request-many-operations-source-blob-2"; BlobInfo sourceBlob1 = BlobInfo.builder(BUCKET, sourceBlobName1).build(); BlobInfo sourceBlob2 = BlobInfo.builder(BUCKET, sourceBlobName2).build(); assertNotNull(storage.create(sourceBlob1)); assertNotNull(storage.create(sourceBlob2)); BlobInfo updatedBlob2 = sourceBlob2.toBuilder().contentType(CONTENT_TYPE).build(); - BatchRequest updateRequest = builder - .get(BUCKET, sourceBlobName1) - .update(updatedBlob2) - .build(); - BatchResponse response = storage.submit(updateRequest); - assertEquals(2 * MAX_BATCH_DELETES, response.deletes().size()); - assertEquals(1, response.updates().size()); - assertEquals(1, response.gets().size()); + StorageBatchResult getResult = batch.get(BUCKET, sourceBlobName1); + StorageBatchResult updateResult = batch.update(updatedBlob2); + + batch.submit(); // Check deletes - for (BatchResponse.Result deleteResult : response.deletes()) { - assertFalse(deleteResult.failed()); - assertFalse(deleteResult.get()); + for (StorageBatchResult failedDeleteResult : deleteResults) { + assertFalse(failedDeleteResult.get()); + } + + // Check gets + for (StorageBatchResult failedGetResult : getResults) { + assertNull(failedGetResult.get()); } + Blob remoteBlob1 = getResult.get(); + assertEquals(sourceBlob1.bucket(), remoteBlob1.bucket()); + assertEquals(sourceBlob1.name(), remoteBlob1.name()); // Check updates - Blob remoteUpdatedBlob2 = response.updates().get(0).get(); + for (StorageBatchResult failedUpdateResult : updateResults) { + try { + failedUpdateResult.get(); + fail("Expected StorageException"); + } catch (StorageException ex) { + // expected + } + } + Blob remoteUpdatedBlob2 = updateResult.get(); assertEquals(sourceBlob2.bucket(), remoteUpdatedBlob2.bucket()); assertEquals(sourceBlob2.name(), remoteUpdatedBlob2.name()); assertEquals(updatedBlob2.contentType(), remoteUpdatedBlob2.contentType()); - // Check gets - Blob remoteBlob1 = response.gets().get(0).get(); - assertEquals(sourceBlob1.bucket(), remoteBlob1.bucket()); - assertEquals(sourceBlob1.name(), remoteBlob1.name()); - assertTrue(remoteBlob1.delete()); assertTrue(remoteUpdatedBlob2.delete()); } @@ -877,25 +885,36 @@ public void testBatchRequestFail() { Blob remoteBlob = storage.create(blob); assertNotNull(remoteBlob); BlobInfo updatedBlob = BlobInfo.builder(BUCKET, blobName, -1L).build(); - BatchRequest batchRequest = BatchRequest.builder() - .update(updatedBlob, Storage.BlobTargetOption.generationMatch()) - .delete(BUCKET, blobName, Storage.BlobSourceOption.generationMatch(-1L)) - .delete(BlobId.of(BUCKET, blobName, -1L)) - .get(BUCKET, blobName, Storage.BlobGetOption.generationMatch(-1L)) - .get(BlobId.of(BUCKET, blobName, -1L)) - .build(); - BatchResponse batchResponse = storage.submit(batchRequest); - assertEquals(1, batchResponse.updates().size()); - assertEquals(2, batchResponse.deletes().size()); - assertEquals(2, batchResponse.gets().size()); - assertTrue(batchResponse.updates().get(0).failed()); - assertTrue(batchResponse.gets().get(0).failed()); - assertFalse(batchResponse.gets().get(1).failed()); - assertNull(batchResponse.gets().get(1).get()); - assertTrue(batchResponse.deletes().get(0).failed()); - assertFalse(batchResponse.deletes().get(1).failed()); - assertFalse(batchResponse.deletes().get(1).get()); - assertTrue(remoteBlob.delete()); + StorageBatch batch = storage.batch(); + StorageBatchResult updateResult = + batch.update(updatedBlob, Storage.BlobTargetOption.generationMatch()); + StorageBatchResult deleteResult1 = + batch.delete(BUCKET, blobName, Storage.BlobSourceOption.generationMatch(-1L)); + StorageBatchResult deleteResult2 = batch.delete(BlobId.of(BUCKET, blobName, -1L)); + StorageBatchResult getResult1 = + batch.get(BUCKET, blobName, Storage.BlobGetOption.generationMatch(-1L)); + StorageBatchResult getResult2 = batch.get(BlobId.of(BUCKET, blobName, -1L)); + batch.submit(); + try { + updateResult.get(); + fail("Expected StorageException"); + } catch (StorageException ex) { + // expected + } + try { + deleteResult1.get(); + fail("Expected StorageException"); + } catch (StorageException ex) { + // expected + } + assertFalse(deleteResult2.get()); + try { + getResult1.get(); + fail("Expected StorageException"); + } catch (StorageException ex) { + // expected + } + assertNull(getResult2.get()); } @Test From e8351974a55ecbb474ba094c5dd8e07647fd7e01 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 20 May 2016 20:58:15 +0200 Subject: [PATCH 355/375] Release 0.2.2 --- gcloud-java-bigquery/pom.xml | 2 +- gcloud-java-compute/pom.xml | 2 +- gcloud-java-contrib/pom.xml | 2 +- gcloud-java-core/pom.xml | 2 +- gcloud-java-datastore/pom.xml | 2 +- gcloud-java-dns/pom.xml | 2 +- gcloud-java-examples/pom.xml | 2 +- gcloud-java-resourcemanager/pom.xml | 2 +- gcloud-java-storage/pom.xml | 2 +- gcloud-java/pom.xml | 2 +- pom.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/gcloud-java-bigquery/pom.xml b/gcloud-java-bigquery/pom.xml index e5db6a5f189e..09cf598b2aad 100644 --- a/gcloud-java-bigquery/pom.xml +++ b/gcloud-java-bigquery/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.2-SNAPSHOT + 0.2.2 gcloud-java-bigquery diff --git a/gcloud-java-compute/pom.xml b/gcloud-java-compute/pom.xml index df53a9a713c6..678f2d7efbff 100644 --- a/gcloud-java-compute/pom.xml +++ b/gcloud-java-compute/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.2-SNAPSHOT + 0.2.2 gcloud-java-compute diff --git a/gcloud-java-contrib/pom.xml b/gcloud-java-contrib/pom.xml index 0ee4f2158287..20ed77c2e8f5 100644 --- a/gcloud-java-contrib/pom.xml +++ b/gcloud-java-contrib/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.2-SNAPSHOT + 0.2.2 gcloud-java-contrib diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml index e7b1242f0f9c..a902906a950f 100644 --- a/gcloud-java-core/pom.xml +++ b/gcloud-java-core/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.2-SNAPSHOT + 0.2.2 gcloud-java-core diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index 367bbe9dc743..b64efde74c5f 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.2-SNAPSHOT + 0.2.2 gcloud-java-datastore diff --git a/gcloud-java-dns/pom.xml b/gcloud-java-dns/pom.xml index 244989231278..44ccc3d0517e 100644 --- a/gcloud-java-dns/pom.xml +++ b/gcloud-java-dns/pom.xml @@ -13,7 +13,7 @@ com.google.cloud gcloud-java-pom - 0.2.2-SNAPSHOT + 0.2.2 gcloud-java-dns diff --git a/gcloud-java-examples/pom.xml b/gcloud-java-examples/pom.xml index ae4e30050fa6..d56df31aa37b 100644 --- a/gcloud-java-examples/pom.xml +++ b/gcloud-java-examples/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.2-SNAPSHOT + 0.2.2 gcloud-java-examples diff --git a/gcloud-java-resourcemanager/pom.xml b/gcloud-java-resourcemanager/pom.xml index fb04cf13299f..35d6282e28e8 100644 --- a/gcloud-java-resourcemanager/pom.xml +++ b/gcloud-java-resourcemanager/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.2-SNAPSHOT + 0.2.2 gcloud-java-resourcemanager diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml index 2f5c42ee2a6a..e48e32b2bef9 100644 --- a/gcloud-java-storage/pom.xml +++ b/gcloud-java-storage/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.2-SNAPSHOT + 0.2.2 gcloud-java-storage diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml index 2df6728d40d8..012717c32b61 100644 --- a/gcloud-java/pom.xml +++ b/gcloud-java/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.2-SNAPSHOT + 0.2.2 diff --git a/pom.xml b/pom.xml index 85b5f0b02ae1..8bed25ea9cb3 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud gcloud-java-pom pom - 0.2.2-SNAPSHOT + 0.2.2 GCloud Java https://github.com/GoogleCloudPlatform/gcloud-java From 4aa33a18f1b870cdb956b06347cac2af9906a592 Mon Sep 17 00:00:00 2001 From: travis-ci Date: Fri, 20 May 2016 20:40:30 +0000 Subject: [PATCH 356/375] Updating version in README files. [ci skip] --- README.md | 6 +++--- gcloud-java-bigquery/README.md | 6 +++--- gcloud-java-compute/README.md | 6 +++--- gcloud-java-contrib/README.md | 6 +++--- gcloud-java-core/README.md | 6 +++--- gcloud-java-datastore/README.md | 6 +++--- gcloud-java-dns/README.md | 6 +++--- gcloud-java-examples/README.md | 6 +++--- gcloud-java-resourcemanager/README.md | 6 +++--- gcloud-java-storage/README.md | 6 +++--- gcloud-java/README.md | 6 +++--- 11 files changed, 33 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 5abe1c50a3db..c5d7c7b1ee58 100644 --- a/README.md +++ b/README.md @@ -34,16 +34,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java - 0.2.1 + 0.2.2 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java:0.2.1' +compile 'com.google.cloud:gcloud-java:0.2.2' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java" % "0.2.1" +libraryDependencies += "com.google.cloud" % "gcloud-java" % "0.2.2" ``` Example Applications diff --git a/gcloud-java-bigquery/README.md b/gcloud-java-bigquery/README.md index ba6d041a7aba..682221240717 100644 --- a/gcloud-java-bigquery/README.md +++ b/gcloud-java-bigquery/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-bigquery - 0.2.1 + 0.2.2 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-bigquery:0.2.1' +compile 'com.google.cloud:gcloud-java-bigquery:0.2.2' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-bigquery" % "0.2.1" +libraryDependencies += "com.google.cloud" % "gcloud-java-bigquery" % "0.2.2" ``` Example Application diff --git a/gcloud-java-compute/README.md b/gcloud-java-compute/README.md index db5461c9a47c..81d46fd1270d 100644 --- a/gcloud-java-compute/README.md +++ b/gcloud-java-compute/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-compute - 0.2.1 + 0.2.2 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-compute:0.2.1' +compile 'com.google.cloud:gcloud-java-compute:0.2.2' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-compute" % "0.2.1" +libraryDependencies += "com.google.cloud" % "gcloud-java-compute" % "0.2.2" ``` Example Application diff --git a/gcloud-java-contrib/README.md b/gcloud-java-contrib/README.md index de1cad8bfdd5..42801649b277 100644 --- a/gcloud-java-contrib/README.md +++ b/gcloud-java-contrib/README.md @@ -16,16 +16,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-contrib - 0.2.1 + 0.2.2 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-contrib:0.2.1' +compile 'com.google.cloud:gcloud-java-contrib:0.2.2' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-contrib" % "0.2.1" +libraryDependencies += "com.google.cloud" % "gcloud-java-contrib" % "0.2.2" ``` Java Versions diff --git a/gcloud-java-core/README.md b/gcloud-java-core/README.md index ac137785f483..b9d33a72437d 100644 --- a/gcloud-java-core/README.md +++ b/gcloud-java-core/README.md @@ -19,16 +19,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-core - 0.2.1 + 0.2.2 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-core:0.2.1' +compile 'com.google.cloud:gcloud-java-core:0.2.2' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-core" % "0.2.1" +libraryDependencies += "com.google.cloud" % "gcloud-java-core" % "0.2.2" ``` Troubleshooting diff --git a/gcloud-java-datastore/README.md b/gcloud-java-datastore/README.md index 00007645032e..e033a5298584 100644 --- a/gcloud-java-datastore/README.md +++ b/gcloud-java-datastore/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-datastore - 0.2.1 + 0.2.2 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-datastore:0.2.1' +compile 'com.google.cloud:gcloud-java-datastore:0.2.2' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-datastore" % "0.2.1" +libraryDependencies += "com.google.cloud" % "gcloud-java-datastore" % "0.2.2" ``` Example Application diff --git a/gcloud-java-dns/README.md b/gcloud-java-dns/README.md index 6e9cb0d25f1a..161617127ef6 100644 --- a/gcloud-java-dns/README.md +++ b/gcloud-java-dns/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-dns - 0.2.1 + 0.2.2 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-dns:0.2.1' +compile 'com.google.cloud:gcloud-java-dns:0.2.2' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-dns" % "0.2.1" +libraryDependencies += "com.google.cloud" % "gcloud-java-dns" % "0.2.2" ``` Example Application diff --git a/gcloud-java-examples/README.md b/gcloud-java-examples/README.md index 84cb6d581d8a..b51af6c09fff 100644 --- a/gcloud-java-examples/README.md +++ b/gcloud-java-examples/README.md @@ -19,16 +19,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-examples - 0.2.1 + 0.2.2 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-examples:0.2.1' +compile 'com.google.cloud:gcloud-java-examples:0.2.2' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-examples" % "0.2.1" +libraryDependencies += "com.google.cloud" % "gcloud-java-examples" % "0.2.2" ``` To run examples from your command line: diff --git a/gcloud-java-resourcemanager/README.md b/gcloud-java-resourcemanager/README.md index a3ad3b30158a..519c0e92a0ac 100644 --- a/gcloud-java-resourcemanager/README.md +++ b/gcloud-java-resourcemanager/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-resourcemanager - 0.2.1 + 0.2.2 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-resourcemanager:0.2.1' +compile 'com.google.cloud:gcloud-java-resourcemanager:0.2.2' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-resourcemanager" % "0.2.1" +libraryDependencies += "com.google.cloud" % "gcloud-java-resourcemanager" % "0.2.2" ``` Example Application diff --git a/gcloud-java-storage/README.md b/gcloud-java-storage/README.md index 4b62c2407664..e5dd12d407b6 100644 --- a/gcloud-java-storage/README.md +++ b/gcloud-java-storage/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-storage - 0.2.1 + 0.2.2 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-storage:0.2.1' +compile 'com.google.cloud:gcloud-java-storage:0.2.2' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-storage" % "0.2.1" +libraryDependencies += "com.google.cloud" % "gcloud-java-storage" % "0.2.2" ``` Example Application diff --git a/gcloud-java/README.md b/gcloud-java/README.md index 7b4d85efb78e..87c1404ce001 100644 --- a/gcloud-java/README.md +++ b/gcloud-java/README.md @@ -27,16 +27,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java - 0.2.1 + 0.2.2 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java:0.2.1' +compile 'com.google.cloud:gcloud-java:0.2.2' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java" % "0.2.1" +libraryDependencies += "com.google.cloud" % "gcloud-java" % "0.2.2" ``` Troubleshooting From 1b913b981840a970e877043a786eee20b3aada38 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 20 May 2016 23:05:49 +0200 Subject: [PATCH 357/375] Update version to 0.2.3-SNAPSHOT --- gcloud-java-bigquery/pom.xml | 2 +- gcloud-java-compute/pom.xml | 2 +- gcloud-java-contrib/pom.xml | 2 +- gcloud-java-core/pom.xml | 2 +- gcloud-java-datastore/pom.xml | 2 +- gcloud-java-dns/pom.xml | 2 +- gcloud-java-examples/pom.xml | 2 +- gcloud-java-resourcemanager/pom.xml | 2 +- gcloud-java-storage/pom.xml | 2 +- gcloud-java/pom.xml | 2 +- pom.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/gcloud-java-bigquery/pom.xml b/gcloud-java-bigquery/pom.xml index 09cf598b2aad..87b0efdd3cff 100644 --- a/gcloud-java-bigquery/pom.xml +++ b/gcloud-java-bigquery/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.2 + 0.2.3-SNAPSHOT gcloud-java-bigquery diff --git a/gcloud-java-compute/pom.xml b/gcloud-java-compute/pom.xml index 678f2d7efbff..57de0db7627f 100644 --- a/gcloud-java-compute/pom.xml +++ b/gcloud-java-compute/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.2 + 0.2.3-SNAPSHOT gcloud-java-compute diff --git a/gcloud-java-contrib/pom.xml b/gcloud-java-contrib/pom.xml index 20ed77c2e8f5..341750b29225 100644 --- a/gcloud-java-contrib/pom.xml +++ b/gcloud-java-contrib/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.2 + 0.2.3-SNAPSHOT gcloud-java-contrib diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml index a902906a950f..8ebc30a629b9 100644 --- a/gcloud-java-core/pom.xml +++ b/gcloud-java-core/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.2 + 0.2.3-SNAPSHOT gcloud-java-core diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index b64efde74c5f..bcbd50334e2f 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.2 + 0.2.3-SNAPSHOT gcloud-java-datastore diff --git a/gcloud-java-dns/pom.xml b/gcloud-java-dns/pom.xml index 44ccc3d0517e..6a18f5c69857 100644 --- a/gcloud-java-dns/pom.xml +++ b/gcloud-java-dns/pom.xml @@ -13,7 +13,7 @@ com.google.cloud gcloud-java-pom - 0.2.2 + 0.2.3-SNAPSHOT gcloud-java-dns diff --git a/gcloud-java-examples/pom.xml b/gcloud-java-examples/pom.xml index d56df31aa37b..ec22aa6b4e0d 100644 --- a/gcloud-java-examples/pom.xml +++ b/gcloud-java-examples/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.2 + 0.2.3-SNAPSHOT gcloud-java-examples diff --git a/gcloud-java-resourcemanager/pom.xml b/gcloud-java-resourcemanager/pom.xml index 35d6282e28e8..64cecd4385ff 100644 --- a/gcloud-java-resourcemanager/pom.xml +++ b/gcloud-java-resourcemanager/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.2 + 0.2.3-SNAPSHOT gcloud-java-resourcemanager diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml index e48e32b2bef9..996ced995ce3 100644 --- a/gcloud-java-storage/pom.xml +++ b/gcloud-java-storage/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.2 + 0.2.3-SNAPSHOT gcloud-java-storage diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml index 012717c32b61..ed6a7115af6e 100644 --- a/gcloud-java/pom.xml +++ b/gcloud-java/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.2 + 0.2.3-SNAPSHOT diff --git a/pom.xml b/pom.xml index 8bed25ea9cb3..862e3c4c20f7 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud gcloud-java-pom pom - 0.2.2 + 0.2.3-SNAPSHOT GCloud Java https://github.com/GoogleCloudPlatform/gcloud-java From fe4c90cba1be85c6885676eb1fa0214318448845 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Sun, 22 May 2016 22:53:08 +0200 Subject: [PATCH 358/375] Implement Pub/Sub management methods, add javadoc and tests (#1015) --- gcloud-java-pubsub/pom.xml | 6 + .../java/com/google/cloud/pubsub/PubSub.java | 217 ++- .../com/google/cloud/pubsub/PubSubImpl.java | 305 ++++- .../com/google/cloud/pubsub/Subscription.java | 2 +- .../google/cloud/pubsub/SubscriptionInfo.java | 8 +- .../java/com/google/cloud/pubsub/Topic.java | 2 +- .../cloud/pubsub/spi/DefaultPubSubRpc.java | 3 +- .../google/cloud/pubsub/BaseSystemTest.java | 431 ++++++ .../google/cloud/pubsub/LocalSystemTest.java | 54 + .../google/cloud/pubsub/PubSubImplTest.java | 1198 +++++++++++++++++ 10 files changed, 2185 insertions(+), 41 deletions(-) create mode 100644 gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/BaseSystemTest.java create mode 100644 gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/LocalSystemTest.java create mode 100644 gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PubSubImplTest.java diff --git a/gcloud-java-pubsub/pom.xml b/gcloud-java-pubsub/pom.xml index 77902a588260..621afa656e37 100644 --- a/gcloud-java-pubsub/pom.xml +++ b/gcloud-java-pubsub/pom.xml @@ -48,6 +48,12 @@ 4.12 test + + org.easymock + easymock + 3.4 + test + diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java index 48de7002d54f..b98315e77a75 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java @@ -101,7 +101,7 @@ private PullOption(Option.OptionType option, Object value) { } /** - * Returns an option to specify the maximum number of messages that can be executed + * Returns an option to specify the maximum number of messages that can be processed * concurrently at any time. */ public static PullOption maxConcurrentCallbacks(int maxConcurrency) { @@ -110,74 +110,275 @@ public static PullOption maxConcurrentCallbacks(int maxConcurrency) { } /** - * A callback to process pulled messages. - * The message will be ack'ed upon successful return or nack'ed if exception is thrown. + * A callback to process pulled messages. The received message will be ack'ed upon successful + * return or nack'ed if exception is thrown. */ interface MessageProcessor { + /** + * Processes the received {@code message}. If this method returns correctly the message is + * ack'ed. If this method throws an exception the message is nack'ed. + */ void process(Message message) throws Exception; } /** - * An interface to control message consumer settings. + * An interface to control a message consumer. */ interface MessageConsumer extends AutoCloseable { + /** + * Stops pulling messages from the subscription associated with this {@code MessageConsumer} and + * frees all resources. Messages that have already been pulled are processed before closing. + */ + @Override + void close() throws Exception; } + /** + * Creates a new topic. + * + * @return the created topic + * @throws PubSubException upon failure + */ Topic create(TopicInfo topic); + /** + * Sends a request for creating a topic. This method returns a {@code Future} object to consume + * the result. {@link Future#get()} returns the created topic or {@code null} if not found. + */ Future createAsync(TopicInfo topic); - // null if not found + /** + * Returns the requested topic or {@code null} if not found. + * + * @throws PubSubException upon failure + */ Topic getTopic(String topic); + /** + * Sends a request for getting a topic. This method returns a {@code Future} object to consume the + * result. {@link Future#get()} returns the requested topic or {@code null} if not found. + * + * @throws PubSubException upon failure + */ Future getTopicAsync(String topic); - // false if not found + /** + * Deletes the requested topic. + * + * @return {@code true} if the topic was deleted, {@code false} if it was not found + */ boolean deleteTopic(String topic); + /** + * Sends a request for deleting a topic. This method returns a {@code Future} object to consume + * the result. {@link Future#get()} returns {@code true} if the topic was deleted, {@code false} + * if it was not found. + */ Future deleteTopicAsync(String topic); + /** + * Lists the topics. This method returns a {@link Page} object that can be used to consume + * paginated results. Use {@link ListOption} to specify the page size or the page token from which + * to start listing topics. + * + * @throws PubSubException upon failure + */ Page listTopics(ListOption... options); + /** + * Sends a request for listing topics. This method returns a {@code Future} object to consume + * the result. {@link Future#get()} returns an {@link AsyncPage} object that can be used to + * asynchronously handle paginated results. Use {@link ListOption} to specify the page size or the + * page token from which to start listing topics. + */ Future> listTopicsAsync(ListOption... options); + /** + * Publishes a message to the provided topic. This method returns a service-generated id for the + * published message. Service-generated ids are guaranteed to be unique within the topic. + * + * @param topic the topic where the message is published + * @param message the message to publish + * @return a unique service-generated id for the message + * @throws PubSubException upon failure, if the topic does not exist or if the message has empty + * payload and no attributes + */ String publish(String topic, Message message); + /** + * Sends a request for publishing a message to the provided topic. This method returns a + * {@code Future} object to consume the result. {@link Future#get()} returns a service-generated + * id for the published message. Service-generated ids are guaranteed to be unique within the + * topic. + * + * @param topic the topic where the message is published + * @param message the message to publish + * @return a {@code Future} for the unique service-generated id for the message + */ Future publishAsync(String topic, Message message); + /** + * Publishes a number of messages to the provided topic. This method returns a list of + * service-generated ids for the published messages. Service-generated ids are guaranteed to be + * unique within the topic. + * + * @param topic the topic where the message is published + * @param message the first message to publish + * @param messages other messages to publish + * @return a list of unique, service-generated, ids. Ids are in the same order as the messages. + * @throws PubSubException upon failure, if the topic does not exist or if one of the messages has + * empty payload and no attributes + */ List publish(String topic, Message message, Message... messages); + /** + * Sends a request to publish a number of messages to the provided topic. This method returns a + * {@code Future} object to consume the result. {@link Future#get()} returns a list of + * service-generated ids for the published messages. Service-generated ids are guaranteed to be + * unique within the topic. + * + * @param topic the topic where the message is published + * @param message the first message to publish + * @param messages other messages to publish + * @return a {@code Future} for the unique, service-generated ids. Ids are in the same order as + * the messages. + */ Future> publishAsync(String topic, Message message, Message... messages); + /** + * Publishes a number of messages to the provided topic. This method returns a list of + * service-generated ids for the published messages. Service-generated ids are guaranteed to be + * unique within the topic. + * + * @param topic the topic where the message is published + * @param messages the messages to publish + * @return a list of unique, service-generated, ids. Ids are in the same order as the messages. + * @throws PubSubException upon failure, if the topic does not exist or if one of the messages has + * empty payload and no attributes + */ List publish(String topic, Iterable messages); + /** + * Sends a request to publish a number of messages to the provided topic. This method returns a + * {@code Future} object to consume the result. {@link Future#get()} returns a list of + * service-generated ids for the published messages. Service-generated ids are guaranteed to be + * unique within the topic. + * + * @param topic the topic where the message is published + * @param messages the messages to publish + * @return a {@code Future} for the unique, service-generated ids. Ids are in the same order as + * the messages + */ Future> publishAsync(String topic, Iterable messages); + /** + * Creates a new subscription. + * + * @return the created subscription + * @throws PubSubException upon failure + */ Subscription create(SubscriptionInfo subscription); + /** + * Sends a request for creating a subscription. This method returns a {@code Future} object to + * consume the result. {@link Future#get()} returns the created subscription or {@code null} if + * not found. + */ Future createAsync(SubscriptionInfo subscription); - // null if not found + /** + * Returns the requested subscription or {@code null} if not found. + */ Subscription getSubscription(String subscription); + /** + * Sends a request for getting a subscription. This method returns a {@code Future} object to + * consume the result. {@link Future#get()} returns the requested subscription or {@code null} if + * not found. + */ Future getSubscriptionAsync(String subscription); + /** + * Sets the push configuration for a specified subscription. This may be used to change a push + * subscription to a pull one (passing a {@code null} {@code pushConfig} parameter) or vice versa. + * This methods can also be used to change the endpoint URL and other attributes of a push + * subscription. Messages will accumulate for delivery regardless of changes to the push + * configuration. + * + * @param subscription the subscription for which to replace push configuration + * @param pushConfig the new push configuration. Use {@code null} to unset it + * @throws PubSubException upon failure, or if the subscription does not exist + */ void replacePushConfig(String subscription, PushConfig pushConfig); + /** + * Sends a request for updating the push configuration for a specified subscription. This may be + * used to change a push subscription to a pull one (passing a {@code null} {@code pushConfig} + * parameter) or vice versa. This methods can also be used to change the endpoint URL and other + * attributes of a push subscription. Messages will accumulate for delivery regardless of changes + * to the push configuration. The method returns a {@code Future} object that can be used to wait + * for the replace operation to be completed. + * + * @param subscription the subscription for which to replace push configuration + * @param pushConfig the new push configuration. Use {@code null} to unset it + * @return a {@code Future} to wait for the replace operation to be completed. + */ Future replacePushConfigAsync(String subscription, PushConfig pushConfig); - // false if not found + /** + * Deletes the requested subscription. + * + * @return {@code true} if the subscription was deleted, {@code false} if it was not found + * @throws PubSubException upon failure + */ boolean deleteSubscription(String subscription); + /** + * Sends a request for deleting a subscription. This method returns a {@code Future} object to + * consume the result. {@link Future#get()} returns {@code true} if the subscription was deleted, + * {@code false} if it was not found. + */ Future deleteSubscriptionAsync(String subscription); + /** + * Lists the subscriptions. This method returns a {@link Page} object that can be used to consume + * paginated results. Use {@link ListOption} to specify the page size or the page token from which + * to start listing subscriptions. + * + * @throws PubSubException upon failure + */ Page listSubscriptions(ListOption... options); + /** + * Sends a request for listing subscriptions. This method returns a {@code Future} object to + * consume the result. {@link Future#get()} returns an {@link AsyncPage} object that can be used + * to asynchronously handle paginated results. Use {@link ListOption} to specify the page size or + * the page token from which to start listing subscriptions. + * + * @throws PubSubException upon failure + */ Future> listSubscriptionsAsync(ListOption... options); + /** + * Lists the identities of the subscriptions for the provided topic. This method returns a + * {@link Page} object that can be used to consume paginated results. Use {@link ListOption} to + * specify the page size or the page token from which to start listing subscriptions. + * + * @param topic the topic for which to list subscriptions + * @throws PubSubException upon failure + */ Page listSubscriptions(String topic, ListOption... options); + /** + * Sends a request for listing the identities of subscriptions for the provided topic. This method + * returns a {@code Future} object to consume the result. {@link Future#get()} returns an + * {@link AsyncPage} object that can be used to asynchronously handle paginated results. Use + * {@link ListOption} to specify the page size or the page token from which to start listing + * subscriptions. + * + * @param topic the topic for which to list subscriptions + */ Future> listSubscriptionsAsync(String topic, ListOption... options); Iterator pull(String subscription, int maxMessages); diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java index bd69103b9819..948f9904b31c 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java @@ -16,22 +16,45 @@ package com.google.cloud.pubsub; +import static com.google.api.client.util.Preconditions.checkArgument; +import static com.google.cloud.pubsub.PubSub.ListOption.OptionType.PAGE_SIZE; +import static com.google.cloud.pubsub.PubSub.ListOption.OptionType.PAGE_TOKEN; import static com.google.common.util.concurrent.Futures.lazyTransform; import com.google.cloud.AsyncPage; +import com.google.cloud.AsyncPageImpl; import com.google.cloud.BaseService; import com.google.cloud.Page; +import com.google.cloud.PageImpl; import com.google.cloud.pubsub.spi.PubSubRpc; import com.google.cloud.pubsub.spi.v1.PublisherApi; +import com.google.cloud.pubsub.spi.v1.SubscriberApi; import com.google.common.base.Function; import com.google.common.base.Throwables; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import com.google.common.util.concurrent.Uninterruptibles; import com.google.protobuf.Empty; +import com.google.pubsub.v1.DeleteSubscriptionRequest; import com.google.pubsub.v1.DeleteTopicRequest; +import com.google.pubsub.v1.GetSubscriptionRequest; import com.google.pubsub.v1.GetTopicRequest; - +import com.google.pubsub.v1.ListSubscriptionsRequest; +import com.google.pubsub.v1.ListSubscriptionsResponse; +import com.google.pubsub.v1.ListTopicSubscriptionsRequest; +import com.google.pubsub.v1.ListTopicSubscriptionsResponse; +import com.google.pubsub.v1.ListTopicsRequest; +import com.google.pubsub.v1.ListTopicsResponse; +import com.google.pubsub.v1.ModifyPushConfigRequest; +import com.google.pubsub.v1.PublishRequest; +import com.google.pubsub.v1.PublishResponse; + +import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; @@ -40,11 +63,96 @@ class PubSubImpl extends BaseService implements PubSub { private final PubSubRpc rpc; + private static final Function EMPTY_TO_VOID_FUNCTION = new Function() { + @Override + public Void apply(Empty empty) { + return null; + } + }; + private static final Function EMPTY_TO_BOOLEAN_FUNCTION = + new Function() { + @Override + public Boolean apply(Empty input) { + return input != null; + } + }; + PubSubImpl(PubSubOptions options) { super(options); rpc = options.rpc(); } + private abstract static class BasePageFetcher implements AsyncPageImpl.NextPageFetcher { + + private static final long serialVersionUID = -2122989557125999209L; + + private final PubSubOptions serviceOptions; + private final Map requestOptions; + + private BasePageFetcher(PubSubOptions serviceOptions, String cursor, + Map requestOptions) { + this.serviceOptions = serviceOptions; + this.requestOptions = + PageImpl.nextRequestOptions(PAGE_TOKEN, cursor, requestOptions); + } + + PubSubOptions serviceOptions() { + return serviceOptions; + } + + Map requestOptions() { + return requestOptions; + } + } + + private static class TopicPageFetcher extends BasePageFetcher { + + private static final long serialVersionUID = -7153536453427361814L; + + TopicPageFetcher(PubSubOptions serviceOptions, String cursor, + Map requestOptions) { + super(serviceOptions, cursor, requestOptions); + } + + @Override + public Future> nextPage() { + return listTopicsAsync(serviceOptions(), requestOptions()); + } + } + + private static class SubscriptionPageFetcher extends BasePageFetcher { + + private static final long serialVersionUID = -5634446170301177992L; + + SubscriptionPageFetcher(PubSubOptions serviceOptions, String cursor, + Map requestOptions) { + super(serviceOptions, cursor, requestOptions); + } + + @Override + public Future> nextPage() { + return listSubscriptionsAsync(serviceOptions(), requestOptions()); + } + } + + private static class SubscriptionNamePageFetcher extends BasePageFetcher { + + private static final long serialVersionUID = 7250525437694464444L; + + private final String topic; + + SubscriptionNamePageFetcher(String topic, PubSubOptions serviceOptions, String cursor, + Map requestOptions) { + super(serviceOptions, cursor, requestOptions); + this.topic = topic; + } + + @Override + public Future> nextPage() { + return listSubscriptionsAsync(topic, serviceOptions(), requestOptions()); + } + } + private static V get(Future future) { try { return Uninterruptibles.getUninterruptibly(future); @@ -86,113 +194,251 @@ public Future deleteTopicAsync(String topic) { DeleteTopicRequest request = DeleteTopicRequest.newBuilder() .setTopic(PublisherApi.formatTopicName(options().projectId(), topic)) .build(); - return lazyTransform(rpc.delete(request), new Function() { + return lazyTransform(rpc.delete(request), EMPTY_TO_BOOLEAN_FUNCTION); + } + + private static ListTopicsRequest listTopicsRequest(PubSubOptions serviceOptions, + Map options) { + ListTopicsRequest.Builder builder = ListTopicsRequest.newBuilder(); + builder.setProject(SubscriberApi.formatProjectName(serviceOptions.projectId())); + Integer pageSize = PAGE_SIZE.get(options); + String pageToken = PAGE_TOKEN.get(options); + if (pageSize != null) { + builder.setPageSize(pageSize); + } + if (pageToken != null) { + builder.setPageToken(pageToken); + } + return builder.build(); + } + + private static Future> listTopicsAsync(final PubSubOptions serviceOptions, + final Map options) { + final ListTopicsRequest request = listTopicsRequest(serviceOptions, options); + Future list = serviceOptions.rpc().list(request); + return lazyTransform(list, new Function>() { @Override - public Boolean apply(Empty input) { - return true; + public AsyncPage apply(ListTopicsResponse listTopicsResponse) { + List topics = listTopicsResponse.getTopicsList() == null ? ImmutableList.of() + : Lists.transform(listTopicsResponse.getTopicsList(), + Topic.fromPbFunction(serviceOptions.service())); + String cursor = listTopicsResponse.getNextPageToken().equals("") ? null + : listTopicsResponse.getNextPageToken(); + return new AsyncPageImpl<>( + new TopicPageFetcher(serviceOptions, cursor, options), cursor, topics); } }); } @Override public Page listTopics(ListOption... options) { - return null; + return get(listTopicsAsync(options)); } @Override public Future> listTopicsAsync(ListOption... options) { - return null; + return listTopicsAsync(options(), optionMap(options)); } @Override public String publish(String topic, Message message) { - return null; + return get(publishAsync(topic, message)); + } + + private static PublishRequest publishRequest(PubSubOptions serviceOptions, String topic, + Iterable messages) { + PublishRequest.Builder builder = PublishRequest.newBuilder(); + builder.setTopic(PublisherApi.formatTopicName(serviceOptions.projectId(), topic)); + builder.addAllMessages(Iterables.transform(messages, Message.TO_PB_FUNCTION)); + return builder.build(); } @Override public Future publishAsync(String topic, Message message) { - return null; + return lazyTransform( + rpc.publish(publishRequest(options(), topic, Collections.singletonList(message))), + new Function() { + @Override + public String apply(PublishResponse publishResponse) { + return publishResponse.getMessageIdsList().get(0); + } + }); } @Override public List publish(String topic, Message message, Message... messages) { - return null; + return publish(topic, Lists.asList(message, messages)); } @Override public Future> publishAsync(String topic, Message message, Message... messages) { - return null; + return publishAsync(topic, Lists.asList(message, messages)); } @Override public List publish(String topic, Iterable messages) { - return null; + return get(publishAsync(topic, messages)); } @Override public Future> publishAsync(String topic, Iterable messages) { - return null; + return lazyTransform(rpc.publish(publishRequest(options(), topic, messages)), + new Function>() { + @Override + public List apply(PublishResponse publishResponse) { + return publishResponse.getMessageIdsList(); + } + }); } @Override public Subscription create(SubscriptionInfo subscription) { - return null; + return get(createAsync(subscription)); } @Override public Future createAsync(SubscriptionInfo subscription) { - return null; + return lazyTransform(rpc.create(subscription.toPb(options().projectId())), + Subscription.fromPbFunction(this)); } @Override public Subscription getSubscription(String subscription) { - return null; + return get(getSubscriptionAsync(subscription)); } @Override public Future getSubscriptionAsync(String subscription) { - return null; + GetSubscriptionRequest request = GetSubscriptionRequest.newBuilder() + .setSubscription(SubscriberApi.formatSubscriptionName(options().projectId(), subscription)) + .build(); + return lazyTransform(rpc.get(request), Subscription.fromPbFunction(this)); } @Override public void replacePushConfig(String subscription, PushConfig pushConfig) { - + get(replacePushConfigAsync(subscription, pushConfig)); } @Override public Future replacePushConfigAsync(String subscription, PushConfig pushConfig) { - return null; + ModifyPushConfigRequest request = ModifyPushConfigRequest.newBuilder() + .setSubscription(SubscriberApi.formatSubscriptionName(options().projectId(), subscription)) + .setPushConfig(pushConfig != null ? pushConfig.toPb() + : com.google.pubsub.v1.PushConfig.getDefaultInstance()) + .build(); + return lazyTransform(rpc.modify(request), EMPTY_TO_VOID_FUNCTION); } @Override public boolean deleteSubscription(String subscription) { - return false; + return get(deleteSubscriptionAsync(subscription)); } @Override public Future deleteSubscriptionAsync(String subscription) { - return null; + DeleteSubscriptionRequest request = DeleteSubscriptionRequest.newBuilder() + .setSubscription(SubscriberApi.formatSubscriptionName(options().projectId(), subscription)) + .build(); + return lazyTransform(rpc.delete(request), EMPTY_TO_BOOLEAN_FUNCTION); + } + + private static ListSubscriptionsRequest listSubscriptionsRequest(PubSubOptions serviceOptions, + Map options) { + ListSubscriptionsRequest.Builder builder = ListSubscriptionsRequest.newBuilder(); + builder.setProject(SubscriberApi.formatProjectName(serviceOptions.projectId())); + Integer pageSize = PAGE_SIZE.getInteger(options); + String pageToken = PAGE_TOKEN.getString(options); + if (pageSize != null) { + builder.setPageSize(pageSize); + } + if (pageToken != null) { + builder.setPageToken(pageToken); + } + return builder.build(); + } + + private static Future> listSubscriptionsAsync( + final PubSubOptions serviceOptions, final Map options) { + final ListSubscriptionsRequest request = listSubscriptionsRequest(serviceOptions, options); + Future list = serviceOptions.rpc().list(request); + return lazyTransform(list, new Function>() { + @Override + public AsyncPage apply(ListSubscriptionsResponse listSubscriptionsResponse) { + List subscriptions = listSubscriptionsResponse.getSubscriptionsList() == null + ? ImmutableList.of() + : Lists.transform(listSubscriptionsResponse.getSubscriptionsList(), + Subscription.fromPbFunction(serviceOptions.service())); + String cursor = listSubscriptionsResponse.getNextPageToken().equals("") ? null + : listSubscriptionsResponse.getNextPageToken(); + return new AsyncPageImpl<>(new SubscriptionPageFetcher(serviceOptions, cursor, options), + cursor, subscriptions); + } + }); } @Override public Page listSubscriptions(ListOption... options) { - return null; + return get(listSubscriptionsAsync(options)); } - @Override public Future> listSubscriptionsAsync(ListOption... options) { - return null; + return listSubscriptionsAsync(options(), optionMap(options)); + } + + private static ListTopicSubscriptionsRequest listSubscriptionsRequest(String topic, + PubSubOptions serviceOptions, Map options) { + ListTopicSubscriptionsRequest.Builder builder = ListTopicSubscriptionsRequest.newBuilder(); + builder.setTopic(PublisherApi.formatTopicName(serviceOptions.projectId(), topic)); + Integer pageSize = PAGE_SIZE.getInteger(options); + String pageToken = PAGE_TOKEN.getString(options); + if (pageSize != null) { + builder.setPageSize(pageSize); + } + if (pageToken != null) { + builder.setPageToken(pageToken); + } + return builder.build(); + } + + private static Future> listSubscriptionsAsync(final String topic, + final PubSubOptions serviceOptions, final Map options) { + final ListTopicSubscriptionsRequest request = + listSubscriptionsRequest(topic, serviceOptions, options); + Future list = serviceOptions.rpc().list(request); + return lazyTransform(list, + new Function>() { + @Override + public AsyncPage apply( + ListTopicSubscriptionsResponse listSubscriptionsResponse) { + List subscriptions = + listSubscriptionsResponse.getSubscriptionsList() == null + ? ImmutableList.of() + : Lists.transform(listSubscriptionsResponse.getSubscriptionsList(), + new Function() { + @Override + public SubscriptionId apply(String compositeSubscription) { + return SubscriptionId.fromPb(compositeSubscription); + } + }); + String cursor = listSubscriptionsResponse.getNextPageToken().equals("") ? null + : listSubscriptionsResponse.getNextPageToken(); + return new AsyncPageImpl<>( + new SubscriptionNamePageFetcher(topic, serviceOptions, cursor, options), cursor, + subscriptions); + } + }); } @Override public Page listSubscriptions(String topic, ListOption... options) { - return null; + return get(listSubscriptionsAsync(topic, options)); } @Override public Future> listSubscriptionsAsync(String topic, ListOption... options) { - return null; + return listSubscriptionsAsync(topic, options(), optionMap(options)); } @Override @@ -279,6 +525,15 @@ public Future modifyAckDeadlineAsync(String subscription, int deadline, Ti return null; } + static Map optionMap(Option... options) { + Map optionMap = Maps.newHashMap(); + for (Option option : options) { + Object prev = optionMap.put(option.optionType(), option.value()); + checkArgument(prev == null, "Duplicate option %s", option); + } + return optionMap; + } + @Override public void close() throws Exception { rpc.close(); diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java index 7dd203a73348..9e1ed2f53579 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Subscription.java @@ -178,7 +178,7 @@ static Function fromPbFunction( return new Function() { @Override public Subscription apply(com.google.pubsub.v1.Subscription subscriptionPb) { - return fromPb(pubsub, subscriptionPb); + return subscriptionPb != null ? fromPb(pubsub, subscriptionPb) : null; } }; } diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionInfo.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionInfo.java index 3c8722d6e6f9..8e619b5bf633 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionInfo.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/SubscriptionInfo.java @@ -102,8 +102,8 @@ public abstract static class Builder { * again during that time (on a best-effort basis). For pull subscriptions, this value is used * as the initial value for the ack deadline. To override the ack deadline value for a given * message, use {@link PubSub#modifyAckDeadline(String, int, TimeUnit, Iterable)}. For push - * delivery, this value is used to set the request timeout for the call to the push endpoint. If - * not specified, the default value of 10 seconds is used. + * delivery, this value is used to set the request timeout for the call to the push endpoint. + * This value must be between 10 and 600 seconds, if not specified, 10 seconds is used. */ public abstract Builder ackDeadLineSeconds(int ackDeadLineSeconds); @@ -216,8 +216,8 @@ public PushConfig pushConfig() { * again during that time (on a best-effort basis). For pull subscriptions, this value is used * as the initial value for the ack deadline. To override the ack deadline value for a given * message, use {@link PubSub#modifyAckDeadline(String, int, TimeUnit, Iterable)}. For push - * delivery, this value is used to set the request timeout for the call to the push endpoint. If - * not specified, the default value of 10 seconds is used. + * delivery, this value is used to set the request timeout for the call to the push endpoint. This + * value must be between 10 and 600 seconds, if not specified, 10 seconds is used. */ public long ackDeadlineSeconds() { return ackDeadlineSeconds; diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Topic.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Topic.java index 4c08e485bb9d..65ed737fc0cd 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Topic.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Topic.java @@ -155,7 +155,7 @@ static Function fromPbFunction(final PubSub p return new Function() { @Override public Topic apply(com.google.pubsub.v1.Topic topicPb) { - return fromPb(pubsub, topicPb); + return topicPb != null ? fromPb(pubsub, topicPb) : null; } }; } diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java index 7878a6d83835..1745b03cf7d7 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java @@ -153,7 +153,7 @@ public V apply(ApiException exception) { @Override public Future create(Topic topic) { - // TODO: it would be nice if we can get the idempotent inforamtion from the ApiCallSettings + // TODO: it would be nice if we can get the idempotent information from the ApiCallSettings // or from the exception return translate(publisherApi.createTopicCallable().futureCall(topic), true); } @@ -185,7 +185,6 @@ public Future list(ListTopicSubscriptionsRequest @Override public Future delete(DeleteTopicRequest request) { - // TODO: check if null is not going to work for Empty return translate(publisherApi.deleteTopicCallable().futureCall(request), true, Code.NOT_FOUND.value()); } diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/BaseSystemTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/BaseSystemTest.java new file mode 100644 index 000000000000..3360632b45ce --- /dev/null +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/BaseSystemTest.java @@ -0,0 +1,431 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import com.google.cloud.AsyncPage; +import com.google.cloud.Page; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Sets; + +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +/** + * A base class for system tests. This class can be extended to run system tests in different + * environments (e.g. local emulator or remote Pub/Sub service). + */ +public abstract class BaseSystemTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + /** + * Returns the Pub/Sub service used to issue requests. This service can be such that it interacts + * with the remote Pub/Sub service (for integration tests) or with an emulator + * (for local testing). + */ + protected abstract PubSub pubsub(); + + /** + * Formats a resource name for testing purpose. For instance, for tests against the remote + * service, it is recommended to append to the name a random or time-based seed to prevent + * name clashes. + */ + protected abstract String formatForTest(String resourceName); + + @Test + public void testCreateGetAndDeleteTopic() { + String name = formatForTest("test-create-get-delete-topic"); + Topic topic = pubsub().create(TopicInfo.of(name)); + assertEquals(name, topic.name()); + Topic remoteTopic = pubsub().getTopic(name); + assertEquals(topic, remoteTopic); + assertTrue(topic.delete()); + } + + @Test + public void testGetTopic_NotExist() { + String name = formatForTest("test-get-non-existing-topic"); + assertNull(pubsub().getTopic(name)); + } + + @Test + public void testDeleteTopic_NotExist() { + assertFalse(pubsub().deleteTopic(formatForTest("test-delete-non-existing-topic"))); + } + + @Test + public void testCreateGetAndDeleteTopicAsync() throws ExecutionException, InterruptedException { + String name = formatForTest("test-create-get-delete-async-topic"); + Future topicFuture = pubsub().createAsync(TopicInfo.of(name)); + Topic createdTopic = topicFuture.get(); + assertEquals(name, createdTopic.name()); + topicFuture = pubsub().getTopicAsync(name); + assertEquals(createdTopic, topicFuture.get()); + assertTrue(createdTopic.deleteAsync().get()); + } + + @Test + public void testListTopics() { + Topic topic1 = pubsub().create(TopicInfo.of(formatForTest("test-list-topic1"))); + Topic topic2 = pubsub().create(TopicInfo.of(formatForTest("test-list-topic2"))); + Topic topic3 = pubsub().create(TopicInfo.of(formatForTest("test-list-topic3"))); + Set topicNames = Sets.newHashSet(); + // We use 1 as page size to force pagination + Page topics = pubsub().listTopics(PubSub.ListOption.pageSize(1)); + Iterator iterator = topics.iterateAll(); + while (iterator.hasNext()) { + topicNames.add(iterator.next().name()); + } + assertTrue(topicNames.contains(topic1.name())); + assertTrue(topicNames.contains(topic2.name())); + assertTrue(topicNames.contains(topic3.name())); + assertTrue(topic1.delete()); + assertTrue(topic2.delete()); + assertTrue(topic3.delete()); + } + + @Test + public void testListTopicsAsync() throws ExecutionException, InterruptedException { + Topic topic1 = pubsub().create(TopicInfo.of(formatForTest("test-list-async-topic1"))); + Topic topic2 = pubsub().create(TopicInfo.of(formatForTest("test-list-async-topic2"))); + Topic topic3 = pubsub().create(TopicInfo.of(formatForTest("test-list-async-topic3"))); + Set topicNames = Sets.newHashSet(); + Future> pageFuture = pubsub().listTopicsAsync(PubSub.ListOption.pageSize(1)); + Iterator iterator = pageFuture.get().iterateAll(); + while (iterator.hasNext()) { + topicNames.add(iterator.next().name()); + } + assertTrue(topicNames.contains(topic1.name())); + assertTrue(topicNames.contains(topic2.name())); + assertTrue(topicNames.contains(topic3.name())); + assertTrue(topic1.delete()); + assertTrue(topic2.delete()); + assertTrue(topic3.delete()); + } + + @Test + public void testPublishOneMessage() { + String topic = formatForTest("test-publish-one-message-topic"); + pubsub().create(TopicInfo.of(topic)); + Message message = Message.of("payload"); + assertNotNull(pubsub().publish(topic, message)); + assertTrue(pubsub().deleteTopic(topic)); + } + + @Test + public void testPublishNonExistingTopic() { + String topic = formatForTest("test-publish-non-existing-topic"); + Message message = Message.of("payload"); + thrown.expect(PubSubException.class); + pubsub().publish(topic, message); + } + + @Test + public void testPublishOneMessageAsync() throws ExecutionException, InterruptedException { + String topic = formatForTest("test-publish-one-message-async-topic"); + pubsub().create(TopicInfo.of(topic)); + Message message = Message.of("payload"); + Future publishFuture = pubsub().publishAsync(topic, message); + assertNotNull(publishFuture.get()); + assertTrue(pubsub().deleteTopic(topic)); + } + + @Test + public void testPublishMoreMessages() { + String topic = formatForTest("test-publish-more-messages-topic"); + pubsub().create(TopicInfo.of(topic)); + Message message1 = Message.of("payload1"); + Message message2 = Message.of("payload2"); + List messageIds = pubsub().publish(topic, message1, message2); + assertEquals(2, messageIds.size()); + assertTrue(pubsub().deleteTopic(topic)); + } + + @Test + public void testPublishMoreMessagesAsync() throws ExecutionException, InterruptedException { + String topic = formatForTest("test-publish-more-messages-topic-async-topic"); + pubsub().create(TopicInfo.of(topic)); + Message message1 = Message.of("payload1"); + Message message2 = Message.of("payload2"); + Future> publishFuture = pubsub().publishAsync(topic, message1, message2); + assertEquals(2, publishFuture.get().size()); + assertTrue(pubsub().deleteTopic(topic)); + } + + @Test + public void testPublishMessageList() { + String topic = formatForTest("test-publish-message-list-topic"); + pubsub().create(TopicInfo.of(topic)); + Message message1 = Message.of("payload1"); + Message message2 = Message.of("payload2"); + List messageIds = pubsub().publish(topic, ImmutableList.of(message1, message2)); + assertEquals(2, messageIds.size()); + assertTrue(pubsub().deleteTopic(topic)); + } + + @Test + public void testPublishMessagesListAsync() throws ExecutionException, InterruptedException { + String topic = formatForTest("test-publish-message-list-async-topic"); + pubsub().create(TopicInfo.of(topic)); + Message message1 = Message.of("payload1"); + Message message2 = Message.of("payload2"); + Future> publishFuture = + pubsub().publishAsync(topic, ImmutableList.of(message1, message2)); + assertEquals(2, publishFuture.get().size()); + assertTrue(pubsub().deleteTopic(topic)); + } + + @Test + public void testCreateGetAndDeleteSubscription() { + String topic = formatForTest("test-create-get-delete-subscription-topic"); + pubsub().create(TopicInfo.of(topic)); + String name = formatForTest("test-create-get-delete-subscription"); + Subscription subscription = pubsub().create(SubscriptionInfo.of(topic, name)); + assertEquals(TopicId.of(pubsub().options().projectId(), topic), subscription.topic()); + assertEquals(name, subscription.name()); + assertNull(subscription.pushConfig()); + // todo(mziccard) seems not to work on the emulator (returns 60) - see #989 + // assertEquals(10, subscription.ackDeadlineSeconds()); + Subscription remoteSubscription = pubsub().getSubscription(name); + assertEquals(subscription, remoteSubscription); + assertTrue(subscription.delete()); + assertTrue(pubsub().deleteTopic(topic)); + } + + @Test + public void testGetSubscription_NotExist() { + assertNull(pubsub().getSubscription(formatForTest("test-get-non-existing-subscription"))); + } + + @Test + public void testDeleteSubscription_NotExist() { + assertFalse( + pubsub().deleteSubscription(formatForTest("test-delete-non-existing-subscription"))); + } + + @Test + public void testCreateGetAndDeleteSubscriptionAsync() + throws ExecutionException, InterruptedException { + String topic = formatForTest("test-create-get-delete-async-subscription-topic"); + pubsub().create(TopicInfo.of(topic)); + String name = formatForTest("test-create-get-delete-async-subscription"); + String endpoint = "https://" + pubsub().options().projectId() + ".appspot.com/push"; + PushConfig pushConfig = PushConfig.of(endpoint); + Future subscriptionFuture = + pubsub().createAsync(SubscriptionInfo.builder(topic, name).pushConfig(pushConfig).build()); + Subscription subscription = subscriptionFuture.get(); + assertEquals(TopicId.of(pubsub().options().projectId(), topic), subscription.topic()); + assertEquals(name, subscription.name()); + assertEquals(pushConfig, subscription.pushConfig()); + // todo(mziccard) seems not to work on the emulator (returns 60) - see #989 + // assertEquals(10, subscription.ackDeadlineSeconds()); + subscriptionFuture = pubsub().getSubscriptionAsync(name); + Subscription remoteSubscription = subscriptionFuture.get(); + assertEquals(subscription, remoteSubscription); + assertTrue(subscription.deleteAsync().get()); + assertTrue(pubsub().deleteTopic(topic)); + } + + @Test + @Ignore("Emulator incosistency; see issue ##988") + public void testGetSubscriptionDeletedTopic() { + String topic = formatForTest("test-get-deleted-topic-subscription-topic"); + pubsub().create(TopicInfo.of(topic)); + String name = formatForTest("test-get-deleted-topic-subscription"); + Subscription subscription = pubsub().create(SubscriptionInfo.of(topic, name)); + assertEquals(TopicId.of(pubsub().options().projectId(), topic), subscription.topic()); + assertEquals(name, subscription.name()); + assertNull(subscription.pushConfig()); + // todo(mziccard) seems not to work on the emulator (returns 60) - see #989 + // assertEquals(10, subscription.ackDeadlineSeconds()); + assertTrue(pubsub().deleteTopic(topic)); + assertNull(pubsub().getTopic(topic)); + Subscription remoteSubscription = pubsub().getSubscription(name); + assertEquals(TopicId.of("_deleted-topic_"), remoteSubscription.topic()); + assertEquals(name, remoteSubscription.name()); + assertNull(remoteSubscription.pushConfig()); + assertTrue(subscription.delete()); + } + + @Test + public void testReplaceSubscriptionPushConfig() { + String topic = formatForTest("test-replace-push-config-topic"); + pubsub().create(TopicInfo.of(topic)); + String name = formatForTest("test-replace-push-config-subscription"); + String endpoint = "https://" + pubsub().options().projectId() + ".appspot.com/push"; + PushConfig pushConfig = PushConfig.of(endpoint); + Subscription subscription = + pubsub().create(SubscriptionInfo.builder(topic, name).pushConfig(pushConfig).build()); + assertEquals(TopicId.of(pubsub().options().projectId(), topic), subscription.topic()); + assertEquals(name, subscription.name()); + assertEquals(pushConfig, subscription.pushConfig()); + // todo(mziccard) seems not to work on the emulator (returns 60) - see #989 + // assertEquals(10, subscription.ackDeadlineSeconds()); + pubsub().replacePushConfig(name, null); + Subscription remoteSubscription = pubsub().getSubscription(name); + assertEquals(TopicId.of(pubsub().options().projectId(), topic), remoteSubscription.topic()); + assertEquals(name, remoteSubscription.name()); + assertNull(remoteSubscription.pushConfig()); + // todo(mziccard) seems not to work on the emulator (returns 60) - see #989 + // assertEquals(10, remoteSubscription.ackDeadlineSeconds()); + assertTrue(subscription.delete()); + assertTrue(pubsub().deleteTopic(topic)); + } + + @Test + public void testReplaceNonExistingSubscriptionPushConfig() { + String name = formatForTest("test-replace-push-config-non-existing-subscription"); + thrown.expect(PubSubException.class); + pubsub().replacePushConfig(name, null); + } + + @Test + public void testReplaceSubscriptionPushConfigAsync() + throws ExecutionException, InterruptedException { + String topic = formatForTest("test-replace-push-config-async-topic"); + pubsub().create(TopicInfo.of(topic)); + String name = formatForTest("test-replace-push-config-async-subscription"); + Future subscriptionFuture = + pubsub().createAsync(SubscriptionInfo.of(topic, name)); + Subscription subscription = subscriptionFuture.get(); + assertEquals(TopicId.of(pubsub().options().projectId(), topic), subscription.topic()); + assertEquals(name, subscription.name()); + assertNull(subscription.pushConfig()); + // todo(mziccard) seems not to work on the emulator (returns 60) - see #989 + // assertEquals(10, subscription.ackDeadlineSeconds()); + String endpoint = "https://" + pubsub().options().projectId() + ".appspot.com/push"; + PushConfig pushConfig = PushConfig.of(endpoint); + pubsub().replacePushConfigAsync(name, pushConfig).get(); + Subscription remoteSubscription = pubsub().getSubscriptionAsync(name).get(); + assertEquals(TopicId.of(pubsub().options().projectId(), topic), remoteSubscription.topic()); + assertEquals(name, remoteSubscription.name()); + assertEquals(pushConfig, remoteSubscription.pushConfig()); + // todo(mziccard) seems not to work on the emulator (returns 60) - see #989 + // assertEquals(10, remoteSubscription.ackDeadlineSeconds()); + assertTrue(subscription.deleteAsync().get()); + assertTrue(pubsub().deleteTopic(topic)); + } + + @Test + public void testListSubscriptions() { + String topicName1 = formatForTest("test-list-subscriptions-topic1"); + String topicName2 = formatForTest("test-list-subscriptions-topic2"); + Topic topic1 = pubsub().create(TopicInfo.of(topicName1)); + Topic topic2 = pubsub().create(TopicInfo.of(topicName2)); + String subscriptionName1 = formatForTest("test-list-subscriptions-subscription1"); + String subscriptionName2 = formatForTest("test-list-subscriptions-subscription2"); + String subscriptionName3 = formatForTest("test-list-subscriptions-subscription3"); + Subscription subscription1 = + pubsub().create(SubscriptionInfo.of(topicName1, subscriptionName1)); + Subscription subscription2 = + pubsub().create(SubscriptionInfo.of(topicName1, subscriptionName2)); + Subscription subscription3 = + pubsub().create(SubscriptionInfo.of(topicName2, subscriptionName3)); + Set subscriptionNames = Sets.newHashSet(); + // We use 1 as page size to force pagination + Page subscriptions = pubsub().listSubscriptions(PubSub.ListOption.pageSize(1)); + Iterator iterator = subscriptions.iterateAll(); + while (iterator.hasNext()) { + String name = iterator.next().name(); + subscriptionNames.add(name); + } + assertTrue(subscriptionNames.contains(subscriptionName1)); + assertTrue(subscriptionNames.contains(subscriptionName2)); + assertTrue(subscriptionNames.contains(subscriptionName3)); + Set topicSubscriptionNames = Sets.newHashSet(); + Page topic1Subscriptions = + topic1.listSubscriptions(PubSub.ListOption.pageSize(1)); + Iterator firstStringPageIterator = topic1Subscriptions.values().iterator(); + topicSubscriptionNames.add(firstStringPageIterator.next().subscription()); + assertFalse(firstStringPageIterator.hasNext()); + Iterator topicSubscriptionsIterator = + topic1Subscriptions.nextPage().iterateAll(); + while (topicSubscriptionsIterator.hasNext()) { + topicSubscriptionNames.add(topicSubscriptionsIterator.next().subscription()); + } + assertEquals(2, topicSubscriptionNames.size()); + assertTrue(topicSubscriptionNames.contains(subscriptionName1)); + assertTrue(topicSubscriptionNames.contains(subscriptionName2)); + assertTrue(topic1.delete()); + assertTrue(topic2.delete()); + assertTrue(subscription1.delete()); + assertTrue(subscription2.delete()); + assertTrue(subscription3.delete()); + } + + @Test + public void testListSubscriptionsAsync() throws ExecutionException, InterruptedException { + String topicName1 = formatForTest("test-list-subscriptions-async-topic1"); + String topicName2 = formatForTest("test-list-subscriptions-async-topic2"); + Topic topic1 = pubsub().create(TopicInfo.of(topicName1)); + Topic topic2 = pubsub().create(TopicInfo.of(topicName2)); + String subscriptionName1 = formatForTest("test-list-subscriptions-async-subscription1"); + String subscriptionName2 = formatForTest("test-list-subscriptions-async-subscription2"); + String subscriptionName3 = formatForTest("test-list-subscriptions-async-subscription3"); + Subscription subscription1 = + pubsub().create(SubscriptionInfo.of(topicName1, subscriptionName1)); + Subscription subscription2 = + pubsub().create(SubscriptionInfo.of(topicName1, subscriptionName2)); + Subscription subscription3 = + pubsub().create(SubscriptionInfo.of(topicName2, subscriptionName3)); + // We use 1 as page size to force pagination + Set subscriptionNames = Sets.newHashSet(); + Future> pageFuture = + pubsub().listSubscriptionsAsync(PubSub.ListOption.pageSize(1)); + Iterator iterator = pageFuture.get().iterateAll(); + while (iterator.hasNext()) { + subscriptionNames.add(iterator.next().name()); + } + assertTrue(subscriptionNames.contains(subscriptionName1)); + assertTrue(subscriptionNames.contains(subscriptionName2)); + assertTrue(subscriptionNames.contains(subscriptionName3)); + Set topicSubscriptionNames = Sets.newHashSet(); + AsyncPage topic1Subscriptions = + topic1.listSubscriptionsAsync(PubSub.ListOption.pageSize(1)).get(); + Iterator firstStringPageIterator = topic1Subscriptions.values().iterator(); + topicSubscriptionNames.add(firstStringPageIterator.next().subscription()); + assertFalse(firstStringPageIterator.hasNext()); + Iterator topicSubscriptionsIterator = + topic1Subscriptions.nextPageAsync().get().iterateAll(); + while (topicSubscriptionsIterator.hasNext()) { + topicSubscriptionNames.add(topicSubscriptionsIterator.next().subscription()); + } + assertEquals(2, topicSubscriptionNames.size()); + assertTrue(topicSubscriptionNames.contains(subscriptionName1)); + assertTrue(topicSubscriptionNames.contains(subscriptionName2)); + assertTrue(topic1.delete()); + assertTrue(topic2.delete()); + assertTrue(subscription1.delete()); + assertTrue(subscription2.delete()); + assertTrue(subscription3.delete()); + } +} diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/LocalSystemTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/LocalSystemTest.java new file mode 100644 index 000000000000..618a2b9bd926 --- /dev/null +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/LocalSystemTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import com.google.cloud.pubsub.testing.LocalPubsubHelper; + +import org.junit.AfterClass; +import org.junit.BeforeClass; + +import java.io.IOException; + +public class LocalSystemTest extends BaseSystemTest { + + private static LocalPubsubHelper pubsubHelper; + private static PubSub pubsub; + + @Override + protected PubSub pubsub() { + return pubsub; + } + + @Override + protected String formatForTest(String resourceName) { + return resourceName; + } + + @BeforeClass + public static void startServer() throws IOException, InterruptedException { + pubsubHelper = new LocalPubsubHelper(); + pubsubHelper.start(); + pubsub = pubsubHelper.options().service(); + } + + @AfterClass + public static void stopServer() throws Exception { + pubsub.options().rpc().close(); + pubsubHelper.reset(); + pubsubHelper.stop(); + } +} diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PubSubImplTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PubSubImplTest.java new file mode 100644 index 000000000000..f9817d72b6b0 --- /dev/null +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PubSubImplTest.java @@ -0,0 +1,1198 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static com.google.cloud.pubsub.spi.v1.SubscriberApi.formatSubscriptionName; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import com.google.cloud.AsyncPage; +import com.google.cloud.Page; +import com.google.cloud.RetryParams; +import com.google.cloud.pubsub.PubSub.ListOption; +import com.google.cloud.pubsub.spi.PubSubRpc; +import com.google.cloud.pubsub.spi.PubSubRpcFactory; +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Iterables; +import com.google.common.collect.Iterators; +import com.google.common.collect.Lists; +import com.google.common.util.concurrent.Futures; +import com.google.protobuf.Empty; +import com.google.pubsub.v1.DeleteSubscriptionRequest; +import com.google.pubsub.v1.DeleteTopicRequest; +import com.google.pubsub.v1.GetSubscriptionRequest; +import com.google.pubsub.v1.GetTopicRequest; +import com.google.pubsub.v1.ListSubscriptionsRequest; +import com.google.pubsub.v1.ListSubscriptionsResponse; +import com.google.pubsub.v1.ListTopicSubscriptionsRequest; +import com.google.pubsub.v1.ListTopicSubscriptionsResponse; +import com.google.pubsub.v1.ListTopicsRequest; +import com.google.pubsub.v1.ListTopicsResponse; +import com.google.pubsub.v1.ModifyPushConfigRequest; +import com.google.pubsub.v1.PublishRequest; +import com.google.pubsub.v1.PublishResponse; + +import org.easymock.EasyMock; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +public class PubSubImplTest { + + private static final String PROJECT = "project"; + private static final String PROJECT_PB = "projects/project"; + private static final String TOPIC = "topic"; + private static final String TOPIC_NAME_PB = "projects/project/topics/topic"; + private static final TopicInfo TOPIC_INFO = TopicInfo.of(TOPIC); + private static final Function TOPIC_TO_PB_FUNCTION = + new Function() { + @Override + public com.google.pubsub.v1.Topic apply(TopicInfo topicInfo) { + return topicInfo.toPb(PROJECT); + } + }; + private static final Message MESSAGE = Message.of("payload"); + private static final String SUBSCRIPTION = "subscription"; + private static final String SUBSCRIPTION_NAME_PB = "projects/project/subscriptions/subscription"; + private static final PushConfig PUSH_CONFIG = PushConfig.of("endpoint"); + private static final SubscriptionInfo SUBSCRIPTION_INFO = + SubscriptionInfo.builder(TOPIC, SUBSCRIPTION) + .ackDeadLineSeconds(42) + .pushConfig(PUSH_CONFIG) + .build(); + private static final SubscriptionInfo COMPLETE_SUBSCRIPTION_INFO = + SubscriptionInfo.builder(TopicId.of(PROJECT, TOPIC), SUBSCRIPTION) + .ackDeadLineSeconds(42) + .pushConfig(PUSH_CONFIG) + .build(); + private static final Function + SUBSCRIPTION_TO_PB_FUNCTION = + new Function() { + @Override + public com.google.pubsub.v1.Subscription apply(SubscriptionInfo subscriptionInfo) { + return subscriptionInfo.toPb(PROJECT); + } + }; + private static final Function SUBSCRIPTION_ID_TO_PB_FUNCTION = + new Function() { + @Override + public String apply(SubscriptionId subscriptionId) { + return formatSubscriptionName(subscriptionId.project(), subscriptionId.subscription()); + } + }; + + private PubSubOptions options; + private PubSubRpcFactory rpcFactoryMock; + private PubSubRpc pubsubRpcMock; + private PubSub pubsub; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Before + public void setUp() { + rpcFactoryMock = EasyMock.createStrictMock(PubSubRpcFactory.class); + pubsubRpcMock = EasyMock.createStrictMock(PubSubRpc.class); + EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(PubSubOptions.class))) + .andReturn(pubsubRpcMock).times(1); + options = PubSubOptions.builder() + .projectId(PROJECT) + .serviceRpcFactory(rpcFactoryMock) + .retryParams(RetryParams.noRetries()) + .build(); + EasyMock.replay(rpcFactoryMock, pubsubRpcMock); + EasyMock.reset(pubsubRpcMock); + } + + @After + public void tearDown() { + EasyMock.verify(rpcFactoryMock, pubsubRpcMock); + } + + @Test + public void testGetOptions() { + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + assertSame(options, pubsub.options()); + } + + @Test + public void testCreateTopic() { + com.google.pubsub.v1.Topic topicPb = TOPIC_INFO.toPb(PROJECT); + Future response = Futures.immediateFuture(topicPb); + EasyMock.expect(pubsubRpcMock.create(topicPb)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + Topic topic = pubsub.create(TOPIC_INFO); + assertEquals(new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO)), topic); + } + + @Test + public void testCreateTopicAsync() throws ExecutionException, InterruptedException { + com.google.pubsub.v1.Topic topicPb = TOPIC_INFO.toPb(PROJECT); + Future response = Futures.immediateFuture(topicPb); + EasyMock.expect(pubsubRpcMock.create(topicPb)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + Topic topic = pubsub.createAsync(TOPIC_INFO).get(); + assertEquals(new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO)), topic); + } + + @Test + public void testGetTopic() { + GetTopicRequest request = GetTopicRequest.newBuilder().setTopic(TOPIC_NAME_PB).build(); + Future response = + Futures.immediateFuture(TOPIC_INFO.toPb(PROJECT)); + EasyMock.expect(pubsubRpcMock.get(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + Topic topic = pubsub.getTopic(TOPIC); + assertEquals(new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO)), topic); + } + + @Test + public void testGetTopic_Null() { + GetTopicRequest request = GetTopicRequest.newBuilder().setTopic(TOPIC_NAME_PB).build(); + Future responseFuture = Futures.immediateFuture(null); + EasyMock.expect(pubsubRpcMock.get(request)).andReturn(responseFuture); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + assertNull(pubsub.getTopic(TOPIC)); + } + + @Test + public void testGetTopicAsync() throws ExecutionException, InterruptedException { + GetTopicRequest request = GetTopicRequest.newBuilder().setTopic(TOPIC_NAME_PB).build(); + Future response = + Futures.immediateFuture(TOPIC_INFO.toPb(PROJECT)); + EasyMock.expect(pubsubRpcMock.get(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + Future topicFuture = pubsub.getTopicAsync(TOPIC); + assertEquals(new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO)), topicFuture.get()); + } + + @Test + public void testGetTopicAsync_Null() throws ExecutionException, InterruptedException { + GetTopicRequest request = GetTopicRequest.newBuilder().setTopic(TOPIC_NAME_PB).build(); + Future responseFuture = Futures.immediateFuture(null); + EasyMock.expect(pubsubRpcMock.get(request)).andReturn(responseFuture); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + assertNull(pubsub.getTopicAsync(TOPIC).get()); + } + + @Test + public void testDeleteTopic() { + DeleteTopicRequest request = DeleteTopicRequest.newBuilder().setTopic(TOPIC_NAME_PB).build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + assertTrue(pubsub.deleteTopic(TOPIC)); + } + + @Test + public void testDeleteTopic_Null() { + DeleteTopicRequest request = DeleteTopicRequest.newBuilder().setTopic(TOPIC_NAME_PB).build(); + Future response = Futures.immediateFuture(null); + EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + assertFalse(pubsub.deleteTopic(TOPIC)); + } + + @Test + public void testDeleteTopicAsync() throws ExecutionException, InterruptedException { + DeleteTopicRequest request = DeleteTopicRequest.newBuilder().setTopic(TOPIC_NAME_PB).build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + assertTrue(pubsub.deleteTopicAsync(TOPIC).get()); + } + + @Test + public void testDeleteTopicAsync_Null() throws ExecutionException, InterruptedException { + DeleteTopicRequest request = DeleteTopicRequest.newBuilder().setTopic(TOPIC_NAME_PB).build(); + Future response = Futures.immediateFuture(null); + EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + assertFalse(pubsub.deleteTopicAsync(TOPIC).get()); + } + + @Test + public void testListTopics() { + String cursor = "cursor"; + pubsub = options.service(); + ListTopicsRequest request = ListTopicsRequest.newBuilder().setProject(PROJECT_PB).build(); + List topicList = ImmutableList.of( + new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO)), + new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO))); + ListTopicsResponse response = ListTopicsResponse.newBuilder() + .setNextPageToken("cursor") + .addAllTopics(Lists.transform(topicList, TOPIC_TO_PB_FUNCTION)) + .build(); + Future futureResponse = Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); + EasyMock.replay(pubsubRpcMock); + Page page = pubsub.listTopics(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(topicList.toArray(), Iterables.toArray(page.values(), Topic.class)); + } + + @Test + public void testListTopicsNextPage() { + String cursor1 = "cursor"; + pubsub = options.service(); + ListTopicsRequest request1 = ListTopicsRequest.newBuilder().setProject(PROJECT_PB).build(); + ListTopicsRequest request2 = ListTopicsRequest.newBuilder() + .setProject(PROJECT_PB) + .setPageToken(cursor1) + .build(); + List topicList1 = ImmutableList.of( + new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO)), + new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO))); + List topicList2 = ImmutableList.of( + new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO))); + ListTopicsResponse response1 = ListTopicsResponse.newBuilder() + .setNextPageToken(cursor1) + .addAllTopics(Lists.transform(topicList1, TOPIC_TO_PB_FUNCTION)) + .build(); + String cursor2 = "nextCursor"; + ListTopicsResponse response2 = ListTopicsResponse.newBuilder() + .setNextPageToken(cursor2) + .addAllTopics(Lists.transform(topicList2, TOPIC_TO_PB_FUNCTION)) + .build(); + Future futureResponse1 = Futures.immediateFuture(response1); + Future futureResponse2 = Futures.immediateFuture(response2); + EasyMock.expect(pubsubRpcMock.list(request1)).andReturn(futureResponse1); + EasyMock.expect(pubsubRpcMock.list(request2)).andReturn(futureResponse2); + EasyMock.replay(pubsubRpcMock); + Page page = pubsub.listTopics(); + assertEquals(cursor1, page.nextPageCursor()); + assertArrayEquals(topicList1.toArray(), Iterables.toArray(page.values(), Topic.class)); + page = page.nextPage(); + assertEquals(cursor2, page.nextPageCursor()); + assertArrayEquals(topicList2.toArray(), Iterables.toArray(page.values(), Topic.class)); + } + + @Test + public void testListTopicsEmpty() { + pubsub = options.service(); + ListTopicsRequest request = ListTopicsRequest.newBuilder().setProject(PROJECT_PB).build(); + List topicList = ImmutableList.of(); + ListTopicsResponse response = ListTopicsResponse.newBuilder() + .setNextPageToken("") + .addAllTopics(Lists.transform(topicList, TOPIC_TO_PB_FUNCTION)) + .build(); + Future futureResponse = Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); + EasyMock.replay(pubsubRpcMock); + Page page = pubsub.listTopics(); + assertNull(page.nextPageCursor()); + assertNull(page.nextPage()); + assertArrayEquals(topicList.toArray(), Iterators.toArray(page.iterateAll(), Topic.class)); + } + + @Test + public void testListTopicsWithOptions() { + String cursor = "cursor"; + pubsub = options.service(); + ListTopicsRequest request = ListTopicsRequest.newBuilder() + .setProject(PROJECT_PB) + .setPageSize(42) + .setPageToken(cursor) + .build(); + List topicList = ImmutableList.of( + new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO)), + new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO))); + ListTopicsResponse response = ListTopicsResponse.newBuilder() + .setNextPageToken("") + .addAllTopics(Lists.transform(topicList, TOPIC_TO_PB_FUNCTION)) + .build(); + Future futureResponse = Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); + EasyMock.replay(pubsubRpcMock); + Page page = pubsub.listTopics(ListOption.pageSize(42), ListOption.pageToken(cursor)); + assertNull(page.nextPageCursor()); + assertNull(page.nextPage()); + assertArrayEquals(topicList.toArray(), Iterables.toArray(page.values(), Topic.class)); + } + + @Test + public void testListTopicsAsync() throws ExecutionException, InterruptedException { + String cursor = "cursor"; + pubsub = options.service(); + ListTopicsRequest request = ListTopicsRequest.newBuilder().setProject(PROJECT_PB).build(); + List topicList = ImmutableList.of( + new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO)), + new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO))); + ListTopicsResponse response = ListTopicsResponse.newBuilder() + .setNextPageToken("cursor") + .addAllTopics(Lists.transform(topicList, TOPIC_TO_PB_FUNCTION)) + .build(); + Future futureResponse = Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); + EasyMock.replay(pubsubRpcMock); + AsyncPage page = pubsub.listTopicsAsync().get(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(topicList.toArray(), Iterables.toArray(page.values(), Topic.class)); + } + + @Test + public void testListTopicsAsyncNextPage() throws ExecutionException, InterruptedException { + String cursor1 = "cursor"; + pubsub = options.service(); + ListTopicsRequest request1 = ListTopicsRequest.newBuilder().setProject(PROJECT_PB).build(); + ListTopicsRequest request2 = ListTopicsRequest.newBuilder() + .setProject(PROJECT_PB) + .setPageToken(cursor1) + .build(); + List topicList1 = ImmutableList.of( + new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO)), + new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO))); + List topicList2 = ImmutableList.of( + new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO))); + ListTopicsResponse response1 = ListTopicsResponse.newBuilder() + .setNextPageToken(cursor1) + .addAllTopics(Lists.transform(topicList1, TOPIC_TO_PB_FUNCTION)) + .build(); + String cursor2 = "nextCursor"; + ListTopicsResponse response2 = ListTopicsResponse.newBuilder() + .setNextPageToken(cursor2) + .addAllTopics(Lists.transform(topicList2, TOPIC_TO_PB_FUNCTION)) + .build(); + Future futureResponse1 = Futures.immediateFuture(response1); + Future futureResponse2 = Futures.immediateFuture(response2); + EasyMock.expect(pubsubRpcMock.list(request1)).andReturn(futureResponse1); + EasyMock.expect(pubsubRpcMock.list(request2)).andReturn(futureResponse2); + EasyMock.replay(pubsubRpcMock); + AsyncPage page = pubsub.listTopicsAsync().get(); + assertEquals(cursor1, page.nextPageCursor()); + assertArrayEquals(topicList1.toArray(), Iterables.toArray(page.values(), Topic.class)); + page = page.nextPageAsync().get(); + assertEquals(cursor2, page.nextPageCursor()); + assertArrayEquals(topicList2.toArray(), Iterables.toArray(page.values(), Topic.class)); + } + + @Test + public void testListTopicsAsyncEmpty() throws ExecutionException, InterruptedException { + pubsub = options.service(); + ListTopicsRequest request = ListTopicsRequest.newBuilder().setProject(PROJECT_PB).build(); + List topicList = ImmutableList.of(); + ListTopicsResponse response = ListTopicsResponse.newBuilder() + .setNextPageToken("") + .addAllTopics(Lists.transform(topicList, TOPIC_TO_PB_FUNCTION)) + .build(); + Future futureResponse = Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); + EasyMock.replay(pubsubRpcMock); + AsyncPage page = pubsub.listTopicsAsync().get(); + assertNull(page.nextPageCursor()); + assertNull(page.nextPageAsync().get()); + assertNull(page.nextPage()); + assertArrayEquals(topicList.toArray(), Iterators.toArray(page.iterateAll(), Topic.class)); + } + + @Test + public void testListTopicsAsyncWithOptions() throws ExecutionException, InterruptedException { + String cursor = "cursor"; + pubsub = options.service(); + ListTopicsRequest request = ListTopicsRequest.newBuilder() + .setProject(PROJECT_PB) + .setPageSize(42) + .setPageToken(cursor) + .build(); + List topicList = ImmutableList.of( + new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO)), + new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO))); + ListTopicsResponse response = ListTopicsResponse.newBuilder() + .setNextPageToken("") + .addAllTopics(Lists.transform(topicList, TOPIC_TO_PB_FUNCTION)) + .build(); + Future futureResponse = Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); + EasyMock.replay(pubsubRpcMock); + AsyncPage page = + pubsub.listTopicsAsync(ListOption.pageSize(42), ListOption.pageToken(cursor)).get(); + assertNull(page.nextPageCursor()); + assertNull(page.nextPageAsync().get()); + assertArrayEquals(topicList.toArray(), Iterables.toArray(page.values(), Topic.class)); + } + + @Test + public void testPublishOneMessage() { + PublishRequest request = PublishRequest.newBuilder() + .setTopic(TOPIC_NAME_PB) + .addAllMessages(ImmutableList.of(MESSAGE.toPb())) + .build(); + String messageId = "messageId"; + PublishResponse response = PublishResponse.newBuilder().addMessageIds(messageId).build(); + Future responseFuture = Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.publish(request)).andReturn(responseFuture); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + assertEquals(messageId, pubsub.publish(TOPIC, MESSAGE)); + } + + @Test + public void testPublishOneMessageAsync() throws ExecutionException, InterruptedException { + PublishRequest request = PublishRequest.newBuilder() + .setTopic(TOPIC_NAME_PB) + .addMessages(MESSAGE.toPb()) + .build(); + String messageId = "messageId"; + PublishResponse response = PublishResponse.newBuilder().addMessageIds(messageId).build(); + Future responseFuture = Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.publish(request)).andReturn(responseFuture); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + assertEquals(messageId, pubsub.publishAsync(TOPIC, MESSAGE).get()); + } + + @Test + public void testPublishMoreMessages() { + PublishRequest request = PublishRequest.newBuilder() + .setTopic(TOPIC_NAME_PB) + .addAllMessages(ImmutableList.of(MESSAGE.toPb(), MESSAGE.toPb())) + .build(); + List messageIds = ImmutableList.of("messageId1", "messageId2"); + PublishResponse response = PublishResponse.newBuilder() + .addAllMessageIds(messageIds) + .build(); + Future responseFuture = Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.publish(request)).andReturn(responseFuture); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + assertEquals(messageIds, pubsub.publish(TOPIC, MESSAGE, MESSAGE)); + } + + @Test + public void testPublishMoreMessagesAsync() throws ExecutionException, InterruptedException { + PublishRequest request = PublishRequest.newBuilder() + .setTopic(TOPIC_NAME_PB) + .addAllMessages(ImmutableList.of(MESSAGE.toPb(), MESSAGE.toPb())) + .build(); + List messageIds = ImmutableList.of("messageId1", "messageId2"); + PublishResponse response = PublishResponse.newBuilder() + .addAllMessageIds(messageIds) + .build(); + Future responseFuture = Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.publish(request)).andReturn(responseFuture); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + assertEquals(messageIds, pubsub.publishAsync(TOPIC, MESSAGE, MESSAGE).get()); + } + + @Test + public void testPublishMessageList() { + PublishRequest request = PublishRequest.newBuilder() + .setTopic(TOPIC_NAME_PB) + .addAllMessages(ImmutableList.of(MESSAGE.toPb(), MESSAGE.toPb())) + .build(); + List messageIds = ImmutableList.of("messageId1", "messageId2"); + PublishResponse response = PublishResponse.newBuilder() + .addAllMessageIds(messageIds) + .build(); + Future responseFuture = Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.publish(request)).andReturn(responseFuture); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + assertEquals(messageIds, pubsub.publish(TOPIC, ImmutableList.of(MESSAGE, MESSAGE))); + } + + @Test + public void testPublishMessageListAsync() throws ExecutionException, InterruptedException { + PublishRequest request = PublishRequest.newBuilder() + .setTopic(TOPIC_NAME_PB) + .addAllMessages(ImmutableList.of(MESSAGE.toPb(), MESSAGE.toPb())) + .build(); + List messageIds = ImmutableList.of("messageId1", "messageId2"); + PublishResponse response = PublishResponse.newBuilder() + .addAllMessageIds(messageIds) + .build(); + Future responseFuture = Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.publish(request)).andReturn(responseFuture); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + assertEquals(messageIds, pubsub.publishAsync(TOPIC, ImmutableList.of(MESSAGE, MESSAGE)).get()); + } + + @Test + public void testCreateSubscription() { + com.google.pubsub.v1.Subscription subscriptionPb = SUBSCRIPTION_INFO.toPb(PROJECT); + Future response = + Futures.immediateFuture(subscriptionPb); + EasyMock.expect(pubsubRpcMock.create(subscriptionPb)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + Subscription subscription = pubsub.create(SUBSCRIPTION_INFO); + assertEquals( + new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO)), + subscription); + } + + @Test + public void testCreateSubscriptionAsync() throws ExecutionException, InterruptedException { + com.google.pubsub.v1.Subscription subscriptionPb = SUBSCRIPTION_INFO.toPb(PROJECT); + Future response = + Futures.immediateFuture(subscriptionPb); + EasyMock.expect(pubsubRpcMock.create(subscriptionPb)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + Subscription subscription = pubsub.createAsync(SUBSCRIPTION_INFO).get(); + assertEquals( + new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO)), + subscription); + } + + @Test + public void testGetSubscription() { + GetSubscriptionRequest request = + GetSubscriptionRequest.newBuilder().setSubscription(SUBSCRIPTION_NAME_PB).build(); + Future response = + Futures.immediateFuture(SUBSCRIPTION_INFO.toPb(PROJECT)); + EasyMock.expect(pubsubRpcMock.get(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + Subscription subscription = pubsub.getSubscription(SUBSCRIPTION); + assertEquals( + new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO)), + subscription); + } + + @Test + public void testGetSubscription_Null() { + GetSubscriptionRequest request = + GetSubscriptionRequest.newBuilder().setSubscription(SUBSCRIPTION_NAME_PB).build(); + Future response = Futures.immediateFuture(null); + EasyMock.expect(pubsubRpcMock.get(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + assertNull(pubsub.getSubscription(SUBSCRIPTION)); + } + + @Test + public void testGetSubscriptionAsync() throws ExecutionException, InterruptedException { + GetSubscriptionRequest request = + GetSubscriptionRequest.newBuilder().setSubscription(SUBSCRIPTION_NAME_PB).build(); + Future response = + Futures.immediateFuture(SUBSCRIPTION_INFO.toPb(PROJECT)); + EasyMock.expect(pubsubRpcMock.get(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + Subscription subscription = pubsub.getSubscriptionAsync(SUBSCRIPTION).get(); + assertEquals( + new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO)), + subscription); + } + + @Test + public void testGetSubscriptionAsync_Null() throws ExecutionException, InterruptedException { + GetSubscriptionRequest request = + GetSubscriptionRequest.newBuilder().setSubscription(SUBSCRIPTION_NAME_PB).build(); + Future response = Futures.immediateFuture(null); + EasyMock.expect(pubsubRpcMock.get(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + assertNull(pubsub.getSubscriptionAsync(SUBSCRIPTION).get()); + } + + @Test + public void testDeleteSubscription() { + DeleteSubscriptionRequest request = DeleteSubscriptionRequest.newBuilder() + .setSubscription(SUBSCRIPTION_NAME_PB) + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + assertTrue(pubsub.deleteSubscription(SUBSCRIPTION)); + } + + @Test + public void testDeleteSubscription_Null() { + DeleteSubscriptionRequest request = DeleteSubscriptionRequest.newBuilder() + .setSubscription(SUBSCRIPTION_NAME_PB) + .build(); + Future response = Futures.immediateFuture(null); + EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + assertFalse(pubsub.deleteSubscription(SUBSCRIPTION)); + } + + @Test + public void testDeleteSubscriptionAsync() throws ExecutionException, InterruptedException { + DeleteSubscriptionRequest request = DeleteSubscriptionRequest.newBuilder() + .setSubscription(SUBSCRIPTION_NAME_PB) + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + assertTrue(pubsub.deleteSubscriptionAsync(SUBSCRIPTION).get()); + } + + @Test + public void testDeleteSubscriptionAsync_Null() throws ExecutionException, InterruptedException { + DeleteSubscriptionRequest request = DeleteSubscriptionRequest.newBuilder() + .setSubscription(SUBSCRIPTION_NAME_PB) + .build(); + Future response = Futures.immediateFuture(null); + EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + assertFalse(pubsub.deleteSubscriptionAsync(SUBSCRIPTION).get()); + } + + @Test + public void testReplacePushConfig() { + ModifyPushConfigRequest request = ModifyPushConfigRequest.newBuilder() + .setSubscription(SUBSCRIPTION_NAME_PB) + .setPushConfig(PUSH_CONFIG.toPb()) + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + pubsub.replacePushConfig(SUBSCRIPTION, PUSH_CONFIG); + } + + @Test + public void testReplacePushConfig_Null() { + ModifyPushConfigRequest request = ModifyPushConfigRequest.newBuilder() + .setSubscription(SUBSCRIPTION_NAME_PB) + .setPushConfig(com.google.pubsub.v1.PushConfig.getDefaultInstance()) + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + pubsub.replacePushConfig(SUBSCRIPTION, null); + } + + @Test + public void testReplacePushConfigAsync() throws ExecutionException, InterruptedException { + ModifyPushConfigRequest request = ModifyPushConfigRequest.newBuilder() + .setSubscription(SUBSCRIPTION_NAME_PB) + .setPushConfig(PUSH_CONFIG.toPb()) + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + pubsub.replacePushConfigAsync(SUBSCRIPTION, PUSH_CONFIG).get(); + } + + @Test + public void testReplacePushConfigAsync_Null() throws ExecutionException, InterruptedException { + ModifyPushConfigRequest request = ModifyPushConfigRequest.newBuilder() + .setSubscription(SUBSCRIPTION_NAME_PB) + .setPushConfig(com.google.pubsub.v1.PushConfig.getDefaultInstance()) + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub = options.service(); + pubsub.replacePushConfigAsync(SUBSCRIPTION, null).get(); + } + + @Test + public void testListSubscriptions() { + String cursor = "cursor"; + pubsub = options.service(); + ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder() + .setProject(PROJECT_PB) + .build(); + List subscriptionList = ImmutableList.of( + new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO)), + new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO))); + ListSubscriptionsResponse response = ListSubscriptionsResponse.newBuilder() + .setNextPageToken("cursor") + .addAllSubscriptions(Lists.transform(subscriptionList, SUBSCRIPTION_TO_PB_FUNCTION)) + .build(); + Future futureResponse = Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); + EasyMock.replay(pubsubRpcMock); + Page page = pubsub.listSubscriptions(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(subscriptionList.toArray(), + Iterables.toArray(page.values(), Subscription.class)); + } + + @Test + public void testListSubscriptionsNextPage() { + String cursor1 = "cursor"; + pubsub = options.service(); + ListSubscriptionsRequest request1 = ListSubscriptionsRequest.newBuilder() + .setProject(PROJECT_PB) + .build(); + ListSubscriptionsRequest request2 = ListSubscriptionsRequest.newBuilder() + .setProject(PROJECT_PB) + .setPageToken(cursor1) + .build(); + List subscriptionList1 = ImmutableList.of( + new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO)), + new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO))); + List subscriptionList2 = ImmutableList.of( + new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO))); + ListSubscriptionsResponse response1 = ListSubscriptionsResponse.newBuilder() + .setNextPageToken(cursor1) + .addAllSubscriptions(Lists.transform(subscriptionList1, SUBSCRIPTION_TO_PB_FUNCTION)) + .build(); + String cursor2 = "nextCursor"; + ListSubscriptionsResponse response2 = ListSubscriptionsResponse.newBuilder() + .setNextPageToken(cursor2) + .addAllSubscriptions(Lists.transform(subscriptionList2, SUBSCRIPTION_TO_PB_FUNCTION)) + .build(); + Future futureResponse1 = Futures.immediateFuture(response1); + Future futureResponse2 = Futures.immediateFuture(response2); + EasyMock.expect(pubsubRpcMock.list(request1)).andReturn(futureResponse1); + EasyMock.expect(pubsubRpcMock.list(request2)).andReturn(futureResponse2); + EasyMock.replay(pubsubRpcMock); + Page page = pubsub.listSubscriptions(); + assertEquals(cursor1, page.nextPageCursor()); + assertArrayEquals(subscriptionList1.toArray(), + Iterables.toArray(page.values(), Subscription.class)); + page = page.nextPage(); + assertEquals(cursor2, page.nextPageCursor()); + assertArrayEquals(subscriptionList2.toArray(), + Iterables.toArray(page.values(), Subscription.class)); + } + + @Test + public void testListSubscriptionsEmpty() { + pubsub = options.service(); + ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder() + .setProject(PROJECT_PB) + .build(); + List subscriptionList = ImmutableList.of(); + ListSubscriptionsResponse response = ListSubscriptionsResponse.newBuilder() + .setNextPageToken("") + .addAllSubscriptions(Lists.transform(subscriptionList, SUBSCRIPTION_TO_PB_FUNCTION)) + .build(); + Future futureResponse = Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); + EasyMock.replay(pubsubRpcMock); + Page page = pubsub.listSubscriptions(); + assertNull(page.nextPageCursor()); + assertNull(page.nextPage()); + assertArrayEquals(subscriptionList.toArray(), + Iterables.toArray(page.values(), Subscription.class)); + } + + @Test + public void testListSubscriptionsWithOptions() { + String cursor = "cursor"; + pubsub = options.service(); + ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder() + .setProject(PROJECT_PB) + .setPageSize(42) + .setPageToken(cursor) + .build(); + List subscriptionList = ImmutableList.of( + new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO)), + new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO))); + ListSubscriptionsResponse response = ListSubscriptionsResponse.newBuilder() + .setNextPageToken("") + .addAllSubscriptions(Lists.transform(subscriptionList, SUBSCRIPTION_TO_PB_FUNCTION)) + .build(); + Future futureResponse = Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); + EasyMock.replay(pubsubRpcMock); + Page page = + pubsub.listSubscriptions(ListOption.pageSize(42), ListOption.pageToken(cursor)); + assertNull(page.nextPageCursor()); + assertNull(page.nextPage()); + assertArrayEquals(subscriptionList.toArray(), + Iterables.toArray(page.values(), Subscription.class)); + } + + @Test + public void testListSubscriptionsAsync() throws ExecutionException, InterruptedException { + String cursor = "cursor"; + pubsub = options.service(); + ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder() + .setProject(PROJECT_PB) + .build(); + List subscriptionList = ImmutableList.of( + new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO)), + new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO))); + ListSubscriptionsResponse response = ListSubscriptionsResponse.newBuilder() + .setNextPageToken("cursor") + .addAllSubscriptions(Lists.transform(subscriptionList, SUBSCRIPTION_TO_PB_FUNCTION)) + .build(); + Future futureResponse = Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); + EasyMock.replay(pubsubRpcMock); + AsyncPage page = pubsub.listSubscriptionsAsync().get(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(subscriptionList.toArray(), + Iterables.toArray(page.values(), Subscription.class)); + } + + @Test + public void testListSubscriptionsAsyncNextPage() throws ExecutionException, InterruptedException { + String cursor1 = "cursor"; + pubsub = options.service(); + ListSubscriptionsRequest request1 = ListSubscriptionsRequest.newBuilder() + .setProject(PROJECT_PB) + .build(); + ListSubscriptionsRequest request2 = ListSubscriptionsRequest.newBuilder() + .setProject(PROJECT_PB) + .setPageToken(cursor1) + .build(); + List subscriptionList1 = ImmutableList.of( + new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO)), + new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO))); + List subscriptionList2 = ImmutableList.of( + new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO))); + ListSubscriptionsResponse response1 = ListSubscriptionsResponse.newBuilder() + .setNextPageToken(cursor1) + .addAllSubscriptions(Lists.transform(subscriptionList1, SUBSCRIPTION_TO_PB_FUNCTION)) + .build(); + String cursor2 = "nextCursor"; + ListSubscriptionsResponse response2 = ListSubscriptionsResponse.newBuilder() + .setNextPageToken(cursor2) + .addAllSubscriptions(Lists.transform(subscriptionList2, SUBSCRIPTION_TO_PB_FUNCTION)) + .build(); + Future futureResponse1 = Futures.immediateFuture(response1); + Future futureResponse2 = Futures.immediateFuture(response2); + EasyMock.expect(pubsubRpcMock.list(request1)).andReturn(futureResponse1); + EasyMock.expect(pubsubRpcMock.list(request2)).andReturn(futureResponse2); + EasyMock.replay(pubsubRpcMock); + AsyncPage page = pubsub.listSubscriptionsAsync().get(); + assertEquals(cursor1, page.nextPageCursor()); + assertArrayEquals(subscriptionList1.toArray(), + Iterables.toArray(page.values(), Subscription.class)); + page = page.nextPageAsync().get(); + assertEquals(cursor2, page.nextPageCursor()); + assertArrayEquals(subscriptionList2.toArray(), + Iterables.toArray(page.values(), Subscription.class)); + } + + @Test + public void testListSubscriptionsAsyncEmpty() throws ExecutionException, InterruptedException { + pubsub = options.service(); + ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder() + .setProject(PROJECT_PB) + .build(); + List subscriptionList = ImmutableList.of(); + ListSubscriptionsResponse response = ListSubscriptionsResponse.newBuilder() + .setNextPageToken("") + .addAllSubscriptions(Lists.transform(subscriptionList, SUBSCRIPTION_TO_PB_FUNCTION)) + .build(); + Future futureResponse = Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); + EasyMock.replay(pubsubRpcMock); + AsyncPage page = pubsub.listSubscriptionsAsync().get(); + assertNull(page.nextPageCursor()); + assertNull(page.nextPageAsync().get()); + assertNull(page.nextPage()); + assertArrayEquals(subscriptionList.toArray(), + Iterables.toArray(page.values(), Subscription.class)); + } + + @Test + public void testListSubscriptionsAsyncWithOptions() + throws ExecutionException, InterruptedException { + String cursor = "cursor"; + pubsub = options.service(); + ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder() + .setProject(PROJECT_PB) + .setPageSize(42) + .setPageToken(cursor) + .build(); + List subscriptionList = ImmutableList.of( + new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO)), + new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO))); + ListSubscriptionsResponse response = ListSubscriptionsResponse.newBuilder() + .setNextPageToken("") + .addAllSubscriptions(Lists.transform(subscriptionList, SUBSCRIPTION_TO_PB_FUNCTION)) + .build(); + Future futureResponse = Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); + EasyMock.replay(pubsubRpcMock); + AsyncPage page = + pubsub.listSubscriptionsAsync(ListOption.pageSize(42), ListOption.pageToken(cursor)).get(); + assertNull(page.nextPageCursor()); + assertNull(page.nextPage()); + assertNull(page.nextPageAsync().get()); + assertArrayEquals(subscriptionList.toArray(), + Iterables.toArray(page.values(), Subscription.class)); + } + + @Test + public void testListTopicSubscriptions() { + String cursor = "cursor"; + pubsub = options.service(); + ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder() + .setTopic(TOPIC_NAME_PB) + .build(); + List subscriptionList = ImmutableList.of( + new SubscriptionId(PROJECT, "subscription1"), + new SubscriptionId(PROJECT, "subscription2")); + ListTopicSubscriptionsResponse response = ListTopicSubscriptionsResponse.newBuilder() + .setNextPageToken("cursor") + .addAllSubscriptions(Lists.transform(subscriptionList, SUBSCRIPTION_ID_TO_PB_FUNCTION)) + .build(); + Future futureResponse = + Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); + EasyMock.replay(pubsubRpcMock); + Page page = pubsub.listSubscriptions(TOPIC); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(subscriptionList.toArray(), + Iterables.toArray(page.values(), SubscriptionId.class)); + } + + @Test + public void testListTopicSubscriptionsNextPage() { + String cursor1 = "cursor"; + pubsub = options.service(); + ListTopicSubscriptionsRequest request1 = ListTopicSubscriptionsRequest.newBuilder() + .setTopic(TOPIC_NAME_PB) + .build(); + ListTopicSubscriptionsRequest request2 = ListTopicSubscriptionsRequest.newBuilder() + .setTopic(TOPIC_NAME_PB) + .setPageToken(cursor1) + .build(); + List subscriptionList1 = ImmutableList.of( + new SubscriptionId(PROJECT, "subscription1"), + new SubscriptionId(PROJECT, "subscription2")); + List subscriptionList2 = ImmutableList.of( + new SubscriptionId(PROJECT, "subscription3")); + ListTopicSubscriptionsResponse response1 = ListTopicSubscriptionsResponse.newBuilder() + .setNextPageToken(cursor1) + .addAllSubscriptions(Lists.transform(subscriptionList1, SUBSCRIPTION_ID_TO_PB_FUNCTION)) + .build(); + String cursor2 = "nextCursor"; + ListTopicSubscriptionsResponse response2 = ListTopicSubscriptionsResponse.newBuilder() + .setNextPageToken(cursor2) + .addAllSubscriptions(Lists.transform(subscriptionList2, SUBSCRIPTION_ID_TO_PB_FUNCTION)) + .build(); + Future futureResponse1 = + Futures.immediateFuture(response1); + Future futureResponse2 = + Futures.immediateFuture(response2); + EasyMock.expect(pubsubRpcMock.list(request1)).andReturn(futureResponse1); + EasyMock.expect(pubsubRpcMock.list(request2)).andReturn(futureResponse2); + EasyMock.replay(pubsubRpcMock); + Page page = pubsub.listSubscriptions(TOPIC); + assertEquals(cursor1, page.nextPageCursor()); + assertArrayEquals(subscriptionList1.toArray(), + Iterables.toArray(page.values(), SubscriptionId.class)); + page = page.nextPage(); + assertEquals(cursor2, page.nextPageCursor()); + assertArrayEquals(subscriptionList2.toArray(), + Iterables.toArray(page.values(), SubscriptionId.class)); + } + + @Test + public void testListTopicSubscriptionsEmpty() { + pubsub = options.service(); + ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder() + .setTopic(TOPIC_NAME_PB) + .build(); + List subscriptionList = ImmutableList.of(); + ListTopicSubscriptionsResponse response = ListTopicSubscriptionsResponse.newBuilder() + .setNextPageToken("") + .addAllSubscriptions(Lists.transform(subscriptionList, SUBSCRIPTION_ID_TO_PB_FUNCTION)) + .build(); + Future futureResponse = + Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); + EasyMock.replay(pubsubRpcMock); + Page page = pubsub.listSubscriptions(TOPIC); + assertNull(page.nextPageCursor()); + assertNull(page.nextPage()); + assertArrayEquals(subscriptionList.toArray(), + Iterables.toArray(page.values(), SubscriptionId.class)); + } + + @Test + public void testListTopicSubscriptionsWithOptions() { + String cursor = "cursor"; + pubsub = options.service(); + ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder() + .setTopic(TOPIC_NAME_PB) + .setPageSize(42) + .setPageToken(cursor) + .build(); + List subscriptionList = ImmutableList.of( + new SubscriptionId(PROJECT, "subscription1"), + new SubscriptionId(PROJECT, "subscription2")); + ListTopicSubscriptionsResponse response = ListTopicSubscriptionsResponse.newBuilder() + .setNextPageToken("") + .addAllSubscriptions(Lists.transform(subscriptionList, SUBSCRIPTION_ID_TO_PB_FUNCTION)) + .build(); + Future futureResponse = + Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); + EasyMock.replay(pubsubRpcMock); + Page page = + pubsub.listSubscriptions(TOPIC, ListOption.pageSize(42), ListOption.pageToken(cursor)); + assertNull(page.nextPageCursor()); + assertNull(page.nextPage()); + assertArrayEquals(subscriptionList.toArray(), + Iterables.toArray(page.values(), SubscriptionId.class)); + } + + @Test + public void testListTopicSubscriptionsAsync() throws ExecutionException, InterruptedException { + String cursor = "cursor"; + pubsub = options.service(); + ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder() + .setTopic(TOPIC_NAME_PB) + .build(); + List subscriptionList = ImmutableList.of( + new SubscriptionId(PROJECT, "subscription1"), + new SubscriptionId(PROJECT, "subscription2")); + ListTopicSubscriptionsResponse response = ListTopicSubscriptionsResponse.newBuilder() + .setNextPageToken("cursor") + .addAllSubscriptions(Lists.transform(subscriptionList, SUBSCRIPTION_ID_TO_PB_FUNCTION)) + .build(); + Future futureResponse = + Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); + EasyMock.replay(pubsubRpcMock); + AsyncPage page = pubsub.listSubscriptionsAsync(TOPIC).get(); + assertEquals(cursor, page.nextPageCursor()); + assertArrayEquals(subscriptionList.toArray(), + Iterables.toArray(page.values(), SubscriptionId.class)); + } + + @Test + public void testListTopicSubscriptionsAsyncNextPage() + throws ExecutionException, InterruptedException { + String cursor1 = "cursor"; + pubsub = options.service(); + ListTopicSubscriptionsRequest request1 = ListTopicSubscriptionsRequest.newBuilder() + .setTopic(TOPIC_NAME_PB) + .build(); + ListTopicSubscriptionsRequest request2 = ListTopicSubscriptionsRequest.newBuilder() + .setTopic(TOPIC_NAME_PB) + .setPageToken(cursor1) + .build(); + List subscriptionList1 = ImmutableList.of( + new SubscriptionId(PROJECT, "subscription1"), + new SubscriptionId(PROJECT, "subscription2")); + List subscriptionList2 = ImmutableList.of( + new SubscriptionId(PROJECT, "subscription3")); + ListTopicSubscriptionsResponse response1 = ListTopicSubscriptionsResponse.newBuilder() + .setNextPageToken(cursor1) + .addAllSubscriptions(Lists.transform(subscriptionList1, SUBSCRIPTION_ID_TO_PB_FUNCTION)) + .build(); + String cursor2 = "nextCursor"; + ListTopicSubscriptionsResponse response2 = ListTopicSubscriptionsResponse.newBuilder() + .setNextPageToken(cursor2) + .addAllSubscriptions(Lists.transform(subscriptionList2, SUBSCRIPTION_ID_TO_PB_FUNCTION)) + .build(); + Future futureResponse1 = + Futures.immediateFuture(response1); + Future futureResponse2 = + Futures.immediateFuture(response2); + EasyMock.expect(pubsubRpcMock.list(request1)).andReturn(futureResponse1); + EasyMock.expect(pubsubRpcMock.list(request2)).andReturn(futureResponse2); + EasyMock.replay(pubsubRpcMock); + AsyncPage page = pubsub.listSubscriptionsAsync(TOPIC).get(); + assertEquals(cursor1, page.nextPageCursor()); + assertArrayEquals(subscriptionList1.toArray(), + Iterables.toArray(page.values(), SubscriptionId.class)); + page = page.nextPageAsync().get(); + assertEquals(cursor2, page.nextPageCursor()); + assertArrayEquals(subscriptionList2.toArray(), + Iterables.toArray(page.values(), SubscriptionId.class)); + } + + @Test + public void testListTopicSubscriptionsAsyncEmpty() + throws ExecutionException, InterruptedException { + pubsub = options.service(); + ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder() + .setTopic(TOPIC_NAME_PB) + .build(); + List subscriptionList = ImmutableList.of(); + ListTopicSubscriptionsResponse response = ListTopicSubscriptionsResponse.newBuilder() + .setNextPageToken("") + .addAllSubscriptions(Lists.transform(subscriptionList, SUBSCRIPTION_ID_TO_PB_FUNCTION)) + .build(); + Future futureResponse = + Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); + EasyMock.replay(pubsubRpcMock); + AsyncPage page = pubsub.listSubscriptionsAsync(TOPIC).get(); + assertNull(page.nextPageCursor()); + assertNull(page.nextPage()); + assertNull(page.nextPageAsync().get()); + assertArrayEquals(subscriptionList.toArray(), + Iterables.toArray(page.values(), SubscriptionId.class)); + } + + @Test + public void testListTopicSubscriptionsAsyncWithOptions() + throws ExecutionException, InterruptedException { + String cursor = "cursor"; + pubsub = options.service(); + ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder() + .setTopic(TOPIC_NAME_PB) + .setPageSize(42) + .setPageToken(cursor) + .build(); + List subscriptionList = ImmutableList.of( + new SubscriptionId(PROJECT, "subscription1"), + new SubscriptionId(PROJECT, "subscription2")); + ListTopicSubscriptionsResponse response = ListTopicSubscriptionsResponse.newBuilder() + .setNextPageToken("") + .addAllSubscriptions(Lists.transform(subscriptionList, SUBSCRIPTION_ID_TO_PB_FUNCTION)) + .build(); + Future futureResponse = + Futures.immediateFuture(response); + EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); + EasyMock.replay(pubsubRpcMock); + AsyncPage page = pubsub.listSubscriptionsAsync( + TOPIC, ListOption.pageSize(42), ListOption.pageToken(cursor)).get(); + assertNull(page.nextPageCursor()); + assertNull(page.nextPage()); + assertNull(page.nextPageAsync().get()); + assertArrayEquals(subscriptionList.toArray(), + Iterables.toArray(page.values(), SubscriptionId.class)); + } + + @Test + public void testClose() throws Exception { + pubsub = options.service(); + pubsubRpcMock.close(); + EasyMock.expectLastCall(); + EasyMock.replay(pubsubRpcMock); + pubsub.close(); + } +} From 235152ecfc11fd6cfc5cb9b88f0e625e8d725c5d Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 25 May 2016 20:07:38 +0200 Subject: [PATCH 359/375] Implement modifyAckDeadline methods, add javadoc and tests (#1022) --- .../java/com/google/cloud/pubsub/PubSub.java | 64 +++++++++++++ .../com/google/cloud/pubsub/PubSubImpl.java | 16 +++- .../cloud/pubsub/spi/DefaultPubSubRpc.java | 4 +- .../pubsub/testing/LocalPubsubHelper.java | 8 +- .../google/cloud/pubsub/LocalSystemTest.java | 2 +- .../google/cloud/pubsub/PubSubImplTest.java | 96 +++++++++++++++++++ 6 files changed, 178 insertions(+), 12 deletions(-) diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java index b98315e77a75..e6b496be8e5f 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java @@ -403,14 +403,78 @@ interface MessageConsumer extends AutoCloseable { Future nackAsync(String subscription, Iterable ackIds); + /** + * Modifies the acknowledge deadline of the given messages. {@code deadline} must be >= 0 and is + * the new deadline with respect to the time the modify request was received by the Pub/Sub + * service. For example, if {@code deadline} is 10 and {@code unit} is {@link TimeUnit#SECONDS}, + * the new ack deadline will expire 10 seconds after the modify request was received by the + * service. Specifying 0 may be used to make the message available for another pull request + * (corresponds to calling {@link #nack(String, String, String...)}). + * + * @param subscription the subscription whose messages need to update their acknowledge deadline + * @param deadline the new deadline, relative to the time the modify request is received by the + * Pub/Sub service + * @param unit time unit for the {@code deadline} parameter + * @param ackId the ack id of the first message for which the acknowledge deadline must be + * modified + * @param ackIds other ack ids of messages for which the acknowledge deadline must be modified + * @throws PubSubException upon failure, or if the subscription was not found + */ void modifyAckDeadline(String subscription, int deadline, TimeUnit unit, String ackId, String... ackIds); + /** + * Sends a request to modify the acknowledge deadline of the given messages. {@code deadline} + * must be >= 0 and is the new deadline with respect to the time the modify request was received + * by the Pub/Sub service. For example, if {@code deadline} is 10 and {@code unit} is + * {@link TimeUnit#SECONDS}, the new ack deadline will expire 10 seconds after the modify request + * was received by the service. Specifying 0 may be used to make the message available for another + * pull request (corresponds to calling {@link #nackAsync(String, Iterable)}). The method returns + * a {@code Future} object that can be used to wait for the modify operation to be completed. + * + * @param subscription the subscription whose messages need to update their acknowledge deadline + * @param deadline the new deadline, relative to the time the modify request is received by the + * Pub/Sub service + * @param unit time unit for the {@code deadline} parameter + * @param ackId the ack id of the first message for which the acknowledge deadline must be + * modified + * @param ackIds other ack ids of messages for which the acknowledge deadline must be modified + */ Future modifyAckDeadlineAsync(String subscription, int deadline, TimeUnit unit, String ackId, String... ackIds); + /** + * Modifies the acknowledge deadline of the given messages. {@code deadline} must be >= 0 and is + * the new deadline with respect to the time the modify request was received by the Pub/Sub + * service. For example, if {@code deadline} is 10 and {@code unit} is {@link TimeUnit#SECONDS}, + * the new ack deadline will expire 10 seconds after the modify request was received by the + * service. Specifying 0 may be used to make the message available for another pull request + * (corresponds to calling {@link #nack(String, Iterable)}). + * + * @param subscription the subscription whose messages need to update their acknowledge deadline + * @param deadline the new deadline, relative to the time the modify request is received by the + * Pub/Sub service + * @param unit time unit for the {@code deadline} parameter + * @param ackIds the ack ids of messages for which the acknowledge deadline must be modified + * @throws PubSubException upon failure, or if the subscription was not found + */ void modifyAckDeadline(String subscription, int deadline, TimeUnit unit, Iterable ackIds); + /** + * Sends a request to modify the acknowledge deadline of the given messages. {@code deadline} + * must be >= 0 and is the new deadline with respect to the time the modify request was received + * by the Pub/Sub service. For example, if {@code deadline} is 10 and {@code unit} is + * {@link TimeUnit#SECONDS}, the new ack deadline will expire 10 seconds after the modify request + * was received by the service. Specifying 0 may be used to make the message available for another + * pull request (corresponds to calling {@link #nackAsync(String, Iterable)}). The method returns + * a {@code Future} object that can be used to wait for the modify operation to be completed. + * + * @param subscription the subscription whose messages need to update their acknowledge deadline + * @param deadline the new deadline, relative to the time the modify request is received by the + * Pub/Sub service + * @param unit time unit for the {@code deadline} parameter + * @param ackIds the ack ids of messages for which the acknowledge deadline must be modified + */ Future modifyAckDeadlineAsync(String subscription, int deadline, TimeUnit unit, Iterable ackIds); diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java index 948f9904b31c..ec1ca920d91d 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java @@ -16,9 +16,9 @@ package com.google.cloud.pubsub; -import static com.google.api.client.util.Preconditions.checkArgument; import static com.google.cloud.pubsub.PubSub.ListOption.OptionType.PAGE_SIZE; import static com.google.cloud.pubsub.PubSub.ListOption.OptionType.PAGE_TOKEN; +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.util.concurrent.Futures.lazyTransform; import com.google.cloud.AsyncPage; @@ -47,6 +47,7 @@ import com.google.pubsub.v1.ListTopicSubscriptionsResponse; import com.google.pubsub.v1.ListTopicsRequest; import com.google.pubsub.v1.ListTopicsResponse; +import com.google.pubsub.v1.ModifyAckDeadlineRequest; import com.google.pubsub.v1.ModifyPushConfigRequest; import com.google.pubsub.v1.PublishRequest; import com.google.pubsub.v1.PublishResponse; @@ -504,25 +505,30 @@ public Future nackAsync(String subscription, Iterable ackIds) { @Override public void modifyAckDeadline(String subscription, int deadline, TimeUnit unit, String ackId, String... ackIds) { - + get(modifyAckDeadlineAsync(subscription, deadline, unit, Lists.asList(ackId, ackIds))); } @Override public Future modifyAckDeadlineAsync(String subscription, int deadline, TimeUnit unit, String ackId, String... ackIds) { - return null; + return modifyAckDeadlineAsync(subscription, deadline, unit, Lists.asList(ackId, ackIds)); } @Override public void modifyAckDeadline(String subscription, int deadline, TimeUnit unit, Iterable ackIds) { - + get(modifyAckDeadlineAsync(subscription, deadline, unit, ackIds)); } @Override public Future modifyAckDeadlineAsync(String subscription, int deadline, TimeUnit unit, Iterable ackIds) { - return null; + ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() + .setSubscription(SubscriberApi.formatSubscriptionName(options().projectId(), subscription)) + .setAckDeadlineSeconds((int) TimeUnit.SECONDS.convert(deadline, unit)) + .addAllAckIds(ackIds) + .build(); + return lazyTransform(rpc.modify(request), EMPTY_TO_VOID_FUNCTION); } static Map optionMap(Option... options) { diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java index 1745b03cf7d7..7df6cb2632f5 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java @@ -54,13 +54,13 @@ import com.google.pubsub.v1.Subscription; import com.google.pubsub.v1.Topic; -import org.joda.time.Duration; - import io.grpc.ManagedChannel; import io.grpc.Status.Code; import io.grpc.netty.NegotiationType; import io.grpc.netty.NettyChannelBuilder; +import org.joda.time.Duration; + import java.io.IOException; import java.util.Set; import java.util.concurrent.Future; diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/testing/LocalPubsubHelper.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/testing/LocalPubsubHelper.java index 5a6cf6574211..4ec128709e62 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/testing/LocalPubsubHelper.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/testing/LocalPubsubHelper.java @@ -23,6 +23,10 @@ import com.google.cloud.RetryParams; import com.google.cloud.pubsub.PubSubOptions; +import io.grpc.ManagedChannel; +import io.grpc.netty.NegotiationType; +import io.grpc.netty.NettyChannelBuilder; + import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; @@ -31,10 +35,6 @@ import java.util.List; import java.util.UUID; -import io.grpc.ManagedChannel; -import io.grpc.netty.NegotiationType; -import io.grpc.netty.NettyChannelBuilder; - /** * A class that runs a Pubsub emulator instance for use in tests. */ diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/LocalSystemTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/LocalSystemTest.java index 618a2b9bd926..ed1bef26c7cb 100644 --- a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/LocalSystemTest.java +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/LocalSystemTest.java @@ -47,7 +47,7 @@ public static void startServer() throws IOException, InterruptedException { @AfterClass public static void stopServer() throws Exception { - pubsub.options().rpc().close(); + pubsub.close(); pubsubHelper.reset(); pubsubHelper.stop(); } diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PubSubImplTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PubSubImplTest.java index f9817d72b6b0..3c5b811307f5 100644 --- a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PubSubImplTest.java +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PubSubImplTest.java @@ -47,6 +47,7 @@ import com.google.pubsub.v1.ListTopicSubscriptionsResponse; import com.google.pubsub.v1.ListTopicsRequest; import com.google.pubsub.v1.ListTopicsResponse; +import com.google.pubsub.v1.ModifyAckDeadlineRequest; import com.google.pubsub.v1.ModifyPushConfigRequest; import com.google.pubsub.v1.PublishRequest; import com.google.pubsub.v1.PublishResponse; @@ -61,6 +62,7 @@ import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; public class PubSubImplTest { @@ -1187,6 +1189,100 @@ public void testListTopicSubscriptionsAsyncWithOptions() Iterables.toArray(page.values(), SubscriptionId.class)); } + @Test + public void testModifyAckDeadlineOneMessage() { + pubsub = options.service(); + ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() + .setAckDeadlineSeconds(10) + .setSubscription(SUBSCRIPTION_NAME_PB) + .addAckIds("ackId") + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub.modifyAckDeadline(SUBSCRIPTION, 10, TimeUnit.SECONDS, "ackId"); + } + + @Test + public void testModifyAckDeadlineOneMessageAsync() + throws ExecutionException, InterruptedException { + pubsub = options.service(); + ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() + .setAckDeadlineSeconds(10) + .setSubscription(SUBSCRIPTION_NAME_PB) + .addAckIds("ackId") + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + Future future = + pubsub.modifyAckDeadlineAsync(SUBSCRIPTION, 10, TimeUnit.SECONDS, "ackId"); + assertNull(future.get()); + } + + @Test + public void testModifyAckDeadlineMoreMessages() { + pubsub = options.service(); + ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() + .setAckDeadlineSeconds(10) + .setSubscription(SUBSCRIPTION_NAME_PB) + .addAllAckIds(ImmutableList.of("ackId1", "ackId2")) + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub.modifyAckDeadline(SUBSCRIPTION, 10, TimeUnit.SECONDS, "ackId1", "ackId2"); + } + + @Test + public void testModifyAckDeadlineMoreMessagesAsync() + throws ExecutionException, InterruptedException { + pubsub = options.service(); + ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() + .setAckDeadlineSeconds(10) + .setSubscription(SUBSCRIPTION_NAME_PB) + .addAllAckIds(ImmutableList.of("ackId1", "ackId2")) + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + Future future = + pubsub.modifyAckDeadlineAsync(SUBSCRIPTION, 10, TimeUnit.SECONDS, "ackId1", "ackId2"); + assertNull(future.get()); + } + + @Test + public void testModifyAckDeadlineMessageList() { + pubsub = options.service(); + List ackIds = ImmutableList.of("ackId1", "ackId2"); + ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() + .setAckDeadlineSeconds(10) + .setSubscription(SUBSCRIPTION_NAME_PB) + .addAllAckIds(ackIds) + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub.modifyAckDeadline(SUBSCRIPTION, 10, TimeUnit.SECONDS, ackIds); + } + + @Test + public void testModifyAckDeadlineMessageListAsync() + throws ExecutionException, InterruptedException { + pubsub = options.service(); + List ackIds = ImmutableList.of("ackId1", "ackId2"); + ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() + .setAckDeadlineSeconds(10) + .setSubscription(SUBSCRIPTION_NAME_PB) + .addAllAckIds(ackIds) + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + Future future = pubsub.modifyAckDeadlineAsync(SUBSCRIPTION, 10, TimeUnit.SECONDS, ackIds); + assertNull(future.get()); + } + @Test public void testClose() throws Exception { pubsub = options.service(); From b872399fe0c8a444cc5b52a89fd3baff9cd18aab Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 26 May 2016 13:27:57 +0200 Subject: [PATCH 360/375] Fix deleted topic name: _deleted_topic_ -> _deleted-topic_ (#1023) --- .../src/main/java/com/google/cloud/pubsub/TopicId.java | 4 ++-- .../java/com/google/cloud/pubsub/SubscriptionInfoTest.java | 2 +- .../src/test/java/com/google/cloud/pubsub/TopicIdTest.java | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicId.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicId.java index a86d7ad84977..458df8372dd4 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicId.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicId.java @@ -33,7 +33,7 @@ public final class TopicId implements Serializable { private static final long serialVersionUID = -4913169763174877777L; - private static final String DELETED_TOPIC_NAME = "_deleted_topic_"; + private static final String DELETED_TOPIC_NAME = "_deleted-topic_"; private static final TopicId DELETED_TOPIC = new TopicId(null, DELETED_TOPIC_NAME, true); private final String project; @@ -68,7 +68,7 @@ public String topic() { /** * Returns {@code true} if this object is the identity of a deleted topic, {@code false} * otherwhise. If {@code isDeleted()} is {@code true}, {@link #topic()} returns - * "{@code _deleted_topic_}" and {@link #project()} returns {@code null}. + * "{@code _deleted-topic_}" and {@link #project()} returns {@code null}. */ public boolean isDeleted() { return isDeleted; diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionInfoTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionInfoTest.java index be832a9c8994..36846f06f26a 100644 --- a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionInfoTest.java +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/SubscriptionInfoTest.java @@ -113,7 +113,7 @@ public void testToAndFromPb() { SubscriptionInfo.fromPb(subscriptionInfo.toPb("project"))); com.google.pubsub.v1.Subscription subscription = SUBSCRIPTION_INFO.toPb("project"); subscriptionInfo = - SubscriptionInfo.fromPb(subscription.toBuilder().setTopic("_deleted_topic_").build()); + SubscriptionInfo.fromPb(subscription.toBuilder().setTopic("_deleted-topic_").build()); assertEquals(TopicId.deletedTopic(), subscriptionInfo.topic()); assertEquals(NAME, subscriptionInfo.name()); assertEquals(PUSH_CONFIG, subscriptionInfo.pushConfig()); diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/TopicIdTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/TopicIdTest.java index a75732709be9..c8d5da25bc89 100644 --- a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/TopicIdTest.java +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/TopicIdTest.java @@ -29,6 +29,7 @@ public class TopicIdTest { private static final String PROJECT = "project"; private static final String NAME = "topic"; private static final String TOPIC_PB = "projects/project/topics/topic"; + private static final String DELETED_TOPIC_NAME = "_deleted-topic_"; @Test public void testOf() { @@ -45,7 +46,7 @@ public void testOf() { public void testDeletedTopic() { TopicId deletedTopic = TopicId.deletedTopic(); assertNull(deletedTopic.project()); - assertEquals("_deleted_topic_", deletedTopic.topic()); + assertEquals(DELETED_TOPIC_NAME, deletedTopic.topic()); assertTrue(deletedTopic.isDeleted()); assertSame(deletedTopic, TopicId.deletedTopic()); } @@ -60,6 +61,7 @@ public void testToAndFromPb() { topicPb = topicId.toPb("otherProject"); assertEquals("projects/otherProject/topics/topic", topicPb); compareTopicId(TopicId.of("otherProject", NAME), TopicId.fromPb(topicPb)); + assertSame(TopicId.deletedTopic(), TopicId.fromPb(DELETED_TOPIC_NAME)); } private void compareTopicId(TopicId expected, TopicId value) { From 11f457382068ce5b5266028000bc4ee51c0521ef Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Sat, 28 May 2016 22:37:10 +0200 Subject: [PATCH 361/375] Add OAuth2AuthCredentials class and tests (#1030) --- README.md | 15 +- .../com/google/cloud/AuthCredentials.java | 83 ++++++++++++ .../com/google/cloud/AuthCredentialsTest.java | 128 ++++++++++++++++++ .../com/google/cloud/SerializationTest.java | 4 +- 4 files changed, 225 insertions(+), 5 deletions(-) create mode 100644 gcloud-java-core/src/test/java/com/google/cloud/AuthCredentialsTest.java diff --git a/README.md b/README.md index c5d7c7b1ee58..76dff042d27d 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ First, ensure that the necessary Google Cloud APIs are enabled for your project. Next, choose a method for authenticating API requests from within your project: 1. When using `gcloud-java` libraries from within Compute/App Engine, no additional authentication steps are necessary. -2. When using `gcloud-java` libraries elsewhere, there are two options: +2. When using `gcloud-java` libraries elsewhere, there are three options: * [Generate a JSON service account key](https://cloud.google.com/storage/docs/authentication?hl=en#service_accounts). After downloading that key, you must do one of the following: * Define the environment variable GOOGLE_APPLICATION_CREDENTIALS to be the location of the key. For example: ```bash @@ -116,11 +116,18 @@ Next, choose a method for authenticating API requests from within your project: * Supply the JSON credentials file when building the service options. For example, this Storage object has the necessary permissions to interact with your Google Cloud Storage data: ```java Storage storage = StorageOptions.builder() - .authCredentials(AuthCredentials.createForJson(new FileInputStream("/path/to/my/key.json")) + .authCredentials(AuthCredentials.createForJson(new FileInputStream("/path/to/my/key.json")) + .build() + .service(); + ``` + * If running locally for development/testing, you can use Google Cloud SDK. Download the SDK if you haven't already, then login using the SDK (`gcloud auth login` in command line). Be sure to set your project ID as described above. + * If you already have an OAuth2 access token, you can use it to authenticate (notice that in this case the access token will not be automatically refreshed): + ```java + Storage storage = StorageOptions.builder() + .authCredentials(AuthCredentials.createFor("your_access_token")) .build() .service(); - ``` - * If running locally for development/testing, you can use use Google Cloud SDK. Download the SDK if you haven't already, then login using the SDK (`gcloud auth login` in command line). Be sure to set your project ID as described above. + ``` `gcloud-java` looks for credentials in the following order, stopping once it finds credentials: diff --git a/gcloud-java-core/src/main/java/com/google/cloud/AuthCredentials.java b/gcloud-java-core/src/main/java/com/google/cloud/AuthCredentials.java index ec5a631f5f54..792831bb9edc 100644 --- a/gcloud-java-core/src/main/java/com/google/cloud/AuthCredentials.java +++ b/gcloud-java-core/src/main/java/com/google/cloud/AuthCredentials.java @@ -341,6 +341,67 @@ public RestorableState capture() { } } + /** + * Represents OAuth2 credentials. These credentials can be created given an OAuth2 access token. + * The access token will not be automatically refreshed. + */ + public static class OAuth2AuthCredentials extends AuthCredentials { + + private final GoogleCredentials credentials; + private final String accessToken; + private final Date expirationTime; + + private static class OAuth2AuthCredentialsState + implements RestorableState, Serializable { + + private static final long serialVersionUID = -7760693952274496205L; + + private final String accessToken; + private final Date expirationTime; + + private OAuth2AuthCredentialsState(String accessToken, Date expirationTime) { + this.accessToken = accessToken; + this.expirationTime = expirationTime; + } + + @Override + public AuthCredentials restore() { + return new OAuth2AuthCredentials(accessToken, expirationTime); + } + + @Override + public int hashCode() { + return Objects.hash(accessToken, expirationTime); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof OAuth2AuthCredentialsState)) { + return false; + } + OAuth2AuthCredentialsState other = (OAuth2AuthCredentialsState) obj; + return Objects.equals(accessToken, other.accessToken) + && Objects.equals(expirationTime, other.expirationTime); + } + } + + OAuth2AuthCredentials(String accessToken, Date expirationTime) { + this.accessToken = checkNotNull(accessToken); + this.expirationTime = expirationTime; + this.credentials = new GoogleCredentials(new AccessToken(accessToken, expirationTime)); + } + + @Override + public GoogleCredentials credentials() { + return credentials; + } + + @Override + public RestorableState capture() { + return new OAuth2AuthCredentialsState(accessToken, expirationTime); + } + } + /** * A placeholder for credentials to signify that requests sent to the server should not be * authenticated. This is typically useful when using the local service emulators, such as @@ -428,6 +489,28 @@ public static ServiceAccountAuthCredentials createFor(String account, PrivateKey return new ServiceAccountAuthCredentials(account, privateKey); } + /** + * Creates OAuth2 Credentials given the string representation of an access token. The access token + * will not be automatically refreshed. + * + * @param accessToken string representation of an access token + * @return the credentials instance + */ + public static OAuth2AuthCredentials createFor(String accessToken) { + return createFor(accessToken, (Date) null); + } + + /** + * Creates OAuth2 Credentials given the string representation of an access token and its + * expiration time. The access token will not be automatically refreshed. + * + * @param accessToken string representation of an access token + * @return the credentials instance + */ + public static OAuth2AuthCredentials createFor(String accessToken, Date expirationTime) { + return new OAuth2AuthCredentials(accessToken, expirationTime); + } + /** * Creates a placeholder denoting that no credentials should be used. This is typically useful * when using the local service emulators, such as {@code LocalDatastoreHelper} and diff --git a/gcloud-java-core/src/test/java/com/google/cloud/AuthCredentialsTest.java b/gcloud-java-core/src/test/java/com/google/cloud/AuthCredentialsTest.java new file mode 100644 index 000000000000..9074c2d103a6 --- /dev/null +++ b/gcloud-java-core/src/test/java/com/google/cloud/AuthCredentialsTest.java @@ -0,0 +1,128 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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; + +import static com.google.common.base.Charsets.UTF_8; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; + +import com.google.auth.oauth2.AccessToken; +import com.google.auth.oauth2.ServiceAccountCredentials; +import com.google.cloud.AuthCredentials.OAuth2AuthCredentials; +import com.google.cloud.AuthCredentials.ServiceAccountAuthCredentials; +import com.google.common.io.BaseEncoding; + +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.Signature; +import java.security.SignatureException; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.util.Date; + +public class AuthCredentialsTest { + + private static final String ACCESS_TOKEN = "accessToken"; + private static final Date EXPIRATION_DATE = new Date(); + private static final String SERVICE_ACCOUNT = "someclientid@developer.gserviceaccount.com"; + private static final String PRIVATE_KEY_STRING = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoG" + + "BAL2xolH1zrISQ8+GzOV29BNjjzq4/HIP8Psd1+cZb81vDklSF+95wB250MSE0BDc81pvIMwj5OmIfLg1NY6uB1xav" + + "OPpVdx1z664AGc/BEJ1zInXGXaQ6s+SxGenVq40Yws57gikQGMZjttpf1Qbz4DjkxsbRoeaRHn06n9pH1ejAgMBAAE" + + "CgYEAkWcm0AJF5LMhbWKbjkxm/LG06UNApkHX6vTOOOODkonM/qDBnhvKCj8Tan+PaU2j7679Cd19qxCm4SBQJET7e" + + "BhqLD9L2j9y0h2YUQnLbISaqUS1/EXcr2C1Lf9VCEn1y/GYuDYqs85rGoQ4ZYfM9ClROSq86fH+cbIIssqJqukCQQD" + + "18LjfJz/ichFeli5/l1jaFid2XoCH3T6TVuuysszVx68fh60gSIxEF/0X2xB+wuPxTP4IQ+t8tD/ktd232oWXAkEAx" + + "XPych2QBHePk9/lek4tOkKBgfnDzex7S/pI0G1vpB3VmzBbCsokn9lpOv7JV8071GDlW/7R6jlLfpQy3hN31QJAE10" + + "osSk99m5Uv8XDU3hvHnywDrnSFOBulNs7I47AYfSe7TSZhPkxUgsxejddTR27JLyTI8N1PxRSE4feNSOXcQJAMMKJR" + + "JT4U6IS2rmXubREhvaVdLtxFxEnAYQ1JwNfZm/XqBMw6GEy2iaeTetNXVlZRQEIoscyn1y2v/No/F5iYQJBAKBOGAS" + + "oQcBjGTOg/H/SfcE8QVNsKEpthRrs6CkpT80aZ/AV+ksfoIf2zw2M3mAHfrO+TBLdz4sicuFQvlN9SEc="; + private static final String JSON_KEY = "{\n" + + " \"private_key_id\": \"somekeyid\",\n" + + " \"private_key\": \"-----BEGIN PRIVATE KEY-----\\n" + PRIVATE_KEY_STRING + + "\\n-----END PRIVATE KEY-----\\n\",\n" + + " \"client_email\": \"someclientid@developer.gserviceaccount.com\",\n" + + " \"client_id\": \"someclientid.apps.googleusercontent.com\",\n" + + " \"type\": \"service_account\"\n" + + "}"; + private static final AuthCredentials NO_AUTH_CREDENTIALS = AuthCredentials.noAuth(); + private static final OAuth2AuthCredentials OAUTH2_AUTH_CREDENTIALS = + AuthCredentials.createFor(ACCESS_TOKEN, EXPIRATION_DATE); + private static final byte[] BYTES_TO_SIGN = PRIVATE_KEY_STRING.getBytes(UTF_8); + + private static PrivateKey privateKey; + private static byte[] signedBytes; + + @BeforeClass + public static void beforeClass() throws NoSuchAlgorithmException, InvalidKeySpecException, + InvalidKeyException, SignatureException { + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + privateKey = keyFactory.generatePrivate( + new PKCS8EncodedKeySpec(BaseEncoding.base64().decode(PRIVATE_KEY_STRING))); + Signature signature = Signature.getInstance("SHA256withRSA"); + signature.initSign(privateKey); + signature.update(BYTES_TO_SIGN); + signedBytes = signature.sign(); + } + + @Test + public void testNoAuthCredentials() { + assertSame(NO_AUTH_CREDENTIALS, AuthCredentials.noAuth()); + assertNull(NO_AUTH_CREDENTIALS.credentials()); + } + + @Test + public void testOAuth2AuthCredentials() { + AccessToken accessToken = OAUTH2_AUTH_CREDENTIALS.credentials().getAccessToken(); + assertEquals(ACCESS_TOKEN, accessToken.getTokenValue()); + assertEquals(EXPIRATION_DATE, accessToken.getExpirationTime()); + OAuth2AuthCredentials oAuth2AuthCredentials = + AuthCredentials.createFor(ACCESS_TOKEN); + accessToken = oAuth2AuthCredentials.credentials().getAccessToken(); + assertEquals(ACCESS_TOKEN, accessToken.getTokenValue()); + assertNull(accessToken.getExpirationTime()); + } + + @Test + public void testServiceAccountFromJson() throws IOException, SignatureException { + ServiceAccountAuthCredentials serviceAccountAuthCredentials = + AuthCredentials.createForJson(new ByteArrayInputStream(JSON_KEY.getBytes())); + ServiceAccountCredentials credentials = serviceAccountAuthCredentials.credentials(); + assertEquals(SERVICE_ACCOUNT, serviceAccountAuthCredentials.account()); + assertEquals(SERVICE_ACCOUNT, credentials.getClientEmail()); + assertEquals(privateKey, credentials.getPrivateKey()); + assertArrayEquals(signedBytes, serviceAccountAuthCredentials.sign(BYTES_TO_SIGN)); + } + + @Test + public void testServiceAccountFromKey() throws IOException, SignatureException { + ServiceAccountAuthCredentials serviceAccountAuthCredentials = + AuthCredentials.createFor(SERVICE_ACCOUNT, privateKey); + ServiceAccountCredentials credentials = serviceAccountAuthCredentials.credentials(); + assertEquals(SERVICE_ACCOUNT, serviceAccountAuthCredentials.account()); + assertEquals(SERVICE_ACCOUNT, credentials.getClientEmail()); + assertEquals(privateKey, credentials.getPrivateKey()); + assertArrayEquals(signedBytes, serviceAccountAuthCredentials.sign(BYTES_TO_SIGN)); + } +} diff --git a/gcloud-java-core/src/test/java/com/google/cloud/SerializationTest.java b/gcloud-java-core/src/test/java/com/google/cloud/SerializationTest.java index 75347b250227..7fa778a524eb 100644 --- a/gcloud-java-core/src/test/java/com/google/cloud/SerializationTest.java +++ b/gcloud-java-core/src/test/java/com/google/cloud/SerializationTest.java @@ -22,6 +22,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.Serializable; +import java.util.Date; public class SerializationTest extends BaseSerializationTest { @@ -94,7 +95,8 @@ protected Serializable[] serializableObjects() { protected Restorable[] restorableObjects() { try { return new Restorable[]{AuthCredentials.createForAppEngine(), AuthCredentials.noAuth(), - AuthCredentials.createForJson(new ByteArrayInputStream(JSON_KEY.getBytes()))}; + AuthCredentials.createForJson(new ByteArrayInputStream(JSON_KEY.getBytes())), + AuthCredentials.createFor("accessToken", new Date())}; } catch (IOException ex) { // never reached throw new RuntimeException(ex); From f4055bd58fb87627d91a8a45c4b08d1da2d81d9a Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Sat, 28 May 2016 22:37:46 +0200 Subject: [PATCH 362/375] Add javadoc and tests for functional Topic class (#1021) --- .../java/com/google/cloud/pubsub/Topic.java | 128 ++++++- .../com/google/cloud/pubsub/TopicInfo.java | 15 +- .../com/google/cloud/pubsub/TopicTest.java | 320 ++++++++++++++++++ 3 files changed, 448 insertions(+), 15 deletions(-) create mode 100644 gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/TopicTest.java diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Topic.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Topic.java index 65ed737fc0cd..a2b348f4e91d 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Topic.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Topic.java @@ -30,7 +30,13 @@ import java.util.concurrent.Future; /** - * PubSub Topic. + * A Google Cloud Pub/Sub topic. A topic is a named resource to which messages are sent by + * publishers. Subscribers can receive messages sent to a topic by creating subscriptions. + * {@code Topic} adds a layer of service-related functionality over {@link TopicInfo}. Objects of + * this class are immutable. To get a {@code Topic} object with the most recent information use + * {@link #reload} or {@link #reloadAsync}. + * + * @see Pub/Sub Data Model */ public class Topic extends TopicInfo { @@ -39,6 +45,9 @@ public class Topic extends TopicInfo { private final PubSubOptions options; private transient PubSub pubsub; + /** + * A builder for {@code Topic} objects. + */ public static final class Builder extends TopicInfo.Builder { private final PubSub pubsub; @@ -73,70 +82,173 @@ public Builder toBuilder() { } @Override - public int hashCode() { + public final int hashCode() { return Objects.hash(options, super.hashCode()); } @Override - public boolean equals(Object obj) { - if (this == obj) { + public final boolean equals(Object obj) { + if (obj == this) { return true; } - if (obj == null || getClass() != obj.getClass()) { + if (obj == null || !obj.getClass().equals(Topic.class)) { return false; } Topic other = (Topic) obj; - return Objects.equals(name(), other.name()) && Objects.equals(options, other.options); + return baseEquals(other) && Objects.equals(options, other.options); } + /** + * Returns the topic's {@code PubSub} object used to issue requests. + */ public PubSub pubSub() { return pubsub; } + /** + * Deletes this topic. + * + * @return {@code true} if the topic was deleted, {@code false} if it was not found + * @throws PubSubException upon failure + */ public boolean delete() { return pubsub.deleteTopic(name()); } + /** + * Sends a request for deleting this topic. This method returns a {@code Future} object to consume + * the result. {@link Future#get()} returns {@code true} if the topic was deleted, {@code false} + * if it was not found. + * + * @throws PubSubException upon failure + */ public Future deleteAsync() { return pubsub.deleteTopicAsync(name()); } + /** + * Fetches current topic's latest information. Returns {@code null} if the topic does not exist. + * + * @return a {@code Topic} object with latest information or {@code null} if not found + * @throws PubSubException upon failure + */ public Topic reload() { return pubsub.getTopic(name()); } + /** + * Sends a request to fetch current topic's latest information. This method returns a + * {@code Future} object to consume the result. {@link Future#get()} returns a {@code Topic} + * object with latest information or {@code null} if not found. + * + * @throws PubSubException upon failure + */ public Future reloadAsync() { return pubsub.getTopicAsync(name()); } + /** + * Publishes a message to this topic. This method returns a service-generated id for the published + * message. Service-generated ids are guaranteed to be unique within the topic. + * + * @param message the message to publish + * @return a unique service-generated id for the message + * @throws PubSubException upon failure, if the topic does not exist or if the message has empty + * payload and no attributes + */ public String publish(Message message) { return pubsub.publish(name(), message); } + /** + * Sends a request for publishing a message to the this topic. This method returns a + * {@code Future} object to consume the result. {@link Future#get()} returns a service-generated + * id for the published message. Service-generated ids are guaranteed to be unique within the + * topic. + * + * @param message the message to publish + * @return a {@code Future} for the unique service-generated id for the message + */ public Future publishAsync(Message message) { return pubsub.publishAsync(name(), message); } + /** + * Publishes a number of messages to this topic. This method returns a list of service-generated + * ids for the published messages. Service-generated ids are guaranteed to be unique within the + * topic. + * + * @param message the first message to publish + * @param messages other messages to publish + * @return a list of unique, service-generated, ids. Ids are in the same order as the messages. + * @throws PubSubException upon failure, if the topic does not exist or if one of the messages has + * empty payload and no attributes + */ public List publish(Message message, Message... messages) { return pubsub.publish(name(), message, messages); } + /** + * Sends a request to publish a number of messages to this topic. This method returns a + * {@code Future} object to consume the result. {@link Future#get()} returns a list of + * service-generated ids for the published messages. Service-generated ids are guaranteed to be + * unique within the topic. + * + * @param message the first message to publish + * @param messages other messages to publish + * @return a {@code Future} for the unique, service-generated ids. Ids are in the same order as + * the messages. + */ public Future> publishAsync(Message message, Message... messages) { return pubsub.publishAsync(name(), message, messages); } + /** + * Publishes a number of messages to this topic. This method returns a list ofservice-generated + * ids for the published messages. Service-generated ids are guaranteed to be unique within the + * topic. + * + * @param messages the messages to publish + * @return a list of unique, service-generated, ids. Ids are in the same order as the messages. + * @throws PubSubException upon failure, if the topic does not exist or if one of the messages has + * empty payload and no attributes + */ public List publish(Iterable messages) { return pubsub.publish(name(), messages); } + /** + * Sends a request to publish a number of messages to this topic. This method returns a + * {@code Future} object to consume the result. {@link Future#get()} returns a list of + * service-generated ids for the published messages. Service-generated ids are guaranteed to be + * unique within the topic. + * + * @param messages the messages to publish + * @return a {@code Future} for the unique, service-generated ids. Ids are in the same order as + * the messages. + */ public Future> publishAsync(Iterable messages) { return pubsub.publishAsync(name(), messages); } + /** + * Lists the identities of the subscriptions for this topic. This method returns a {@link Page} + * object that can be used to consume paginated results. Use {@link ListOption} to specify the + * page size or the page token from which to start listing subscriptions. + * + * @throws PubSubException upon failure + */ public Page listSubscriptions(ListOption... options) { return pubsub.listSubscriptions(name(), options); } + /** + * Sends a request for listing the identities of subscriptions for this topic. This method returns + * a {@code Future} object to consume the result. {@link Future#get()} returns an + * {@link AsyncPage} object that can be used to asynchronously handle paginated results. Use + * {@link ListOption} to specify the page size or the page token from which to start listing + * subscriptions. + */ public Future> listSubscriptionsAsync(ListOption... options) { return pubsub.listSubscriptionsAsync(name(), options); } @@ -146,9 +258,9 @@ private void readObject(ObjectInputStream input) throws IOException, ClassNotFou this.pubsub = options.service(); } - static Topic fromPb(PubSub storage, com.google.pubsub.v1.Topic topicPb) { + static Topic fromPb(PubSub pubsub, com.google.pubsub.v1.Topic topicPb) { TopicInfo topicInfo = TopicInfo.fromPb(topicPb); - return new Topic(storage, new BuilderImpl(topicInfo)); + return new Topic(pubsub, new BuilderImpl(topicInfo)); } static Function fromPbFunction(final PubSub pubsub) { diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicInfo.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicInfo.java index 8c90a0c2705d..e1b2dc6275a0 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicInfo.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/TopicInfo.java @@ -98,15 +98,16 @@ public int hashCode() { return Objects.hash(name); } + final boolean baseEquals(TopicInfo topicInfo) { + return Objects.equals(name, topicInfo.name); + } + @Override public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null || !obj.getClass().equals(this.getClass())) { - return false; - } - return Objects.equals(name, ((TopicInfo) obj).name); + return obj == this + || obj != null + && obj.getClass().equals(TopicInfo.class) + && baseEquals((TopicInfo) obj); } @Override diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/TopicTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/TopicTest.java new file mode 100644 index 000000000000..911c6ec0d627 --- /dev/null +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/TopicTest.java @@ -0,0 +1,320 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.createStrictMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import com.google.cloud.AsyncPage; +import com.google.cloud.AsyncPageImpl; +import com.google.cloud.Page; +import com.google.cloud.PageImpl; +import com.google.cloud.pubsub.PubSub.ListOption; +import com.google.common.collect.ImmutableList; +import com.google.common.util.concurrent.Futures; + +import org.junit.After; +import org.junit.Test; + +import java.util.List; +import java.util.concurrent.ExecutionException; + +public class TopicTest { + + private static final String NAME = "topic"; + private static final TopicInfo TOPIC_INFO = TopicInfo.of(NAME); + + private final PubSub serviceMockReturnsOptions = createStrictMock(PubSub.class); + private final PubSubOptions mockOptions = createMock(PubSubOptions.class); + private PubSub pubsub; + private Topic expectedTopic; + private Topic topic; + + private void initializeExpectedTopic(int optionsCalls) { + expect(serviceMockReturnsOptions.options()).andReturn(mockOptions).times(optionsCalls); + replay(serviceMockReturnsOptions); + pubsub = createStrictMock(PubSub.class); + expectedTopic = new Topic(serviceMockReturnsOptions, new Topic.BuilderImpl(TOPIC_INFO)); + } + + private void initializeTopic() { + topic = new Topic(pubsub, new Topic.BuilderImpl(TOPIC_INFO)); + } + + @After + public void tearDown() throws Exception { + verify(pubsub, serviceMockReturnsOptions); + } + + @Test + public void testBuilder() { + initializeExpectedTopic(2); + replay(pubsub); + Topic builtTopic = expectedTopic.toBuilder().name("newTopic").build(); + assertEquals("newTopic", builtTopic.name()); + } + + @Test + public void testToBuilder() { + initializeExpectedTopic(2); + replay(pubsub); + compareTopic(expectedTopic, expectedTopic.toBuilder().build()); + } + + @Test + public void testReload() { + initializeExpectedTopic(2); + TopicInfo updatedInfo = TOPIC_INFO.toBuilder().name("newTopic").build(); + Topic expectedTopic = + new Topic(serviceMockReturnsOptions, new TopicInfo.BuilderImpl(updatedInfo)); + expect(pubsub.options()).andReturn(mockOptions); + expect(pubsub.getTopic(NAME)).andReturn(expectedTopic); + replay(pubsub); + initializeTopic(); + Topic updatedTopic = topic.reload(); + compareTopic(expectedTopic, updatedTopic); + } + + @Test + public void testReloadNull() { + initializeExpectedTopic(1); + expect(pubsub.options()).andReturn(mockOptions); + expect(pubsub.getTopic(NAME)).andReturn(null); + replay(pubsub); + initializeTopic(); + assertNull(topic.reload()); + } + + @Test + public void testReloadAsync() throws ExecutionException, InterruptedException { + initializeExpectedTopic(2); + TopicInfo updatedInfo = TOPIC_INFO.toBuilder().name("newTopic").build(); + Topic expectedTopic = + new Topic(serviceMockReturnsOptions, new TopicInfo.BuilderImpl(updatedInfo)); + expect(pubsub.options()).andReturn(mockOptions); + expect(pubsub.getTopicAsync(NAME)) + .andReturn(Futures.immediateFuture(expectedTopic)); + replay(pubsub); + initializeTopic(); + Topic updatedTopic = topic.reloadAsync().get(); + compareTopic(expectedTopic, updatedTopic); + } + + @Test + public void testReloadAsyncNull() throws ExecutionException, InterruptedException { + initializeExpectedTopic(1); + expect(pubsub.options()).andReturn(mockOptions); + expect(pubsub.getTopicAsync(NAME)).andReturn(Futures.immediateFuture(null)); + replay(pubsub); + initializeTopic(); + assertNull(topic.reloadAsync().get()); + } + + @Test + public void testDeleteTrue() { + initializeExpectedTopic(1); + expect(pubsub.options()).andReturn(mockOptions); + expect(pubsub.deleteTopic(NAME)).andReturn(true); + replay(pubsub); + initializeTopic(); + assertTrue(topic.delete()); + } + + @Test + public void testDeleteFalse() { + initializeExpectedTopic(1); + expect(pubsub.options()).andReturn(mockOptions); + expect(pubsub.deleteTopic(NAME)).andReturn(false); + replay(pubsub); + initializeTopic(); + assertFalse(topic.delete()); + } + + @Test + public void testDeleteAsyncTrue() throws ExecutionException, InterruptedException { + initializeExpectedTopic(1); + expect(pubsub.options()).andReturn(mockOptions); + expect(pubsub.deleteTopicAsync(NAME)).andReturn(Futures.immediateFuture(true)); + replay(pubsub); + initializeTopic(); + assertTrue(topic.deleteAsync().get()); + } + + @Test + public void testDeleteAsyncFalse() throws ExecutionException, InterruptedException { + initializeExpectedTopic(1); + expect(pubsub.options()).andReturn(mockOptions); + expect(pubsub.deleteTopicAsync(NAME)).andReturn(Futures.immediateFuture(false)); + replay(pubsub); + initializeTopic(); + assertFalse(topic.deleteAsync().get()); + } + + @Test + public void testPublishOneMessage() { + initializeExpectedTopic(1); + expect(pubsub.options()).andReturn(mockOptions); + Message message = Message.of("payload1"); + String messageId = "messageId"; + expect(pubsub.publish(NAME, message)).andReturn(messageId); + replay(pubsub); + initializeTopic(); + assertEquals(messageId, topic.publish(message)); + } + + @Test + public void testPublishOneMessageAsync() throws ExecutionException, InterruptedException { + initializeExpectedTopic(1); + expect(pubsub.options()).andReturn(mockOptions); + Message message = Message.of("payload1"); + String messageId = "messageId"; + expect(pubsub.publishAsync(NAME, message)) + .andReturn(Futures.immediateFuture(messageId)); + replay(pubsub); + initializeTopic(); + assertEquals(messageId, topic.publishAsync(message).get()); + } + + @Test + public void testPublishMoreMessages() { + initializeExpectedTopic(1); + expect(pubsub.options()).andReturn(mockOptions); + Message message1 = Message.of("payload1"); + Message message2 = Message.of("payload2"); + List messageIds = ImmutableList.of("messageId1", "messageId2"); + expect(pubsub.publish(NAME, message1, message2)).andReturn(messageIds); + replay(pubsub); + initializeTopic(); + assertEquals(messageIds, topic.publish(message1, message2)); + } + + @Test + public void testPublishMoreMessagesAsync() throws ExecutionException, InterruptedException { + initializeExpectedTopic(1); + expect(pubsub.options()).andReturn(mockOptions); + Message message1 = Message.of("payload1"); + Message message2 = Message.of("payload2"); + List messageIds = ImmutableList.of("messageId1", "messageId2"); + expect(pubsub.publishAsync(NAME, message1, message2)) + .andReturn(Futures.immediateFuture(messageIds)); + replay(pubsub); + initializeTopic(); + assertEquals(messageIds, topic.publishAsync(message1, message2).get()); + } + + @Test + public void testPublishMessageList() { + initializeExpectedTopic(1); + expect(pubsub.options()).andReturn(mockOptions); + Message message1 = Message.of("payload1"); + Message message2 = Message.of("payload2"); + List messages = ImmutableList.of(message1, message2); + List messageIds = ImmutableList.of("messageId1", "messageId2"); + expect(pubsub.publish(NAME, messages)).andReturn(messageIds); + replay(pubsub); + initializeTopic(); + assertEquals(messageIds, topic.publish(messages)); + } + + @Test + public void testPublishMessageListAsync() throws ExecutionException, InterruptedException { + initializeExpectedTopic(1); + expect(pubsub.options()).andReturn(mockOptions); + Message message1 = Message.of("payload1"); + Message message2 = Message.of("payload2"); + List messages = ImmutableList.of(message1, message2); + List messageIds = ImmutableList.of("messageId1", "messageId2"); + expect(pubsub.publishAsync(NAME, messages)) + .andReturn(Futures.immediateFuture(messageIds)); + replay(pubsub); + initializeTopic(); + assertEquals(messageIds, topic.publishAsync(messages).get()); + } + + @Test + public void testListSubscriptions() { + initializeExpectedTopic(1); + expect(pubsub.options()).andReturn(mockOptions); + final List subscriptions = ImmutableList.of( + new SubscriptionId("project", "subscription1"), + new SubscriptionId("project", "subscription2")); + Page result = new PageImpl<>(null, null, subscriptions); + expect(pubsub.listSubscriptions(NAME)).andReturn(result); + replay(pubsub); + initializeTopic(); + assertEquals(subscriptions, topic.listSubscriptions().values()); + } + + @Test + public void testListSubscriptionsWithOptions() { + initializeExpectedTopic(1); + expect(pubsub.options()).andReturn(mockOptions); + final List subscriptions = ImmutableList.of( + new SubscriptionId("project", "subscription1"), + new SubscriptionId("project", "subscription2")); + Page result = new PageImpl<>(null, null, subscriptions); + expect(pubsub.listSubscriptions(NAME, ListOption.pageSize(42))).andReturn(result); + replay(pubsub); + initializeTopic(); + assertEquals(subscriptions, topic.listSubscriptions(ListOption.pageSize(42)).values()); + } + + @Test + public void testListSubscriptionsAsync() throws ExecutionException, InterruptedException { + initializeExpectedTopic(1); + expect(pubsub.options()).andReturn(mockOptions); + final List subscriptions = ImmutableList.of( + new SubscriptionId("project", "subscription1"), + new SubscriptionId("project", "subscription2")); + AsyncPage result = new AsyncPageImpl<>(null, null, subscriptions); + expect(pubsub.listSubscriptionsAsync(NAME)) + .andReturn(Futures.immediateFuture(result)); + replay(pubsub); + initializeTopic(); + assertEquals(subscriptions, topic.listSubscriptionsAsync().get().values()); + } + + @Test + public void testListSubscriptionsAsyncWithOptions() + throws ExecutionException, InterruptedException { + initializeExpectedTopic(1); + expect(pubsub.options()).andReturn(mockOptions); + final List subscriptions = ImmutableList.of( + new SubscriptionId("project", "subscription1"), + new SubscriptionId("project", "subscription2")); + AsyncPage result = new AsyncPageImpl<>(null, null, subscriptions); + expect(pubsub.listSubscriptionsAsync(NAME, ListOption.pageSize(42))) + .andReturn(Futures.immediateFuture(result)); + replay(pubsub); + initializeTopic(); + assertEquals(subscriptions, + topic.listSubscriptionsAsync(ListOption.pageSize(42)).get().values()); + } + + private void compareTopic(Topic expected, Topic value) { + assertEquals(expected, value); + assertEquals(expected.name(), value.name()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} From d3a49ead2a1e4805c55b266e2b3fb0d2e84cc0b7 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 1 Jun 2016 08:29:45 +0200 Subject: [PATCH 363/375] Add createTime() to BlobInfo and Blob classes (#1034) --- .../java/com/google/cloud/storage/Blob.java | 6 +++++ .../com/google/cloud/storage/BlobInfo.java | 25 +++++++++++++++++++ .../google/cloud/storage/BlobInfoTest.java | 6 +++++ .../com/google/cloud/storage/BlobTest.java | 5 ++++ 4 files changed, 42 insertions(+) diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/Blob.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Blob.java index 9b74b686d8f9..3cbb3826541f 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/Blob.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/Blob.java @@ -295,6 +295,12 @@ Builder updateTime(Long updateTime) { return this; } + @Override + Builder createTime(Long createTime) { + infoBuilder.createTime(createTime); + return this; + } + @Override Builder isDirectory(boolean isDirectory) { infoBuilder.isDirectory(isDirectory); diff --git a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobInfo.java b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobInfo.java index f7d21b09a8ee..85404ff84b82 100644 --- a/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobInfo.java +++ b/gcloud-java-storage/src/main/java/com/google/cloud/storage/BlobInfo.java @@ -73,6 +73,7 @@ public StorageObject apply(BlobInfo blobInfo) { private final Long metageneration; private final Long deleteTime; private final Long updateTime; + private final Long createTime; private final String contentType; private final String contentEncoding; private final String contentDisposition; @@ -188,6 +189,8 @@ public abstract static class Builder { abstract Builder updateTime(Long updateTime); + abstract Builder createTime(Long createTime); + abstract Builder isDirectory(boolean isDirectory); /** @@ -218,6 +221,7 @@ static final class BuilderImpl extends Builder { private Long metageneration; private Long deleteTime; private Long updateTime; + private Long createTime; private Boolean isDirectory; BuilderImpl(BlobId blobId) { @@ -245,6 +249,7 @@ static final class BuilderImpl extends Builder { metageneration = blobInfo.metageneration; deleteTime = blobInfo.deleteTime; updateTime = blobInfo.updateTime; + createTime = blobInfo.createTime; isDirectory = blobInfo.isDirectory; } @@ -369,6 +374,12 @@ Builder updateTime(Long updateTime) { return this; } + @Override + Builder createTime(Long createTime) { + this.createTime = createTime; + return this; + } + @Override Builder isDirectory(boolean isDirectory) { this.isDirectory = isDirectory; @@ -403,6 +414,7 @@ public BlobInfo build() { metageneration = builder.metageneration; deleteTime = builder.deleteTime; updateTime = builder.updateTime; + createTime = builder.createTime; isDirectory = firstNonNull(builder.isDirectory, Boolean.FALSE); } @@ -600,6 +612,13 @@ public Long updateTime() { return updateTime; } + /** + * Returns the creation time of the blob. + */ + public Long createTime() { + return createTime; + } + /** * Returns {@code true} if the current blob represents a directory. This can only happen if the * blob is returned by {@link Storage#list(String, Storage.BlobListOption...)} when the @@ -660,6 +679,9 @@ public ObjectAccessControl apply(Acl acl) { if (updateTime != null) { storageObject.setUpdated(new DateTime(updateTime)); } + if (createTime != null) { + storageObject.setTimeCreated(new DateTime(createTime)); + } if (size != null) { storageObject.setSize(BigInteger.valueOf(size)); } @@ -773,6 +795,9 @@ static BlobInfo fromPb(StorageObject storageObject) { if (storageObject.getUpdated() != null) { builder.updateTime(storageObject.getUpdated().getValue()); } + if (storageObject.getTimeCreated() != null) { + builder.createTime(storageObject.getTimeCreated().getValue()); + } if (storageObject.getSize() != null) { builder.size(storageObject.getSize().longValue()); } diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobInfoTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobInfoTest.java index 03d28f8e988e..020e61e9d12e 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobInfoTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobInfoTest.java @@ -60,6 +60,7 @@ public class BlobInfoTest { private static final String SELF_LINK = "http://storage/b/n"; private static final Long SIZE = 1024L; private static final Long UPDATE_TIME = DELETE_TIME - 1L; + private static final Long CREATE_TIME = UPDATE_TIME - 1L; private static final BlobInfo BLOB_INFO = BlobInfo.builder("b", "n", GENERATION) .acl(ACL) .componentCount(COMPONENT_COUNT) @@ -80,6 +81,7 @@ public class BlobInfoTest { .selfLink(SELF_LINK) .size(SIZE) .updateTime(UPDATE_TIME) + .createTime(CREATE_TIME) .build(); private static final BlobInfo DIRECTORY_INFO = BlobInfo.builder("b", "n/") .size(0L) @@ -127,6 +129,7 @@ public void testBuilder() { assertEquals(SELF_LINK, BLOB_INFO.selfLink()); assertEquals(SIZE, BLOB_INFO.size()); assertEquals(UPDATE_TIME, BLOB_INFO.updateTime()); + assertEquals(CREATE_TIME, BLOB_INFO.createTime()); assertFalse(BLOB_INFO.isDirectory()); assertEquals("b", DIRECTORY_INFO.bucket()); assertEquals("n/", DIRECTORY_INFO.name()); @@ -138,6 +141,7 @@ public void testBuilder() { assertNull(DIRECTORY_INFO.contentEncoding()); assertNull(DIRECTORY_INFO.contentLanguage()); assertNull(DIRECTORY_INFO.crc32c()); + assertNull(DIRECTORY_INFO.createTime()); assertNull(DIRECTORY_INFO.deleteTime()); assertNull(DIRECTORY_INFO.etag()); assertNull(DIRECTORY_INFO.generation()); @@ -165,6 +169,7 @@ private void compareBlobs(BlobInfo expected, BlobInfo value) { assertEquals(expected.contentEncoding(), value.contentEncoding()); assertEquals(expected.contentLanguage(), value.contentLanguage()); assertEquals(expected.crc32c(), value.crc32c()); + assertEquals(expected.createTime(), value.createTime()); assertEquals(expected.deleteTime(), value.deleteTime()); assertEquals(expected.etag(), value.etag()); assertEquals(expected.generation(), value.generation()); @@ -200,6 +205,7 @@ public void testToPbAndFromPb() { assertNull(blobInfo.contentEncoding()); assertNull(blobInfo.contentLanguage()); assertNull(blobInfo.crc32c()); + assertNull(blobInfo.createTime()); assertNull(blobInfo.deleteTime()); assertNull(blobInfo.etag()); assertNull(blobInfo.generation()); diff --git a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobTest.java b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobTest.java index 14cd6970fa87..440f932dd54d 100644 --- a/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobTest.java +++ b/gcloud-java-storage/src/test/java/com/google/cloud/storage/BlobTest.java @@ -73,6 +73,7 @@ public class BlobTest { private static final String SELF_LINK = "http://storage/b/n"; private static final Long SIZE = 1024L; private static final Long UPDATE_TIME = DELETE_TIME - 1L; + private static final Long CREATE_TIME = UPDATE_TIME - 1L; private static final BlobInfo FULL_BLOB_INFO = BlobInfo.builder("b", "n", GENERATION) .acl(ACL) .componentCount(COMPONENT_COUNT) @@ -93,6 +94,7 @@ public class BlobTest { .selfLink(SELF_LINK) .size(SIZE) .updateTime(UPDATE_TIME) + .createTime(CREATE_TIME) .build(); private static final BlobInfo BLOB_INFO = BlobInfo.builder("b", "n").metageneration(42L).build(); private static final BlobInfo DIRECTORY_INFO = BlobInfo.builder("b", "n/") @@ -347,6 +349,7 @@ public void testBuilder() { .selfLink(SELF_LINK) .size(SIZE) .updateTime(UPDATE_TIME) + .createTime(CREATE_TIME) .build(); assertEquals("b", blob.bucket()); assertEquals("n", blob.name()); @@ -358,6 +361,7 @@ public void testBuilder() { assertEquals(CONTENT_ENCODING, blob.contentEncoding()); assertEquals(CONTENT_LANGUAGE, blob.contentLanguage()); assertEquals(CRC32, blob.crc32c()); + assertEquals(CREATE_TIME, blob.createTime()); assertEquals(DELETE_TIME, blob.deleteTime()); assertEquals(ETAG, blob.etag()); assertEquals(GENERATED_ID, blob.generatedId()); @@ -385,6 +389,7 @@ public void testBuilder() { assertNull(blob.contentEncoding()); assertNull(blob.contentLanguage()); assertNull(blob.crc32c()); + assertNull(blob.createTime()); assertNull(blob.deleteTime()); assertNull(blob.etag()); assertNull(blob.generatedId()); From 6df07ba03b911dd99dee2717d774869bbc5889b7 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 1 Jun 2016 12:55:37 +0200 Subject: [PATCH 364/375] Implement ack and nack methods, add javadoc and tests (#1027) --- .../java/com/google/cloud/pubsub/PubSub.java | 98 +++++++++- .../com/google/cloud/pubsub/PubSubImpl.java | 19 +- .../google/cloud/pubsub/PubSubImplTest.java | 173 ++++++++++++++++++ 3 files changed, 276 insertions(+), 14 deletions(-) diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java index e6b496be8e5f..428f74b64024 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java @@ -387,25 +387,107 @@ interface MessageConsumer extends AutoCloseable { MessageConsumer pullAsync(String subscription, MessageProcessor callback, PullOption... options); + /** + * Acknowledges the given messages for the provided subscription. Ack ids identify the messages to + * acknowledge, as returned in {@link ReceivedMessage#ackId()} by {@link #pull(String, int)} and + * {@link #pullAsync(String, int)}. + * + * @param subscription the subscription whose messages must be acknowledged + * @param ackId the ack id of the first message to acknowledge + * @param ackIds other ack ids of messages to acknowledge + * @throws PubSubException upon failure, or if the subscription was not found + */ void ack(String subscription, String ackId, String... ackIds); + /** + * Sends a request to acknowledge the given messages for the provided subscription. Ack ids + * identify the messages to acknowledge, as returned in {@link ReceivedMessage#ackId()} by + * {@link #pull(String, int)} and {@link #pullAsync(String, int)}. The method returns a + * {@code Future} object that can be used to wait for the acknowledge operation to be completed. + * + * @param subscription the subscription whose messages must be acknowledged + * @param ackId the ack id of the first message to acknowledge + * @param ackIds other ack ids of messages to acknowledge + */ Future ackAsync(String subscription, String ackId, String... ackIds); + /** + * Acknowledges the given messages for the provided subscription. Ack ids identify the messages to + * acknowledge, as returned in {@link ReceivedMessage#ackId()} by {@link #pull(String, int)} and + * {@link #pullAsync(String, int)}. + * + * @param subscription the subscription whose messages must be acknowledged + * @param ackIds the ack ids of messages to acknowledge + * @throws PubSubException upon failure, or if the subscription was not found + */ void ack(String subscription, Iterable ackIds); + /** + * Sends a request to acknowledge the given messages for the provided subscription. Ack ids + * identify the messages to acknowledge, as returned in {@link ReceivedMessage#ackId()} by + * {@link #pull(String, int)} and {@link #pullAsync(String, int)}. The method returns a + * {@code Future} object that can be used to wait for the acknowledge operation to be completed. + * + * @param subscription the subscription whose messages must be acknowledged + * @param ackIds the ack ids of messages to acknowledge + */ Future ackAsync(String subscription, Iterable ackIds); + /** + * "Nacks" the given messages for the provided subscription. Ack ids identify the messages to + * "nack", as returned in {@link ReceivedMessage#ackId()} by {@link #pull(String, int)} and + * {@link #pullAsync(String, int)}. This method corresponds to calling + * {@link #modifyAckDeadline(String, int, TimeUnit, String, String...)} with a deadline of 0. + * + * @param subscription the subscription whose messages must be "nacked" + * @param ackId the ack id of the first message to "nack" + * @param ackIds other ack ids of messages to "nack" + * @throws PubSubException upon failure, or if the subscription was not found + */ void nack(String subscription, String ackId, String... ackIds); + /** + * Sends a request to "nack" the given messages for the provided subscription. Ack ids identify + * the messages to "nack", as returned in {@link ReceivedMessage#ackId()} by + * {@link #pull(String, int)} and {@link #pullAsync(String, int)}. This method corresponds to + * calling {@link #modifyAckDeadlineAsync(String, int, TimeUnit, String, String...)} with a + * deadline of 0. The method returns a {@code Future} object that can be used to wait for the + * "nack" operation to be completed. + * + * @param subscription the subscription whose messages must be "nacked" + * @param ackId the ack id of the first message to "nack" + * @param ackIds other ack ids of messages to "nack" + */ Future nackAsync(String subscription, String ackId, String... ackIds); + /** + * "Nacks" the given messages for the provided subscription. Ack ids identify the messages to + * "nack", as returned in {@link ReceivedMessage#ackId()} by {@link #pull(String, int)} and + * {@link #pullAsync(String, int)}. This method corresponds to calling + * {@link #modifyAckDeadline(String, int, TimeUnit, Iterable)} with a deadline of 0. + * + * @param subscription the subscription whose messages must be "nacked" + * @param ackIds the ack ids of messages to "nack" + * @throws PubSubException upon failure, or if the subscription was not found + */ void nack(String subscription, Iterable ackIds); + /** + * Sends a request to "nack" the given messages for the provided subscription. Ack ids identify + * the messages to "nack", as returned in {@link ReceivedMessage#ackId()} by + * {@link #pull(String, int)} and {@link #pullAsync(String, int)}. This method corresponds to + * calling {@link #modifyAckDeadlineAsync(String, int, TimeUnit, Iterable)} with a deadline of 0. + * The method returns a {@code Future} object that can be used to wait for the "nack" operation to + * be completed. + * + * @param subscription the subscription whose messages must be "nacked" + * @param ackIds the ack ids of messages to "nack" + */ Future nackAsync(String subscription, Iterable ackIds); /** - * Modifies the acknowledge deadline of the given messages. {@code deadline} must be >= 0 and is - * the new deadline with respect to the time the modify request was received by the Pub/Sub + * Modifies the acknowledge deadline of the given messages. {@code deadline} must be >= 0 and + * is the new deadline with respect to the time the modify request was received by the Pub/Sub * service. For example, if {@code deadline} is 10 and {@code unit} is {@link TimeUnit#SECONDS}, * the new ack deadline will expire 10 seconds after the modify request was received by the * service. Specifying 0 may be used to make the message available for another pull request @@ -425,8 +507,8 @@ void modifyAckDeadline(String subscription, int deadline, TimeUnit unit, String /** * Sends a request to modify the acknowledge deadline of the given messages. {@code deadline} - * must be >= 0 and is the new deadline with respect to the time the modify request was received - * by the Pub/Sub service. For example, if {@code deadline} is 10 and {@code unit} is + * must be >= 0 and is the new deadline with respect to the time the modify request was + * received by the Pub/Sub service. For example, if {@code deadline} is 10 and {@code unit} is * {@link TimeUnit#SECONDS}, the new ack deadline will expire 10 seconds after the modify request * was received by the service. Specifying 0 may be used to make the message available for another * pull request (corresponds to calling {@link #nackAsync(String, Iterable)}). The method returns @@ -444,8 +526,8 @@ Future modifyAckDeadlineAsync(String subscription, int deadline, TimeUnit String ackId, String... ackIds); /** - * Modifies the acknowledge deadline of the given messages. {@code deadline} must be >= 0 and is - * the new deadline with respect to the time the modify request was received by the Pub/Sub + * Modifies the acknowledge deadline of the given messages. {@code deadline} must be >= 0 and + * is the new deadline with respect to the time the modify request was received by the Pub/Sub * service. For example, if {@code deadline} is 10 and {@code unit} is {@link TimeUnit#SECONDS}, * the new ack deadline will expire 10 seconds after the modify request was received by the * service. Specifying 0 may be used to make the message available for another pull request @@ -462,8 +544,8 @@ Future modifyAckDeadlineAsync(String subscription, int deadline, TimeUnit /** * Sends a request to modify the acknowledge deadline of the given messages. {@code deadline} - * must be >= 0 and is the new deadline with respect to the time the modify request was received - * by the Pub/Sub service. For example, if {@code deadline} is 10 and {@code unit} is + * must be >= 0 and is the new deadline with respect to the time the modify request was + * received by the Pub/Sub service. For example, if {@code deadline} is 10 and {@code unit} is * {@link TimeUnit#SECONDS}, the new ack deadline will expire 10 seconds after the modify request * was received by the service. Specifying 0 may be used to make the message available for another * pull request (corresponds to calling {@link #nackAsync(String, Iterable)}). The method returns diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java index ec1ca920d91d..042f76b5197c 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java @@ -37,6 +37,7 @@ import com.google.common.collect.Maps; import com.google.common.util.concurrent.Uninterruptibles; import com.google.protobuf.Empty; +import com.google.pubsub.v1.AcknowledgeRequest; import com.google.pubsub.v1.DeleteSubscriptionRequest; import com.google.pubsub.v1.DeleteTopicRequest; import com.google.pubsub.v1.GetSubscriptionRequest; @@ -466,40 +467,46 @@ public MessageConsumer pullAsync(String subscription, MessageProcessor callback, @Override public void ack(String subscription, String ackId, String... ackIds) { + ack(subscription, Lists.asList(ackId, ackIds)); } @Override public Future ackAsync(String subscription, String ackId, String... ackIds) { - return null; + return ackAsync(subscription, Lists.asList(ackId, ackIds)); } @Override public void ack(String subscription, Iterable ackIds) { - + get(ackAsync(subscription, ackIds)); } @Override public Future ackAsync(String subscription, Iterable ackIds) { - return null; + AcknowledgeRequest request = AcknowledgeRequest.newBuilder() + .setSubscription(SubscriberApi.formatSubscriptionName(options().projectId(), subscription)) + .addAllAckIds(ackIds) + .build(); + return lazyTransform(rpc.acknowledge(request), EMPTY_TO_VOID_FUNCTION); } @Override public void nack(String subscription, String ackId, String... ackIds) { + nack(subscription, Lists.asList(ackId, ackIds)); } @Override public Future nackAsync(String subscription, String ackId, String... ackIds) { - return null; + return nackAsync(subscription, Lists.asList(ackId, ackIds)); } @Override public void nack(String subscription, Iterable ackIds) { - + get(nackAsync(subscription, ackIds)); } @Override public Future nackAsync(String subscription, Iterable ackIds) { - return null; + return modifyAckDeadlineAsync(subscription, 0, TimeUnit.SECONDS, ackIds); } @Override diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PubSubImplTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PubSubImplTest.java index 3c5b811307f5..6084266492f0 100644 --- a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PubSubImplTest.java +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PubSubImplTest.java @@ -37,6 +37,7 @@ import com.google.common.collect.Lists; import com.google.common.util.concurrent.Futures; import com.google.protobuf.Empty; +import com.google.pubsub.v1.AcknowledgeRequest; import com.google.pubsub.v1.DeleteSubscriptionRequest; import com.google.pubsub.v1.DeleteTopicRequest; import com.google.pubsub.v1.GetSubscriptionRequest; @@ -1189,6 +1190,178 @@ public void testListTopicSubscriptionsAsyncWithOptions() Iterables.toArray(page.values(), SubscriptionId.class)); } + @Test + public void testAckOneMessage() { + pubsub = options.service(); + AcknowledgeRequest request = AcknowledgeRequest.newBuilder() + .setSubscription(SUBSCRIPTION_NAME_PB) + .addAckIds("ackId") + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.acknowledge(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub.ack(SUBSCRIPTION, "ackId"); + } + + @Test + public void testAckOneMessageAsync() throws ExecutionException, InterruptedException { + pubsub = options.service(); + AcknowledgeRequest request = AcknowledgeRequest.newBuilder() + .setSubscription(SUBSCRIPTION_NAME_PB) + .addAckIds("ackId") + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.acknowledge(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + Future future = pubsub.ackAsync(SUBSCRIPTION, "ackId"); + assertNull(future.get()); + } + + @Test + public void testAckMoreMessages() { + pubsub = options.service(); + AcknowledgeRequest request = AcknowledgeRequest.newBuilder() + .setSubscription(SUBSCRIPTION_NAME_PB) + .addAllAckIds(ImmutableList.of("ackId1", "ackId2")) + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.acknowledge(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub.ack(SUBSCRIPTION, "ackId1", "ackId2"); + } + + @Test + public void testAckMoreMessagesAsync() throws ExecutionException, InterruptedException { + pubsub = options.service(); + AcknowledgeRequest request = AcknowledgeRequest.newBuilder() + .setSubscription(SUBSCRIPTION_NAME_PB) + .addAllAckIds(ImmutableList.of("ackId1", "ackId2")) + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.acknowledge(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + Future future = pubsub.ackAsync(SUBSCRIPTION, "ackId1", "ackId2"); + assertNull(future.get()); + } + + @Test + public void testAckMessageList() { + pubsub = options.service(); + List ackIds = ImmutableList.of("ackId1", "ackId2"); + AcknowledgeRequest request = AcknowledgeRequest.newBuilder() + .setSubscription(SUBSCRIPTION_NAME_PB) + .addAllAckIds(ackIds) + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.acknowledge(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub.ack(SUBSCRIPTION, ackIds); + } + + @Test + public void testAckMessageListAsync() throws ExecutionException, InterruptedException { + pubsub = options.service(); + List ackIds = ImmutableList.of("ackId1", "ackId2"); + AcknowledgeRequest request = AcknowledgeRequest.newBuilder() + .setSubscription(SUBSCRIPTION_NAME_PB) + .addAllAckIds(ackIds) + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.acknowledge(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + Future future = pubsub.ackAsync(SUBSCRIPTION, ackIds); + assertNull(future.get()); + } + + @Test + public void testNackOneMessage() { + pubsub = options.service(); + ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() + .setAckDeadlineSeconds(0) + .setSubscription(SUBSCRIPTION_NAME_PB) + .addAckIds("ackId") + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub.nack(SUBSCRIPTION, "ackId"); + } + + @Test + public void testNackOneMessageAsync() throws ExecutionException, InterruptedException { + pubsub = options.service(); + ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() + .setAckDeadlineSeconds(0) + .setSubscription(SUBSCRIPTION_NAME_PB) + .addAckIds("ackId") + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + Future future = pubsub.nackAsync(SUBSCRIPTION, "ackId"); + assertNull(future.get()); + } + + @Test + public void testNackMoreMessages() { + pubsub = options.service(); + ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() + .setAckDeadlineSeconds(0) + .setSubscription(SUBSCRIPTION_NAME_PB) + .addAllAckIds(ImmutableList.of("ackId1", "ackId2")) + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub.nack(SUBSCRIPTION, "ackId1", "ackId2"); + } + + @Test + public void testNackMoreMessagesAsync() throws ExecutionException, InterruptedException { + pubsub = options.service(); + ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() + .setAckDeadlineSeconds(0) + .setSubscription(SUBSCRIPTION_NAME_PB) + .addAllAckIds(ImmutableList.of("ackId1", "ackId2")) + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + Future future = pubsub.nackAsync(SUBSCRIPTION, "ackId1", "ackId2"); + assertNull(future.get()); + } + + @Test + public void testNackMessageList() { + pubsub = options.service(); + List ackIds = ImmutableList.of("ackId1", "ackId2"); + ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() + .setAckDeadlineSeconds(0) + .setSubscription(SUBSCRIPTION_NAME_PB) + .addAllAckIds(ackIds) + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + pubsub.nack(SUBSCRIPTION, ackIds); + } + + @Test + public void testNackMessageListAsync() throws ExecutionException, InterruptedException { + pubsub = options.service(); + List ackIds = ImmutableList.of("ackId1", "ackId2"); + ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() + .setAckDeadlineSeconds(0) + .setSubscription(SUBSCRIPTION_NAME_PB) + .addAllAckIds(ackIds) + .build(); + Future response = Futures.immediateFuture(Empty.getDefaultInstance()); + EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); + EasyMock.replay(pubsubRpcMock); + Future future = pubsub.nackAsync(SUBSCRIPTION, ackIds); + assertNull(future.get()); + } + @Test public void testModifyAckDeadlineOneMessage() { pubsub = options.service(); From 9f96cf09c067a88584f17cf259ec52aa7c148ae3 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 1 Jun 2016 23:56:59 +0200 Subject: [PATCH 365/375] Add javadoc and tests for functional ReceivedMessage class (#1038) --- .../java/com/google/cloud/pubsub/Message.java | 17 +- .../google/cloud/pubsub/ReceivedMessage.java | 84 +++++++- .../cloud/pubsub/ReceivedMessageTest.java | 187 ++++++++++++++++++ 3 files changed, 276 insertions(+), 12 deletions(-) create mode 100644 gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/ReceivedMessageTest.java diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Message.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Message.java index b83e5a6296f6..cc65536d8a84 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Message.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/Message.java @@ -37,7 +37,7 @@ * a key {@code iana.org/language_tag} and value {@code en} could be added to messages to mark them * as readable by an English-speaking subscriber. * - *

    To be published a message must have a non-empty payload, or at least one attribute. + *

    To be published, a message must have a non-empty payload, or at least one attribute. * * @see Pub/Sub Data Model */ @@ -64,11 +64,11 @@ private static final class InternalByteArray extends ByteArray { private static final long serialVersionUID = -3330181485911805428L; - protected InternalByteArray(ByteString byteString) { + InternalByteArray(ByteString byteString) { super(byteString); } - protected InternalByteArray(ByteArray byteArray) { + InternalByteArray(ByteArray byteArray) { super(byteArray); } @@ -244,17 +244,24 @@ public ByteArray payload() { return payload; } + final boolean baseEquals(Message message) { + return Objects.equals(id, message.id) + && Objects.equals(payload, message.payload) + && Objects.equals(attributes, message.attributes) + && Objects.equals(publishTime, message.publishTime); + } + @Override public boolean equals(Object obj) { return obj == this || obj != null && obj.getClass().equals(Message.class) - && Objects.equals(toPb(), ((Message) obj).toPb()); + && baseEquals((Message) obj); } @Override public int hashCode() { - return Objects.hash(serialVersionUID, id, payload, attributes, publishTime); + return Objects.hash(id, payload, attributes, publishTime); } @Override diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/ReceivedMessage.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/ReceivedMessage.java index c3cb705cb6d7..1af9a5ae46d2 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/ReceivedMessage.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/ReceivedMessage.java @@ -27,7 +27,16 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -public class ReceivedMessage extends Message { +/** + * A Google Cloud Pub/Sub received message. A received message has all the information in + * {@link Message} as well as the acknowledge id. The ack id can be used to acknowledge the received + * message. + * + *

    {@code ReceivedMessage} also adds a layer of service-related functionality over + * {@link Message} that help manage received messages (see {@link #ack()}, {@link #nack()} and + * {@link #modifyAckDeadline(int, TimeUnit)}). + */ +public final class ReceivedMessage extends Message { private static final long serialVersionUID = -4178477763916251733L; @@ -124,48 +133,109 @@ public int hashCode() { @Override public boolean equals(Object obj) { - if (this == obj) { + if (obj == this) { return true; } - if (obj == null || getClass() != obj.getClass()) { + if (obj == null || !obj.getClass().equals(ReceivedMessage.class)) { return false; } ReceivedMessage other = (ReceivedMessage) obj; - return Objects.equals(toPb(), other.toPb()) && Objects.equals(options, other.options); + return baseEquals(other) && Objects.equals(options, other.options); } - public PubSub pubSub() { + /** + * Returns the received message's {@code PubSub} object used to issue requests. + */ + public PubSub pubsub() { return pubsub; } + /** + * Returns the name of the subscription this message was received from. + */ public String subscription() { return subscription; } + /** + * Returns the acknowledge id of the message. The ack id can be used to acknowledge the received + * message. + */ public String ackId() { return ackId; } + /** + * Acknowledges the current message. + * + * @throws PubSubException upon failure, or if the subscription was not found + */ public void ack() { pubsub.ack(subscription, ackId); } + /** + * Sends a request to acknowledge the current message. The method returns a {@code Future} object + * that can be used to wait for the acknowledge operation to be completed. + * + * @throws PubSubException upon failure, or if the subscription was not found + */ public Future ackAsync() { return pubsub.ackAsync(subscription, ackId); } + /** + * "Nacks" the current message. This method corresponds to calling + * {@link #modifyAckDeadline(int, TimeUnit)} with a deadline of 0. + * + * @throws PubSubException upon failure, or if the subscription was not found + */ public void nack() { pubsub.nack(subscription, ackId); } + /** + * Sends a request to "nack" the current message. This method corresponds to calling + * {@link #modifyAckDeadlineAsync(int, TimeUnit)} with a deadline of 0. The method returns a + * {@code Future} object that can be used to wait for the "nack" operation to be completed. + * + * @throws PubSubException upon failure, or if the subscription was not found + */ public Future nackAsync() { return pubsub.nackAsync(subscription, ackId); } + /** + * Modifies the acknowledge deadline of the current message. {@code deadline} must be >= 0 and + * is the new deadline with respect to the time the modify request was received by the Pub/Sub + * service. For example, if {@code deadline} is 10 and {@code unit} is {@link TimeUnit#SECONDS}, + * the new ack deadline will expire 10 seconds after the modify request was received by the + * service. Specifying 0 may be used to make the message available for another pull request + * (corresponds to calling {@link #nack()}. + * + * @param deadline the new deadline, relative to the time the modify request is received by the + * Pub/Sub service + * @param unit {@code deadline} time unit + * @throws PubSubException upon failure, or if the subscription was not found + */ public void modifyAckDeadline(int deadline, TimeUnit unit) { pubsub.modifyAckDeadline(subscription, deadline, unit, ackId); } + /** + * Sends a request to modify the acknowledge deadline of the given messages. {@code deadline} + * must be >= 0 and is the new deadline with respect to the time the modify request was + * received by the Pub/Sub service. For example, if {@code deadline} is 10 and {@code unit} is + * {@link TimeUnit#SECONDS}, the new ack deadline will expire 10 seconds after the modify request + * was received by the service. Specifying 0 may be used to make the message available for another + * pull request (corresponds to calling {@link #nackAsync()}. The method returns a {@code Future} + * object that can be used to wait for the modify operation to be completed. + * + * @param deadline the new deadline, relative to the time the modify request is received by the + * Pub/Sub service + * @param unit {@code deadline} time unit + * @throws PubSubException upon failure, or if the subscription was not found + */ public Future modifyAckDeadlineAsync(int deadline, TimeUnit unit) { return pubsub.modifyAckDeadlineAsync(subscription, deadline, unit, ackId); } @@ -175,10 +245,10 @@ private void readObject(ObjectInputStream input) throws IOException, ClassNotFou this.pubsub = options.service(); } - static ReceivedMessage fromPb(PubSub storage, String subscription, + static ReceivedMessage fromPb(PubSub pubsub, String subscription, com.google.pubsub.v1.ReceivedMessage msgPb) { Message message = fromPb(msgPb.getMessage()); String ackId = msgPb.getAckId(); - return new Builder(subscription, ackId, storage, new BuilderImpl(message)).build(); + return new Builder(subscription, ackId, pubsub, new BuilderImpl(message)).build(); } } diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/ReceivedMessageTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/ReceivedMessageTest.java new file mode 100644 index 000000000000..f21fbd106674 --- /dev/null +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/ReceivedMessageTest.java @@ -0,0 +1,187 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.createStrictMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; + +import com.google.api.client.util.Charsets; +import com.google.cloud.ByteArray; +import com.google.common.collect.ImmutableMap; +import com.google.common.util.concurrent.Futures; + +import org.easymock.EasyMock; +import org.junit.After; +import org.junit.Test; + +import java.nio.charset.StandardCharsets; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +public class ReceivedMessageTest { + + private static final String SUBSCRIPTION = "subscription"; + private static final String ACK_ID = "ackId"; + private static final String MESSAGE_ID = "messageId"; + private static final String PAYLOAD_STRING = "payload"; + private static final ByteArray PAYLOAD = + ByteArray.copyFrom("payload".getBytes(StandardCharsets.UTF_8)); + private static final Map ATTRIBUTES = + ImmutableMap.of("key1", "value1", "key2", "value2"); + private static final Long PUBLISH_TIME = 42L; + private static final Message MESSAGE = Message.builder(PAYLOAD) + .id(MESSAGE_ID) + .attributes(ATTRIBUTES) + .publishTime(PUBLISH_TIME) + .build(); + private static final com.google.pubsub.v1.ReceivedMessage RECEIVED_MESSAGE_PB = + com.google.pubsub.v1.ReceivedMessage.newBuilder() + .setMessage(MESSAGE.toPb()) + .setAckId(ACK_ID) + .build(); + + private final PubSub serviceMockReturnsOptions = createStrictMock(PubSub.class); + private final PubSubOptions mockOptions = createMock(PubSubOptions.class); + private PubSub pubsub; + private ReceivedMessage expectedMessage; + private ReceivedMessage message; + + private void initializeExpectedMessage(int optionsCalls) { + expect(serviceMockReturnsOptions.options()).andReturn(mockOptions).times(optionsCalls); + replay(serviceMockReturnsOptions); + pubsub = createStrictMock(PubSub.class); + expectedMessage = + ReceivedMessage.fromPb(serviceMockReturnsOptions, SUBSCRIPTION, RECEIVED_MESSAGE_PB); + } + + private void initializeMessage() { + message = ReceivedMessage.fromPb(pubsub, SUBSCRIPTION, RECEIVED_MESSAGE_PB); + } + + @After + public void tearDown() throws Exception { + verify(pubsub, serviceMockReturnsOptions); + } + + @Test + public void testBuilder() { + initializeExpectedMessage(3); + replay(pubsub); + Map attributes = ImmutableMap.of("newKey1", "newVal1"); + ReceivedMessage builtMessage = expectedMessage.toBuilder() + .payload("newPayload") + .id("newMessageId") + .attributes(attributes) + .publishTime(PUBLISH_TIME + 1) + .build(); + assertSame(serviceMockReturnsOptions, builtMessage.pubsub()); + assertEquals(SUBSCRIPTION, builtMessage.subscription()); + assertEquals(ACK_ID, builtMessage.ackId()); + assertEquals("newMessageId", builtMessage.id()); + assertArrayEquals("newPayload".getBytes(Charsets.UTF_8), builtMessage.payload().toByteArray()); + assertEquals("newPayload", builtMessage.payloadAsString()); + assertEquals(attributes, builtMessage.attributes()); + assertEquals(PUBLISH_TIME + 1, (long) builtMessage.publishTime()); + builtMessage = builtMessage.toBuilder() + .payload(PAYLOAD) + .id(MESSAGE_ID) + .clearAttributes() + .addAttribute("key1", "value1") + .addAttribute("key2", "value2") + .publishTime(PUBLISH_TIME) + .build(); + assertSame(serviceMockReturnsOptions, builtMessage.pubsub()); + assertEquals(MESSAGE_ID, builtMessage.id()); + assertEquals(PAYLOAD, builtMessage.payload()); + assertEquals(PAYLOAD_STRING, builtMessage.payloadAsString()); + assertEquals(ATTRIBUTES, builtMessage.attributes()); + assertEquals(PUBLISH_TIME, builtMessage.publishTime()); + compareReceivedMessage(expectedMessage, builtMessage); + } + + @Test + public void testToBuilder() { + initializeExpectedMessage(2); + replay(pubsub); + compareReceivedMessage(expectedMessage, expectedMessage.toBuilder().build()); + } + + @Test + public void testAck() { + initializeExpectedMessage(1); + expect(pubsub.options()).andReturn(mockOptions); + pubsub.ack(SUBSCRIPTION, ACK_ID); + EasyMock.expectLastCall(); + replay(pubsub); + initializeMessage(); + message.ack(); + } + + @Test + public void testAckAsync() throws ExecutionException, InterruptedException { + initializeExpectedMessage(1); + expect(pubsub.options()).andReturn(mockOptions); + expect(pubsub.ackAsync(SUBSCRIPTION, ACK_ID)).andReturn(Futures.immediateFuture(null)); + EasyMock.expectLastCall(); + replay(pubsub); + initializeMessage(); + assertNull(message.ackAsync().get()); + } + + @Test + public void testModifyAckDeadline() { + initializeExpectedMessage(1); + expect(pubsub.options()).andReturn(mockOptions); + pubsub.modifyAckDeadline(SUBSCRIPTION, 10, TimeUnit.SECONDS, ACK_ID); + EasyMock.expectLastCall(); + replay(pubsub); + initializeMessage(); + message.modifyAckDeadline(10, TimeUnit.SECONDS); + } + + @Test + public void testModifyAckDeadlineAsync() throws ExecutionException, InterruptedException { + initializeExpectedMessage(1); + expect(pubsub.options()).andReturn(mockOptions); + expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION, 10, TimeUnit.SECONDS, ACK_ID)) + .andReturn(Futures.immediateFuture(null)); + EasyMock.expectLastCall(); + replay(pubsub); + initializeMessage(); + assertNull(message.modifyAckDeadlineAsync(10, TimeUnit.SECONDS).get()); + } + + private void compareReceivedMessage(ReceivedMessage expected, ReceivedMessage value) { + assertEquals(expected, value); + assertEquals(expected.id(), value.id()); + assertEquals(expected.payload(), value.payload()); + assertEquals(expected.payloadAsString(), value.payloadAsString()); + assertEquals(expected.attributes(), value.attributes()); + assertEquals(expected.publishTime(), value.publishTime()); + assertEquals(expected.ackId(), value.ackId()); + assertEquals(expected.subscription(), value.subscription()); + assertEquals(expected.hashCode(), value.hashCode()); + } +} From e3a6d2ed173a57949b9b9c77ac37ff2b534edd01 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 3 Jun 2016 12:42:22 +0200 Subject: [PATCH 366/375] Add AckDeadlineRenewer class for automatic ack deadline renewal (#1031) * Add AckDeadlineRenewer class for automatic ack deadline renewal * Refactor renewer tests and wake up renewer only when needed * Skip removed/re-added messages when scheduling new renewal * Better tuning of ack deadline in renewer --- .../cloud/pubsub/AckDeadlineRenewer.java | 317 ++++++++++++++++++ .../google/cloud/pubsub/PubSubOptions.java | 5 + .../cloud/pubsub/AckDeadlineRenewerTest.java | 281 ++++++++++++++++ 3 files changed, 603 insertions(+) create mode 100644 gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/AckDeadlineRenewer.java create mode 100644 gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/AckDeadlineRenewerTest.java diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/AckDeadlineRenewer.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/AckDeadlineRenewer.java new file mode 100644 index 000000000000..3bea6440e224 --- /dev/null +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/AckDeadlineRenewer.java @@ -0,0 +1,317 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import com.google.cloud.GrpcServiceOptions.ExecutorFactory; +import com.google.cloud.ServiceOptions.Clock; +import com.google.common.base.MoreObjects; +import com.google.common.collect.LinkedListMultimap; +import com.google.common.collect.ListMultimap; +import com.google.common.collect.Multimaps; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Queue; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +/** + * Class for an automatic ack deadline renewer. An ack deadline renewer automatically renews the + * acknowledge deadline of messages added to it (via {@link #add(String, String)} or + * {@link #add(String, Iterable)}. The acknowledge deadlines of added messages are renewed until the + * messages are explicitly removed using {@link #remove(String, String)}. + */ +class AckDeadlineRenewer implements AutoCloseable { + + private static final int MIN_DEADLINE_MILLIS = 10_000; + private static final int DEADLINE_SLACK_MILLIS = 1_000; + private static final int RENEW_THRESHOLD_MILLIS = 3_000; + private static final int NEXT_RENEWAL_THRESHOLD_MILLIS = 1_000; + + private final PubSub pubsub; + private final ScheduledExecutorService executor; + private final ExecutorFactory executorFactory; + private final Clock clock; + private final Queue messageQueue; + private final Map messageDeadlines; + private final Object lock = new Object(); + private final Object futureLock = new Object(); + private Future renewerFuture; + private boolean closed; + + /** + * This class holds the identity of a message to renew: subscription and acknowledge id. + */ + private static class MessageId { + + private final String subscription; + private final String ackId; + + MessageId(String subscription, String ackId) { + this.subscription = subscription; + this.ackId = ackId; + } + + String subscription() { + return subscription; + } + + String ackId() { + return ackId; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof MessageId)) { + return false; + } + MessageId other = (MessageId) obj; + return Objects.equals(other.subscription, this.subscription) + && Objects.equals(other.ackId, this.ackId); + } + + @Override + public int hashCode() { + return Objects.hash(subscription, ackId); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("subscription", subscription) + .add("ackId", ackId) + .toString(); + } + } + + /** + * This class holds the identity of a message to renew and its expected ack deadline. + */ + private static final class Message { + + private final MessageId messageId; + private final Long deadline; + + Message(MessageId messageId, Long deadline) { + this.messageId = messageId; + this.deadline = deadline; + } + + MessageId messageId() { + return messageId; + } + + Long expectedDeadline() { + return deadline; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof Message)) { + return false; + } + Message other = (Message) obj; + return Objects.equals(other.messageId, this.messageId) + && Objects.equals(other.deadline, this.deadline); + } + + @Override + public int hashCode() { + return Objects.hash(messageId, deadline); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("messageId", messageId) + .add("expectedDeadline", deadline) + .toString(); + } + } + + AckDeadlineRenewer(PubSub pubsub) { + PubSubOptions options = pubsub.options(); + this.pubsub = pubsub; + this.executorFactory = options.executorFactory(); + this.executor = executorFactory.get(); + this.clock = options.clock(); + this.messageQueue = new LinkedList<>(); + this.messageDeadlines = new HashMap<>(); + } + + private void unsetAndScheduleNextRenewal() { + synchronized (futureLock) { + renewerFuture = null; + scheduleNextRenewal(); + } + } + + private void scheduleNextRenewal() { + // Schedules next renewal if there are still messages to process and no renewals scheduled that + // could handle them, otherwise does nothing + Message nextMessage; + synchronized (lock) { + Message peek = messageQueue.peek(); + // We remove from the queue messages that were removed from the ack deadline renewer (and + // possibly re-added) + while (peek != null && (!messageDeadlines.containsKey(peek.messageId()) + || messageDeadlines.get(peek.messageId()) > peek.expectedDeadline())) { + messageQueue.poll(); + peek = messageQueue.peek(); + } + nextMessage = peek; + } + synchronized (futureLock) { + if (renewerFuture == null && nextMessage != null) { + long delay = + (nextMessage.expectedDeadline() - clock.millis()) - NEXT_RENEWAL_THRESHOLD_MILLIS; + renewerFuture = executor.schedule(new Runnable() { + @Override + public void run() { + renewAckDeadlines(); + } + }, delay, TimeUnit.MILLISECONDS); + } + } + } + + private void renewAckDeadlines() { + ListMultimap messagesToRenewNext = LinkedListMultimap.create(); + // At every activation we renew all ack deadlines that will expire in the following + // RENEW_THRESHOLD_MILLIS + long threshold = clock.millis() + RENEW_THRESHOLD_MILLIS; + Message message; + while ((message = nextMessageToRenew(threshold)) != null) { + // If the expected deadline is null the message was removed and we must ignore it, otherwise + // we renew its ack deadline + if (message.expectedDeadline() != null) { + messagesToRenewNext.put(message.messageId().subscription(), message.messageId().ackId()); + } + } + for (Map.Entry> entry : Multimaps.asMap(messagesToRenewNext).entrySet()) { + // We send all ack deadline renewals for a subscription + pubsub.modifyAckDeadlineAsync(entry.getKey(), MIN_DEADLINE_MILLIS, TimeUnit.MILLISECONDS, + entry.getValue()); + } + unsetAndScheduleNextRenewal(); + } + + private Message nextMessageToRenew(long threshold) { + synchronized (lock) { + Message message = messageQueue.peek(); + // if the queue is empty or the next expected deadline is after threshold we stop + if (message == null || message.expectedDeadline() > threshold) { + return null; + } + MessageId messageId = messageQueue.poll().messageId(); + // Check if the next expected deadline changed. This can happen if the message was removed + // from the ack deadline renewer or if it was nacked and then pulled again + Long deadline = messageDeadlines.get(messageId); + if (deadline == null || deadline > threshold) { + // the message was removed (deadline == null) or removed and then added back + // (deadline > threshold), we should not renew its deadline (yet) + return new Message(messageId, null); + } else { + // Message deadline must be renewed, we must submit it again to the renewer + add(messageId.subscription(), messageId.ackId()); + return new Message(messageId, deadline); + } + } + } + + /** + * Adds a new message for which the acknowledge deadline should be automatically renewed. The + * message is identified by the subscription from which it was pulled and its acknowledge id. + * Auto-renewal will take place until the message is removed (see + * {@link #remove(String, String)}). + * + * @param subscription the subscription from which the message has been pulled + * @param ackId the message's acknowledge id + */ + void add(String subscription, String ackId) { + synchronized (lock) { + long deadline = clock.millis() + MIN_DEADLINE_MILLIS - DEADLINE_SLACK_MILLIS; + Message message = new Message(new MessageId(subscription, ackId), deadline); + messageQueue.add(message); + messageDeadlines.put(message.messageId(), deadline); + } + scheduleNextRenewal(); + } + + /** + * Adds new messages for which the acknowledge deadlined should be automatically renewed. The + * messages are identified by the subscription from which they were pulled and their + * acknowledge id. Auto-renewal will take place until the messages are removed (see + * {@link #remove(String, String)}). + * + * @param subscription the subscription from which the messages have been pulled + * @param ackIds the acknowledge ids of the messages + */ + void add(String subscription, Iterable ackIds) { + synchronized (lock) { + long deadline = clock.millis() + MIN_DEADLINE_MILLIS - DEADLINE_SLACK_MILLIS; + for (String ackId : ackIds) { + Message message = new Message(new MessageId(subscription, ackId), deadline); + messageQueue.add(message); + messageDeadlines.put(message.messageId(), deadline); + } + } + scheduleNextRenewal(); + } + + /** + * Removes a message from this {@code AckDeadlineRenewer}. The message is identified by the + * subscription from which it was pulled and its acknowledge id. Once the message is removed from + * this {@code AckDeadlineRenewer}, automated ack deadline renewals will stop. + * + * @param subscription the subscription from which the message has been pulled + * @param ackId the message's acknowledge id + */ + void remove(String subscription, String ackId) { + synchronized (lock) { + messageDeadlines.remove(new MessageId(subscription, ackId)); + } + } + + @Override + public void close() throws Exception { + if (closed) { + return; + } + closed = true; + synchronized (lock) { + messageDeadlines.clear(); + messageQueue.clear(); + } + synchronized (futureLock) { + if (renewerFuture != null) { + renewerFuture.cancel(true); + } + } + executorFactory.release(executor); + } +} diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubOptions.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubOptions.java index 420b0d50148b..87a25bf0dc36 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubOptions.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubOptions.java @@ -85,6 +85,11 @@ protected PubSubOptions(Builder builder) { super(PubSubFactory.class, PubSubRpcFactory.class, builder); } + @Override + protected ExecutorFactory executorFactory() { + return super.executorFactory(); + } + @Override protected PubSubFactory defaultServiceFactory() { return DefaultPubSubFactory.INSTANCE; diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/AckDeadlineRenewerTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/AckDeadlineRenewerTest.java new file mode 100644 index 000000000000..07cc70c6e30d --- /dev/null +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/AckDeadlineRenewerTest.java @@ -0,0 +1,281 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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.pubsub; + +import static org.junit.Assert.assertTrue; + +import com.google.cloud.GrpcServiceOptions.ExecutorFactory; +import com.google.common.collect.ImmutableList; + +import org.easymock.EasyMock; +import org.easymock.IAnswer; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; + +public class AckDeadlineRenewerTest { + + private static final int MIN_DEADLINE_MILLIS = 10_000; + + private static final String SUBSCRIPTION1 = "subscription1"; + private static final String SUBSCRIPTION2 = "subscription2"; + private static final String ACK_ID1 = "ack-id1"; + private static final String ACK_ID2 = "ack-id2"; + private static final String ACK_ID3 = "ack-id3"; + + private PubSub pubsub; + private AckDeadlineRenewer ackDeadlineRenewer; + + @Before + public void setUp() { + pubsub = EasyMock.createStrictMock(PubSub.class); + PubSubOptions options = PubSubOptions.builder() + .projectId("projectId") + .build(); + EasyMock.expect(pubsub.options()).andReturn(options); + EasyMock.replay(pubsub); + ackDeadlineRenewer = new AckDeadlineRenewer(pubsub); + } + + @After + public void tearDown() throws Exception { + EasyMock.verify(pubsub); + ackDeadlineRenewer.close(); + } + + private static IAnswer> createAnswer(final CountDownLatch latch, + final AtomicLong renewal) { + return new IAnswer>() { + @Override + public Future answer() throws Throwable { + latch.countDown(); + renewal.set(System.currentTimeMillis()); + return null; + } + }; + } + + @Test + public void testAddOneMessage() throws InterruptedException { + EasyMock.reset(pubsub); + final CountDownLatch firstLatch = new CountDownLatch(1); + final CountDownLatch secondLatch = new CountDownLatch(1); + final AtomicLong firstRenewal = new AtomicLong(); + final AtomicLong secondRenewal = new AtomicLong(); + EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION1, MIN_DEADLINE_MILLIS, + TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1))) + .andAnswer(createAnswer(firstLatch, firstRenewal)); + EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION1, MIN_DEADLINE_MILLIS, + TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1))) + .andAnswer(createAnswer(secondLatch, secondRenewal)); + EasyMock.replay(pubsub); + long addTime = System.currentTimeMillis(); + ackDeadlineRenewer.add(SUBSCRIPTION1, ACK_ID1); + firstLatch.await(); + assertTrue(firstRenewal.get() < (addTime + MIN_DEADLINE_MILLIS)); + secondLatch.await(); + assertTrue(secondRenewal.get() < (firstRenewal.get() + MIN_DEADLINE_MILLIS)); + } + + @Test + public void testAddMessages() throws InterruptedException { + EasyMock.reset(pubsub); + final CountDownLatch firstLatch = new CountDownLatch(2); + final CountDownLatch secondLatch = new CountDownLatch(2); + final AtomicLong firstRenewalSub1 = new AtomicLong(); + final AtomicLong firstRenewalSub2 = new AtomicLong(); + final AtomicLong secondRenewalSub1 = new AtomicLong(); + final AtomicLong secondRenewalSub2 = new AtomicLong(); + EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION1, MIN_DEADLINE_MILLIS, + TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1, ACK_ID2))) + .andAnswer(createAnswer(firstLatch, firstRenewalSub1)); + EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION2, MIN_DEADLINE_MILLIS, + TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1))) + .andAnswer(createAnswer(firstLatch, firstRenewalSub2)); + EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION1, MIN_DEADLINE_MILLIS, + TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1, ACK_ID2))) + .andAnswer(createAnswer(secondLatch, secondRenewalSub1)); + EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION2, MIN_DEADLINE_MILLIS, + TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1, ACK_ID3))) + .andAnswer(createAnswer(secondLatch, secondRenewalSub2)); + EasyMock.replay(pubsub); + long addTime1 = System.currentTimeMillis(); + ackDeadlineRenewer.add(SUBSCRIPTION1, ImmutableList.of(ACK_ID1, ACK_ID2)); + ackDeadlineRenewer.add(SUBSCRIPTION2, ACK_ID1); + firstLatch.await(); + assertTrue(firstRenewalSub1.get() < (addTime1 + MIN_DEADLINE_MILLIS)); + assertTrue(firstRenewalSub2.get() < (addTime1 + MIN_DEADLINE_MILLIS)); + ackDeadlineRenewer.add(SUBSCRIPTION2, ACK_ID3); + secondLatch.await(); + assertTrue(secondRenewalSub1.get() < (firstRenewalSub1.get() + MIN_DEADLINE_MILLIS)); + assertTrue(secondRenewalSub2.get() < (firstRenewalSub2.get() + MIN_DEADLINE_MILLIS)); + } + + @Test + public void testAddExistingMessage() throws InterruptedException { + EasyMock.reset(pubsub); + final CountDownLatch firstLatch = new CountDownLatch(2); + final CountDownLatch secondLatch = new CountDownLatch(2); + final AtomicLong firstRenewalSub1 = new AtomicLong(); + final AtomicLong firstRenewalSub2 = new AtomicLong(); + final AtomicLong secondRenewalSub1 = new AtomicLong(); + final AtomicLong secondRenewalSub2 = new AtomicLong(); + EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION1, MIN_DEADLINE_MILLIS, + TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1, ACK_ID2))) + .andAnswer(createAnswer(firstLatch, firstRenewalSub1)); + EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION2, MIN_DEADLINE_MILLIS, + TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1))) + .andAnswer(createAnswer(firstLatch, firstRenewalSub2)); + EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION1, MIN_DEADLINE_MILLIS, + TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1, ACK_ID2))) + .andAnswer(createAnswer(secondLatch, secondRenewalSub1)); + EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION2, MIN_DEADLINE_MILLIS, + TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1))) + .andAnswer(createAnswer(secondLatch, secondRenewalSub2)); + EasyMock.replay(pubsub); + long addTime1 = System.currentTimeMillis(); + ackDeadlineRenewer.add(SUBSCRIPTION1, ImmutableList.of(ACK_ID1, ACK_ID2)); + ackDeadlineRenewer.add(SUBSCRIPTION2, ACK_ID1); + firstLatch.await(); + assertTrue(firstRenewalSub1.get() < (addTime1 + MIN_DEADLINE_MILLIS)); + assertTrue(firstRenewalSub2.get() < (addTime1 + MIN_DEADLINE_MILLIS)); + ackDeadlineRenewer.add(SUBSCRIPTION2, ACK_ID1); + secondLatch.await(); + assertTrue(secondRenewalSub1.get() < (firstRenewalSub1.get() + MIN_DEADLINE_MILLIS)); + assertTrue(secondRenewalSub2.get() < (firstRenewalSub2.get() + MIN_DEADLINE_MILLIS)); + } + + @Test + public void testRemoveNonExistingMessage() throws InterruptedException { + EasyMock.reset(pubsub); + final CountDownLatch firstLatch = new CountDownLatch(2); + final CountDownLatch secondLatch = new CountDownLatch(2); + final AtomicLong firstRenewalSub1 = new AtomicLong(); + final AtomicLong firstRenewalSub2 = new AtomicLong(); + final AtomicLong secondRenewalSub1 = new AtomicLong(); + final AtomicLong secondRenewalSub2 = new AtomicLong(); + EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION1, MIN_DEADLINE_MILLIS, + TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1, ACK_ID2))) + .andAnswer(createAnswer(firstLatch, firstRenewalSub1)); + EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION2, MIN_DEADLINE_MILLIS, + TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1))) + .andAnswer(createAnswer(firstLatch, firstRenewalSub2)); + EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION1, MIN_DEADLINE_MILLIS, + TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1, ACK_ID2))) + .andAnswer(createAnswer(secondLatch, secondRenewalSub1)); + EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION2, MIN_DEADLINE_MILLIS, + TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1))) + .andAnswer(createAnswer(secondLatch, secondRenewalSub2)); + EasyMock.replay(pubsub); + long addTime1 = System.currentTimeMillis(); + ackDeadlineRenewer.add(SUBSCRIPTION1, ImmutableList.of(ACK_ID1, ACK_ID2)); + ackDeadlineRenewer.add(SUBSCRIPTION2, ACK_ID1); + firstLatch.await(); + assertTrue(firstRenewalSub1.get() < (addTime1 + MIN_DEADLINE_MILLIS)); + assertTrue(firstRenewalSub2.get() < (addTime1 + MIN_DEADLINE_MILLIS)); + ackDeadlineRenewer.remove(SUBSCRIPTION1, ACK_ID3); + secondLatch.await(); + assertTrue(secondRenewalSub1.get() < (firstRenewalSub1.get() + MIN_DEADLINE_MILLIS)); + assertTrue(secondRenewalSub2.get() < (firstRenewalSub2.get() + MIN_DEADLINE_MILLIS)); + } + + @Test + public void testRemoveMessage() throws InterruptedException { + EasyMock.reset(pubsub); + final CountDownLatch firstLatch = new CountDownLatch(2); + final CountDownLatch secondLatch = new CountDownLatch(2); + final AtomicLong firstRenewalSub1 = new AtomicLong(); + final AtomicLong firstRenewalSub2 = new AtomicLong(); + final AtomicLong secondRenewalSub1 = new AtomicLong(); + final AtomicLong secondRenewalSub2 = new AtomicLong(); + EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION1, MIN_DEADLINE_MILLIS, + TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1, ACK_ID2))) + .andAnswer(createAnswer(firstLatch, firstRenewalSub1)); + EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION2, MIN_DEADLINE_MILLIS, + TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1))) + .andAnswer(createAnswer(firstLatch, firstRenewalSub2)); + EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION1, MIN_DEADLINE_MILLIS, + TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1))) + .andAnswer(createAnswer(secondLatch, secondRenewalSub1)); + EasyMock.expect(pubsub.modifyAckDeadlineAsync(SUBSCRIPTION2, MIN_DEADLINE_MILLIS, + TimeUnit.MILLISECONDS, ImmutableList.of(ACK_ID1))) + .andAnswer(createAnswer(secondLatch, secondRenewalSub2)); + EasyMock.replay(pubsub); + long addTime1 = System.currentTimeMillis(); + ackDeadlineRenewer.add(SUBSCRIPTION1, ImmutableList.of(ACK_ID1, ACK_ID2)); + ackDeadlineRenewer.add(SUBSCRIPTION2, ACK_ID1); + firstLatch.await(); + assertTrue(firstRenewalSub1.get() < (addTime1 + MIN_DEADLINE_MILLIS)); + assertTrue(firstRenewalSub2.get() < (addTime1 + MIN_DEADLINE_MILLIS)); + ackDeadlineRenewer.remove(SUBSCRIPTION1, ACK_ID2); + secondLatch.await(); + assertTrue(secondRenewalSub1.get() < (firstRenewalSub1.get() + MIN_DEADLINE_MILLIS)); + assertTrue(secondRenewalSub2.get() < (firstRenewalSub2.get() + MIN_DEADLINE_MILLIS)); + } + + @Test + @SuppressWarnings("unchecked") + public void testClose() throws Exception { + PubSub pubsub = EasyMock.createStrictMock(PubSub.class); + ScheduledExecutorService executor = EasyMock.createStrictMock(ScheduledExecutorService.class); + ExecutorFactory executorFactory = EasyMock.createStrictMock(ExecutorFactory.class); + EasyMock.expect(executorFactory.get()).andReturn(executor); + PubSubOptions options = PubSubOptions.builder() + .projectId("projectId") + .executorFactory(executorFactory) + .build(); + EasyMock.expect(pubsub.options()).andReturn(options); + executorFactory.release(executor); + EasyMock.expectLastCall(); + EasyMock.replay(executor, executorFactory, pubsub); + AckDeadlineRenewer ackDeadlineRenewer = new AckDeadlineRenewer(pubsub); + ackDeadlineRenewer.close(); + EasyMock.verify(pubsub, executor, executorFactory); + } + + @Test + @SuppressWarnings("unchecked") + public void testCloseWithMessage() throws Exception { + PubSub pubsub = EasyMock.createStrictMock(PubSub.class); + ScheduledExecutorService executor = EasyMock.createStrictMock(ScheduledExecutorService.class); + ExecutorFactory executorFactory = EasyMock.createStrictMock(ExecutorFactory.class); + EasyMock.expect(executorFactory.get()).andReturn(executor); + ScheduledFuture future = EasyMock.createStrictMock(ScheduledFuture.class); + EasyMock.expect(executor.schedule(EasyMock.anyObject(), EasyMock.anyLong(), + EasyMock.eq(TimeUnit.MILLISECONDS))).andReturn(future); + PubSubOptions options = PubSubOptions.builder() + .projectId("projectId") + .executorFactory(executorFactory) + .build(); + EasyMock.expect(pubsub.options()).andReturn(options); + EasyMock.expect(future.cancel(true)).andReturn(true); + executorFactory.release(executor); + EasyMock.expectLastCall(); + EasyMock.replay(executor, executorFactory, future, pubsub); + AckDeadlineRenewer ackDeadlineRenewer = new AckDeadlineRenewer(pubsub); + ackDeadlineRenewer.add(SUBSCRIPTION1, ACK_ID1); + ackDeadlineRenewer.close(); + EasyMock.verify(pubsub, executor, executorFactory, future); + } +} From 2fd2d56900ef7be90f1d00855cf6a78cdf53f794 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 6 Jun 2016 20:16:15 +0200 Subject: [PATCH 367/375] Implement Iterator pull methods, add javadoc and tests (#1041) --- .../java/com/google/cloud/pubsub/PubSub.java | 48 ++ .../com/google/cloud/pubsub/PubSubImpl.java | 64 ++- .../cloud/pubsub/spi/DefaultPubSubRpc.java | 6 + .../cloud/pubsub/AckDeadlineRenewerTest.java | 5 + .../google/cloud/pubsub/BaseSystemTest.java | 216 +++++++++ .../google/cloud/pubsub/PubSubImplTest.java | 419 +++++++++++------- 6 files changed, 591 insertions(+), 167 deletions(-) diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java index 428f74b64024..f86817c26345 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSub.java @@ -381,8 +381,56 @@ interface MessageConsumer extends AutoCloseable { */ Future> listSubscriptionsAsync(String topic, ListOption... options); + /** + * Pulls messages from the provided subscription. This method possibly returns no messages if no + * message was available at the time the request was processed by the Pub/Sub service (i.e. the + * system is not allowed to wait until at least one message is available). Pulled messages have + * their acknowledge deadline automatically renewed until they are explicitly consumed using + * {@link Iterator#next()}. + * + *

    Example usage of synchronous message pulling: + *

     {@code
    +   * Iterator messageIterator = pubsub.pull("subscription", 100);
    +   * while (messageIterator.hasNext()) {
    +   *   ReceivedMessage message = messageIterator.next();
    +   *   // message's acknowledge deadline is no longer automatically renewed. If processing takes
    +   *   // long pubsub.modifyAckDeadline(String, String, long, TimeUnit) can be used to extend it.
    +   *   doSomething(message);
    +   *   message.ack(); // or message.nack()
    +   * }}
    + * + * @param subscription the subscription from which to pull messages + * @param maxMessages the maximum number of messages pulled by this method. This method can + * possibly return fewer messages. + * @throws PubSubException upon failure + */ Iterator pull(String subscription, int maxMessages); + /** + * Sends a request for pulling messages from the provided subscription. This method returns a + * {@code Future} object to consume the result. {@link Future#get()} returns a message iterator. + * This method possibly returns no messages if no message was available at the time the request + * was processed by the Pub/Sub service (i.e. the system is not allowed to wait until at least one + * message is available). + * + *

    Example usage of asynchronous message pulling: + *

     {@code
    +   * Future> future = pubsub.pull("subscription", 100);
    +   * // do something while the request gets processed
    +   * Iterator messageIterator = future.get();
    +   * while (messageIterator.hasNext()) {
    +   *   ReceivedMessage message = messageIterator.next();
    +   *   // message's acknowledge deadline is no longer automatically renewed. If processing takes
    +   *   // long pubsub.modifyAckDeadline(String, String, long, TimeUnit) can be used to extend it.
    +   *   doSomething(message);
    +   *   message.ack(); // or message.nack()
    +   * }}
    + * + * @param subscription the subscription from which to pull messages + * @param maxMessages the maximum number of messages pulled by this method. This method can + * possibly return fewer messages. + * @throws PubSubException upon failure + */ Future> pullAsync(String subscription, int maxMessages); MessageConsumer pullAsync(String subscription, MessageProcessor callback, PullOption... options); diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java index 042f76b5197c..800d26c41ce9 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/PubSubImpl.java @@ -16,9 +16,9 @@ package com.google.cloud.pubsub; +import static com.google.api.client.util.Preconditions.checkArgument; import static com.google.cloud.pubsub.PubSub.ListOption.OptionType.PAGE_SIZE; import static com.google.cloud.pubsub.PubSub.ListOption.OptionType.PAGE_TOKEN; -import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.util.concurrent.Futures.lazyTransform; import com.google.cloud.AsyncPage; @@ -29,10 +29,12 @@ import com.google.cloud.pubsub.spi.PubSubRpc; import com.google.cloud.pubsub.spi.v1.PublisherApi; import com.google.cloud.pubsub.spi.v1.SubscriberApi; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterables; +import com.google.common.collect.Iterators; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.util.concurrent.Uninterruptibles; @@ -52,6 +54,8 @@ import com.google.pubsub.v1.ModifyPushConfigRequest; import com.google.pubsub.v1.PublishRequest; import com.google.pubsub.v1.PublishResponse; +import com.google.pubsub.v1.PullRequest; +import com.google.pubsub.v1.PullResponse; import java.util.Collections; import java.util.Iterator; @@ -64,6 +68,8 @@ class PubSubImpl extends BaseService implements PubSub { private final PubSubRpc rpc; + private final AckDeadlineRenewer ackDeadlineRenewer; + private boolean closed; private static final Function EMPTY_TO_VOID_FUNCTION = new Function() { @Override @@ -78,10 +84,25 @@ public Boolean apply(Empty input) { return input != null; } }; + private static final Function + MESSAGE_TO_ACK_ID_FUNCTION = new Function() { + @Override + public String apply(com.google.pubsub.v1.ReceivedMessage message) { + return message.getAckId(); + } + }; PubSubImpl(PubSubOptions options) { super(options); rpc = options.rpc(); + ackDeadlineRenewer = new AckDeadlineRenewer(this); + } + + @VisibleForTesting + PubSubImpl(PubSubOptions options, AckDeadlineRenewer ackDeadlineRenewer) { + super(options); + rpc = options.rpc(); + this.ackDeadlineRenewer = ackDeadlineRenewer; } private abstract static class BasePageFetcher implements AsyncPageImpl.NextPageFetcher { @@ -445,17 +466,35 @@ public Future> listSubscriptionsAsync(String topic, @Override public Iterator pull(String subscription, int maxMessages) { - // this should set return_immediately to true - return null; + return get(pullAsync(subscription, maxMessages)); } @Override - public Future> pullAsync(String subscription, int maxMessages) { - // though this method can set return_immediately to false (as future can be canceled) I - // suggest to keep it false so sync could delegate to asyc and use the same options - // this method also should use the VTKIT thread-pool to renew ack deadline for non consumed - // messages - return null; + public Future> pullAsync(final String subscription, int maxMessages) { + PullRequest request = PullRequest.newBuilder().setReturnImmediately(true) + .setSubscription(SubscriberApi.formatSubscriptionName(options().projectId(), subscription)) + .setMaxMessages(maxMessages) + .setReturnImmediately(true) + .build(); + Future response = rpc.pull(request); + return lazyTransform(response, new Function>() { + @Override + public Iterator apply(PullResponse pullResponse) { + // Add all received messages to the automatic ack deadline renewer + List ackIds = Lists.transform(pullResponse.getReceivedMessagesList(), + MESSAGE_TO_ACK_ID_FUNCTION); + ackDeadlineRenewer.add(subscription, ackIds); + return Iterators.transform(pullResponse.getReceivedMessagesList().iterator(), + new Function() { + @Override + public ReceivedMessage apply(com.google.pubsub.v1.ReceivedMessage receivedMessage) { + // Remove consumed message from automatic ack deadline renewer + ackDeadlineRenewer.remove(subscription, receivedMessage.getAckId()); + return ReceivedMessage.fromPb(PubSubImpl.this, subscription, receivedMessage); + } + }); + } + }); } @Override @@ -549,6 +588,13 @@ public Future modifyAckDeadlineAsync(String subscription, int deadline, Ti @Override public void close() throws Exception { + if (closed) { + return; + } + closed = true; rpc.close(); + if (ackDeadlineRenewer != null) { + ackDeadlineRenewer.close(); + } } } diff --git a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java index 7df6cb2632f5..4ac3837088f8 100644 --- a/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java +++ b/gcloud-java-pubsub/src/main/java/com/google/cloud/pubsub/spi/DefaultPubSubRpc.java @@ -73,6 +73,8 @@ public class DefaultPubSubRpc implements PubSubRpc { private final ScheduledExecutorService executor; private final ExecutorFactory executorFactory; + private boolean closed; + private static final class InternalPubSubOptions extends PubSubOptions { private static final long serialVersionUID = -7997372049256706185L; @@ -233,6 +235,10 @@ public Future modify(ModifyPushConfigRequest request) { @Override public void close() throws Exception { + if (closed) { + return; + } + closed = true; subscriberApi.close(); publisherApi.close(); executorFactory.release(executor); diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/AckDeadlineRenewerTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/AckDeadlineRenewerTest.java index 07cc70c6e30d..bf912e0a79f7 100644 --- a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/AckDeadlineRenewerTest.java +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/AckDeadlineRenewerTest.java @@ -25,7 +25,9 @@ import org.easymock.IAnswer; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.Timeout; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Future; @@ -47,6 +49,9 @@ public class AckDeadlineRenewerTest { private PubSub pubsub; private AckDeadlineRenewer ackDeadlineRenewer; + @Rule + public Timeout globalTimeout = Timeout.seconds(60); + @Before public void setUp() { pubsub = EasyMock.createStrictMock(PubSub.class); diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/BaseSystemTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/BaseSystemTest.java index 3360632b45ce..8eb03a7de073 100644 --- a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/BaseSystemTest.java +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/BaseSystemTest.java @@ -22,6 +22,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import com.google.api.client.util.Lists; import com.google.cloud.AsyncPage; import com.google.cloud.Page; import com.google.common.collect.ImmutableList; @@ -37,6 +38,7 @@ import java.util.Set; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; /** * A base class for system tests. This class can be extended to run system tests in different @@ -428,4 +430,218 @@ public void testListSubscriptionsAsync() throws ExecutionException, InterruptedE assertTrue(subscription2.delete()); assertTrue(subscription3.delete()); } + + @Test + public void testPullMessages() { + String topic = formatForTest("test-pull-messages-topic"); + pubsub().create(TopicInfo.of(topic)); + String subscription = formatForTest("test-pull-messages-subscription"); + pubsub().create(SubscriptionInfo.of(topic, subscription)); + Message message1 = Message.of("payload1"); + Message message2 = Message.of("payload2"); + List messageIds = pubsub().publish(topic, ImmutableList.of(message1, message2)); + assertEquals(2, messageIds.size()); + Iterator iterator = pubsub().pull(subscription, 2); + assertEquals(message1.payloadAsString(), iterator.next().payloadAsString()); + assertEquals(message2.payloadAsString(), iterator.next().payloadAsString()); + assertTrue(pubsub().deleteSubscription(subscription)); + assertTrue(pubsub().deleteTopic(topic)); + } + + @Test + public void testPullMessagesAndAutoRenewDeadline() throws InterruptedException { + String topic = formatForTest("test-pull-messages-and-renew-deadline-topic"); + pubsub().create(TopicInfo.of(topic)); + String subscription = formatForTest("test-pull-messages-and-renew-deadline-subscription"); + pubsub().create(SubscriptionInfo.builder(topic, subscription).ackDeadLineSeconds(10).build()); + Message message1 = Message.of("payload1"); + Message message2 = Message.of("payload2"); + // todo(mziccard): use batch publish if #1017 gets fixed, or remove this comment + pubsub().publish(topic, message1); + pubsub().publish(topic, message2); + Iterator iterator = pubsub().pull(subscription, 2); + ReceivedMessage consumedMessage = iterator.next(); + Thread.sleep(15000); + // first message was consumed while second message is still being renewed + Iterator nextIterator = pubsub().pull(subscription, 2); + assertTrue(nextIterator.hasNext()); + ReceivedMessage message = nextIterator.next(); + assertEquals(consumedMessage.payloadAsString(), message.payloadAsString()); + assertFalse(nextIterator.hasNext()); + consumedMessage.ack(); + iterator.next().ack(); + nextIterator = pubsub().pull(subscription, 2); + assertFalse(nextIterator.hasNext()); + assertTrue(pubsub().deleteSubscription(subscription)); + assertTrue(pubsub().deleteTopic(topic)); + } + + @Test + public void testPullMessagesAndModifyAckDeadline() throws InterruptedException { + String topic = formatForTest("test-pull-messages-and-modify-deadline-topic"); + pubsub().create(TopicInfo.of(topic)); + String subscription = formatForTest("test-pull-messages-and-modify-deadline-subscription"); + pubsub().create(SubscriptionInfo.builder(topic, subscription).ackDeadLineSeconds(10).build()); + Message message1 = Message.of("payload1"); + Message message2 = Message.of("payload2"); + // todo(mziccard): use batch publish if #1017 gets fixed, or remove this comment + pubsub().publish(topic, message1); + pubsub().publish(topic, message2); + // Consume all messages and stop ack renewal + List receivedMessages = Lists.newArrayList(pubsub().pull(subscription, 2)); + receivedMessages.get(0).modifyAckDeadline(60, TimeUnit.SECONDS); + Thread.sleep(15000); + // first message was renewed while second message should still be sent on pull requests + Iterator nextIterator = pubsub().pull(subscription, 2); + assertTrue(nextIterator.hasNext()); + ReceivedMessage message = nextIterator.next(); + assertEquals(receivedMessages.get(1).payloadAsString(), message.payloadAsString()); + assertFalse(nextIterator.hasNext()); + assertTrue(pubsub().deleteSubscription(subscription)); + assertTrue(pubsub().deleteTopic(topic)); + } + + @Test + public void testPullNonExistingSubscription() { + thrown.expect(PubSubException.class); + pubsub().pull(formatForTest("non-existing-subscription"), 2); + } + + @Test + public void testPullMessagesAsync() throws ExecutionException, InterruptedException { + String topic = formatForTest("test-pull-messages-async-topic"); + pubsub().create(TopicInfo.of(topic)); + String subscription = formatForTest("test-pull-messages-async-subscription"); + pubsub().create(SubscriptionInfo.of(topic, subscription)); + Message message1 = Message.of("payload1"); + Message message2 = Message.of("payload2"); + List messageIds = pubsub().publish(topic, ImmutableList.of(message1, message2)); + assertEquals(2, messageIds.size()); + Iterator iterator = pubsub().pullAsync(subscription, 2).get(); + assertEquals(message1.payloadAsString(), iterator.next().payloadAsString()); + assertEquals(message2.payloadAsString(), iterator.next().payloadAsString()); + assertTrue(pubsub().deleteSubscription(subscription)); + assertTrue(pubsub().deleteTopic(topic)); + } + + @Test + public void testPullAsyncNonExistingSubscription() + throws ExecutionException, InterruptedException { + thrown.expect(ExecutionException.class); + pubsub().pullAsync(formatForTest("non-existing-subscription"), 2).get(); + } + + @Test + public void testAckAndNackOneMessage() { + String topic = formatForTest("test-ack-one-message-topic"); + pubsub().create(TopicInfo.of(topic)); + String subscription = formatForTest("test-ack-one-message-subscription"); + pubsub().create(SubscriptionInfo.of(topic, subscription)); + Message message = Message.of("payload"); + assertNotNull(pubsub().publish(topic, message)); + Iterator receivedMessages = pubsub().pull(subscription, 1); + receivedMessages.next().nack(); + receivedMessages = pubsub().pull(subscription, 1); + receivedMessages.next().ack(); + assertFalse(pubsub().pull(subscription, 1).hasNext()); + assertTrue(pubsub().deleteSubscription(subscription)); + assertTrue(pubsub().deleteTopic(topic)); + } + + @Test + public void testAckAndNackOneMessageAsync() throws ExecutionException, InterruptedException { + String topic = formatForTest("test-ack-one-message-async-topic"); + pubsub().create(TopicInfo.of(topic)); + String subscription = formatForTest("test-ack-one-message-async-subscription"); + pubsub().create(SubscriptionInfo.of(topic, subscription)); + Message message = Message.of("payload"); + assertNotNull(pubsub().publish(topic, message)); + Iterator receivedMessages = pubsub().pull(subscription, 1); + receivedMessages.next().nackAsync().get(); + receivedMessages = pubsub().pull(subscription, 1); + receivedMessages.next().ackAsync().get(); + assertFalse(pubsub().pull(subscription, 1).hasNext()); + assertTrue(pubsub().deleteSubscription(subscription)); + assertTrue(pubsub().deleteTopic(topic)); + } + + @Test + public void testAckAndNackMoreMessages() throws ExecutionException, InterruptedException { + String topic = formatForTest("test-ack-more-messages-topic"); + pubsub().create(TopicInfo.of(topic)); + String subscription = formatForTest("test-ack-more-messages-subscription"); + pubsub().create(SubscriptionInfo.of(topic, subscription)); + Message message1 = Message.of("payload1"); + Message message2 = Message.of("payload2"); + assertNotNull(pubsub().publish(topic, message1, message2)); + Iterator receivedMessages = pubsub().pull(subscription, 2); + pubsub().nack(subscription, receivedMessages.next().ackId(), receivedMessages.next().ackId()); + receivedMessages = pubsub().pull(subscription, 2); + pubsub().ack(subscription, receivedMessages.next().ackId(), receivedMessages.next().ackId()); + assertFalse(pubsub().pull(subscription, 2).hasNext()); + assertTrue(pubsub().deleteSubscription(subscription)); + assertTrue(pubsub().deleteTopic(topic)); + } + + @Test + public void testAckAndNackMoreMessagesAsync() throws ExecutionException, InterruptedException { + String topic = formatForTest("test-ack-more-messages-async-topic"); + pubsub().create(TopicInfo.of(topic)); + String subscription = formatForTest("test-ack-more-messages-async-subscription"); + pubsub().create(SubscriptionInfo.of(topic, subscription)); + Message message1 = Message.of("payload1"); + Message message2 = Message.of("payload2"); + assertNotNull(pubsub().publish(topic, message1, message2)); + Iterator receivedMessages = pubsub().pull(subscription, 2); + pubsub() + .nackAsync(subscription, receivedMessages.next().ackId(), receivedMessages.next().ackId()) + .get(); + receivedMessages = pubsub().pull(subscription, 2); + pubsub() + .ackAsync(subscription, receivedMessages.next().ackId(), receivedMessages.next().ackId()) + .get(); + assertFalse(pubsub().pull(subscription, 2).hasNext()); + assertTrue(pubsub().deleteSubscription(subscription)); + assertTrue(pubsub().deleteTopic(topic)); + } + + @Test + public void testAckAndNackMessageList() throws ExecutionException, InterruptedException { + String topic = formatForTest("test-ack-message-list-topic"); + pubsub().create(TopicInfo.of(topic)); + String subscription = formatForTest("test-ack-message-list-subscription"); + pubsub().create(SubscriptionInfo.of(topic, subscription)); + Message message1 = Message.of("payload1"); + Message message2 = Message.of("payload2"); + assertNotNull(pubsub().publish(topic, ImmutableList.of(message1, message2))); + Iterator receivedMessages = pubsub().pull(subscription, 2); + pubsub().nack(subscription, + ImmutableList.of(receivedMessages.next().ackId(), receivedMessages.next().ackId())); + receivedMessages = pubsub().pull(subscription, 2); + pubsub().ack(subscription, + ImmutableList.of(receivedMessages.next().ackId(), receivedMessages.next().ackId())); + assertFalse(pubsub().pull(subscription, 2).hasNext()); + assertTrue(pubsub().deleteSubscription(subscription)); + assertTrue(pubsub().deleteTopic(topic)); + } + + @Test + public void testAckAndNackMessageListAsync() throws ExecutionException, InterruptedException { + String topic = formatForTest("test-ack-message-list-async-topic"); + pubsub().create(TopicInfo.of(topic)); + String subscription = formatForTest("test-ack-message-list-async-subscription"); + pubsub().create(SubscriptionInfo.of(topic, subscription)); + Message message1 = Message.of("payload1"); + Message message2 = Message.of("payload2"); + assertNotNull(pubsub().publish(topic, ImmutableList.of(message1, message2))); + Iterator receivedMessages = pubsub().pull(subscription, 2); + pubsub().nackAsync(subscription, + ImmutableList.of(receivedMessages.next().ackId(), receivedMessages.next().ackId())).get(); + receivedMessages = pubsub().pull(subscription, 2); + pubsub().ackAsync(subscription, + ImmutableList.of(receivedMessages.next().ackId(), receivedMessages.next().ackId())).get(); + assertFalse(pubsub().pull(subscription, 2).hasNext()); + assertTrue(pubsub().deleteSubscription(subscription)); + assertTrue(pubsub().deleteTopic(topic)); + } } diff --git a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PubSubImplTest.java b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PubSubImplTest.java index 6084266492f0..7a9fee0d999d 100644 --- a/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PubSubImplTest.java +++ b/gcloud-java-pubsub/src/test/java/com/google/cloud/pubsub/PubSubImplTest.java @@ -52,6 +52,8 @@ import com.google.pubsub.v1.ModifyPushConfigRequest; import com.google.pubsub.v1.PublishRequest; import com.google.pubsub.v1.PublishResponse; +import com.google.pubsub.v1.PullRequest; +import com.google.pubsub.v1.PullResponse; import org.easymock.EasyMock; import org.junit.After; @@ -60,6 +62,7 @@ import org.junit.Test; import org.junit.rules.ExpectedException; +import java.util.Iterator; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @@ -93,6 +96,18 @@ public com.google.pubsub.v1.Topic apply(TopicInfo topicInfo) { .ackDeadLineSeconds(42) .pushConfig(PUSH_CONFIG) .build(); + private static final Message MESSAGE1 = Message.of("payload1"); + private static final com.google.pubsub.v1.ReceivedMessage MESSAGE_PB1 = + com.google.pubsub.v1.ReceivedMessage.newBuilder() + .setMessage(MESSAGE1.toPb()) + .setAckId("ackId1") + .build(); + private static final Message MESSAGE2 = Message.of("payload2"); + private static final com.google.pubsub.v1.ReceivedMessage MESSAGE_PB2 = + com.google.pubsub.v1.ReceivedMessage.newBuilder() + .setMessage(MESSAGE2.toPb()) + .setAckId("ackId2") + .build(); private static final Function SUBSCRIPTION_TO_PB_FUNCTION = new Function() { @@ -112,6 +127,7 @@ public String apply(SubscriptionId subscriptionId) { private PubSubOptions options; private PubSubRpcFactory rpcFactoryMock; private PubSubRpc pubsubRpcMock; + private AckDeadlineRenewer renewerMock; private PubSub pubsub; @Rule @@ -121,26 +137,32 @@ public String apply(SubscriptionId subscriptionId) { public void setUp() { rpcFactoryMock = EasyMock.createStrictMock(PubSubRpcFactory.class); pubsubRpcMock = EasyMock.createStrictMock(PubSubRpc.class); - EasyMock.expect(rpcFactoryMock.create(EasyMock.anyObject(PubSubOptions.class))) - .andReturn(pubsubRpcMock).times(1); - options = PubSubOptions.builder() - .projectId(PROJECT) - .serviceRpcFactory(rpcFactoryMock) - .retryParams(RetryParams.noRetries()) - .build(); - EasyMock.replay(rpcFactoryMock, pubsubRpcMock); - EasyMock.reset(pubsubRpcMock); + renewerMock = EasyMock.createStrictMock(AckDeadlineRenewer.class); + options = EasyMock.createMock(PubSubOptions.class); + EasyMock.expect(options.projectId()).andReturn(PROJECT).anyTimes(); + EasyMock.expect(options.rpc()).andReturn(pubsubRpcMock).anyTimes(); + EasyMock.expect(options.retryParams()).andReturn(RetryParams.noRetries()).anyTimes(); + EasyMock.replay(rpcFactoryMock, pubsubRpcMock, renewerMock, options); + EasyMock.reset(pubsubRpcMock, renewerMock); } @After public void tearDown() { - EasyMock.verify(rpcFactoryMock, pubsubRpcMock); + EasyMock.verify(rpcFactoryMock, pubsubRpcMock, renewerMock, options); + } + + private void resetOptionsForList(int pageCount) { + EasyMock.reset(options); + EasyMock.expect(options.projectId()).andReturn(PROJECT).times(pageCount); + EasyMock.expect(options.rpc()).andReturn(pubsubRpcMock).times(pageCount); + EasyMock.expect(options.service()).andReturn(pubsub).times(pageCount); + EasyMock.replay(options); } @Test public void testGetOptions() { - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); assertSame(options, pubsub.options()); } @@ -149,8 +171,8 @@ public void testCreateTopic() { com.google.pubsub.v1.Topic topicPb = TOPIC_INFO.toPb(PROJECT); Future response = Futures.immediateFuture(topicPb); EasyMock.expect(pubsubRpcMock.create(topicPb)).andReturn(response); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); Topic topic = pubsub.create(TOPIC_INFO); assertEquals(new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO)), topic); } @@ -160,8 +182,8 @@ public void testCreateTopicAsync() throws ExecutionException, InterruptedExcepti com.google.pubsub.v1.Topic topicPb = TOPIC_INFO.toPb(PROJECT); Future response = Futures.immediateFuture(topicPb); EasyMock.expect(pubsubRpcMock.create(topicPb)).andReturn(response); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); Topic topic = pubsub.createAsync(TOPIC_INFO).get(); assertEquals(new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO)), topic); } @@ -172,8 +194,8 @@ public void testGetTopic() { Future response = Futures.immediateFuture(TOPIC_INFO.toPb(PROJECT)); EasyMock.expect(pubsubRpcMock.get(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); Topic topic = pubsub.getTopic(TOPIC); assertEquals(new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO)), topic); } @@ -183,8 +205,8 @@ public void testGetTopic_Null() { GetTopicRequest request = GetTopicRequest.newBuilder().setTopic(TOPIC_NAME_PB).build(); Future responseFuture = Futures.immediateFuture(null); EasyMock.expect(pubsubRpcMock.get(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); assertNull(pubsub.getTopic(TOPIC)); } @@ -194,8 +216,8 @@ public void testGetTopicAsync() throws ExecutionException, InterruptedException Future response = Futures.immediateFuture(TOPIC_INFO.toPb(PROJECT)); EasyMock.expect(pubsubRpcMock.get(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); Future topicFuture = pubsub.getTopicAsync(TOPIC); assertEquals(new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO)), topicFuture.get()); } @@ -205,8 +227,8 @@ public void testGetTopicAsync_Null() throws ExecutionException, InterruptedExcep GetTopicRequest request = GetTopicRequest.newBuilder().setTopic(TOPIC_NAME_PB).build(); Future responseFuture = Futures.immediateFuture(null); EasyMock.expect(pubsubRpcMock.get(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); assertNull(pubsub.getTopicAsync(TOPIC).get()); } @@ -215,8 +237,8 @@ public void testDeleteTopic() { DeleteTopicRequest request = DeleteTopicRequest.newBuilder().setTopic(TOPIC_NAME_PB).build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); assertTrue(pubsub.deleteTopic(TOPIC)); } @@ -225,8 +247,8 @@ public void testDeleteTopic_Null() { DeleteTopicRequest request = DeleteTopicRequest.newBuilder().setTopic(TOPIC_NAME_PB).build(); Future response = Futures.immediateFuture(null); EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); assertFalse(pubsub.deleteTopic(TOPIC)); } @@ -235,8 +257,8 @@ public void testDeleteTopicAsync() throws ExecutionException, InterruptedExcepti DeleteTopicRequest request = DeleteTopicRequest.newBuilder().setTopic(TOPIC_NAME_PB).build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); assertTrue(pubsub.deleteTopicAsync(TOPIC).get()); } @@ -245,15 +267,16 @@ public void testDeleteTopicAsync_Null() throws ExecutionException, InterruptedEx DeleteTopicRequest request = DeleteTopicRequest.newBuilder().setTopic(TOPIC_NAME_PB).build(); Future response = Futures.immediateFuture(null); EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); assertFalse(pubsub.deleteTopicAsync(TOPIC).get()); } @Test public void testListTopics() { String cursor = "cursor"; - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); + resetOptionsForList(1); ListTopicsRequest request = ListTopicsRequest.newBuilder().setProject(PROJECT_PB).build(); List topicList = ImmutableList.of( new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO)), @@ -264,7 +287,7 @@ public void testListTopics() { .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); Page page = pubsub.listTopics(); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(topicList.toArray(), Iterables.toArray(page.values(), Topic.class)); @@ -273,7 +296,8 @@ public void testListTopics() { @Test public void testListTopicsNextPage() { String cursor1 = "cursor"; - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); + resetOptionsForList(2); ListTopicsRequest request1 = ListTopicsRequest.newBuilder().setProject(PROJECT_PB).build(); ListTopicsRequest request2 = ListTopicsRequest.newBuilder() .setProject(PROJECT_PB) @@ -297,7 +321,7 @@ public void testListTopicsNextPage() { Future futureResponse2 = Futures.immediateFuture(response2); EasyMock.expect(pubsubRpcMock.list(request1)).andReturn(futureResponse1); EasyMock.expect(pubsubRpcMock.list(request2)).andReturn(futureResponse2); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); Page page = pubsub.listTopics(); assertEquals(cursor1, page.nextPageCursor()); assertArrayEquals(topicList1.toArray(), Iterables.toArray(page.values(), Topic.class)); @@ -308,7 +332,8 @@ public void testListTopicsNextPage() { @Test public void testListTopicsEmpty() { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); + resetOptionsForList(1); ListTopicsRequest request = ListTopicsRequest.newBuilder().setProject(PROJECT_PB).build(); List topicList = ImmutableList.of(); ListTopicsResponse response = ListTopicsResponse.newBuilder() @@ -317,7 +342,7 @@ public void testListTopicsEmpty() { .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); Page page = pubsub.listTopics(); assertNull(page.nextPageCursor()); assertNull(page.nextPage()); @@ -327,7 +352,8 @@ public void testListTopicsEmpty() { @Test public void testListTopicsWithOptions() { String cursor = "cursor"; - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); + resetOptionsForList(1); ListTopicsRequest request = ListTopicsRequest.newBuilder() .setProject(PROJECT_PB) .setPageSize(42) @@ -342,7 +368,7 @@ public void testListTopicsWithOptions() { .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); Page page = pubsub.listTopics(ListOption.pageSize(42), ListOption.pageToken(cursor)); assertNull(page.nextPageCursor()); assertNull(page.nextPage()); @@ -352,7 +378,8 @@ public void testListTopicsWithOptions() { @Test public void testListTopicsAsync() throws ExecutionException, InterruptedException { String cursor = "cursor"; - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); + resetOptionsForList(1); ListTopicsRequest request = ListTopicsRequest.newBuilder().setProject(PROJECT_PB).build(); List topicList = ImmutableList.of( new Topic(pubsub, new TopicInfo.BuilderImpl(TOPIC_INFO)), @@ -363,7 +390,7 @@ public void testListTopicsAsync() throws ExecutionException, InterruptedExceptio .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); AsyncPage page = pubsub.listTopicsAsync().get(); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(topicList.toArray(), Iterables.toArray(page.values(), Topic.class)); @@ -372,7 +399,8 @@ public void testListTopicsAsync() throws ExecutionException, InterruptedExceptio @Test public void testListTopicsAsyncNextPage() throws ExecutionException, InterruptedException { String cursor1 = "cursor"; - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); + resetOptionsForList(2); ListTopicsRequest request1 = ListTopicsRequest.newBuilder().setProject(PROJECT_PB).build(); ListTopicsRequest request2 = ListTopicsRequest.newBuilder() .setProject(PROJECT_PB) @@ -396,7 +424,7 @@ public void testListTopicsAsyncNextPage() throws ExecutionException, Interrupted Future futureResponse2 = Futures.immediateFuture(response2); EasyMock.expect(pubsubRpcMock.list(request1)).andReturn(futureResponse1); EasyMock.expect(pubsubRpcMock.list(request2)).andReturn(futureResponse2); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); AsyncPage page = pubsub.listTopicsAsync().get(); assertEquals(cursor1, page.nextPageCursor()); assertArrayEquals(topicList1.toArray(), Iterables.toArray(page.values(), Topic.class)); @@ -407,7 +435,8 @@ public void testListTopicsAsyncNextPage() throws ExecutionException, Interrupted @Test public void testListTopicsAsyncEmpty() throws ExecutionException, InterruptedException { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); + resetOptionsForList(1); ListTopicsRequest request = ListTopicsRequest.newBuilder().setProject(PROJECT_PB).build(); List topicList = ImmutableList.of(); ListTopicsResponse response = ListTopicsResponse.newBuilder() @@ -416,7 +445,7 @@ public void testListTopicsAsyncEmpty() throws ExecutionException, InterruptedExc .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); AsyncPage page = pubsub.listTopicsAsync().get(); assertNull(page.nextPageCursor()); assertNull(page.nextPageAsync().get()); @@ -427,7 +456,8 @@ public void testListTopicsAsyncEmpty() throws ExecutionException, InterruptedExc @Test public void testListTopicsAsyncWithOptions() throws ExecutionException, InterruptedException { String cursor = "cursor"; - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); + resetOptionsForList(1); ListTopicsRequest request = ListTopicsRequest.newBuilder() .setProject(PROJECT_PB) .setPageSize(42) @@ -442,7 +472,7 @@ public void testListTopicsAsyncWithOptions() throws ExecutionException, Interrup .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); AsyncPage page = pubsub.listTopicsAsync(ListOption.pageSize(42), ListOption.pageToken(cursor)).get(); assertNull(page.nextPageCursor()); @@ -460,8 +490,8 @@ public void testPublishOneMessage() { PublishResponse response = PublishResponse.newBuilder().addMessageIds(messageId).build(); Future responseFuture = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.publish(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); assertEquals(messageId, pubsub.publish(TOPIC, MESSAGE)); } @@ -475,8 +505,8 @@ public void testPublishOneMessageAsync() throws ExecutionException, InterruptedE PublishResponse response = PublishResponse.newBuilder().addMessageIds(messageId).build(); Future responseFuture = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.publish(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); assertEquals(messageId, pubsub.publishAsync(TOPIC, MESSAGE).get()); } @@ -492,8 +522,8 @@ public void testPublishMoreMessages() { .build(); Future responseFuture = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.publish(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); assertEquals(messageIds, pubsub.publish(TOPIC, MESSAGE, MESSAGE)); } @@ -509,8 +539,8 @@ public void testPublishMoreMessagesAsync() throws ExecutionException, Interrupte .build(); Future responseFuture = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.publish(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); assertEquals(messageIds, pubsub.publishAsync(TOPIC, MESSAGE, MESSAGE).get()); } @@ -526,8 +556,8 @@ public void testPublishMessageList() { .build(); Future responseFuture = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.publish(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); assertEquals(messageIds, pubsub.publish(TOPIC, ImmutableList.of(MESSAGE, MESSAGE))); } @@ -543,8 +573,8 @@ public void testPublishMessageListAsync() throws ExecutionException, Interrupted .build(); Future responseFuture = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.publish(request)).andReturn(responseFuture); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); assertEquals(messageIds, pubsub.publishAsync(TOPIC, ImmutableList.of(MESSAGE, MESSAGE)).get()); } @@ -554,8 +584,8 @@ public void testCreateSubscription() { Future response = Futures.immediateFuture(subscriptionPb); EasyMock.expect(pubsubRpcMock.create(subscriptionPb)).andReturn(response); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); Subscription subscription = pubsub.create(SUBSCRIPTION_INFO); assertEquals( new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO)), @@ -568,8 +598,8 @@ public void testCreateSubscriptionAsync() throws ExecutionException, Interrupted Future response = Futures.immediateFuture(subscriptionPb); EasyMock.expect(pubsubRpcMock.create(subscriptionPb)).andReturn(response); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); Subscription subscription = pubsub.createAsync(SUBSCRIPTION_INFO).get(); assertEquals( new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO)), @@ -583,8 +613,8 @@ public void testGetSubscription() { Future response = Futures.immediateFuture(SUBSCRIPTION_INFO.toPb(PROJECT)); EasyMock.expect(pubsubRpcMock.get(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); Subscription subscription = pubsub.getSubscription(SUBSCRIPTION); assertEquals( new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO)), @@ -597,8 +627,8 @@ public void testGetSubscription_Null() { GetSubscriptionRequest.newBuilder().setSubscription(SUBSCRIPTION_NAME_PB).build(); Future response = Futures.immediateFuture(null); EasyMock.expect(pubsubRpcMock.get(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); assertNull(pubsub.getSubscription(SUBSCRIPTION)); } @@ -609,8 +639,8 @@ public void testGetSubscriptionAsync() throws ExecutionException, InterruptedExc Future response = Futures.immediateFuture(SUBSCRIPTION_INFO.toPb(PROJECT)); EasyMock.expect(pubsubRpcMock.get(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); Subscription subscription = pubsub.getSubscriptionAsync(SUBSCRIPTION).get(); assertEquals( new Subscription(pubsub, new SubscriptionInfo.BuilderImpl(COMPLETE_SUBSCRIPTION_INFO)), @@ -623,8 +653,8 @@ public void testGetSubscriptionAsync_Null() throws ExecutionException, Interrupt GetSubscriptionRequest.newBuilder().setSubscription(SUBSCRIPTION_NAME_PB).build(); Future response = Futures.immediateFuture(null); EasyMock.expect(pubsubRpcMock.get(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); assertNull(pubsub.getSubscriptionAsync(SUBSCRIPTION).get()); } @@ -635,8 +665,8 @@ public void testDeleteSubscription() { .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); assertTrue(pubsub.deleteSubscription(SUBSCRIPTION)); } @@ -647,8 +677,8 @@ public void testDeleteSubscription_Null() { .build(); Future response = Futures.immediateFuture(null); EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); assertFalse(pubsub.deleteSubscription(SUBSCRIPTION)); } @@ -659,8 +689,8 @@ public void testDeleteSubscriptionAsync() throws ExecutionException, Interrupted .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); assertTrue(pubsub.deleteSubscriptionAsync(SUBSCRIPTION).get()); } @@ -671,8 +701,8 @@ public void testDeleteSubscriptionAsync_Null() throws ExecutionException, Interr .build(); Future response = Futures.immediateFuture(null); EasyMock.expect(pubsubRpcMock.delete(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); assertFalse(pubsub.deleteSubscriptionAsync(SUBSCRIPTION).get()); } @@ -684,8 +714,8 @@ public void testReplacePushConfig() { .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); pubsub.replacePushConfig(SUBSCRIPTION, PUSH_CONFIG); } @@ -697,8 +727,8 @@ public void testReplacePushConfig_Null() { .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); pubsub.replacePushConfig(SUBSCRIPTION, null); } @@ -710,8 +740,8 @@ public void testReplacePushConfigAsync() throws ExecutionException, InterruptedE .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); pubsub.replacePushConfigAsync(SUBSCRIPTION, PUSH_CONFIG).get(); } @@ -723,15 +753,16 @@ public void testReplacePushConfigAsync_Null() throws ExecutionException, Interru .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); - pubsub = options.service(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub = new PubSubImpl(options, renewerMock); pubsub.replacePushConfigAsync(SUBSCRIPTION, null).get(); } @Test public void testListSubscriptions() { String cursor = "cursor"; - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); + resetOptionsForList(1); ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder() .setProject(PROJECT_PB) .build(); @@ -744,7 +775,7 @@ public void testListSubscriptions() { .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); Page page = pubsub.listSubscriptions(); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(subscriptionList.toArray(), @@ -754,7 +785,8 @@ public void testListSubscriptions() { @Test public void testListSubscriptionsNextPage() { String cursor1 = "cursor"; - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); + resetOptionsForList(2); ListSubscriptionsRequest request1 = ListSubscriptionsRequest.newBuilder() .setProject(PROJECT_PB) .build(); @@ -780,7 +812,7 @@ public void testListSubscriptionsNextPage() { Future futureResponse2 = Futures.immediateFuture(response2); EasyMock.expect(pubsubRpcMock.list(request1)).andReturn(futureResponse1); EasyMock.expect(pubsubRpcMock.list(request2)).andReturn(futureResponse2); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); Page page = pubsub.listSubscriptions(); assertEquals(cursor1, page.nextPageCursor()); assertArrayEquals(subscriptionList1.toArray(), @@ -793,7 +825,8 @@ public void testListSubscriptionsNextPage() { @Test public void testListSubscriptionsEmpty() { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); + resetOptionsForList(1); ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder() .setProject(PROJECT_PB) .build(); @@ -804,7 +837,7 @@ public void testListSubscriptionsEmpty() { .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); Page page = pubsub.listSubscriptions(); assertNull(page.nextPageCursor()); assertNull(page.nextPage()); @@ -815,7 +848,8 @@ public void testListSubscriptionsEmpty() { @Test public void testListSubscriptionsWithOptions() { String cursor = "cursor"; - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); + resetOptionsForList(1); ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder() .setProject(PROJECT_PB) .setPageSize(42) @@ -830,7 +864,7 @@ public void testListSubscriptionsWithOptions() { .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); Page page = pubsub.listSubscriptions(ListOption.pageSize(42), ListOption.pageToken(cursor)); assertNull(page.nextPageCursor()); @@ -842,7 +876,8 @@ public void testListSubscriptionsWithOptions() { @Test public void testListSubscriptionsAsync() throws ExecutionException, InterruptedException { String cursor = "cursor"; - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); + resetOptionsForList(1); ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder() .setProject(PROJECT_PB) .build(); @@ -855,7 +890,7 @@ public void testListSubscriptionsAsync() throws ExecutionException, InterruptedE .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); AsyncPage page = pubsub.listSubscriptionsAsync().get(); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(subscriptionList.toArray(), @@ -865,7 +900,8 @@ public void testListSubscriptionsAsync() throws ExecutionException, InterruptedE @Test public void testListSubscriptionsAsyncNextPage() throws ExecutionException, InterruptedException { String cursor1 = "cursor"; - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); + resetOptionsForList(2); ListSubscriptionsRequest request1 = ListSubscriptionsRequest.newBuilder() .setProject(PROJECT_PB) .build(); @@ -891,7 +927,7 @@ public void testListSubscriptionsAsyncNextPage() throws ExecutionException, Inte Future futureResponse2 = Futures.immediateFuture(response2); EasyMock.expect(pubsubRpcMock.list(request1)).andReturn(futureResponse1); EasyMock.expect(pubsubRpcMock.list(request2)).andReturn(futureResponse2); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); AsyncPage page = pubsub.listSubscriptionsAsync().get(); assertEquals(cursor1, page.nextPageCursor()); assertArrayEquals(subscriptionList1.toArray(), @@ -904,7 +940,8 @@ public void testListSubscriptionsAsyncNextPage() throws ExecutionException, Inte @Test public void testListSubscriptionsAsyncEmpty() throws ExecutionException, InterruptedException { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); + resetOptionsForList(1); ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder() .setProject(PROJECT_PB) .build(); @@ -915,7 +952,7 @@ public void testListSubscriptionsAsyncEmpty() throws ExecutionException, Interru .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); AsyncPage page = pubsub.listSubscriptionsAsync().get(); assertNull(page.nextPageCursor()); assertNull(page.nextPageAsync().get()); @@ -928,7 +965,8 @@ public void testListSubscriptionsAsyncEmpty() throws ExecutionException, Interru public void testListSubscriptionsAsyncWithOptions() throws ExecutionException, InterruptedException { String cursor = "cursor"; - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); + resetOptionsForList(1); ListSubscriptionsRequest request = ListSubscriptionsRequest.newBuilder() .setProject(PROJECT_PB) .setPageSize(42) @@ -943,7 +981,7 @@ public void testListSubscriptionsAsyncWithOptions() .build(); Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); AsyncPage page = pubsub.listSubscriptionsAsync(ListOption.pageSize(42), ListOption.pageToken(cursor)).get(); assertNull(page.nextPageCursor()); @@ -956,7 +994,7 @@ public void testListSubscriptionsAsyncWithOptions() @Test public void testListTopicSubscriptions() { String cursor = "cursor"; - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder() .setTopic(TOPIC_NAME_PB) .build(); @@ -970,7 +1008,7 @@ public void testListTopicSubscriptions() { Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); Page page = pubsub.listSubscriptions(TOPIC); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(subscriptionList.toArray(), @@ -980,7 +1018,7 @@ public void testListTopicSubscriptions() { @Test public void testListTopicSubscriptionsNextPage() { String cursor1 = "cursor"; - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); ListTopicSubscriptionsRequest request1 = ListTopicSubscriptionsRequest.newBuilder() .setTopic(TOPIC_NAME_PB) .build(); @@ -1008,7 +1046,7 @@ public void testListTopicSubscriptionsNextPage() { Futures.immediateFuture(response2); EasyMock.expect(pubsubRpcMock.list(request1)).andReturn(futureResponse1); EasyMock.expect(pubsubRpcMock.list(request2)).andReturn(futureResponse2); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); Page page = pubsub.listSubscriptions(TOPIC); assertEquals(cursor1, page.nextPageCursor()); assertArrayEquals(subscriptionList1.toArray(), @@ -1021,7 +1059,7 @@ public void testListTopicSubscriptionsNextPage() { @Test public void testListTopicSubscriptionsEmpty() { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder() .setTopic(TOPIC_NAME_PB) .build(); @@ -1033,7 +1071,7 @@ public void testListTopicSubscriptionsEmpty() { Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); Page page = pubsub.listSubscriptions(TOPIC); assertNull(page.nextPageCursor()); assertNull(page.nextPage()); @@ -1044,7 +1082,7 @@ public void testListTopicSubscriptionsEmpty() { @Test public void testListTopicSubscriptionsWithOptions() { String cursor = "cursor"; - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder() .setTopic(TOPIC_NAME_PB) .setPageSize(42) @@ -1060,7 +1098,7 @@ public void testListTopicSubscriptionsWithOptions() { Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); Page page = pubsub.listSubscriptions(TOPIC, ListOption.pageSize(42), ListOption.pageToken(cursor)); assertNull(page.nextPageCursor()); @@ -1072,7 +1110,7 @@ public void testListTopicSubscriptionsWithOptions() { @Test public void testListTopicSubscriptionsAsync() throws ExecutionException, InterruptedException { String cursor = "cursor"; - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder() .setTopic(TOPIC_NAME_PB) .build(); @@ -1086,7 +1124,7 @@ public void testListTopicSubscriptionsAsync() throws ExecutionException, Interru Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); AsyncPage page = pubsub.listSubscriptionsAsync(TOPIC).get(); assertEquals(cursor, page.nextPageCursor()); assertArrayEquals(subscriptionList.toArray(), @@ -1097,7 +1135,7 @@ public void testListTopicSubscriptionsAsync() throws ExecutionException, Interru public void testListTopicSubscriptionsAsyncNextPage() throws ExecutionException, InterruptedException { String cursor1 = "cursor"; - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); ListTopicSubscriptionsRequest request1 = ListTopicSubscriptionsRequest.newBuilder() .setTopic(TOPIC_NAME_PB) .build(); @@ -1125,7 +1163,7 @@ public void testListTopicSubscriptionsAsyncNextPage() Futures.immediateFuture(response2); EasyMock.expect(pubsubRpcMock.list(request1)).andReturn(futureResponse1); EasyMock.expect(pubsubRpcMock.list(request2)).andReturn(futureResponse2); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); AsyncPage page = pubsub.listSubscriptionsAsync(TOPIC).get(); assertEquals(cursor1, page.nextPageCursor()); assertArrayEquals(subscriptionList1.toArray(), @@ -1139,7 +1177,7 @@ public void testListTopicSubscriptionsAsyncNextPage() @Test public void testListTopicSubscriptionsAsyncEmpty() throws ExecutionException, InterruptedException { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder() .setTopic(TOPIC_NAME_PB) .build(); @@ -1151,7 +1189,7 @@ public void testListTopicSubscriptionsAsyncEmpty() Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); AsyncPage page = pubsub.listSubscriptionsAsync(TOPIC).get(); assertNull(page.nextPageCursor()); assertNull(page.nextPage()); @@ -1164,7 +1202,7 @@ public void testListTopicSubscriptionsAsyncEmpty() public void testListTopicSubscriptionsAsyncWithOptions() throws ExecutionException, InterruptedException { String cursor = "cursor"; - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); ListTopicSubscriptionsRequest request = ListTopicSubscriptionsRequest.newBuilder() .setTopic(TOPIC_NAME_PB) .setPageSize(42) @@ -1180,7 +1218,7 @@ public void testListTopicSubscriptionsAsyncWithOptions() Future futureResponse = Futures.immediateFuture(response); EasyMock.expect(pubsubRpcMock.list(request)).andReturn(futureResponse); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); AsyncPage page = pubsub.listSubscriptionsAsync( TOPIC, ListOption.pageSize(42), ListOption.pageToken(cursor)).get(); assertNull(page.nextPageCursor()); @@ -1190,63 +1228,123 @@ public void testListTopicSubscriptionsAsyncWithOptions() Iterables.toArray(page.values(), SubscriptionId.class)); } + @Test + public void testPullMessages() { + pubsub = new PubSubImpl(options, renewerMock); + PullRequest request = PullRequest.newBuilder() + .setSubscription(SUBSCRIPTION_NAME_PB) + .setMaxMessages(42) + .setReturnImmediately(true) + .build(); + List messageList = ImmutableList.of( + ReceivedMessage.fromPb(pubsub, SUBSCRIPTION, MESSAGE_PB1), + ReceivedMessage.fromPb(pubsub, SUBSCRIPTION, MESSAGE_PB2)); + PullResponse response = PullResponse.newBuilder() + .addReceivedMessages(MESSAGE_PB1) + .addReceivedMessages(MESSAGE_PB2) + .build(); + EasyMock.expect(pubsubRpcMock.pull(request)).andReturn(Futures.immediateFuture(response)); + renewerMock.add(SUBSCRIPTION, ImmutableList.of("ackId1", "ackId2")); + EasyMock.replay(pubsubRpcMock, renewerMock); + Iterator messageIterator = pubsub.pull(SUBSCRIPTION, 42); + EasyMock.reset(renewerMock); + for (ReceivedMessage message : messageList) { + renewerMock.remove(SUBSCRIPTION, message.ackId()); + EasyMock.expectLastCall(); + } + EasyMock.replay(renewerMock); + while (messageIterator.hasNext()) { + messageIterator.next(); + } + } + + @Test + public void testPullMessagesAsync() throws ExecutionException, InterruptedException { + pubsub = new PubSubImpl(options, renewerMock); + PullRequest request = PullRequest.newBuilder() + .setSubscription(SUBSCRIPTION_NAME_PB) + .setMaxMessages(42) + .setReturnImmediately(true) + .build(); + List messageList = ImmutableList.of( + ReceivedMessage.fromPb(pubsub, SUBSCRIPTION, MESSAGE_PB1), + ReceivedMessage.fromPb(pubsub, SUBSCRIPTION, MESSAGE_PB2)); + PullResponse response = PullResponse.newBuilder() + .addReceivedMessages(MESSAGE_PB1) + .addReceivedMessages(MESSAGE_PB2) + .build(); + EasyMock.expect(pubsubRpcMock.pull(request)).andReturn(Futures.immediateFuture(response)); + renewerMock.add(SUBSCRIPTION, ImmutableList.of("ackId1", "ackId2")); + EasyMock.replay(pubsubRpcMock, renewerMock); + Iterator messageIterator = pubsub.pullAsync(SUBSCRIPTION, 42).get(); + EasyMock.reset(renewerMock); + for (ReceivedMessage message : messageList) { + renewerMock.remove(SUBSCRIPTION, message.ackId()); + EasyMock.expectLastCall(); + } + EasyMock.replay(renewerMock); + while (messageIterator.hasNext()) { + messageIterator.next(); + } + } + @Test public void testAckOneMessage() { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); AcknowledgeRequest request = AcknowledgeRequest.newBuilder() .setSubscription(SUBSCRIPTION_NAME_PB) .addAckIds("ackId") .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.acknowledge(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); pubsub.ack(SUBSCRIPTION, "ackId"); } @Test public void testAckOneMessageAsync() throws ExecutionException, InterruptedException { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); AcknowledgeRequest request = AcknowledgeRequest.newBuilder() .setSubscription(SUBSCRIPTION_NAME_PB) .addAckIds("ackId") .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.acknowledge(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); Future future = pubsub.ackAsync(SUBSCRIPTION, "ackId"); assertNull(future.get()); } @Test public void testAckMoreMessages() { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); AcknowledgeRequest request = AcknowledgeRequest.newBuilder() .setSubscription(SUBSCRIPTION_NAME_PB) .addAllAckIds(ImmutableList.of("ackId1", "ackId2")) .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.acknowledge(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); pubsub.ack(SUBSCRIPTION, "ackId1", "ackId2"); } @Test public void testAckMoreMessagesAsync() throws ExecutionException, InterruptedException { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); AcknowledgeRequest request = AcknowledgeRequest.newBuilder() .setSubscription(SUBSCRIPTION_NAME_PB) .addAllAckIds(ImmutableList.of("ackId1", "ackId2")) .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.acknowledge(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); Future future = pubsub.ackAsync(SUBSCRIPTION, "ackId1", "ackId2"); assertNull(future.get()); } @Test public void testAckMessageList() { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); List ackIds = ImmutableList.of("ackId1", "ackId2"); AcknowledgeRequest request = AcknowledgeRequest.newBuilder() .setSubscription(SUBSCRIPTION_NAME_PB) @@ -1254,13 +1352,13 @@ public void testAckMessageList() { .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.acknowledge(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); pubsub.ack(SUBSCRIPTION, ackIds); } @Test public void testAckMessageListAsync() throws ExecutionException, InterruptedException { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); List ackIds = ImmutableList.of("ackId1", "ackId2"); AcknowledgeRequest request = AcknowledgeRequest.newBuilder() .setSubscription(SUBSCRIPTION_NAME_PB) @@ -1268,14 +1366,14 @@ public void testAckMessageListAsync() throws ExecutionException, InterruptedExce .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.acknowledge(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); Future future = pubsub.ackAsync(SUBSCRIPTION, ackIds); assertNull(future.get()); } @Test public void testNackOneMessage() { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() .setAckDeadlineSeconds(0) .setSubscription(SUBSCRIPTION_NAME_PB) @@ -1283,13 +1381,13 @@ public void testNackOneMessage() { .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); pubsub.nack(SUBSCRIPTION, "ackId"); } @Test public void testNackOneMessageAsync() throws ExecutionException, InterruptedException { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() .setAckDeadlineSeconds(0) .setSubscription(SUBSCRIPTION_NAME_PB) @@ -1297,14 +1395,14 @@ public void testNackOneMessageAsync() throws ExecutionException, InterruptedExce .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); Future future = pubsub.nackAsync(SUBSCRIPTION, "ackId"); assertNull(future.get()); } @Test public void testNackMoreMessages() { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() .setAckDeadlineSeconds(0) .setSubscription(SUBSCRIPTION_NAME_PB) @@ -1312,13 +1410,13 @@ public void testNackMoreMessages() { .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); pubsub.nack(SUBSCRIPTION, "ackId1", "ackId2"); } @Test public void testNackMoreMessagesAsync() throws ExecutionException, InterruptedException { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() .setAckDeadlineSeconds(0) .setSubscription(SUBSCRIPTION_NAME_PB) @@ -1326,14 +1424,14 @@ public void testNackMoreMessagesAsync() throws ExecutionException, InterruptedEx .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); Future future = pubsub.nackAsync(SUBSCRIPTION, "ackId1", "ackId2"); assertNull(future.get()); } @Test public void testNackMessageList() { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); List ackIds = ImmutableList.of("ackId1", "ackId2"); ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() .setAckDeadlineSeconds(0) @@ -1342,13 +1440,13 @@ public void testNackMessageList() { .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); pubsub.nack(SUBSCRIPTION, ackIds); } @Test public void testNackMessageListAsync() throws ExecutionException, InterruptedException { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); List ackIds = ImmutableList.of("ackId1", "ackId2"); ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() .setAckDeadlineSeconds(0) @@ -1357,14 +1455,14 @@ public void testNackMessageListAsync() throws ExecutionException, InterruptedExc .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); Future future = pubsub.nackAsync(SUBSCRIPTION, ackIds); assertNull(future.get()); } @Test public void testModifyAckDeadlineOneMessage() { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() .setAckDeadlineSeconds(10) .setSubscription(SUBSCRIPTION_NAME_PB) @@ -1372,14 +1470,14 @@ public void testModifyAckDeadlineOneMessage() { .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); pubsub.modifyAckDeadline(SUBSCRIPTION, 10, TimeUnit.SECONDS, "ackId"); } @Test public void testModifyAckDeadlineOneMessageAsync() throws ExecutionException, InterruptedException { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() .setAckDeadlineSeconds(10) .setSubscription(SUBSCRIPTION_NAME_PB) @@ -1387,7 +1485,7 @@ public void testModifyAckDeadlineOneMessageAsync() .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); Future future = pubsub.modifyAckDeadlineAsync(SUBSCRIPTION, 10, TimeUnit.SECONDS, "ackId"); assertNull(future.get()); @@ -1395,7 +1493,7 @@ public void testModifyAckDeadlineOneMessageAsync() @Test public void testModifyAckDeadlineMoreMessages() { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() .setAckDeadlineSeconds(10) .setSubscription(SUBSCRIPTION_NAME_PB) @@ -1403,14 +1501,14 @@ public void testModifyAckDeadlineMoreMessages() { .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); pubsub.modifyAckDeadline(SUBSCRIPTION, 10, TimeUnit.SECONDS, "ackId1", "ackId2"); } @Test public void testModifyAckDeadlineMoreMessagesAsync() throws ExecutionException, InterruptedException { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() .setAckDeadlineSeconds(10) .setSubscription(SUBSCRIPTION_NAME_PB) @@ -1418,7 +1516,7 @@ public void testModifyAckDeadlineMoreMessagesAsync() .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); Future future = pubsub.modifyAckDeadlineAsync(SUBSCRIPTION, 10, TimeUnit.SECONDS, "ackId1", "ackId2"); assertNull(future.get()); @@ -1426,7 +1524,7 @@ public void testModifyAckDeadlineMoreMessagesAsync() @Test public void testModifyAckDeadlineMessageList() { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); List ackIds = ImmutableList.of("ackId1", "ackId2"); ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() .setAckDeadlineSeconds(10) @@ -1435,14 +1533,14 @@ public void testModifyAckDeadlineMessageList() { .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); pubsub.modifyAckDeadline(SUBSCRIPTION, 10, TimeUnit.SECONDS, ackIds); } @Test public void testModifyAckDeadlineMessageListAsync() throws ExecutionException, InterruptedException { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); List ackIds = ImmutableList.of("ackId1", "ackId2"); ModifyAckDeadlineRequest request = ModifyAckDeadlineRequest.newBuilder() .setAckDeadlineSeconds(10) @@ -1451,17 +1549,22 @@ public void testModifyAckDeadlineMessageListAsync() .build(); Future response = Futures.immediateFuture(Empty.getDefaultInstance()); EasyMock.expect(pubsubRpcMock.modify(request)).andReturn(response); - EasyMock.replay(pubsubRpcMock); + EasyMock.replay(pubsubRpcMock, renewerMock); Future future = pubsub.modifyAckDeadlineAsync(SUBSCRIPTION, 10, TimeUnit.SECONDS, ackIds); assertNull(future.get()); } @Test public void testClose() throws Exception { - pubsub = options.service(); + pubsub = new PubSubImpl(options, renewerMock); pubsubRpcMock.close(); EasyMock.expectLastCall(); - EasyMock.replay(pubsubRpcMock); + EasyMock.expectLastCall(); + renewerMock.close(); + EasyMock.expectLastCall(); + EasyMock.replay(pubsubRpcMock, renewerMock); + pubsub.close(); + // closing again should do nothing pubsub.close(); } } From eb6f182752951c2033154a1c408f64e85e675d78 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 8 Jun 2016 11:50:11 +0200 Subject: [PATCH 368/375] Add support for incomplete entities to Datastore.put (#1040) Add support for entities with incomplete key to Datastore.put --- .../datastore/BaseDatastoreBatchWriter.java | 64 ++++++++++++-- .../com/google/cloud/datastore/Datastore.java | 15 +++- .../cloud/datastore/DatastoreBatchWriter.java | 50 +++++++---- .../cloud/datastore/DatastoreHelper.java | 4 + .../google/cloud/datastore/DatastoreImpl.java | 87 ++++++++++++------- .../cloud/datastore/DatastoreReader.java | 2 +- .../cloud/datastore/DatastoreWriter.java | 43 ++++++--- .../BaseDatastoreBatchWriterTest.java | 52 +++++++++-- .../google/cloud/datastore/DatastoreTest.java | 26 +++--- 9 files changed, 249 insertions(+), 94 deletions(-) diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/BaseDatastoreBatchWriter.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/BaseDatastoreBatchWriter.java index 8804ef7e8dda..59a2a033d015 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/BaseDatastoreBatchWriter.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/BaseDatastoreBatchWriter.java @@ -131,17 +131,65 @@ public final void update(Entity... entities) { } } - @SafeVarargs + private void putInternal(FullEntity entity) { + Key key = entity.key(); + toAdd.remove(key); + toUpdate.remove(key); + toDelete.remove(key); + toPut.put(key, entity); + } + @Override - public final void put(Entity... entities) { + public final Entity put(FullEntity entity) { + return DatastoreHelper.put(this, entity); + } + + @SuppressWarnings("unchecked") + @Override + public final void putWithDeferredIdAllocation(FullEntity... entities) { validateActive(); - for (Entity entity : entities) { - Key key = entity.key(); - toAdd.remove(key); - toUpdate.remove(key); - toDelete.remove(key); - toPut.put(key, entity); + for (FullEntity entity : entities) { + IncompleteKey key = entity.key(); + Preconditions.checkArgument(key != null, "Entity must have a key"); + if (key instanceof Key) { + putInternal(Entity.convert((FullEntity) entity)); + } else { + toAddAutoId.add((FullEntity) entity); + } + } + } + + @SuppressWarnings("unchecked") + @Override + public final List put(FullEntity... entities) { + validateActive(); + List incompleteKeys = Lists.newArrayListWithExpectedSize(entities.length); + for (FullEntity entity : entities) { + IncompleteKey key = entity.key(); + Preconditions.checkArgument(key != null, "Entity must have a key"); + if (!(key instanceof Key)) { + incompleteKeys.add(key); + } } + Iterator allocated; + if (!incompleteKeys.isEmpty()) { + IncompleteKey[] toAllocate = Iterables.toArray(incompleteKeys, IncompleteKey.class); + allocated = datastore().allocateId(toAllocate).iterator(); + } else { + allocated = Collections.emptyIterator(); + } + List answer = Lists.newArrayListWithExpectedSize(entities.length); + for (FullEntity entity : entities) { + if (entity.key() instanceof Key) { + putInternal((FullEntity) entity); + answer.add(Entity.convert((FullEntity) entity)); + } else { + Entity entityWithAllocatedId = Entity.builder(allocated.next(), entity).build(); + putInternal(entityWithAllocatedId); + answer.add(entityWithAllocatedId); + } + } + return answer; } @Override diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Datastore.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Datastore.java index 8b2afcb5ad0c..efc56d532751 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Datastore.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/Datastore.java @@ -77,28 +77,35 @@ interface TransactionCallable { * @throws DatastoreException upon failure * @see #allocateId(IncompleteKey) */ - List allocateId(IncompleteKey... key); + List allocateId(IncompleteKey... keys); /** * {@inheritDoc} * @throws DatastoreException upon failure */ @Override - void update(Entity... entity); + void update(Entity... entities); /** * {@inheritDoc} * @throws DatastoreException upon failure */ @Override - void put(Entity... entity); + Entity put(FullEntity entity); /** * {@inheritDoc} * @throws DatastoreException upon failure */ @Override - void delete(Key... key); + List put(FullEntity... entities); + + /** + * {@inheritDoc} + * @throws DatastoreException upon failure + */ + @Override + void delete(Key... keys); /** * Returns a new KeyFactory for this service diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreBatchWriter.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreBatchWriter.java index 918711aa2822..1c067a719585 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreBatchWriter.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreBatchWriter.java @@ -19,60 +19,72 @@ import java.util.List; /** - * An interface to represent a batch of write operations. - * All write operation for a batch writer will be applied to the Datastore in one RPC call. + * An interface to represent a batch of write operations. All write operation for a batch writer + * will be applied to the Datastore in one RPC call. */ interface DatastoreBatchWriter extends DatastoreWriter { /** - * Datastore add operation. - * This method will also allocate id for any entity with an incomplete key. - * As oppose to {@link #add(FullEntity)}, this method will defer any necessary id allocation + * Datastore add operation. This method will also allocate id for any entity with an incomplete + * key. As opposed to {@link #add(FullEntity)}, this method will defer any necessary id allocation * to submit time. * * @throws IllegalArgumentException if any of the given entities is missing a key - * @throws DatastoreException if a given entity with a - * complete key was already added to this writer or if not active + * @throws DatastoreException if a given entity with a complete key was already added to this + * writer or if not active */ - void addWithDeferredIdAllocation(FullEntity... entity); + void addWithDeferredIdAllocation(FullEntity... entities); /** * {@inheritDoc} * For entities with complete keys that were marked for deletion in this writer the operation * will be changed to {@link #put}. - * @throws DatastoreException if a given entity with the - * same complete key was already added to this writer, if writer is not active or - * if id allocation for an entity with an incomplete key failed. + * + * @throws DatastoreException if a given entity with the same complete key was already added to + * this writer, if writer is not active or if id allocation for an entity with an incomplete + * key failed. */ @Override - List add(FullEntity... entity); + List add(FullEntity... entities); /** * {@inheritDoc} * This operation will be converted to {@link #put} operation for entities that were already - * added or put in this writer - * @throws DatastoreException if an entity is marked for - * deletion in this writer or if not active + * added or put in this writer. + * + * @throws DatastoreException if an entity is marked for deletion in this writer or if not active */ @Override - void update(Entity... entity); + void update(Entity... entities); /** * {@inheritDoc} * This operation will also remove from this batch any prior writes for entities with the same - * keys + * keys + * * @throws DatastoreException if not active */ @Override - void delete(Key... key); + void delete(Key... keys); + + /** + * Datastore put operation. This method will also allocate id for any entity with an incomplete + * key. As opposed to {@link #put(FullEntity[])}, this method will defer any necessary id + * allocation to submit time. + * + * @throws IllegalArgumentException if any of the given entities is missing a key + * @throws DatastoreException if not active + */ + void putWithDeferredIdAllocation(FullEntity... entities); /** * {@inheritDoc} * This operation will also remove from this writer any prior writes for the same entities. + * * @throws DatastoreException if not active */ @Override - void put(Entity... entity); + List put(FullEntity... entities); /** * Returns {@code true} if still active (write operations were not sent to the Datastore). diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreHelper.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreHelper.java index 04b3e96c5175..655b1722b1ca 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreHelper.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreHelper.java @@ -51,6 +51,10 @@ static Entity add(DatastoreWriter writer, FullEntity entity) { return writer.add(new FullEntity[] {entity}).get(0); } + static Entity put(DatastoreWriter writer, FullEntity entity) { + return writer.put(new FullEntity[] {entity}).get(0); + } + static KeyFactory newKeyFactory(DatastoreOptions options) { return new KeyFactory(options.projectId(), options.namespace()); } diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java index 07ca76d2118f..69a6c72ce83f 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreImpl.java @@ -87,11 +87,12 @@ com.google.datastore.v1beta3.RunQueryResponse runQuery( try { return RetryHelper.runWithRetries( new Callable() { - @Override public com.google.datastore.v1beta3.RunQueryResponse call() - throws DatastoreException { - return datastoreRpc.runQuery(requestPb); - } - }, retryParams, EXCEPTION_HANDLER, options().clock()); + @Override + public com.google.datastore.v1beta3.RunQueryResponse call() + throws DatastoreException { + return datastoreRpc.runQuery(requestPb); + } + }, retryParams, EXCEPTION_HANDLER, options().clock()); } catch (RetryHelperException e) { throw DatastoreException.translateAndThrow(e); } @@ -125,11 +126,12 @@ com.google.datastore.v1beta3.AllocateIdsResponse allocateIds( try { return RetryHelper.runWithRetries( new Callable() { - @Override public com.google.datastore.v1beta3.AllocateIdsResponse call() - throws DatastoreException { - return datastoreRpc.allocateIds(requestPb); - } - }, retryParams, EXCEPTION_HANDLER, options().clock()); + @Override + public com.google.datastore.v1beta3.AllocateIdsResponse call() + throws DatastoreException { + return datastoreRpc.allocateIds(requestPb); + } + }, retryParams, EXCEPTION_HANDLER, options().clock()); } catch (RetryHelperException e) { throw DatastoreException.translateAndThrow(e); } @@ -166,7 +168,7 @@ public List add(FullEntity... entities) { "Duplicate entity with the key %s", entity.key()); } } else { - Preconditions.checkArgument(entity.hasKey(), "entity %s is missing a key", entity); + Preconditions.checkArgument(entity.hasKey(), "Entity %s is missing a key", entity); } mutationsPb.add(com.google.datastore.v1beta3.Mutation.newBuilder() .setInsert(entity.toPb()).build()); @@ -281,19 +283,19 @@ com.google.datastore.v1beta3.LookupResponse lookup( try { return RetryHelper.runWithRetries( new Callable() { - @Override public com.google.datastore.v1beta3.LookupResponse call() - throws DatastoreException { - return datastoreRpc.lookup(requestPb); - } - }, retryParams, EXCEPTION_HANDLER, options().clock()); + @Override + public com.google.datastore.v1beta3.LookupResponse call() + throws DatastoreException { + return datastoreRpc.lookup(requestPb); + } + }, retryParams, EXCEPTION_HANDLER, options().clock()); } catch (RetryHelperException e) { throw DatastoreException.translateAndThrow(e); } } - @SafeVarargs @Override - public final void update(Entity... entities) { + public void update(Entity... entities) { if (entities.length > 0) { List mutationsPb = new ArrayList<>(); @@ -309,22 +311,47 @@ public final void update(Entity... entities) { } } - @SafeVarargs @Override - public final void put(Entity... entities) { - if (entities.length > 0) { - List mutationsPb = - new ArrayList<>(); - Map dedupEntities = new LinkedHashMap<>(); - for (Entity entity : entities) { - dedupEntities.put(entity.key(), entity); - } - for (Entity e : dedupEntities.values()) { + public Entity put(FullEntity entity) { + return DatastoreHelper.put(this, entity); + } + + @SuppressWarnings("unchecked") + @Override + public List put(FullEntity... entities) { + if (entities.length == 0) { + return Collections.emptyList(); + } + List mutationsPb = new ArrayList<>(); + Map dedupEntities = new LinkedHashMap<>(); + for (FullEntity entity : entities) { + Preconditions.checkArgument(entity.hasKey(), "Entity %s is missing a key", entity); + if (entity.key() instanceof Key) { + Entity completeEntity = Entity.convert((FullEntity) entity); + dedupEntities.put(completeEntity.key(), completeEntity); + } else { mutationsPb.add( - com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(e.toPb()).build()); + com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(entity.toPb()).build()); + } + } + for (Entity entity : dedupEntities.values()) { + mutationsPb.add( + com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(entity.toPb()).build()); + } + com.google.datastore.v1beta3.CommitResponse commitResponse = commitMutation(mutationsPb); + Iterator mutationResults = + commitResponse.getMutationResultsList().iterator(); + ImmutableList.Builder responseBuilder = ImmutableList.builder(); + for (FullEntity entity : entities) { + Entity completeEntity = dedupEntities.get(entity.key()); + if (completeEntity != null) { + responseBuilder.add(completeEntity); + } else { + responseBuilder.add( + Entity.builder(Key.fromPb(mutationResults.next().getKey()), entity).build()); } - commitMutation(mutationsPb); } + return responseBuilder.build(); } @Override diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreReader.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreReader.java index e3989f29ef8b..156203103d03 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreReader.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreReader.java @@ -40,7 +40,7 @@ public interface DatastoreReader { * @throws DatastoreException upon failure * @see #get(Key) */ - Iterator get(Key... key); + Iterator get(Key... keys); /** * Returns a list with a value for each given key (ordered by input). {@code null} values are diff --git a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreWriter.java b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreWriter.java index 2771bb39ea60..0c66149c2e2b 100644 --- a/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreWriter.java +++ b/gcloud-java-datastore/src/main/java/com/google/cloud/datastore/DatastoreWriter.java @@ -24,8 +24,7 @@ public interface DatastoreWriter { /** - * Datastore add operation. - * This method will automatically allocate an id if necessary. + * Datastore add operation. This method will automatically allocate an id if necessary. * * @param entity the entity to add * @return an {@code Entity} with the same properties and a key that is either newly allocated @@ -36,8 +35,8 @@ public interface DatastoreWriter { Entity add(FullEntity entity); /** - * Datastore add operation. - * This method will automatically allocate id for any entity with an incomplete key. + * Datastore add operation. This method will automatically allocate id for any entity with an + * incomplete key. * * @return a list of {@code Entity} ordered by input with the same properties and a key that * is either newly allocated or the same one if was already complete @@ -45,23 +44,39 @@ public interface DatastoreWriter { * @throws IllegalArgumentException if any of the given entities is missing a key * @see #add(FullEntity) */ - List add(FullEntity... entity); + List add(FullEntity... entities); /** - * A Datastore update operation. - * The operation will fail if an entity with the same key does not already exist. + * A Datastore update operation. The operation will fail if an entity with the same key does not + * already exist. */ - void update(Entity... entity); + void update(Entity... entities); /** - * A Datastore put (a.k.a upsert) operation. - * The operation will add or modify the entities. + * A Datastore put (a.k.a upsert) operation. This method will automatically allocate an id if + * necessary. + * + * @param entity the entity to put + * @return an {@code Entity} with the same properties and a key that is either newly allocated + * or the same one if key is already complete + * @throws DatastoreException upon failure + * @throws IllegalArgumentException if the given entity is missing a key + */ + Entity put(FullEntity entity); + + /** + * A Datastore put (a.k.a upsert) operation. This method will automatically allocate id for any + * entity with an incomplete key. + * + * @return a list of updated or inserted {@code Entity}, ordered by input. Returned keys are + * either newly allocated or the same one if was already complete. + * @throws DatastoreException upon failure + * @throws IllegalArgumentException if any of the given entities is missing a key */ - void put(Entity... entity); + List put(FullEntity... entities); /** - * A datastore delete operation. - * It is OK request a deletion of a non-existing entity. + * A datastore delete operation. It is OK request a deletion of a non-existing entity. */ - void delete(Key... key); + void delete(Key... keys); } diff --git a/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/BaseDatastoreBatchWriterTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/BaseDatastoreBatchWriterTest.java index 6a30314082b7..9fc7fb0a6dc2 100644 --- a/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/BaseDatastoreBatchWriterTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/BaseDatastoreBatchWriterTest.java @@ -211,8 +211,44 @@ public void testPut() throws Exception { pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(ENTITY1.toPb()).build()); pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(ENTITY2.toPb()).build()); pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(ENTITY3.toPb()).build()); - batchWriter.put(ENTITY1, ENTITY2); - batchWriter.put(ENTITY3); + List putEntities = batchWriter.put(ENTITY1, ENTITY2); + Entity putEntity = batchWriter.put(ENTITY3); + assertEquals(ENTITY1, putEntities.get(0)); + assertEquals(ENTITY2, putEntities.get(1)); + assertEquals(ENTITY3, putEntity); + assertEquals(pbs, batchWriter.toMutationPbList()); + } + + @Test + public void testPutIncompleteKey() throws Exception { + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(ENTITY1.toPb()).build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder() + .setUpsert(Entity.builder(KEY2, INCOMPLETE_ENTITY_1).build().toPb()) + .build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder() + .setUpsert(Entity.builder(KEY3, INCOMPLETE_ENTITY_2).build().toPb()) + .build()); + Entity putEntity = batchWriter.put(ENTITY1); + List putEntities = batchWriter.put(INCOMPLETE_ENTITY_1, INCOMPLETE_ENTITY_2); + assertEquals(ENTITY1, putEntity); + assertEquals(Entity.builder(KEY2, INCOMPLETE_ENTITY_1).build(), putEntities.get(0)); + assertEquals(Entity.builder(KEY3, INCOMPLETE_ENTITY_2).build(), putEntities.get(1)); + assertEquals(pbs, batchWriter.toMutationPbList()); + } + + @Test + public void testPutWithDeferredAllocation() throws Exception { + List pbs = new LinkedList<>(); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder() + .setInsert(INCOMPLETE_ENTITY_1.toPb()) + .build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder() + .setInsert(INCOMPLETE_ENTITY_2.toPb()) + .build()); + pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(ENTITY1.toPb()).build()); + batchWriter.put(ENTITY1); + batchWriter.putWithDeferredIdAllocation(INCOMPLETE_ENTITY_1, INCOMPLETE_ENTITY_2); assertEquals(pbs, batchWriter.toMutationPbList()); } @@ -221,8 +257,10 @@ public void testPutAfterPut() throws Exception { Entity entity = Entity.builder(ENTITY1).set("foo", "bar").build(); List pbs = new LinkedList<>(); pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(entity.toPb()).build()); - batchWriter.put(ENTITY1); - batchWriter.put(entity); + Entity putEntity1 = batchWriter.put(ENTITY1); + Entity putEntity2 = batchWriter.put(entity); + assertEquals(ENTITY1, putEntity1); + assertEquals(entity, putEntity2); assertEquals(pbs, batchWriter.toMutationPbList()); } @@ -242,7 +280,8 @@ public void testPutAfterUpdate() throws Exception { List pbs = new LinkedList<>(); pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(entity.toPb()).build()); batchWriter.update(ENTITY1); - batchWriter.put(entity); + Entity putEntity = batchWriter.put(entity); + assertEquals(entity, putEntity); assertEquals(pbs, batchWriter.toMutationPbList()); } @@ -252,7 +291,8 @@ public void testPutAfterDelete() throws Exception { List pbs = new LinkedList<>(); pbs.add(com.google.datastore.v1beta3.Mutation.newBuilder().setUpsert(entity.toPb()).build()); batchWriter.delete(KEY1); - batchWriter.put(entity); + Entity putEntity = batchWriter.put(entity); + assertEquals(entity, putEntity); assertEquals(pbs, batchWriter.toMutationPbList()); } diff --git a/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java index d73d6964e064..75a4d00883d5 100644 --- a/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java +++ b/gcloud-java-datastore/src/test/java/com/google/cloud/datastore/DatastoreTest.java @@ -903,21 +903,23 @@ public void testUpdate() { @Test public void testPut() { - Iterator keys = - datastore.fetch(ENTITY1.key(), ENTITY2.key(), ENTITY3.key()).iterator(); - assertEquals(ENTITY1, keys.next()); - assertEquals(ENTITY2, keys.next()); - assertNull(keys.next()); - assertFalse(keys.hasNext()); + Entity updatedEntity = Entity.builder(ENTITY1).set("new_property", 42L).build(); + assertEquals(updatedEntity, datastore.put(updatedEntity)); + assertEquals(updatedEntity, datastore.get(updatedEntity.key())); Entity entity2 = Entity.builder(ENTITY2).clear().set("bla", new NullValue()).build(); assertNotEquals(ENTITY2, entity2); - datastore.put(ENTITY3, ENTITY1, entity2); - keys = datastore.fetch(ENTITY1.key(), ENTITY2.key(), ENTITY3.key()).iterator(); - assertEquals(ENTITY1, keys.next()); - assertEquals(entity2, keys.next()); - assertEquals(ENTITY3, keys.next()); - assertFalse(keys.hasNext()); + List entities = datastore.put(ENTITY1, entity2, ENTITY3, PARTIAL_ENTITY1); + assertEquals(ENTITY1, entities.get(0)); + assertEquals(entity2, entities.get(1)); + assertEquals(ENTITY3, entities.get(2)); + assertEquals(PARTIAL_ENTITY1.properties(), entities.get(3).properties()); + assertEquals(PARTIAL_ENTITY1.key().ancestors(), entities.get(3).key().ancestors()); + assertEquals(ENTITY1, datastore.get(ENTITY1.key())); + assertEquals(entity2, datastore.get(entity2.key())); + assertEquals(ENTITY3, datastore.get(ENTITY3.key())); + Entity entity = datastore.get(entities.get(3).key()); + assertEquals(entities.get(3), entity); } @Test From f176d81b67ff585b3784921d4dcd28a502fafeea Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 8 Jun 2016 18:11:02 +0200 Subject: [PATCH 369/375] Extend StorageExample to show how to add ACLs to blobs and buckets (#1033) --- .../examples/storage/StorageExample.java | 257 +++++++++++++++++- 1 file changed, 254 insertions(+), 3 deletions(-) diff --git a/gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/StorageExample.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/StorageExample.java index 1a6aafa60e9d..d8273e65797d 100644 --- a/gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/StorageExample.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/storage/StorageExample.java @@ -20,6 +20,7 @@ import com.google.cloud.AuthCredentials.ServiceAccountAuthCredentials; import com.google.cloud.ReadChannel; import com.google.cloud.WriteChannel; +import com.google.cloud.storage.Acl; import com.google.cloud.storage.Blob; import com.google.cloud.storage.BlobId; import com.google.cloud.storage.BlobInfo; @@ -30,7 +31,9 @@ import com.google.cloud.storage.Storage.CopyRequest; import com.google.cloud.storage.Storage.SignUrlOption; import com.google.cloud.storage.StorageOptions; +import com.google.cloud.storage.spi.StorageRpc; import com.google.cloud.storage.spi.StorageRpc.Tuple; +import com.google.common.collect.ImmutableMap; import java.io.FileOutputStream; import java.io.IOException; @@ -51,6 +54,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -75,7 +79,11 @@ * cp | * compose + | * update_metadata [key=value]* | - * sign_url "} + * sign_url | + * add-acl domain ? OWNER|READER|WRITER | + * add-acl project ? :(OWNERS|EDITORS|VIEWERS) OWNER|READER|WRITER | + * add-acl user ? |allUsers|allAuthenticatedUsers OWNER|READER|WRITER | + * add-acl group ? OWNER|READER|WRITER"} * * * @@ -87,6 +95,7 @@ public class StorageExample { private static final Map ACTIONS = new HashMap<>(); + private static final Map ACL_ACTIONS = new HashMap<>(); private abstract static class StorageAction { @@ -119,6 +128,48 @@ public String params() { } } + private static class ParentAction extends StorageAction> { + + private final Map subActions; + + ParentAction(Map subActions) { + this.subActions = ImmutableMap.copyOf(subActions); + } + + @Override + @SuppressWarnings("unchecked") + void run(Storage storage, StorageRpc.Tuple subaction) throws Exception { + subaction.x().run(storage, subaction.y()); + } + + @Override + StorageRpc.Tuple parse(String... args) throws Exception { + if (args.length >= 1) { + StorageAction action = subActions.get(args[0]); + if (action != null) { + Object actionArguments = action.parse(Arrays.copyOfRange(args, 1, args.length)); + return StorageRpc.Tuple.of(action, actionArguments); + } else { + throw new IllegalArgumentException("Unrecognized entity '" + args[0] + "'."); + } + } + throw new IllegalArgumentException("Missing required entity."); + } + + @Override + public String params() { + StringBuilder builder = new StringBuilder(); + for (Map.Entry entry : subActions.entrySet()) { + builder.append('\n').append(entry.getKey()); + String param = entry.getValue().params(); + if (param != null && !param.isEmpty()) { + builder.append(' ').append(param); + } + } + return builder.toString(); + } + } + /** * This class demonstrates how to retrieve Bucket or Blob metadata. * If more than one blob is supplied a Batch operation would be used to get all blobs metadata @@ -127,6 +178,12 @@ public String params() { * @see Objects: get */ private static class InfoAction extends BlobsAction { + + /** + * Gets information for the provided blobs, using the {@code storage} service. If + * {@code blobIds} contains only one blob identity and {@code blobIds[0].name()} is empty, this + * method gets information for the bucket identified by {@code blobIds[0].bucket()}. + */ @Override public void run(Storage storage, BlobId... blobIds) { if (blobIds.length == 1) { @@ -512,6 +569,194 @@ public String params() { } } + private abstract static class AclAction extends StorageAction> { + + /** + * Sets the ACL according to the provided {@code params}, using the {@code storage} service. If + * {@code params.x()} returns a complete blob identity, the {@code params.y()} ACL is added to + * the blob. If {@code params.x().name()} is empty, the {@code params.y()} ACL is added to the + * bucket identified by {@code params.x().bucket()}. + */ + @Override + public void run(Storage storage, Tuple params) { + BlobId blobId = params.x(); + Acl acl = params.y(); + if (blobId.name().isEmpty()) { + Bucket bucket = storage.get(blobId.bucket()); + if (bucket == null) { + System.out.printf("Bucket %s does not exist%n", blobId.bucket()); + return; + } + bucket.toBuilder().acl(addAcl(bucket.acl(), acl)).build().update(); + System.out.printf("Added ACL %s to bucket %s%n", acl, blobId.bucket()); + } else { + Blob blob = storage.get(blobId); + if (blob == null) { + System.out.printf("Blob %s does not exist%n", blobId); + return; + } + blob.toBuilder().acl(addAcl(blob.acl(), acl)).build().update(); + System.out.printf("Added ACL %s to blob %s%n", acl, blobId); + } + } + + private static List addAcl(List acls, Acl newAcl) { + List newAcls = new LinkedList<>(acls); + newAcls.add(newAcl); + return newAcls; + } + } + + /** + * This class demonstrates how to add an ACL to a blob or a bucket for a group of users + * (identified by the group's email). + * + * @see Access + * Control Lists (ACLs) + */ + private static class AddGroupAclAction extends AclAction { + + @Override + Tuple parse(String... args) { + if (args.length >= 3) { + BlobId blob; + int nextArg; + if (args.length == 3) { + blob = BlobId.of(args[0], ""); + nextArg = 1; + } else if (args.length == 4) { + blob = BlobId.of(args[0], args[1]); + nextArg = 2; + } else { + throw new IllegalArgumentException("Too many arguments."); + } + String group = args[nextArg++]; + Acl.Role role = Acl.Role.valueOf(args[nextArg]); + return Tuple.of(blob, Acl.of(new Acl.Group(group), role)); + } + throw new IllegalArgumentException("Missing required bucket, groupEmail or role arguments."); + } + + @Override + public String params() { + return " ? OWNER|READER|WRITER"; + } + } + + /** + * This class demonstrates how to add an ACL to a blob or a bucket for a domain. + * + * @see Access + * Control Lists (ACLs) + */ + private static class AddDomainAclAction extends AclAction { + + @Override + Tuple parse(String... args) { + if (args.length >= 3) { + BlobId blob; + int nextArg; + if (args.length == 3) { + blob = BlobId.of(args[0], ""); + nextArg = 1; + } else if (args.length == 4) { + blob = BlobId.of(args[0], args[1]); + nextArg = 2; + } else { + throw new IllegalArgumentException("Too many arguments."); + } + String domain = args[nextArg++]; + Acl.Role role = Acl.Role.valueOf(args[nextArg]); + return Tuple.of(blob, Acl.of(new Acl.Domain(domain), role)); + } + throw new IllegalArgumentException("Missing required bucket, domain or role arguments."); + } + + @Override + public String params() { + return " ? OWNER|READER|WRITER"; + } + } + + /** + * This class demonstrates how to add an ACL to a blob or a bucket for either a user (if an email + * is provided), all users (if {@code allUsers} is provided), or all authenticated users (if + * {@code allAuthenticatedUsers} is provided). + * + * @see Access + * Control Lists (ACLs) + */ + private static class AddUserAclAction extends AclAction { + + @Override + Tuple parse(String... args) { + if (args.length >= 3) { + BlobId blob; + int nextArg; + if (args.length == 3) { + blob = BlobId.of(args[0], ""); + nextArg = 1; + } else if (args.length == 4) { + blob = BlobId.of(args[0], args[1]); + nextArg = 2; + } else { + throw new IllegalArgumentException("Too many arguments."); + } + String user = args[nextArg++]; + Acl.Role role = Acl.Role.valueOf(args[nextArg]); + return Tuple.of(blob, Acl.of(new Acl.User(user), role)); + } + throw new IllegalArgumentException("Missing required bucket, userEmail or role arguments."); + } + + @Override + public String params() { + return " ? |allUsers|allAuthenticatedUsers OWNER|READER|WRITER"; + } + } + + /** + * This class demonstrates how to add an ACL to a blob or a bucket for all users that have a + * specific role in a provided project. + * + * @see Access + * Control Lists (ACLs) + */ + private static class AddProjectAclAction extends AclAction { + + @Override + Tuple parse(String... args) { + if (args.length >= 3) { + BlobId blob; + int nextArg; + if (args.length == 3) { + blob = BlobId.of(args[0], ""); + nextArg = 1; + } else if (args.length == 4) { + blob = BlobId.of(args[0], args[1]); + nextArg = 2; + } else { + throw new IllegalArgumentException("Too many arguments."); + } + String[] projectAndRole = args[nextArg++].split(":"); + if (projectAndRole.length != 2) { + throw new IllegalArgumentException( + "Project entity must be specified as :(OWNERS|READERS|WRITERS)"); + } else { + Acl.Project.ProjectRole projectRole = Acl.Project.ProjectRole.valueOf(projectAndRole[1]); + Acl.Role role = Acl.Role.valueOf(args[nextArg]); + return Tuple.of(blob, Acl.of(new Acl.Project(projectRole, projectAndRole[0]), role)); + } + } + throw new IllegalArgumentException("Missing required bucket, project or role arguments."); + } + + @Override + public String params() { + return " ? :(OWNERS|EDITORS|VIEWERS) OWNER|READER|WRITER"; + } + } + static { ACTIONS.put("info", new InfoAction()); ACTIONS.put("delete", new DeleteAction()); @@ -522,6 +767,11 @@ public String params() { ACTIONS.put("compose", new ComposeAction()); ACTIONS.put("update_metadata", new UpdateMetadataAction()); ACTIONS.put("sign_url", new SignUrlAction()); + ACL_ACTIONS.put("group", new AddGroupAclAction()); + ACL_ACTIONS.put("domain", new AddDomainAclAction()); + ACL_ACTIONS.put("user", new AddUserAclAction()); + ACL_ACTIONS.put("project", new AddProjectAclAction()); + ACTIONS.put("add-acl", new ParentAction(ACL_ACTIONS)); } private static void printUsage() { @@ -531,10 +781,11 @@ private static void printUsage() { String param = entry.getValue().params(); if (param != null && !param.isEmpty()) { - actionAndParams.append(' ').append(param); + // Add extra padding for multi-line action + actionAndParams.append(' ').append(param.replace("\n", "\n\t\t")); } } - System.out.printf("Usage: %s [] operation *%s%n", + System.out.printf("Usage: %s [] operation [entity] *%s%n", StorageExample.class.getSimpleName(), actionAndParams); } From 3b35a9ed52201555115144706ed9016dc7dc7549 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 9 Jun 2016 14:57:17 +0200 Subject: [PATCH 370/375] Add whenDone method and CompletionCallback to Job and Operation (#1016) --- README.md | 17 +- .../java/com/google/cloud/bigquery/Job.java | 62 +++- .../google/cloud/bigquery/package-info.java | 4 +- .../com/google/cloud/bigquery/JobTest.java | 117 ++++++- .../cloud/bigquery/it/ITBigQueryTest.java | 36 +- gcloud-java-compute/README.md | 18 +- .../com/google/cloud/compute/Operation.java | 70 +++- .../google/cloud/compute/package-info.java | 12 +- .../google/cloud/compute/OperationTest.java | 135 +++++++- .../cloud/compute/it/ITComputeTest.java | 308 +++++------------- .../java/com/google/cloud/WaitForOption.java | 225 +++++++++++++ .../com/google/cloud/SerializationTest.java | 5 +- .../com/google/cloud/WaitForOptionTest.java | 124 +++++++ .../examples/bigquery/BigQueryExample.java | 1 + .../snippets/CreateTableAndLoadData.java | 8 +- .../CreateAddressDiskAndInstance.java | 22 +- .../compute/snippets/CreateInstance.java | 8 +- .../compute/snippets/CreateSnapshot.java | 10 +- 18 files changed, 852 insertions(+), 330 deletions(-) create mode 100644 gcloud-java-core/src/main/java/com/google/cloud/WaitForOption.java create mode 100644 gcloud-java-core/src/test/java/com/google/cloud/WaitForOptionTest.java diff --git a/README.md b/README.md index 76dff042d27d..f851112f415a 100644 --- a/README.md +++ b/README.md @@ -173,9 +173,7 @@ if (table == null) { } System.out.println("Loading data into table " + tableId); Job loadJob = table.load(FormatOptions.csv(), "gs://bucket/path"); -while (!loadJob.isDone()) { - Thread.sleep(1000L); -} +loadJob = loadJob.waitFor(); if (loadJob.status().error() != null) { System.out.println("Job completed with errors"); } else { @@ -203,7 +201,6 @@ import com.google.cloud.compute.Compute; import com.google.cloud.compute.ComputeOptions; import com.google.cloud.compute.Disk; import com.google.cloud.compute.DiskId; -import com.google.cloud.compute.Operation; import com.google.cloud.compute.Snapshot; Compute compute = ComputeOptions.defaultInstance().service(); @@ -212,12 +209,10 @@ Disk disk = compute.getDisk(diskId, Compute.DiskOption.fields()); if (disk != null) { String snapshotName = "disk-name-snapshot"; Operation operation = disk.createSnapshot(snapshotName); - while (!operation.isDone()) { - Thread.sleep(1000L); - } + operation = operation.waitFor(); if (operation.errors() == null) { // use snapshot - Snapshot snapshot = compute.getSnapshot("disk-name-snapshot"); + Snapshot snapshot = compute.getSnapshot(snapshotName); } } ``` @@ -234,8 +229,6 @@ import com.google.cloud.compute.InstanceId; import com.google.cloud.compute.InstanceInfo; import com.google.cloud.compute.MachineTypeId; import com.google.cloud.compute.NetworkId; -import com.google.cloud.compute.NetworkInterface; -import com.google.cloud.compute.Operation; Compute compute = ComputeOptions.defaultInstance().service(); ImageId imageId = ImageId.of("debian-cloud", "debian-8-jessie-v20160329"); @@ -246,9 +239,7 @@ InstanceId instanceId = InstanceId.of("us-central1-a", "instance-name"); MachineTypeId machineTypeId = MachineTypeId.of("us-central1-a", "n1-standard-1"); Operation operation = compute.create(InstanceInfo.of(instanceId, machineTypeId, attachedDisk, networkInterface)); -while (!operation.isDone()) { - Thread.sleep(1000L); -} +operation = operation.waitFor(); if (operation.errors() == null) { // use instance Instance instance = compute.getInstance(instanceId); diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Job.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Job.java index bfcca5b5388a..df0849d4b6f4 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Job.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Job.java @@ -18,9 +18,16 @@ import static com.google.common.base.Preconditions.checkNotNull; +import com.google.cloud.Clock; +import com.google.cloud.WaitForOption; +import com.google.cloud.WaitForOption.CheckingPeriod; +import com.google.cloud.WaitForOption.Timeout; + import java.io.IOException; import java.io.ObjectInputStream; import java.util.Objects; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; /** * A Google BigQuery Job. @@ -143,6 +150,59 @@ public boolean isDone() { return job == null || job.status().state() == JobStatus.State.DONE; } + /** + * Blocks until this job completes its execution, either failing or succeeding. This method + * returns current job's latest information. If the job no longer exists, this method returns + * {@code null}. By default, the job status is checked every 500 milliseconds, to configure this + * value use {@link WaitForOption#checkEvery(long, TimeUnit)}. Use + * {@link WaitForOption#timeout(long, TimeUnit)} to set the maximum time to wait. + * + *

    Example usage of {@code waitFor()}: + *

     {@code
    +   * Job completedJob = job.waitFor();
    +   * if (completedJob == null) {
    +   *   // job no longer exists
    +   * } else if (completedJob.status().error() != null) {
    +   *   // job failed, handle error
    +   * } else {
    +   *   // job completed successfully
    +   * }}
    + * + *

    Example usage of {@code waitFor()} with checking period and timeout: + *

     {@code
    +   * Job completedJob = job.waitFor(WaitForOption.checkEvery(1, TimeUnit.SECONDS),
    +   *     WaitForOption.timeout(60, TimeUnit.SECONDS));
    +   * if (completedJob == null) {
    +   *   // job no longer exists
    +   * } else if (completedJob.status().error() != null) {
    +   *   // job failed, handle error
    +   * } else {
    +   *   // job completed successfully
    +   * }}
    + * + * @param waitOptions options to configure checking period and timeout + * @throws BigQueryException upon failure + * @throws InterruptedException if the current thread gets interrupted while waiting for the job + * to complete + * @throws TimeoutException if the timeout provided with + * {@link WaitForOption#timeout(long, TimeUnit)} is exceeded. If no such option is provided + * this exception is never thrown. + */ + public Job waitFor(WaitForOption... waitOptions) throws InterruptedException, TimeoutException { + Timeout timeout = Timeout.getOrDefault(waitOptions); + CheckingPeriod checkingPeriod = CheckingPeriod.getOrDefault(waitOptions); + long timeoutMillis = timeout.timeoutMillis(); + Clock clock = options.clock(); + long startTime = clock.millis(); + while (!isDone()) { + if (timeoutMillis != -1 && (clock.millis() - startTime) >= timeoutMillis) { + throw new TimeoutException(); + } + checkingPeriod.sleep(); + } + return reload(); + } + /** * Fetches current job's latest information. Returns {@code null} if the job does not exist. * @@ -151,7 +211,7 @@ public boolean isDone() { * @throws BigQueryException upon failure */ public Job reload(BigQuery.JobOption... options) { - return bigquery.getJob(jobId().job(), options); + return bigquery.getJob(jobId(), options); } /** diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/package-info.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/package-info.java index a701b82c1c2c..3b4d392d26dc 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/package-info.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/package-info.java @@ -33,9 +33,7 @@ * } * System.out.println("Loading data into table " + tableId); * Job loadJob = table.load(FormatOptions.csv(), "gs://bucket/path"); - * while (!loadJob.isDone()) { - * Thread.sleep(1000L); - * } + * loadJob = loadJob.waitFor(); * if (loadJob.status().error() != null) { * System.out.println("Job completed with errors"); * } else { diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobTest.java index 44e5e201e95c..fb47b54428c0 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/JobTest.java @@ -27,10 +27,18 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import com.google.cloud.Clock; +import com.google.cloud.WaitForOption; import com.google.cloud.bigquery.JobStatistics.CopyStatistics; +import org.easymock.EasyMock; import org.junit.After; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; public class JobTest { @@ -66,6 +74,9 @@ public class JobTest { private Job expectedJob; private Job job; + @Rule + public final ExpectedException thrown = ExpectedException.none(); + private void initializeExpectedJob(int optionsCalls) { expect(serviceMockReturnsOptions.options()).andReturn(mockOptions).times(optionsCalls); replay(serviceMockReturnsOptions); @@ -177,13 +188,113 @@ public void testIsDone_NotExists() throws Exception { assertTrue(job.isDone()); } + @Test + public void testWaitFor() throws InterruptedException, TimeoutException { + initializeExpectedJob(2); + BigQuery.JobOption[] expectedOptions = {BigQuery.JobOption.fields(BigQuery.JobField.STATUS)}; + JobStatus status = createStrictMock(JobStatus.class); + expect(status.state()).andReturn(JobStatus.State.DONE); + expect(bigquery.options()).andReturn(mockOptions); + expect(mockOptions.clock()).andReturn(Clock.defaultClock()); + Job completedJob = expectedJob.toBuilder().status(status).build(); + expect(bigquery.getJob(JOB_INFO.jobId(), expectedOptions)).andReturn(completedJob); + expect(bigquery.getJob(JOB_INFO.jobId())).andReturn(completedJob); + replay(status, bigquery, mockOptions); + initializeJob(); + assertSame(completedJob, job.waitFor()); + verify(status, mockOptions); + } + + @Test + public void testWaitFor_Null() throws InterruptedException, TimeoutException { + initializeExpectedJob(1); + BigQuery.JobOption[] expectedOptions = {BigQuery.JobOption.fields(BigQuery.JobField.STATUS)}; + expect(bigquery.options()).andReturn(mockOptions); + expect(mockOptions.clock()).andReturn(Clock.defaultClock()); + expect(bigquery.getJob(JOB_INFO.jobId(), expectedOptions)).andReturn(null); + expect(bigquery.getJob(JOB_INFO.jobId())).andReturn(null); + replay(bigquery, mockOptions); + initializeJob(); + assertNull(job.waitFor()); + verify(mockOptions); + } + + @Test + public void testWaitForWithCheckingPeriod() throws InterruptedException, TimeoutException { + initializeExpectedJob(3); + BigQuery.JobOption[] expectedOptions = {BigQuery.JobOption.fields(BigQuery.JobField.STATUS)}; + TimeUnit timeUnit = createStrictMock(TimeUnit.class); + timeUnit.sleep(42); + EasyMock.expectLastCall(); + JobStatus status = createStrictMock(JobStatus.class); + expect(status.state()).andReturn(JobStatus.State.RUNNING); + expect(status.state()).andReturn(JobStatus.State.DONE); + expect(bigquery.options()).andReturn(mockOptions); + expect(mockOptions.clock()).andReturn(Clock.defaultClock()); + Job runningJob = expectedJob.toBuilder().status(status).build(); + Job completedJob = expectedJob.toBuilder().status(status).build(); + expect(bigquery.getJob(JOB_INFO.jobId(), expectedOptions)).andReturn(runningJob); + expect(bigquery.getJob(JOB_INFO.jobId(), expectedOptions)).andReturn(completedJob); + expect(bigquery.getJob(JOB_INFO.jobId())).andReturn(completedJob); + replay(status, bigquery, timeUnit, mockOptions); + initializeJob(); + assertSame(completedJob, job.waitFor(WaitForOption.checkEvery(42, timeUnit))); + verify(status, timeUnit, mockOptions); + } + + @Test + public void testWaitForWithCheckingPeriod_Null() throws InterruptedException, TimeoutException { + initializeExpectedJob(2); + BigQuery.JobOption[] expectedOptions = {BigQuery.JobOption.fields(BigQuery.JobField.STATUS)}; + TimeUnit timeUnit = createStrictMock(TimeUnit.class); + timeUnit.sleep(42); + EasyMock.expectLastCall(); + expect(bigquery.options()).andReturn(mockOptions); + expect(mockOptions.clock()).andReturn(Clock.defaultClock()); + Job runningJob = expectedJob.toBuilder().status(new JobStatus(JobStatus.State.RUNNING)).build(); + expect(bigquery.getJob(JOB_INFO.jobId(), expectedOptions)).andReturn(runningJob); + expect(bigquery.getJob(JOB_INFO.jobId(), expectedOptions)).andReturn(null); + expect(bigquery.getJob(JOB_INFO.jobId())).andReturn(null); + replay(bigquery, timeUnit, mockOptions); + initializeJob(); + assertNull(job.waitFor(WaitForOption.checkEvery(42, timeUnit))); + verify(bigquery, timeUnit, mockOptions); + } + + @Test + public void testWaitForWithTimeout() throws InterruptedException, TimeoutException { + initializeExpectedJob(2); + BigQuery.JobOption[] expectedOptions = {BigQuery.JobOption.fields(BigQuery.JobField.STATUS)}; + TimeUnit timeUnit = createStrictMock(TimeUnit.class); + timeUnit.sleep(1); + EasyMock.expectLastCall(); + Clock clock = createStrictMock(Clock.class); + expect(clock.millis()).andReturn(0L); + expect(clock.millis()).andReturn(1L); + expect(clock.millis()).andReturn(3L); + JobStatus status = createStrictMock(JobStatus.class); + expect(status.state()).andReturn(JobStatus.State.RUNNING); + expect(status.state()).andReturn(JobStatus.State.RUNNING); + expect(bigquery.options()).andReturn(mockOptions); + expect(mockOptions.clock()).andReturn(clock); + Job runningJob = expectedJob.toBuilder().status(status).build(); + expect(bigquery.getJob(JOB_INFO.jobId(), expectedOptions)).andReturn(runningJob); + expect(bigquery.getJob(JOB_INFO.jobId(), expectedOptions)).andReturn(runningJob); + replay(status, bigquery, timeUnit, clock, mockOptions); + initializeJob(); + thrown.expect(TimeoutException.class); + job.waitFor(WaitForOption.checkEvery(1, timeUnit), + WaitForOption.timeout(3, TimeUnit.MILLISECONDS)); + verify(status, timeUnit, clock, mockOptions); + } + @Test public void testReload() throws Exception { initializeExpectedJob(4); JobInfo updatedInfo = JOB_INFO.toBuilder().etag("etag").build(); Job expectedJob = new Job(serviceMockReturnsOptions, new JobInfo.BuilderImpl(updatedInfo)); expect(bigquery.options()).andReturn(mockOptions); - expect(bigquery.getJob(JOB_INFO.jobId().job())).andReturn(expectedJob); + expect(bigquery.getJob(JOB_INFO.jobId())).andReturn(expectedJob); replay(bigquery); initializeJob(); Job updatedJob = job.reload(); @@ -194,7 +305,7 @@ public void testReload() throws Exception { public void testReloadNull() throws Exception { initializeExpectedJob(1); expect(bigquery.options()).andReturn(mockOptions); - expect(bigquery.getJob(JOB_INFO.jobId().job())).andReturn(null); + expect(bigquery.getJob(JOB_INFO.jobId())).andReturn(null); replay(bigquery); initializeJob(); assertNull(job.reload()); @@ -206,7 +317,7 @@ public void testReloadWithOptions() throws Exception { JobInfo updatedInfo = JOB_INFO.toBuilder().etag("etag").build(); Job expectedJob = new Job(serviceMockReturnsOptions, new JobInfo.BuilderImpl(updatedInfo)); expect(bigquery.options()).andReturn(mockOptions); - expect(bigquery.getJob(JOB_INFO.jobId().job(), BigQuery.JobOption.fields())) + expect(bigquery.getJob(JOB_INFO.jobId(), BigQuery.JobOption.fields())) .andReturn(expectedJob); replay(bigquery); initializeJob(); diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java index 5007c73b69ce..dde170f87859 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java @@ -71,7 +71,6 @@ import org.junit.AfterClass; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.Timeout; @@ -83,6 +82,7 @@ import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.logging.Level; import java.util.logging.Logger; @@ -170,7 +170,7 @@ public class ITBigQueryTest { public Timeout globalTimeout = Timeout.seconds(300); @BeforeClass - public static void beforeClass() throws InterruptedException { + public static void beforeClass() throws InterruptedException, TimeoutException { RemoteBigQueryHelper bigqueryHelper = RemoteBigQueryHelper.create(); RemoteStorageHelper storageHelper = RemoteStorageHelper.create(); bigquery = bigqueryHelper.options().service(); @@ -188,9 +188,7 @@ public static void beforeClass() throws InterruptedException { .schema(TABLE_SCHEMA) .build(); Job job = bigquery.create(JobInfo.of(configuration)); - while (!job.isDone()) { - Thread.sleep(1000); - } + job = job.waitFor(); assertNull(job.status().error()); } @@ -786,7 +784,7 @@ public void testCreateAndGetJobWithSelectedFields() { } @Test - public void testCopyJob() throws InterruptedException { + public void testCopyJob() throws InterruptedException, TimeoutException { String sourceTableName = "test_copy_job_source_table"; String destinationTableName = "test_copy_job_destination_table"; TableId sourceTable = TableId.of(DATASET, sourceTableName); @@ -799,9 +797,7 @@ public void testCopyJob() throws InterruptedException { TableId destinationTable = TableId.of(DATASET, destinationTableName); CopyJobConfiguration configuration = CopyJobConfiguration.of(destinationTable, sourceTable); Job remoteJob = bigquery.create(JobInfo.of(configuration)); - while (!remoteJob.isDone()) { - Thread.sleep(1000); - } + remoteJob = remoteJob.waitFor(); assertNull(remoteJob.status().error()); Table remoteTable = bigquery.getTable(DATASET, destinationTableName); assertNotNull(remoteTable); @@ -813,7 +809,7 @@ public void testCopyJob() throws InterruptedException { } @Test - public void testQueryJob() throws InterruptedException { + public void testQueryJob() throws InterruptedException, TimeoutException { String tableName = "test_query_job_table"; String query = new StringBuilder() .append("SELECT TimestampField, StringField, BooleanField FROM ") @@ -825,9 +821,7 @@ public void testQueryJob() throws InterruptedException { .destinationTable(destinationTable) .build(); Job remoteJob = bigquery.create(JobInfo.of(configuration)); - while (!remoteJob.isDone()) { - Thread.sleep(1000); - } + remoteJob = remoteJob.waitFor(); assertNull(remoteJob.status().error()); QueryResponse response = bigquery.getQueryResults(remoteJob.jobId()); @@ -858,7 +852,7 @@ public void testQueryJob() throws InterruptedException { } @Test - public void testExtractJob() throws InterruptedException { + public void testExtractJob() throws InterruptedException, TimeoutException { String tableName = "test_export_job_table"; TableId destinationTable = TableId.of(DATASET, tableName); LoadJobConfiguration configuration = @@ -866,9 +860,7 @@ public void testExtractJob() throws InterruptedException { .schema(SIMPLE_SCHEMA) .build(); Job remoteLoadJob = bigquery.create(JobInfo.of(configuration)); - while (!remoteLoadJob.isDone()) { - Thread.sleep(1000); - } + remoteLoadJob = remoteLoadJob.waitFor(); assertNull(remoteLoadJob.status().error()); ExtractJobConfiguration extractConfiguration = @@ -876,9 +868,7 @@ public void testExtractJob() throws InterruptedException { .printHeader(false) .build(); Job remoteExtractJob = bigquery.create(JobInfo.of(extractConfiguration)); - while (!remoteExtractJob.isDone()) { - Thread.sleep(1000); - } + remoteExtractJob = remoteExtractJob.waitFor(); assertNull(remoteExtractJob.status().error()); assertEquals(CSV_CONTENT, new String(storage.readAllBytes(BUCKET, EXTRACT_FILE), StandardCharsets.UTF_8)); @@ -886,7 +876,7 @@ public void testExtractJob() throws InterruptedException { } @Test - public void testCancelJob() throws InterruptedException { + public void testCancelJob() throws InterruptedException, TimeoutException { String destinationTableName = "test_cancel_query_job_table"; String query = "SELECT TimestampField, StringField, BooleanField FROM " + TABLE_ID.table(); TableId destinationTable = TableId.of(DATASET, destinationTableName); @@ -896,9 +886,7 @@ public void testCancelJob() throws InterruptedException { .build(); Job remoteJob = bigquery.create(JobInfo.of(configuration)); assertTrue(remoteJob.cancel()); - while (!remoteJob.isDone()) { - Thread.sleep(1000); - } + remoteJob = remoteJob.waitFor(); assertNull(remoteJob.status().error()); } diff --git a/gcloud-java-compute/README.md b/gcloud-java-compute/README.md index 81d46fd1270d..19c0d56b5b41 100644 --- a/gcloud-java-compute/README.md +++ b/gcloud-java-compute/README.md @@ -114,10 +114,8 @@ succeeded: ```java RegionAddressId addressId = RegionAddressId.of("us-central1", "test-address"); Operation operation = compute.create(AddressInfo.of(addressId)); -while (!operation.isDone()) { - Thread.sleep(1000L); -} -operation = operation.reload(); +// Wait for operation to complete +operation = operation.waitFor(); if (operation.errors() == null) { System.out.println("Address " + addressId + " was successfully created"); } else { @@ -150,10 +148,8 @@ DiskId diskId = DiskId.of("us-central1-a", "test-disk"); ImageDiskConfiguration diskConfiguration = ImageDiskConfiguration.of(imageId); DiskInfo disk = DiskInfo.of(diskId, diskConfiguration); Operation operation = compute.create(disk); -while (!operation.isDone()) { - Thread.sleep(1000L); -} -operation = operation.reload(); +// Wait for operation to complete +operation = operation.waitFor(); if (operation.errors() == null) { System.out.println("Disk " + diskId + " was successfully created"); } else { @@ -198,10 +194,8 @@ MachineTypeId machineTypeId = MachineTypeId.of("us-central1-a", "n1-standard-1") InstanceInfo instance = InstanceInfo.of(instanceId, machineTypeId, attachedDisk, networkInterface); Operation operation = compute.create(instance); -while (!operation.isDone()) { - Thread.sleep(1000L); -} -operation = operation.reload(); +// Wait for operation to complete +operation = operation.waitFor(); if (operation.errors() == null) { System.out.println("Instance " + instanceId + " was successfully created"); } else { diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/Operation.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Operation.java index 326b681098a6..78752e9cdaeb 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/Operation.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/Operation.java @@ -18,6 +18,9 @@ import static com.google.common.base.Preconditions.checkNotNull; +import com.google.cloud.Clock; +import com.google.cloud.WaitForOption; +import com.google.cloud.WaitForOption.CheckingPeriod; import com.google.cloud.compute.Compute.OperationOption; import com.google.common.base.Function; import com.google.common.base.MoreObjects; @@ -36,13 +39,15 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; /** * Google Compute Engine operations. Operation identity can be obtained via {@link #operationId()}. * {@link #operationId()} returns {@link GlobalOperationId} for global operations, * {@link RegionOperationId} for region operations, and {@link ZoneOperationId} for zone operations. * To get an {@code Operation} object with the most recent information, use - * {@link #reload(OperationOption...)}. + * {@link #reload(Compute.OperationOption...)}. */ public class Operation implements Serializable { @@ -635,7 +640,7 @@ public String description() { * @return {@code true} if this operation exists, {@code false} otherwise * @throws ComputeException upon failure */ - public boolean exists() throws ComputeException { + public boolean exists() { return reload(OperationOption.fields()) != null; } @@ -652,12 +657,67 @@ public boolean exists() throws ComputeException { * not exist, {@code false} if the state is not {@link Operation.Status#DONE} * @throws ComputeException upon failure */ - public boolean isDone() throws ComputeException { + public boolean isDone() { Operation operation = compute.getOperation(operationId, OperationOption.fields(Compute.OperationField.STATUS)); return operation == null || operation.status() == Status.DONE; } + /** + * Blocks until this operation completes its execution, either failing or succeeding. This method + * returns current operation's latest information. If the operation no longer exists, this method + * returns {@code null}. By default, the operation status is checked every 500 milliseconds, to + * configure this value use {@link WaitForOption#checkEvery(long, TimeUnit)}. Use + * {@link WaitForOption#timeout(long, TimeUnit)} to set the maximum time to wait. + * + *

    Example usage of {@code waitFor()}: + *

     {@code
    +   * Operation completedOperation = operation.waitFor();
    +   * if (completedOperation == null) {
    +   *   // operation no longer exists
    +   * } else if (completedOperation.errors() != null) {
    +   *   // operation failed, handle error
    +   * } else {
    +   *   // operation completed successfully
    +   * }}
    + * + *

    Example usage of {@code waitFor()} with checking period and timeout: + *

     {@code
    +   * Operation completedOperation =
    +   *     operation.waitFor(WaitForOption.checkEvery(1, TimeUnit.SECONDS),
    +   *         WaitForOption.timeout(60, TimeUnit.SECONDS));
    +   * if (completedOperation == null) {
    +   *   // operation no longer exists
    +   * } else if (completedOperation.errors() != null) {
    +   *   // operation failed, handle error
    +   * } else {
    +   *   // operation completed successfully
    +   * }}
    + * + * @param waitOptions options to configure checking period and timeout + * @throws ComputeException upon failure + * @throws InterruptedException if the current thread gets interrupted while waiting for the + * operation to complete + * @throws TimeoutException if the timeout provided with + * {@link WaitForOption#timeout(long, TimeUnit)} is exceeded. If no such option is provided + * this exception is never thrown. + */ + public Operation waitFor(WaitForOption... waitOptions) + throws InterruptedException, TimeoutException { + WaitForOption.Timeout timeout = WaitForOption.Timeout.getOrDefault(waitOptions); + CheckingPeriod checkingPeriod = CheckingPeriod.getOrDefault(waitOptions); + long timeoutMillis = timeout.timeoutMillis(); + Clock clock = options.clock(); + long startTime = clock.millis(); + while (!isDone()) { + if (timeoutMillis != -1 && (clock.millis() - startTime) >= timeoutMillis) { + throw new TimeoutException(); + } + checkingPeriod.sleep(); + } + return reload(); + } + /** * Fetches current operation's latest information. Returns {@code null} if the operation does not * exist. @@ -666,7 +726,7 @@ public boolean isDone() throws ComputeException { * @return an {@code Operation} object with latest information or {@code null} if not found * @throws ComputeException upon failure */ - public Operation reload(OperationOption... options) throws ComputeException { + public Operation reload(OperationOption... options) { return compute.getOperation(operationId, options); } @@ -677,7 +737,7 @@ public Operation reload(OperationOption... options) throws ComputeException { * @return {@code true} if operation was deleted, {@code false} if it was not found * @throws ComputeException upon failure */ - public boolean delete() throws ComputeException { + public boolean delete() { return compute.deleteOperation(operationId); } diff --git a/gcloud-java-compute/src/main/java/com/google/cloud/compute/package-info.java b/gcloud-java-compute/src/main/java/com/google/cloud/compute/package-info.java index b7f589ea3b3f..aff2e4254b57 100644 --- a/gcloud-java-compute/src/main/java/com/google/cloud/compute/package-info.java +++ b/gcloud-java-compute/src/main/java/com/google/cloud/compute/package-info.java @@ -28,12 +28,10 @@ * if (disk != null) { * String snapshotName = "disk-name-snapshot"; * Operation operation = disk.createSnapshot(snapshotName); - * while (!operation.isDone()) { - * Thread.sleep(1000L); - * } + * operation = operation.waitFor(); * if (operation.errors() == null) { * // use snapshot - * Snapshot snapshot = compute.getSnapshot("disk-name-snapshot"); + * Snapshot snapshot = compute.getSnapshot(snapshotName); * } * }} *

    This second example shows how to create a virtual machine instance. Complete source code can @@ -49,10 +47,8 @@ * InstanceId instanceId = InstanceId.of("us-central1-a", "instance-name"); * MachineTypeId machineTypeId = MachineTypeId.of("us-central1-a", "n1-standard-1"); * Operation operation = - * compute.create(InstanceInfo.of(instanceId, machineTypeId, attachedDisk, networkInterface)); - * while (!operation.isDone()) { - * Thread.sleep(1000L); - * } + * compute.create(InstanceInfo.of(instanceId, machineTypeId, attachedDisk, networkInterface)); + * operation = operation.waitFor(); * if (operation.errors() == null) { * // use instance * Instance instance = compute.getInstance(instanceId); diff --git a/gcloud-java-compute/src/test/java/com/google/cloud/compute/OperationTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/OperationTest.java index d45fe48c1134..975610f93609 100644 --- a/gcloud-java-compute/src/test/java/com/google/cloud/compute/OperationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/OperationTest.java @@ -28,24 +28,33 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; +import com.google.cloud.Clock; +import com.google.cloud.WaitForOption; +import com.google.cloud.compute.Operation.OperationError; +import com.google.cloud.compute.Operation.OperationWarning; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import org.easymock.EasyMock; import org.junit.After; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; public class OperationTest { - private static final Operation.OperationError OPERATION_ERROR1 = - new Operation.OperationError("code1", "location1", "message1"); - private static final Operation.OperationError OPERATION_ERROR2 = - new Operation.OperationError("code2", "location2", "message2"); - private static final Operation.OperationWarning OPERATION_WARNING1 = - new Operation.OperationWarning("code1", "message1", ImmutableMap.of("k1", "v1")); - private static final Operation.OperationWarning OPERATION_WARNING2 = - new Operation.OperationWarning("code2", "location2", ImmutableMap.of("k2", "v2")); + private static final OperationError OPERATION_ERROR1 = + new OperationError("code1", "location1", "message1"); + private static final OperationError OPERATION_ERROR2 = + new OperationError("code2", "location2", "message2"); + private static final OperationWarning OPERATION_WARNING1 = + new OperationWarning("code1", "message1", ImmutableMap.of("k1", "v1")); + private static final OperationWarning OPERATION_WARNING2 = + new OperationWarning("code2", "location2", ImmutableMap.of("k2", "v2")); private static final String GENERATED_ID = "1"; private static final String CLIENT_OPERATION_ID = "clientOperationId"; private static final String OPERATION_TYPE = "delete"; @@ -58,9 +67,9 @@ public class OperationTest { private static final Long INSERT_TIME = 1453293540000L; private static final Long START_TIME = 1453293420000L; private static final Long END_TIME = 1453293480000L; - private static final List ERRORS = + private static final List ERRORS = ImmutableList.of(OPERATION_ERROR1, OPERATION_ERROR2); - private static final List WARNINGS = + private static final List WARNINGS = ImmutableList.of(OPERATION_WARNING1, OPERATION_WARNING2); private static final Integer HTTP_ERROR_STATUS_CODE = 404; private static final String HTTP_ERROR_MESSAGE = "NOT FOUND"; @@ -72,6 +81,9 @@ public class OperationTest { private static final RegionOperationId REGION_OPERATION_ID = RegionOperationId.of("project", "region", "op"); + @Rule + public final ExpectedException thrown = ExpectedException.none(); + private final Compute serviceMockReturnsOptions = createStrictMock(Compute.class); private final ComputeOptions mockOptions = createMock(ComputeOptions.class); private Compute compute; @@ -352,6 +364,109 @@ public void testIsDone_NotExists() throws Exception { verify(compute); } + @Test + public void testWaitFor() throws InterruptedException, TimeoutException { + initializeExpectedOperation(4); + Compute.OperationOption[] expectedOptions = + {Compute.OperationOption.fields(Compute.OperationField.STATUS)}; + Operation successOperation = + Operation.fromPb(serviceMockReturnsOptions, globalOperation.toPb().setError(null)); + expect(compute.options()).andReturn(mockOptions); + expect(mockOptions.clock()).andReturn(Clock.defaultClock()); + expect(compute.getOperation(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(successOperation); + expect(compute.getOperation(GLOBAL_OPERATION_ID)).andReturn(successOperation); + replay(compute, mockOptions); + initializeOperation(); + assertSame(successOperation, operation.waitFor()); + verify(mockOptions); + } + + @Test + public void testWaitFor_Null() throws InterruptedException, TimeoutException { + initializeExpectedOperation(3); + Compute.OperationOption[] expectedOptions = + {Compute.OperationOption.fields(Compute.OperationField.STATUS)}; + expect(compute.options()).andReturn(mockOptions); + expect(mockOptions.clock()).andReturn(Clock.defaultClock()); + expect(compute.getOperation(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(null); + expect(compute.getOperation(GLOBAL_OPERATION_ID)).andReturn(null); + replay(compute, mockOptions); + initializeOperation(); + assertNull(operation.waitFor()); + verify(mockOptions); + } + + @Test + public void testWaitForCheckingPeriod() throws InterruptedException, TimeoutException { + initializeExpectedOperation(5); + Compute.OperationOption[] expectedOptions = + {Compute.OperationOption.fields(Compute.OperationField.STATUS)}; + TimeUnit timeUnit = createStrictMock(TimeUnit.class); + timeUnit.sleep(42); + EasyMock.expectLastCall(); + Operation runningOperation = Operation.fromPb(serviceMockReturnsOptions, + globalOperation.toPb().setError(null).setStatus("RUNNING")); + Operation completedOperation = + Operation.fromPb(serviceMockReturnsOptions, globalOperation.toPb().setError(null)); + expect(compute.options()).andReturn(mockOptions); + expect(mockOptions.clock()).andReturn(Clock.defaultClock()); + expect(compute.getOperation(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(runningOperation); + expect(compute.getOperation(GLOBAL_OPERATION_ID, expectedOptions)) + .andReturn(completedOperation); + expect(compute.getOperation(GLOBAL_OPERATION_ID)).andReturn(completedOperation); + replay(compute, timeUnit, mockOptions); + initializeOperation(); + assertSame(completedOperation, operation.waitFor(WaitForOption.checkEvery(42, timeUnit))); + verify(timeUnit, mockOptions); + } + + @Test + public void testWaitForCheckingPeriod_Null() throws InterruptedException, TimeoutException { + initializeExpectedOperation(4); + Compute.OperationOption[] expectedOptions = + {Compute.OperationOption.fields(Compute.OperationField.STATUS)}; + TimeUnit timeUnit = createStrictMock(TimeUnit.class); + timeUnit.sleep(42); + EasyMock.expectLastCall(); + Operation runningOperation = Operation.fromPb(serviceMockReturnsOptions, + globalOperation.toPb().setError(null).setStatus("RUNNING")); + expect(compute.options()).andReturn(mockOptions); + expect(mockOptions.clock()).andReturn(Clock.defaultClock()); + expect(compute.getOperation(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(runningOperation); + expect(compute.getOperation(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(null); + expect(compute.getOperation(GLOBAL_OPERATION_ID)).andReturn(null); + replay(compute, timeUnit, mockOptions); + initializeOperation(); + assertNull(operation.waitFor(WaitForOption.checkEvery(42, timeUnit))); + verify(compute, timeUnit, mockOptions); + } + + @Test + public void testWaitForWithTimeout() throws InterruptedException, TimeoutException { + initializeExpectedOperation(4); + Compute.OperationOption[] expectedOptions = + {Compute.OperationOption.fields(Compute.OperationField.STATUS)}; + TimeUnit timeUnit = createStrictMock(TimeUnit.class); + timeUnit.sleep(1); + EasyMock.expectLastCall(); + Clock clock = createStrictMock(Clock.class); + expect(clock.millis()).andReturn(0L); + expect(clock.millis()).andReturn(1L); + expect(clock.millis()).andReturn(3L); + Operation runningOperation = Operation.fromPb(serviceMockReturnsOptions, + globalOperation.toPb().setError(null).setStatus("RUNNING")); + expect(compute.options()).andReturn(mockOptions); + expect(mockOptions.clock()).andReturn(clock); + expect(compute.getOperation(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(runningOperation); + expect(compute.getOperation(GLOBAL_OPERATION_ID, expectedOptions)).andReturn(runningOperation); + replay(compute, timeUnit, clock, mockOptions); + initializeOperation(); + thrown.expect(TimeoutException.class); + operation.waitFor(WaitForOption.checkEvery(1, timeUnit), + WaitForOption.timeout(3, TimeUnit.MILLISECONDS)); + verify(compute, timeUnit, clock, mockOptions); + } + @Test public void testReload() throws Exception { initializeExpectedOperation(5); diff --git a/gcloud-java-compute/src/test/java/com/google/cloud/compute/it/ITComputeTest.java b/gcloud-java-compute/src/test/java/com/google/cloud/compute/it/ITComputeTest.java index 71013a3c1120..5ee58c6bfda4 100644 --- a/gcloud-java-compute/src/test/java/com/google/cloud/compute/it/ITComputeTest.java +++ b/gcloud-java-compute/src/test/java/com/google/cloud/compute/it/ITComputeTest.java @@ -88,6 +88,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.TimeoutException; public class ITComputeTest { @@ -681,14 +682,12 @@ public void testListZoneOperationsWithFilter() { } @Test - public void testCreateGetAndDeleteRegionAddress() throws InterruptedException { + public void testCreateGetAndDeleteRegionAddress() throws InterruptedException, TimeoutException { String name = BASE_RESOURCE_NAME + "create-and-get-region-address"; AddressId addressId = RegionAddressId.of(REGION, name); AddressInfo addressInfo = AddressInfo.of(addressId); Operation operation = compute.create(addressInfo); - while (!operation.isDone()) { - Thread.sleep(1000L); - } + operation.waitFor(); // test get Address remoteAddress = compute.getAddress(addressId); assertNotNull(remoteAddress); @@ -709,26 +708,20 @@ public void testCreateGetAndDeleteRegionAddress() throws InterruptedException { assertNull(remoteAddress.creationTimestamp()); assertNull(remoteAddress.generatedId()); operation = remoteAddress.delete(); - while (!operation.isDone()) { - Thread.sleep(1000L); - } + operation.waitFor(); assertNull(compute.getAddress(addressId)); } @Test - public void testListRegionAddresses() throws InterruptedException { + public void testListRegionAddresses() throws InterruptedException, TimeoutException { String prefix = BASE_RESOURCE_NAME + "list-region-address"; String[] addressNames = {prefix + "1", prefix + "2"}; AddressId firstAddressId = RegionAddressId.of(REGION, addressNames[0]); AddressId secondAddressId = RegionAddressId.of(REGION, addressNames[1]); Operation firstOperation = compute.create(AddressInfo.of(firstAddressId)); Operation secondOperation = compute.create(AddressInfo.of(secondAddressId)); - while (!firstOperation.isDone()) { - Thread.sleep(1000L); - } - while (!secondOperation.isDone()) { - Thread.sleep(1000L); - } + firstOperation.waitFor(); + secondOperation.waitFor(); Set addressSet = ImmutableSet.copyOf(addressNames); // test list Compute.AddressFilter filter = @@ -772,19 +765,15 @@ public void testListRegionAddresses() throws InterruptedException { } @Test - public void testAggregatedListAddresses() throws InterruptedException { + public void testAggregatedListAddresses() throws InterruptedException, TimeoutException { String prefix = BASE_RESOURCE_NAME + "aggregated-list-address"; String[] addressNames = {prefix + "1", prefix + "2"}; AddressId firstAddressId = RegionAddressId.of(REGION, addressNames[0]); AddressId secondAddressId = GlobalAddressId.of(REGION, addressNames[1]); Operation firstOperation = compute.create(AddressInfo.of(firstAddressId)); Operation secondOperation = compute.create(AddressInfo.of(secondAddressId)); - while (!firstOperation.isDone()) { - Thread.sleep(1000L); - } - while (!secondOperation.isDone()) { - Thread.sleep(1000L); - } + firstOperation.waitFor(); + secondOperation.waitFor(); Set addressSet = ImmutableSet.copyOf(addressNames); Compute.AddressFilter filter = Compute.AddressFilter.equals(Compute.AddressField.NAME, prefix + "\\d"); @@ -807,14 +796,12 @@ public void testAggregatedListAddresses() throws InterruptedException { } @Test - public void testCreateGetAndDeleteGlobalAddress() throws InterruptedException { + public void testCreateGetAndDeleteGlobalAddress() throws InterruptedException, TimeoutException { String name = BASE_RESOURCE_NAME + "create-and-get-global-address"; AddressId addressId = GlobalAddressId.of(name); AddressInfo addressInfo = AddressInfo.of(addressId); Operation operation = compute.create(addressInfo); - while (!operation.isDone()) { - Thread.sleep(1000L); - } + operation.waitFor(); // test get Address remoteAddress = compute.getAddress(addressId); assertNotNull(remoteAddress); @@ -833,26 +820,20 @@ public void testCreateGetAndDeleteGlobalAddress() throws InterruptedException { assertNull(remoteAddress.creationTimestamp()); assertNull(remoteAddress.generatedId()); operation = remoteAddress.delete(); - while (!operation.isDone()) { - Thread.sleep(1000L); - } + operation.waitFor(); assertNull(compute.getAddress(addressId)); } @Test - public void testListGlobalAddresses() throws InterruptedException { + public void testListGlobalAddresses() throws InterruptedException, TimeoutException { String prefix = BASE_RESOURCE_NAME + "list-global-address"; String[] addressNames = {prefix + "1", prefix + "2"}; AddressId firstAddressId = GlobalAddressId.of(addressNames[0]); AddressId secondAddressId = GlobalAddressId.of(addressNames[1]); Operation firstOperation = compute.create(AddressInfo.of(firstAddressId)); Operation secondOperation = compute.create(AddressInfo.of(secondAddressId)); - while (!firstOperation.isDone()) { - Thread.sleep(1000L); - } - while (!secondOperation.isDone()) { - Thread.sleep(1000L); - } + firstOperation.waitFor(); + secondOperation.waitFor(); Set addressSet = ImmutableSet.copyOf(addressNames); // test list Compute.AddressFilter filter = @@ -894,15 +875,13 @@ public void testListGlobalAddresses() throws InterruptedException { } @Test - public void testCreateGetResizeAndDeleteStandardDisk() throws InterruptedException { + public void testCreateGetResizeAndDeleteStandardDisk() throws InterruptedException, TimeoutException { String name = BASE_RESOURCE_NAME + "create-and-get-standard-disk"; DiskId diskId = DiskId.of(ZONE, name); DiskInfo diskInfo = DiskInfo.of(diskId, StandardDiskConfiguration.of(DiskTypeId.of(ZONE, "pd-ssd"), 100L)); Operation operation = compute.create(diskInfo); - while (!operation.isDone()) { - Thread.sleep(1000L); - } + operation.waitFor(); // test get Disk remoteDisk = compute.getDisk(diskId); assertNotNull(remoteDisk); @@ -918,9 +897,7 @@ public void testCreateGetResizeAndDeleteStandardDisk() throws InterruptedExcepti assertNull(remoteDisk.lastAttachTimestamp()); assertNull(remoteDisk.lastDetachTimestamp()); operation = remoteDisk.resize(200L); - while (!operation.isDone()) { - Thread.sleep(1000L); - } + operation.waitFor(); // test resize and get with selected fields remoteDisk = compute.getDisk(diskId, Compute.DiskOption.fields(Compute.DiskField.SIZE_GB)); assertNotNull(remoteDisk); @@ -936,21 +913,17 @@ public void testCreateGetResizeAndDeleteStandardDisk() throws InterruptedExcepti assertNull(remoteDisk.lastAttachTimestamp()); assertNull(remoteDisk.lastDetachTimestamp()); operation = remoteDisk.delete(); - while (!operation.isDone()) { - Thread.sleep(1000L); - } + operation.waitFor(); assertNull(compute.getDisk(diskId)); } @Test - public void testCreateGetAndDeleteImageDisk() throws InterruptedException { + public void testCreateGetAndDeleteImageDisk() throws InterruptedException, TimeoutException { String name = BASE_RESOURCE_NAME + "create-and-get-image-disk"; DiskId diskId = DiskId.of(ZONE, name); DiskInfo diskInfo = DiskInfo.of(diskId, ImageDiskConfiguration.of(IMAGE_ID)); Operation operation = compute.create(diskInfo); - while (!operation.isDone()) { - Thread.sleep(1000L); - } + operation.waitFor(); // test get Disk remoteDisk = compute.getDisk(diskId); assertNotNull(remoteDisk); @@ -985,14 +958,12 @@ public void testCreateGetAndDeleteImageDisk() throws InterruptedException { assertNull(remoteDisk.lastAttachTimestamp()); assertNull(remoteDisk.lastDetachTimestamp()); operation = remoteDisk.delete(); - while (!operation.isDone()) { - Thread.sleep(1000L); - } + operation.waitFor(); assertNull(compute.getDisk(diskId)); } @Test - public void testCreateGetAndDeleteSnapshotAndSnapshotDisk() throws InterruptedException { + public void testCreateGetAndDeleteSnapshotAndSnapshotDisk() throws InterruptedException, TimeoutException { String diskName = BASE_RESOURCE_NAME + "create-and-get-snapshot-disk1"; String snapshotDiskName = BASE_RESOURCE_NAME + "create-and-get-snapshot-disk2"; DiskId diskId = DiskId.of(ZONE, diskName); @@ -1001,14 +972,10 @@ public void testCreateGetAndDeleteSnapshotAndSnapshotDisk() throws InterruptedEx DiskInfo diskInfo = DiskInfo.of(diskId, StandardDiskConfiguration.of(DiskTypeId.of(ZONE, "pd-ssd"), 100L)); Operation operation = compute.create(diskInfo); - while (!operation.isDone()) { - Thread.sleep(1000L); - } + operation.waitFor(); Disk remoteDisk = compute.getDisk(diskId); operation = remoteDisk.createSnapshot(snapshotName); - while (!operation.isDone()) { - Thread.sleep(1000L); - } + operation.waitFor(); // test get snapshot with selected fields Snapshot snapshot = compute.getSnapshot(snapshotName, Compute.SnapshotOption.fields(Compute.SnapshotField.CREATION_TIMESTAMP)); @@ -1038,9 +1005,7 @@ public void testCreateGetAndDeleteSnapshotAndSnapshotDisk() throws InterruptedEx diskInfo = DiskInfo.of(snapshotDiskId, SnapshotDiskConfiguration.of(SnapshotId.of(snapshotName))); operation = compute.create(diskInfo); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); // test get disk remoteDisk = compute.getDisk(snapshotDiskId); assertNotNull(remoteDisk); @@ -1076,19 +1041,15 @@ public void testCreateGetAndDeleteSnapshotAndSnapshotDisk() throws InterruptedEx assertNull(remoteDisk.lastAttachTimestamp()); assertNull(remoteDisk.lastDetachTimestamp()); operation = remoteDisk.delete(); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); assertNull(compute.getDisk(snapshotDiskId)); operation = snapshot.delete(); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); assertNull(compute.getSnapshot(snapshotName)); } @Test - public void testListDisksAndSnapshots() throws InterruptedException { + public void testListDisksAndSnapshots() throws InterruptedException, TimeoutException { String prefix = BASE_RESOURCE_NAME + "list-disks-and-snapshots-disk"; String[] diskNames = {prefix + "1", prefix + "2"}; DiskId firstDiskId = DiskId.of(ZONE, diskNames[0]); @@ -1097,12 +1058,8 @@ public void testListDisksAndSnapshots() throws InterruptedException { StandardDiskConfiguration.of(DiskTypeId.of(ZONE, "pd-ssd"), 100L); Operation firstOperation = compute.create(DiskInfo.of(firstDiskId, configuration)); Operation secondOperation = compute.create(DiskInfo.of(secondDiskId, configuration)); - while (!firstOperation.isDone()) { - Thread.sleep(1000L); - } - while (!secondOperation.isDone()) { - Thread.sleep(1000L); - } + firstOperation.waitFor(); + secondOperation.waitFor(); Set diskSet = ImmutableSet.copyOf(diskNames); // test list disks Compute.DiskFilter diskFilter = @@ -1154,12 +1111,8 @@ public void testListDisksAndSnapshots() throws InterruptedException { SnapshotId secondSnapshotId = SnapshotId.of(diskNames[1]); firstOperation = compute.create(SnapshotInfo.of(firstSnapshotId, firstDiskId)); secondOperation = compute.create(SnapshotInfo.of(secondSnapshotId, secondDiskId)); - while (!firstOperation.isDone()) { - Thread.sleep(1000L); - } - while (!secondOperation.isDone()) { - Thread.sleep(1000L); - } + firstOperation.waitFor(); + secondOperation.waitFor(); // test list snapshots Compute.SnapshotFilter snapshotFilter = Compute.SnapshotFilter.equals(Compute.SnapshotField.NAME, prefix + "\\d"); @@ -1207,7 +1160,7 @@ public void testListDisksAndSnapshots() throws InterruptedException { } @Test - public void testAggregatedListDisks() throws InterruptedException { + public void testAggregatedListDisks() throws InterruptedException, TimeoutException { String prefix = BASE_RESOURCE_NAME + "list-aggregated-disk"; String[] diskZones = {"us-central1-a", "us-east1-c"}; String[] diskNames = {prefix + "1", prefix + "2"}; @@ -1217,12 +1170,8 @@ public void testAggregatedListDisks() throws InterruptedException { StandardDiskConfiguration.of(DiskTypeId.of(ZONE, "pd-ssd"), 100L); Operation firstOperation = compute.create(DiskInfo.of(firstDiskId, configuration)); Operation secondOperation = compute.create(DiskInfo.of(secondDiskId, configuration)); - while (!firstOperation.isDone()) { - Thread.sleep(1000L); - } - while (!secondOperation.isDone()) { - Thread.sleep(1000L); - } + firstOperation.waitFor(); + secondOperation.waitFor(); Set zoneSet = ImmutableSet.copyOf(diskZones); Set diskSet = ImmutableSet.copyOf(diskNames); Compute.DiskFilter diskFilter = @@ -1250,7 +1199,7 @@ public void testAggregatedListDisks() throws InterruptedException { } @Test - public void testCreateGetAndDeprecateImage() throws InterruptedException { + public void testCreateGetAndDeprecateImage() throws InterruptedException, TimeoutException { String diskName = BASE_RESOURCE_NAME + "create-and-get-image-disk"; String imageName = BASE_RESOURCE_NAME + "create-and-get-image"; DiskId diskId = DiskId.of(ZONE, diskName); @@ -1258,15 +1207,11 @@ public void testCreateGetAndDeprecateImage() throws InterruptedException { DiskInfo diskInfo = DiskInfo.of(diskId, StandardDiskConfiguration.of(DiskTypeId.of(ZONE, "pd-ssd"), 100L)); Operation operation = compute.create(diskInfo); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); Disk remoteDisk = compute.getDisk(diskId); ImageInfo imageInfo = ImageInfo.of(imageId, DiskImageConfiguration.of(diskId)); operation = compute.create(imageInfo); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); // test get image with selected fields Image image = compute.getImage(imageId, Compute.ImageOption.fields(Compute.ImageField.CREATION_TIMESTAMP)); @@ -1302,16 +1247,12 @@ public void testCreateGetAndDeprecateImage() throws InterruptedException { .deprecated(System.currentTimeMillis()) .build(); operation = image.deprecate(deprecationStatus); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); image = compute.getImage(imageId); assertEquals(deprecationStatus, image.deprecationStatus()); remoteDisk.delete(); operation = image.delete(); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); assertNull(compute.getImage(imageId)); } @@ -1376,15 +1317,13 @@ public void testListImagesWithFilter() { } @Test - public void testCreateAndGetNetwork() throws InterruptedException { + public void testCreateAndGetNetwork() throws InterruptedException, TimeoutException { String name = BASE_RESOURCE_NAME + "create-and-get-network"; NetworkId networkId = NetworkId.of(name); NetworkInfo networkInfo = NetworkInfo.of(networkId, StandardNetworkConfiguration.of("192.168.0.0/16")); Operation operation = compute.create(networkInfo); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); // test get network with selected fields Network network = compute.getNetwork(networkId.network(), Compute.NetworkOption.fields(Compute.NetworkField.CREATION_TIMESTAMP)); @@ -1404,22 +1343,18 @@ public void testCreateAndGetNetwork() throws InterruptedException { remoteConfiguration = network.configuration(); assertEquals("192.168.0.0/16", remoteConfiguration.ipRange()); operation = network.delete(); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); assertNull(compute.getNetwork(name)); } @Test - public void testListNetworks() throws InterruptedException { + public void testListNetworks() throws InterruptedException, TimeoutException { String name = BASE_RESOURCE_NAME + "list-network"; NetworkId networkId = NetworkId.of(name); NetworkInfo networkInfo = NetworkInfo.of(networkId, StandardNetworkConfiguration.of("192.168.0.0/16")); Operation operation = compute.create(networkInfo); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); // test list Compute.NetworkFilter filter = Compute.NetworkFilter.equals(Compute.NetworkField.NAME, name); Page networkPage = compute.listNetworks(Compute.NetworkListOption.filter(filter)); @@ -1454,21 +1389,17 @@ public void testListNetworks() throws InterruptedException { } assertEquals(1, count); operation = compute.deleteNetwork(networkId); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); assertNull(compute.getNetwork(name)); } @Test - public void testCreateNetworkAndSubnetwork() throws InterruptedException { + public void testCreateNetworkAndSubnetwork() throws InterruptedException, TimeoutException { String networkName = BASE_RESOURCE_NAME + "create-subnetwork-network"; NetworkId networkId = NetworkId.of(networkName); NetworkInfo networkInfo = NetworkInfo.of(networkId, SubnetNetworkConfiguration.of(false)); Operation operation = compute.create(networkInfo); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); // test get network Network network = compute.getNetwork(networkId.network()); assertEquals(networkId.network(), network.networkId().network()); @@ -1481,9 +1412,7 @@ public void testCreateNetworkAndSubnetwork() throws InterruptedException { SubnetworkId subnetworkId = SubnetworkId.of(REGION, subnetworkName); SubnetworkInfo subnetworkInfo = SubnetworkInfo.of(subnetworkId, networkId, "192.168.0.0/16"); operation = compute.create(subnetworkInfo); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); // test get subnetwork with selected fields Subnetwork subnetwork = compute.getSubnetwork(subnetworkId, Compute.SubnetworkOption.fields(Compute.SubnetworkField.CREATION_TIMESTAMP)); @@ -1538,26 +1467,20 @@ public void testCreateNetworkAndSubnetwork() throws InterruptedException { } assertEquals(1, count); operation = subnetwork.delete(); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); operation = compute.deleteNetwork(networkId); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); assertNull(compute.getSubnetwork(subnetworkId)); assertNull(compute.getNetwork(networkName)); } @Test - public void testAggregatedListSubnetworks() throws InterruptedException { + public void testAggregatedListSubnetworks() throws InterruptedException, TimeoutException { String networkName = BASE_RESOURCE_NAME + "list-subnetwork-network"; NetworkId networkId = NetworkId.of(networkName); NetworkInfo networkInfo = NetworkInfo.of(networkId, SubnetNetworkConfiguration.of(false)); Operation operation = compute.create(networkInfo); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); String prefix = BASE_RESOURCE_NAME + "list-subnetwork"; String[] regionNames = {"us-central1", "us-east1"}; String[] subnetworkNames = {prefix + "1", prefix + "2"}; @@ -1570,12 +1493,8 @@ public void testAggregatedListSubnetworks() throws InterruptedException { SubnetworkInfo.of(secondSubnetworkId, networkId, ipRanges[1]); Operation firstOperation = compute.create(firstSubnetworkInfo); Operation secondOperation = compute.create(secondSubnetworkInfo); - while (!firstOperation.isDone()) { - Thread.sleep(1000L); - } - while (!secondOperation.isDone()) { - Thread.sleep(1000L); - } + firstOperation.waitFor(); + secondOperation.waitFor(); Set regionSet = ImmutableSet.copyOf(regionNames); Set subnetworkSet = ImmutableSet.copyOf(subnetworkNames); Set rangeSet = ImmutableSet.copyOf(ipRanges); @@ -1599,30 +1518,22 @@ public void testAggregatedListSubnetworks() throws InterruptedException { assertEquals(2, count); firstOperation = compute.deleteSubnetwork(firstSubnetworkId); secondOperation = compute.deleteSubnetwork(secondSubnetworkId); - while (!firstOperation.isDone()) { - Thread.sleep(1000L); - } - while (!secondOperation.isDone()) { - Thread.sleep(1000L); - } + firstOperation.waitFor(); + secondOperation.waitFor(); operation = compute.deleteNetwork(networkId); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); assertNull(compute.getNetwork(networkName)); } @Test - public void testCreateGetAndDeleteInstance() throws InterruptedException { + public void testCreateGetAndDeleteInstance() throws InterruptedException, TimeoutException { String instanceName = BASE_RESOURCE_NAME + "create-and-get-instance"; String addressName = BASE_RESOURCE_NAME + "create-and-get-instance-address"; // Create an address to assign to the instance AddressId addressId = RegionAddressId.of(REGION, addressName); AddressInfo addressInfo = AddressInfo.of(addressId); Operation operation = compute.create(addressInfo); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); Address address = compute.getAddress(addressId); // Create an instance InstanceId instanceId = InstanceId.of(ZONE, instanceName); @@ -1640,9 +1551,7 @@ public void testCreateGetAndDeleteInstance() throws InterruptedException { .networkInterfaces(networkInterface) .build(); operation = compute.create(instanceInfo); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); // test get Instance remoteInstance = compute.getInstance(instanceId); assertEquals(instanceName, remoteInstance.instanceId().instance()); @@ -1694,15 +1603,13 @@ public void testCreateGetAndDeleteInstance() throws InterruptedException { String newSerialPortOutput = remoteInstance.getSerialPortOutput(1); assertTrue(newSerialPortOutput.contains(serialPortOutput)); operation = remoteInstance.delete(); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); assertNull(compute.getInstance(instanceId)); address.delete(); } @Test - public void testStartStopAndResetInstance() throws InterruptedException { + public void testStartStopAndResetInstance() throws InterruptedException, TimeoutException { String instanceName = BASE_RESOURCE_NAME + "start-stop-reset-instance"; InstanceId instanceId = InstanceId.of(ZONE, instanceName); NetworkId networkId = NetworkId.of("default"); @@ -1715,30 +1622,22 @@ public void testStartStopAndResetInstance() throws InterruptedException { .networkInterfaces(networkInterface) .build(); Operation operation = compute.create(instanceInfo); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); Instance remoteInstance = compute.getInstance(instanceId, Compute.InstanceOption.fields(Compute.InstanceField.STATUS)); assertEquals(InstanceInfo.Status.RUNNING, remoteInstance.status()); operation = remoteInstance.stop(); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); remoteInstance = compute.getInstance(instanceId, Compute.InstanceOption.fields(Compute.InstanceField.STATUS)); assertEquals(InstanceInfo.Status.TERMINATED, remoteInstance.status()); operation = remoteInstance.start(); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); remoteInstance = compute.getInstance(instanceId, Compute.InstanceOption.fields(Compute.InstanceField.STATUS)); assertEquals(InstanceInfo.Status.RUNNING, remoteInstance.status()); operation = remoteInstance.reset(); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); remoteInstance = compute.getInstance(instanceId, Compute.InstanceOption.fields(Compute.InstanceField.STATUS)); assertEquals(InstanceInfo.Status.RUNNING, remoteInstance.status()); @@ -1746,7 +1645,7 @@ public void testStartStopAndResetInstance() throws InterruptedException { } @Test - public void testSetInstanceProperties() throws InterruptedException { + public void testSetInstanceProperties() throws InterruptedException, TimeoutException { String instanceName = BASE_RESOURCE_NAME + "set-properties-instance"; InstanceId instanceId = InstanceId.of(ZONE, instanceName); NetworkId networkId = NetworkId.of("default"); @@ -1759,51 +1658,39 @@ public void testSetInstanceProperties() throws InterruptedException { .networkInterfaces(networkInterface) .build(); Operation operation = compute.create(instanceInfo); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); Instance remoteInstance = compute.getInstance(instanceId); // test set tags List tags = ImmutableList.of("tag1", "tag2"); operation = remoteInstance.setTags(tags); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); remoteInstance = compute.getInstance(instanceId); assertEquals(tags, remoteInstance.tags().values()); // test set metadata Map metadata = ImmutableMap.of("key", "value"); operation = remoteInstance.setMetadata(metadata); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); remoteInstance = compute.getInstance(instanceId); assertEquals(metadata, remoteInstance.metadata().values()); // test set machine type operation = remoteInstance.stop(); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); operation = remoteInstance.setMachineType(MachineTypeId.of(ZONE, "n1-standard-1")); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); remoteInstance = compute.getInstance(instanceId); assertEquals("n1-standard-1", remoteInstance.machineType().type()); assertEquals(ZONE, remoteInstance.machineType().zone()); // test set scheduling options SchedulingOptions options = SchedulingOptions.standard(false, SchedulingOptions.Maintenance.TERMINATE); operation = remoteInstance.setSchedulingOptions(options); - while (!operation.isDone()) { - Thread.sleep(1000L); - } +operation.waitFor(); remoteInstance = compute.getInstance(instanceId); assertEquals(options, remoteInstance.schedulingOptions()); remoteInstance.delete(); } @Test - public void testAttachAndDetachDisk() throws InterruptedException { + public void testAttachAndDetachDisk() throws InterruptedException, TimeoutException { String instanceName = BASE_RESOURCE_NAME + "attach-and-detach-disk-instance"; String diskName = BASE_RESOURCE_NAME + "attach-and-detach-disk"; InstanceId instanceId = InstanceId.of(ZONE, instanceName); @@ -1820,19 +1707,13 @@ public void testAttachAndDetachDisk() throws InterruptedException { DiskId diskId = DiskId.of(ZONE, diskName); Operation diskOperation = compute.create(DiskInfo.of(diskId, StandardDiskConfiguration.of(DiskTypeId.of(ZONE, "pd-ssd")))); - while (!instanceOperation.isDone()) { - Thread.sleep(1000L); - } - while (!diskOperation.isDone()) { - Thread.sleep(1000L); - } + instanceOperation.waitFor(); + diskOperation.waitFor(); Instance remoteInstance = compute.getInstance(instanceId); // test attach disk instanceOperation = remoteInstance.attachDisk("dev1", AttachedDisk.PersistentDiskConfiguration.builder(diskId).build()); - while (!instanceOperation.isDone()) { - Thread.sleep(1000L); - } + instanceOperation.waitFor(); remoteInstance = compute.getInstance(instanceId); Set deviceSet = ImmutableSet.of("dev0", "dev1"); assertEquals(2, remoteInstance.attachedDisks().size()); @@ -1841,9 +1722,7 @@ public void testAttachAndDetachDisk() throws InterruptedException { } // test set disk auto-delete instanceOperation = remoteInstance.setDiskAutoDelete("dev1", true); - while (!instanceOperation.isDone()) { - Thread.sleep(1000L); - } + instanceOperation.waitFor(); remoteInstance = compute.getInstance(instanceId); assertEquals(2, remoteInstance.attachedDisks().size()); for (AttachedDisk remoteAttachedDisk : remoteInstance.attachedDisks()) { @@ -1852,9 +1731,7 @@ public void testAttachAndDetachDisk() throws InterruptedException { } // test detach disk instanceOperation = remoteInstance.detachDisk("dev1"); - while (!instanceOperation.isDone()) { - Thread.sleep(1000L); - } + instanceOperation.waitFor(); remoteInstance = compute.getInstance(instanceId); assertEquals(1, remoteInstance.attachedDisks().size()); assertEquals("dev0", remoteInstance.attachedDisks().get(0).deviceName()); @@ -1863,7 +1740,7 @@ public void testAttachAndDetachDisk() throws InterruptedException { } @Test - public void testAddAndRemoveAccessConfig() throws InterruptedException { + public void testAddAndRemoveAccessConfig() throws InterruptedException, TimeoutException { String instanceName = BASE_RESOURCE_NAME + "add-and-remove-access-instance"; String addressName = BASE_RESOURCE_NAME + "add-and-remove-access-address"; InstanceId instanceId = InstanceId.of(ZONE, instanceName); @@ -1880,15 +1757,8 @@ public void testAddAndRemoveAccessConfig() throws InterruptedException { AddressId addressId = RegionAddressId.of(REGION, addressName); AddressInfo addressInfo = AddressInfo.of(addressId); Operation addressOperation = compute.create(addressInfo); - while (!addressOperation.isDone()) { - Thread.sleep(1000L); - } - while (!instanceOperation.isDone()) { - Thread.sleep(1000L); - } - while (!addressOperation.isDone()) { - Thread.sleep(1000L); - } + addressOperation.waitFor(); + instanceOperation.waitFor(); Address remoteAddress = compute.getAddress(addressId); Instance remoteInstance = compute.getInstance(instanceId); String networkInterfaceName = remoteInstance.networkInterfaces().get(0).name(); @@ -1898,9 +1768,7 @@ public void testAddAndRemoveAccessConfig() throws InterruptedException { .name("NAT") .build(); instanceOperation = remoteInstance.addAccessConfig(networkInterfaceName, accessConfig); - while (!instanceOperation.isDone()) { - Thread.sleep(1000L); - } + instanceOperation.waitFor(); remoteInstance = compute.getInstance(instanceId); List accessConfigurations = remoteInstance.networkInterfaces().get(0).accessConfigurations(); @@ -1908,9 +1776,7 @@ public void testAddAndRemoveAccessConfig() throws InterruptedException { assertEquals("NAT", accessConfigurations.get(0).name()); // test delete access config instanceOperation = remoteInstance.deleteAccessConfig(networkInterfaceName, "NAT"); - while (!instanceOperation.isDone()) { - Thread.sleep(1000L); - } + instanceOperation.waitFor(); remoteInstance = compute.getInstance(instanceId); assertTrue(remoteInstance.networkInterfaces().get(0).accessConfigurations().isEmpty()); remoteInstance.delete(); diff --git a/gcloud-java-core/src/main/java/com/google/cloud/WaitForOption.java b/gcloud-java-core/src/main/java/com/google/cloud/WaitForOption.java new file mode 100644 index 000000000000..8af7a074ab4d --- /dev/null +++ b/gcloud-java-core/src/main/java/com/google/cloud/WaitForOption.java @@ -0,0 +1,225 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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; + +import static com.google.common.base.Preconditions.checkArgument; + +import com.google.common.base.MoreObjects; + +import java.io.Serializable; +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +/** + * This class represents options for methods that wait for changes in the status of a resource. + */ +public abstract class WaitForOption implements Serializable { + + private static final long serialVersionUID = 8443451708032349243L; + + private final OptionType optionType; + + enum OptionType { + CHECKING_PERIOD, + TIMEOUT + } + + private WaitForOption(OptionType optionType) { + this.optionType = optionType; + } + + /** + * This class represents an option to set how frequently the resource status should be checked. + * Objects of this class keep the actual period and related time unit for the checking period. + */ + public static final class CheckingPeriod extends WaitForOption { + + private static final long serialVersionUID = -2481062893220539210L; + private static final CheckingPeriod DEFAULT = new CheckingPeriod(500, TimeUnit.MILLISECONDS); + + private final long period; + private final TimeUnit unit; + + private CheckingPeriod(long period, TimeUnit unit) { + super(OptionType.CHECKING_PERIOD); + this.period = period; + this.unit = unit; + } + + /** + * Returns the checking period. + */ + public long period() { + return period; + } + + /** + * Returns the time unit for {@link #period()}. + */ + public TimeUnit unit() { + return unit; + } + + /** + * Blocks the current thread for the amount of time specified by this object. + * + * @throws InterruptedException if the current thread was interrupted + */ + public void sleep() throws InterruptedException { + unit.sleep(period); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null || !(obj instanceof CheckingPeriod)) { + return false; + } + CheckingPeriod other = (CheckingPeriod) obj; + return baseEquals(other) + && Objects.equals(period, other.period) + && Objects.equals(unit, other.unit); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), period, unit); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("period", period) + .add("unit", unit) + .toString(); + } + + /** + * Returns the {@code CheckingPeriod} option specified in {@code options}. If no + * {@code CheckingPeriod} could be found among {@code options}, the default checking period (500 + * milliseconds) is used. + */ + public static CheckingPeriod getOrDefault(WaitForOption... options) { + return getOrDefaultInternal(OptionType.CHECKING_PERIOD, DEFAULT, options); + } + } + + /** + * This class represents an option to set the maximum time to wait for the resource's status to + * reach the desired state. + */ + public static final class Timeout extends WaitForOption { + + private static final long serialVersionUID = -7120401111985321932L; + private static final Timeout DEFAULT = new Timeout(-1); + + private final long timeoutMillis; + + private Timeout(long timeoutMillis) { + super(OptionType.TIMEOUT); + this.timeoutMillis = timeoutMillis; + } + + /** + * Returns the timeout in milliseconds. + */ + public long timeoutMillis() { + return timeoutMillis; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (obj == null || !(obj instanceof Timeout)) { + return false; + } + Timeout other = (Timeout) obj; + return baseEquals(other) && Objects.equals(timeoutMillis, other.timeoutMillis); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), timeoutMillis); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("timeoutMillis", timeoutMillis) + .toString(); + } + + /** + * Returns the {@code Timeout} option specified in {@code options}. If no {@code Timeout} could + * be found among {@code options}, no timeout will be used. + */ + public static Timeout getOrDefault(WaitForOption... options) { + return getOrDefaultInternal(OptionType.TIMEOUT, DEFAULT, options); + } + } + + OptionType optionType() { + return optionType; + } + + final boolean baseEquals(WaitForOption option) { + return Objects.equals(option.optionType, option.optionType); + } + + final int baseHashCode() { + return Objects.hash(optionType); + } + + @SuppressWarnings("unchecked") + private static T getOrDefaultInternal(OptionType optionType, + T defaultValue, WaitForOption... options) { + T foundOption = null; + for (WaitForOption option : options) { + if (option.optionType.equals(optionType)) { + checkArgument(foundOption == null, "Duplicate option %s", option); + foundOption = (T) option; + } + } + return foundOption != null ? foundOption : defaultValue; + } + + /** + * Returns an option to set how frequently the resource status should be checked. + * + * @param checkEvery the checking period + * @param unit the time unit of the checking period + */ + public static CheckingPeriod checkEvery(long checkEvery, TimeUnit unit) { + checkArgument(checkEvery >= 0, "checkEvery must be >= 0"); + return new CheckingPeriod(checkEvery, unit); + } + + /** + * Returns an option to set the maximum time to wait. + * + * @param timeout the maximum time to wait, expressed in {@code unit} + * @param unit the time unit of the timeout + */ + public static Timeout timeout(long timeout, TimeUnit unit) { + checkArgument(timeout >= 0, "timeout must be >= 0"); + return new Timeout(unit.toMillis(timeout)); + } +} diff --git a/gcloud-java-core/src/test/java/com/google/cloud/SerializationTest.java b/gcloud-java-core/src/test/java/com/google/cloud/SerializationTest.java index 7fa778a524eb..53baa57b96ca 100644 --- a/gcloud-java-core/src/test/java/com/google/cloud/SerializationTest.java +++ b/gcloud-java-core/src/test/java/com/google/cloud/SerializationTest.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.io.Serializable; import java.util.Date; +import java.util.concurrent.TimeUnit; public class SerializationTest extends BaseSerializationTest { @@ -36,6 +37,8 @@ public class SerializationTest extends BaseSerializationTest { new SigningException("message", BASE_SERVICE_EXCEPTION); private static final RetryParams RETRY_PARAMS = RetryParams.defaultInstance(); private static final SomeIamPolicy SOME_IAM_POLICY = new SomeIamPolicy.Builder().build(); + private static final WaitForOption CHECKING_PERIOD = + WaitForOption.checkEvery(42, TimeUnit.SECONDS); private static final String JSON_KEY = "{\n" + " \"private_key_id\": \"somekeyid\",\n" + " \"private_key\": \"-----BEGIN PRIVATE KEY-----\\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggS" @@ -88,7 +91,7 @@ public Builder toBuilder() { @Override protected Serializable[] serializableObjects() { return new Serializable[]{BASE_SERVICE_EXCEPTION, EXCEPTION_HANDLER, IDENTITY, PAGE, - RETRY_PARAMS, SOME_IAM_POLICY, SIGNING_EXCEPTION}; + RETRY_PARAMS, SOME_IAM_POLICY, SIGNING_EXCEPTION, CHECKING_PERIOD}; } @Override diff --git a/gcloud-java-core/src/test/java/com/google/cloud/WaitForOptionTest.java b/gcloud-java-core/src/test/java/com/google/cloud/WaitForOptionTest.java new file mode 100644 index 000000000000..82996e1ca3f8 --- /dev/null +++ b/gcloud-java-core/src/test/java/com/google/cloud/WaitForOptionTest.java @@ -0,0 +1,124 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * 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; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +import com.google.cloud.WaitForOption.CheckingPeriod; +import com.google.cloud.WaitForOption.OptionType; +import com.google.cloud.WaitForOption.Timeout; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import java.util.concurrent.TimeUnit; + +public class WaitForOptionTest { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + private static final CheckingPeriod CHECKING_PERIOD_OPTION = + WaitForOption.checkEvery(42, TimeUnit.MILLISECONDS); + private static final Timeout TIMEOUT_OPTION = WaitForOption.timeout(43, TimeUnit.MILLISECONDS); + + @Test + public void testCheckEvery() { + assertEquals(OptionType.CHECKING_PERIOD, CHECKING_PERIOD_OPTION.optionType()); + assertEquals(42, CHECKING_PERIOD_OPTION.period()); + assertEquals(TimeUnit.MILLISECONDS, CHECKING_PERIOD_OPTION.unit()); + } + + @Test + public void testCheckEvery_InvalidPeriod() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("checkEvery must be >= 0"); + WaitForOption.checkEvery(-1, TimeUnit.MILLISECONDS); + } + + @Test + public void testTimeout() { + assertEquals(OptionType.TIMEOUT, TIMEOUT_OPTION.optionType()); + assertEquals(43, TIMEOUT_OPTION.timeoutMillis()); + Timeout timeoutOption = WaitForOption.timeout(43, TimeUnit.SECONDS); + assertEquals(43_000, timeoutOption.timeoutMillis()); + } + + @Test + public void testTimeout_InvalidTimeout() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("timeout must be >= 0"); + WaitForOption.timeout(-1, TimeUnit.MILLISECONDS); + } + + @Test + public void testEqualsAndHashCode() { + assertEquals(CHECKING_PERIOD_OPTION, CHECKING_PERIOD_OPTION); + assertEquals(TIMEOUT_OPTION, TIMEOUT_OPTION); + assertEquals(CHECKING_PERIOD_OPTION.hashCode(), CHECKING_PERIOD_OPTION.hashCode()); + assertEquals(TIMEOUT_OPTION.hashCode(), TIMEOUT_OPTION.hashCode()); + WaitForOption checkingPeriodOption = WaitForOption.checkEvery(42, TimeUnit.MILLISECONDS); + assertEquals(CHECKING_PERIOD_OPTION, checkingPeriodOption); + assertEquals(CHECKING_PERIOD_OPTION.hashCode(), checkingPeriodOption.hashCode()); + WaitForOption timeoutOption = WaitForOption.timeout(43, TimeUnit.MILLISECONDS); + assertEquals(TIMEOUT_OPTION, timeoutOption); + assertEquals(TIMEOUT_OPTION.hashCode(), timeoutOption.hashCode()); + assertNotEquals(CHECKING_PERIOD_OPTION, TIMEOUT_OPTION); + assertNotEquals(CHECKING_PERIOD_OPTION.hashCode(), TIMEOUT_OPTION.hashCode()); + checkingPeriodOption = WaitForOption.checkEvery(43, TimeUnit.MILLISECONDS); + assertNotEquals(CHECKING_PERIOD_OPTION, checkingPeriodOption); + assertNotEquals(CHECKING_PERIOD_OPTION.hashCode(), checkingPeriodOption.hashCode()); + checkingPeriodOption = WaitForOption.checkEvery(42, TimeUnit.SECONDS); + assertNotEquals(CHECKING_PERIOD_OPTION, checkingPeriodOption); + assertNotEquals(CHECKING_PERIOD_OPTION.hashCode(), checkingPeriodOption.hashCode()); + timeoutOption = WaitForOption.timeout(42, TimeUnit.MILLISECONDS); + assertNotEquals(TIMEOUT_OPTION, timeoutOption); + assertNotEquals(TIMEOUT_OPTION.hashCode(), timeoutOption.hashCode()); + timeoutOption = WaitForOption.timeout(43, TimeUnit.SECONDS); + assertNotEquals(TIMEOUT_OPTION, timeoutOption); + assertNotEquals(TIMEOUT_OPTION.hashCode(), timeoutOption.hashCode()); + } + + @Test + public void testGetOrDefault() { + assertEquals(CHECKING_PERIOD_OPTION, + CheckingPeriod.getOrDefault(CHECKING_PERIOD_OPTION, TIMEOUT_OPTION)); + assertEquals(TIMEOUT_OPTION, + Timeout.getOrDefault(CHECKING_PERIOD_OPTION, TIMEOUT_OPTION)); + CheckingPeriod checkingPeriod = CheckingPeriod.getOrDefault(TIMEOUT_OPTION); + assertEquals(500, checkingPeriod.period()); + assertEquals(TimeUnit.MILLISECONDS, checkingPeriod.unit()); + Timeout timeout = Timeout.getOrDefault(CHECKING_PERIOD_OPTION); + assertEquals(-1, timeout.timeoutMillis()); + } + + @Test + public void testCheckingPeriodGetOrDefault_DuplicateOption() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage(String.format("Duplicate option %s", CHECKING_PERIOD_OPTION)); + CheckingPeriod.getOrDefault(CHECKING_PERIOD_OPTION, CHECKING_PERIOD_OPTION); + } + + @Test + public void testTimeoutGetOrDefault_DuplicateOption() { + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage(String.format("Duplicate option %s", TIMEOUT_OPTION)); + Timeout.getOrDefault(TIMEOUT_OPTION, TIMEOUT_OPTION); + } +} diff --git a/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java index 6acfb5bbef6d..156e475a5ac9 100644 --- a/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java @@ -528,6 +528,7 @@ void run(BigQuery bigquery, JobInfo job) throws Exception { System.out.println("Waiting for job " + startedJob.jobId().job() + " to complete"); Thread.sleep(1000L); } + startedJob = startedJob.reload(); if (startedJob.status().error() == null) { System.out.println("Job " + startedJob.jobId().job() + " succeeded"); } else { diff --git a/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/snippets/CreateTableAndLoadData.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/snippets/CreateTableAndLoadData.java index 01290ec8b491..6772d79a73ca 100644 --- a/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/snippets/CreateTableAndLoadData.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/snippets/CreateTableAndLoadData.java @@ -33,6 +33,8 @@ import com.google.cloud.bigquery.TableId; import com.google.cloud.bigquery.TableInfo; +import java.util.concurrent.TimeoutException; + /** * A snippet for Google Cloud BigQuery showing how to get a BigQuery table or create it if it does * not exist. The snippet also starts a BigQuery job to load data into the table from a Cloud @@ -40,7 +42,7 @@ */ public class CreateTableAndLoadData { - public static void main(String... args) throws InterruptedException { + public static void main(String... args) throws InterruptedException, TimeoutException { BigQuery bigquery = BigQueryOptions.defaultInstance().service(); TableId tableId = TableId.of("dataset", "table"); Table table = bigquery.getTable(tableId); @@ -52,9 +54,7 @@ public static void main(String... args) throws InterruptedException { } System.out.println("Loading data into table " + tableId); Job loadJob = table.load(FormatOptions.csv(), "gs://bucket/path"); - while (!loadJob.isDone()) { - Thread.sleep(1000L); - } + loadJob = loadJob.waitFor(); if (loadJob.status().error() != null) { System.out.println("Job completed with errors"); } else { diff --git a/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateAddressDiskAndInstance.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateAddressDiskAndInstance.java index 5334f746c95b..0a63865904e0 100644 --- a/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateAddressDiskAndInstance.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateAddressDiskAndInstance.java @@ -35,13 +35,15 @@ import com.google.cloud.compute.Operation; import com.google.cloud.compute.RegionAddressId; +import java.util.concurrent.TimeoutException; + /** * A snippet for Google Cloud Compute Engine showing how to create a disk and an address. The * snippet also shows how to create a virtual machine instance using the created disk and address. */ public class CreateAddressDiskAndInstance { - public static void main(String... args) throws InterruptedException { + public static void main(String... args) throws InterruptedException, TimeoutException { // Create a service object // Credentials are inferred from the environment. Compute compute = ComputeOptions.defaultInstance().service(); @@ -50,11 +52,7 @@ public static void main(String... args) throws InterruptedException { RegionAddressId addressId = RegionAddressId.of("us-central1", "test-address"); Operation operation = compute.create(AddressInfo.of(addressId)); // Wait for operation to complete - while (!operation.isDone()) { - Thread.sleep(1000L); - } - // Check operation errors - operation = operation.reload(); + operation = operation.waitFor(); if (operation.errors() == null) { System.out.println("Address " + addressId + " was successfully created"); } else { @@ -69,11 +67,7 @@ public static void main(String... args) throws InterruptedException { DiskInfo disk = DiskInfo.of(diskId, diskConfiguration); operation = compute.create(disk); // Wait for operation to complete - while (!operation.isDone()) { - Thread.sleep(1000L); - } - // Check operation errors - operation = operation.reload(); + operation = operation.waitFor(); if (operation.errors() == null) { System.out.println("Disk " + diskId + " was successfully created"); } else { @@ -96,11 +90,7 @@ public static void main(String... args) throws InterruptedException { InstanceInfo.of(instanceId, machineTypeId, attachedDisk, networkInterface); operation = compute.create(instance); // Wait for operation to complete - while (!operation.isDone()) { - Thread.sleep(1000L); - } - // Check operation errors - operation = operation.reload(); + operation = operation.waitFor(); if (operation.errors() == null) { System.out.println("Instance " + instanceId + " was successfully created"); } else { diff --git a/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateInstance.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateInstance.java index d8162908d133..66c10bace269 100644 --- a/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateInstance.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateInstance.java @@ -28,12 +28,14 @@ import com.google.cloud.compute.NetworkInterface; import com.google.cloud.compute.Operation; +import java.util.concurrent.TimeoutException; + /** * A snippet for Google Cloud Compute Engine showing how to create a virtual machine instance. */ public class CreateInstance { - public static void main(String... args) throws InterruptedException { + public static void main(String... args) throws InterruptedException, TimeoutException { Compute compute = ComputeOptions.defaultInstance().service(); ImageId imageId = ImageId.of("debian-cloud", "debian-8-jessie-v20160329"); NetworkId networkId = NetworkId.of("default"); @@ -43,9 +45,7 @@ public static void main(String... args) throws InterruptedException { MachineTypeId machineTypeId = MachineTypeId.of("us-central1-a", "n1-standard-1"); Operation operation = compute.create(InstanceInfo.of(instanceId, machineTypeId, attachedDisk, networkInterface)); - while (!operation.isDone()) { - Thread.sleep(1000L); - } + operation = operation.waitFor(); if (operation.errors() == null) { // use instance Instance instance = compute.getInstance(instanceId); diff --git a/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateSnapshot.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateSnapshot.java index cc8029936186..35d19e38e18e 100644 --- a/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateSnapshot.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/compute/snippets/CreateSnapshot.java @@ -23,25 +23,25 @@ import com.google.cloud.compute.Operation; import com.google.cloud.compute.Snapshot; +import java.util.concurrent.TimeoutException; + /** * A snippet for Google Cloud Compute Engine showing how to create a snapshot of a disk if the disk * exists. */ public class CreateSnapshot { - public static void main(String... args) throws InterruptedException { + public static void main(String... args) throws InterruptedException, TimeoutException { Compute compute = ComputeOptions.defaultInstance().service(); DiskId diskId = DiskId.of("us-central1-a", "disk-name"); Disk disk = compute.getDisk(diskId, Compute.DiskOption.fields()); if (disk != null) { String snapshotName = "disk-name-snapshot"; Operation operation = disk.createSnapshot(snapshotName); - while (!operation.isDone()) { - Thread.sleep(1000L); - } + operation = operation.waitFor(); if (operation.errors() == null) { // use snapshot - Snapshot snapshot = compute.getSnapshot("disk-name-snapshot"); + Snapshot snapshot = compute.getSnapshot(snapshotName); } } } From 6539fbf54337e0ec0fad2192e0b0bc5beed0f2fa Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 10 Jun 2016 15:49:27 +0200 Subject: [PATCH 371/375] Update bigquery dependency and add support for BYTES datatype (#1045) * Update BigQuery dependency * Add support for BYTES data type --- gcloud-java-bigquery/pom.xml | 2 +- .../com/google/cloud/bigquery/CsvOptions.java | 31 ++-- .../java/com/google/cloud/bigquery/Field.java | 9 +- .../com/google/cloud/bigquery/FieldValue.java | 25 ++- .../cloud/bigquery/InsertAllRequest.java | 31 ++-- .../cloud/bigquery/LoadJobConfiguration.java | 22 ++- .../bigquery/WriteChannelConfiguration.java | 22 ++- .../google/cloud/bigquery/CsvOptionsTest.java | 4 +- .../google/cloud/bigquery/FieldValueTest.java | 12 ++ .../cloud/bigquery/SerializationTest.java | 2 +- .../cloud/bigquery/it/ITBigQueryTest.java | 171 +++++++++++------- .../examples/bigquery/BigQueryExample.java | 11 +- 12 files changed, 226 insertions(+), 116 deletions(-) diff --git a/gcloud-java-bigquery/pom.xml b/gcloud-java-bigquery/pom.xml index 87b0efdd3cff..660dd93916df 100644 --- a/gcloud-java-bigquery/pom.xml +++ b/gcloud-java-bigquery/pom.xml @@ -31,7 +31,7 @@ com.google.apis google-api-services-bigquery - v2-rev270-1.21.0 + v2-rev303-1.22.0 compile diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/CsvOptions.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/CsvOptions.java index b621ed2cc6bc..4273740f91d2 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/CsvOptions.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/CsvOptions.java @@ -34,7 +34,7 @@ public final class CsvOptions extends FormatOptions { private final String encoding; private final String fieldDelimiter; private final String quote; - private final Integer skipLeadingRows; + private final Long skipLeadingRows; public static final class Builder { @@ -43,10 +43,19 @@ public static final class Builder { private String encoding; private String fieldDelimiter; private String quote; - private Integer skipLeadingRows; + private Long skipLeadingRows; private Builder() {} + private Builder(CsvOptions csvOptions) { + this.allowJaggedRows = csvOptions.allowJaggedRows; + this.allowQuotedNewLines = csvOptions.allowQuotedNewLines; + this.encoding = csvOptions.encoding; + this.fieldDelimiter = csvOptions.fieldDelimiter; + this.quote = csvOptions.quote; + this.skipLeadingRows = csvOptions.skipLeadingRows; + } + /** * Set whether BigQuery should accept rows that are missing trailing optional columns. If * {@code true}, BigQuery treats missing trailing columns as null values. If {@code false}, @@ -54,7 +63,7 @@ private Builder() {} * bad records, an invalid error is returned in the job result. By default, rows with missing * trailing columns are considered bad records. */ - public Builder allowJaggedRows(Boolean allowJaggedRows) { + public Builder allowJaggedRows(boolean allowJaggedRows) { this.allowJaggedRows = allowJaggedRows; return this; } @@ -63,7 +72,7 @@ public Builder allowJaggedRows(Boolean allowJaggedRows) { * Sets whether BigQuery should allow quoted data sections that contain newline characters in a * CSV file. By default quoted newline are not allowed. */ - public Builder allowQuotedNewLines(Boolean allowQuotedNewLines) { + public Builder allowQuotedNewLines(boolean allowQuotedNewLines) { this.allowQuotedNewLines = allowQuotedNewLines; return this; } @@ -104,7 +113,7 @@ public Builder fieldDelimiter(String fieldDelimiter) { * string to ISO-8859-1 encoding, and then uses the first byte of the encoded string to split * the data in its raw, binary state. The default value is a double-quote ('"'). If your data * does not contain quoted sections, set the property value to an empty string. If your data - * contains quoted newline characters, you must also set {@link #allowQuotedNewLines(Boolean)} + * contains quoted newline characters, you must also set {@link #allowQuotedNewLines(boolean)} * property to {@code true}. */ public Builder quote(String quote) { @@ -117,7 +126,7 @@ public Builder quote(String quote) { * data. The default value is 0. This property is useful if you have header rows in the file * that should be skipped. */ - public Builder skipLeadingRows(Integer skipLeadingRows) { + public Builder skipLeadingRows(long skipLeadingRows) { this.skipLeadingRows = skipLeadingRows; return this; } @@ -186,7 +195,7 @@ public String quote() { * Returns the number of rows at the top of a CSV file that BigQuery will skip when reading the * data. */ - public Integer skipLeadingRows() { + public Long skipLeadingRows() { return skipLeadingRows; } @@ -194,13 +203,7 @@ public Integer skipLeadingRows() { * Returns a builder for the {@code CsvOptions} object. */ public Builder toBuilder() { - return new Builder() - .allowJaggedRows(allowJaggedRows) - .allowQuotedNewLines(allowQuotedNewLines) - .encoding(encoding) - .fieldDelimiter(fieldDelimiter) - .quote(quote) - .skipLeadingRows(skipLeadingRows); + return new Builder(this); } @Override diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Field.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Field.java index dc805e12c2a2..874049aa033a 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Field.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/Field.java @@ -73,7 +73,7 @@ public static class Type implements Serializable { private static final long serialVersionUID = 2841484762609576959L; public enum Value { - STRING, INTEGER, FLOAT, BOOLEAN, TIMESTAMP, RECORD + BYTES, STRING, INTEGER, FLOAT, BOOLEAN, TIMESTAMP, RECORD } private final Value value; @@ -108,6 +108,13 @@ public List fields() { return fields; } + /** + * Returns a {@link Value#BYTES} field value. + */ + public static Type bytes() { + return new Type(Value.BYTES); + } + /** * Returns a {@link Value#STRING} field value. */ diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/FieldValue.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/FieldValue.java index 1c06b87d639d..1eb3115a3644 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/FieldValue.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/FieldValue.java @@ -23,6 +23,7 @@ import com.google.common.base.Function; import com.google.common.base.MoreObjects; import com.google.common.collect.Lists; +import com.google.common.io.BaseEncoding; import java.io.Serializable; import java.util.List; @@ -54,7 +55,7 @@ public FieldValue apply(Object pb) { public enum Attribute { /** * A primitive field value. A {@code FieldValue} is primitive when the corresponding field has - * type {@link Field.Type#bool()}, {@link Field.Type#string()}, + * type {@link Field.Type#bytes()}, {@link Field.Type#bool()}, {@link Field.Type#string()}, * {@link Field.Type#floatingPoint()}, {@link Field.Type#integer()}, * {@link Field.Type#timestamp()} or the value is set to {@code null}. */ @@ -80,7 +81,7 @@ public enum Attribute { * Returns the attribute of this Field Value. * * @return {@link Attribute#PRIMITIVE} if the field is a primitive type - * ({@link Field.Type#bool()}, {@link Field.Type#string()}, + * ({@link Field.Type#bytes()}, {@link Field.Type#bool()}, {@link Field.Type#string()}, * {@link Field.Type#floatingPoint()}, {@link Field.Type#integer()}, * {@link Field.Type#timestamp()}) or is {@code null}. Returns {@link Attribute#REPEATED} if * the corresponding field has ({@link Field.Mode#REPEATED}) mode. Returns @@ -108,8 +109,8 @@ public Object value() { /** * Returns this field's value as a {@link String}. This method should only be used if the - * corresponding field has primitive type ({@link Field.Type#bool()}, {@link Field.Type#string()}, - * {@link Field.Type#floatingPoint()}, {@link Field.Type#integer()}, + * corresponding field has primitive type ({@link Field.Type#bytes()}, {@link Field.Type#bool()}, + * {@link Field.Type#string()}, {@link Field.Type#floatingPoint()}, {@link Field.Type#integer()}, * {@link Field.Type#timestamp()}). * * @throws ClassCastException if the field is not a primitive type @@ -121,6 +122,22 @@ public String stringValue() { return (String) value; } + /** + * Returns this field's value as a byte array. This method should only be used if the + * corresponding field has primitive type ({@link Field.Type#bytes()}. + * + * @throws ClassCastException if the field is not a primitive type + * @throws NullPointerException if {@link #isNull()} returns {@code true} + * @throws IllegalStateException if the field value is not encoded in base64 + */ + public byte[] bytesValue() { + try { + return BaseEncoding.base64().decode(stringValue()); + } catch (IllegalArgumentException ex) { + throw new IllegalStateException(ex); + } + } + /** * Returns this field's value as a {@code long}. This method should only be used if the * corresponding field has {@link Field.Type#integer()} type. diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/InsertAllRequest.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/InsertAllRequest.java index b46257833b78..569f6990d897 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/InsertAllRequest.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/InsertAllRequest.java @@ -49,7 +49,9 @@ public final class InsertAllRequest implements Serializable { /** * A Google Big Query row to be inserted into a table. Each {@code RowToInsert} has an associated - * id used by BigQuery to detect duplicate insertion requests on a best-effort basis. + * id used by BigQuery to detect duplicate insertion requests on a best-effort basis. Please + * notice that data for fields of type {@link Field.Type#bytes()} must be provided as a base64 + * encoded string. * *

    Example usage of creating a row to insert: *

     {@code
    @@ -58,8 +60,9 @@ public final class InsertAllRequest implements Serializable {
        * recordContent.put("subfieldName1", "value");
        * recordContent.put("subfieldName2", repeatedFieldValue);
        * Map rowContent = new HashMap();
    -   * rowContent.put("fieldName1", true);
    -   * rowContent.put("fieldName2", recordContent);
    +   * rowContent.put("booleanFieldName", true);
    +   * rowContent.put("bytesFieldName", "DQ4KDQ==");
    +   * rowContent.put("recordFieldName", recordContent);
        * RowToInsert row = new RowToInsert("rowId", rowContent);
        * }
    * @@ -116,7 +119,8 @@ public boolean equals(Object obj) { } /** - * Creates a row to be inserted with associated id. + * Creates a row to be inserted with associated id. Please notice that data for fields of type + * {@link Field.Type#bytes()} must be provided as a base64 encoded string. * * @param id id of the row, used to identify duplicates * @param content the actual content of the row @@ -126,7 +130,8 @@ public static RowToInsert of(String id, Map content) { } /** - * Creates a row to be inserted without associated id. + * Creates a row to be inserted without associated id. Please notice that data for fields of + * type {@link Field.Type#bytes()} must be provided as a base64 encoded string. * * @param content the actual content of the row */ @@ -174,7 +179,8 @@ public Builder addRow(RowToInsert rowToInsert) { } /** - * Adds a row to be inserted with associated id. + * Adds a row to be inserted with associated id. Please notice that data for fields of type + * {@link Field.Type#bytes()} must be provided as a base64 encoded string. * *

    Example usage of adding a row with associated id: *

     {@code
    @@ -184,8 +190,9 @@ public Builder addRow(RowToInsert rowToInsert) {
          * recordContent.put("subfieldName1", "value");
          * recordContent.put("subfieldName2", repeatedFieldValue);
          * Map rowContent = new HashMap();
    -     * rowContent.put("fieldName1", true);
    -     * rowContent.put("fieldName2", recordContent);
    +     * rowContent.put("booleanFieldName", true);
    +     * rowContent.put("bytesFieldName", "DQ4KDQ==");
    +     * rowContent.put("recordFieldName", recordContent);
          * builder.addRow("rowId", rowContent);
          * }
    */ @@ -195,7 +202,8 @@ public Builder addRow(String id, Map content) { } /** - * Adds a row to be inserted without an associated id. + * Adds a row to be inserted without an associated id. Please notice that data for fields of + * type {@link Field.Type#bytes()} must be provided as a base64 encoded string. * *

    Example usage of adding a row without an associated id: *

     {@code
    @@ -205,8 +213,9 @@ public Builder addRow(String id, Map content) {
          * recordContent.put("subfieldName1", "value");
          * recordContent.put("subfieldName2", repeatedFieldValue);
          * Map rowContent = new HashMap();
    -     * rowContent.put("fieldName1", true);
    -     * rowContent.put("fieldName2", recordContent);
    +     * rowContent.put("booleanFieldName", true);
    +     * rowContent.put("bytesFieldName", "DQ4KDQ==");
    +     * rowContent.put("recordFieldName", recordContent);
          * builder.addRow(rowContent);
          * }
    */ diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/LoadJobConfiguration.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/LoadJobConfiguration.java index 03e2d7fea05e..ba55d9f67414 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/LoadJobConfiguration.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/LoadJobConfiguration.java @@ -21,6 +21,7 @@ import com.google.api.services.bigquery.model.JobConfigurationLoad; import com.google.common.base.MoreObjects.ToStringHelper; import com.google.common.collect.ImmutableList; +import com.google.common.primitives.Ints; import java.util.List; import java.util.Objects; @@ -97,12 +98,18 @@ private Builder(com.google.api.services.bigquery.model.JobConfiguration configur || loadConfigurationPb.getQuote() != null || loadConfigurationPb.getSkipLeadingRows() != null) { CsvOptions.Builder builder = CsvOptions.builder() - .allowJaggedRows(loadConfigurationPb.getAllowJaggedRows()) - .allowQuotedNewLines(loadConfigurationPb.getAllowQuotedNewlines()) .encoding(loadConfigurationPb.getEncoding()) .fieldDelimiter(loadConfigurationPb.getFieldDelimiter()) - .quote(loadConfigurationPb.getQuote()) - .skipLeadingRows(loadConfigurationPb.getSkipLeadingRows()); + .quote(loadConfigurationPb.getQuote()); + if (loadConfigurationPb.getAllowJaggedRows() != null) { + builder.allowJaggedRows(loadConfigurationPb.getAllowJaggedRows()); + } + if (loadConfigurationPb.getAllowQuotedNewlines() != null) { + builder.allowQuotedNewLines(loadConfigurationPb.getAllowQuotedNewlines()); + } + if (loadConfigurationPb.getSkipLeadingRows() != null) { + builder.skipLeadingRows(loadConfigurationPb.getSkipLeadingRows()); + } this.formatOptions = builder.build(); } this.maxBadRecords = loadConfigurationPb.getMaxBadRecords(); @@ -300,8 +307,11 @@ com.google.api.services.bigquery.model.JobConfiguration toPb() { .setAllowJaggedRows(csvOptions.allowJaggedRows()) .setAllowQuotedNewlines(csvOptions.allowQuotedNewLines()) .setEncoding(csvOptions.encoding()) - .setQuote(csvOptions.quote()) - .setSkipLeadingRows(csvOptions.skipLeadingRows()); + .setQuote(csvOptions.quote()); + if (csvOptions.skipLeadingRows() != null) { + // todo(mziccard) remove checked cast or comment when #1044 is closed + loadConfigurationPb.setSkipLeadingRows(Ints.checkedCast(csvOptions.skipLeadingRows())); + } } if (schema != null) { loadConfigurationPb.setSchema(schema.toPb()); diff --git a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/WriteChannelConfiguration.java b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/WriteChannelConfiguration.java index 898063e7e0ed..354b4c9443db 100644 --- a/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/WriteChannelConfiguration.java +++ b/gcloud-java-bigquery/src/main/java/com/google/cloud/bigquery/WriteChannelConfiguration.java @@ -23,6 +23,7 @@ import com.google.cloud.bigquery.JobInfo.WriteDisposition; import com.google.common.base.MoreObjects; import com.google.common.collect.ImmutableList; +import com.google.common.primitives.Ints; import java.io.Serializable; import java.util.List; @@ -90,12 +91,18 @@ private Builder(com.google.api.services.bigquery.model.JobConfiguration configur || loadConfigurationPb.getQuote() != null || loadConfigurationPb.getSkipLeadingRows() != null) { CsvOptions.Builder builder = CsvOptions.builder() - .allowJaggedRows(loadConfigurationPb.getAllowJaggedRows()) - .allowQuotedNewLines(loadConfigurationPb.getAllowQuotedNewlines()) .encoding(loadConfigurationPb.getEncoding()) .fieldDelimiter(loadConfigurationPb.getFieldDelimiter()) - .quote(loadConfigurationPb.getQuote()) - .skipLeadingRows(loadConfigurationPb.getSkipLeadingRows()); + .quote(loadConfigurationPb.getQuote()); + if (loadConfigurationPb.getAllowJaggedRows() != null) { + builder.allowJaggedRows(loadConfigurationPb.getAllowJaggedRows()); + } + if (loadConfigurationPb.getAllowQuotedNewlines() != null) { + builder.allowQuotedNewLines(loadConfigurationPb.getAllowQuotedNewlines()); + } + if (loadConfigurationPb.getSkipLeadingRows() != null) { + builder.skipLeadingRows(loadConfigurationPb.getSkipLeadingRows()); + } this.formatOptions = builder.build(); } this.maxBadRecords = loadConfigurationPb.getMaxBadRecords(); @@ -271,8 +278,11 @@ com.google.api.services.bigquery.model.JobConfiguration toPb() { .setAllowJaggedRows(csvOptions.allowJaggedRows()) .setAllowQuotedNewlines(csvOptions.allowQuotedNewLines()) .setEncoding(csvOptions.encoding()) - .setQuote(csvOptions.quote()) - .setSkipLeadingRows(csvOptions.skipLeadingRows()); + .setQuote(csvOptions.quote()); + if (csvOptions.skipLeadingRows() != null) { + // todo(mziccard) remove checked cast or comment when #1044 is closed + loadConfigurationPb.setSkipLeadingRows(Ints.checkedCast(csvOptions.skipLeadingRows())); + } } if (schema != null) { loadConfigurationPb.setSchema(schema.toPb()); diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/CsvOptionsTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/CsvOptionsTest.java index df56a5ae096e..edc5e8508188 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/CsvOptionsTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/CsvOptionsTest.java @@ -30,7 +30,7 @@ public class CsvOptionsTest { private static final Charset ENCODING = StandardCharsets.UTF_8; private static final String FIELD_DELIMITER = ","; private static final String QUOTE = "\""; - private static final Integer SKIP_LEADING_ROWS = 42; + private static final long SKIP_LEADING_ROWS = 42L; private static final CsvOptions CSV_OPTIONS = CsvOptions.builder() .allowJaggedRows(ALLOW_JAGGED_ROWS) .allowQuotedNewLines(ALLOW_QUOTED_NEWLINE) @@ -65,7 +65,7 @@ public void testBuilder() { assertEquals(ENCODING.name(), CSV_OPTIONS.encoding()); assertEquals(FIELD_DELIMITER, CSV_OPTIONS.fieldDelimiter()); assertEquals(QUOTE, CSV_OPTIONS.quote()); - assertEquals(SKIP_LEADING_ROWS, CSV_OPTIONS.skipLeadingRows()); + assertEquals(SKIP_LEADING_ROWS, (long) CSV_OPTIONS.skipLeadingRows()); } @Test diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/FieldValueTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/FieldValueTest.java index 82086768b8ce..e104ab909f5b 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/FieldValueTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/FieldValueTest.java @@ -16,6 +16,7 @@ package com.google.cloud.bigquery; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; @@ -24,6 +25,7 @@ import com.google.api.services.bigquery.model.TableCell; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.io.BaseEncoding; import org.junit.Test; @@ -31,11 +33,14 @@ public class FieldValueTest { + private static final byte[] BYTES = {0xD, 0xE, 0xA, 0xD}; + private static final String BYTES_BASE64 = BaseEncoding.base64().encode(BYTES); private static final TableCell BOOLEAN_FIELD = new TableCell().setV("false"); private static final Map INTEGER_FIELD = ImmutableMap.of("v", "1"); private static final Map FLOAT_FIELD = ImmutableMap.of("v", "1.5"); private static final Map STRING_FIELD = ImmutableMap.of("v", "string"); private static final Map TIMESTAMP_FIELD = ImmutableMap.of("v", "42"); + private static final Map BYTES_FIELD = ImmutableMap.of("v", BYTES_BASE64); private static final Map NULL_FIELD = ImmutableMap.of("v", Data.nullOf(String.class)); private static final Map REPEATED_FIELD = @@ -60,6 +65,9 @@ public void testFromPb() { value = FieldValue.fromPb(TIMESTAMP_FIELD); assertEquals(FieldValue.Attribute.PRIMITIVE, value.attribute()); assertEquals(42000000, value.timestampValue()); + value = FieldValue.fromPb(BYTES_FIELD); + assertEquals(FieldValue.Attribute.PRIMITIVE, value.attribute()); + assertArrayEquals(BYTES, value.bytesValue()); value = FieldValue.fromPb(NULL_FIELD); assertNull(value.value()); value = FieldValue.fromPb(REPEATED_FIELD); @@ -94,6 +102,10 @@ public void testEquals() { assertEquals(timestampValue, FieldValue.fromPb(TIMESTAMP_FIELD)); assertEquals(timestampValue.hashCode(), FieldValue.fromPb(TIMESTAMP_FIELD).hashCode()); + FieldValue bytesValue = new FieldValue(FieldValue.Attribute.PRIMITIVE, BYTES_BASE64); + assertEquals(bytesValue, FieldValue.fromPb(BYTES_FIELD)); + assertEquals(bytesValue.hashCode(), FieldValue.fromPb(BYTES_FIELD).hashCode()); + FieldValue nullValue = new FieldValue(FieldValue.Attribute.PRIMITIVE, null); assertEquals(nullValue, FieldValue.fromPb(NULL_FIELD)); assertEquals(nullValue.hashCode(), FieldValue.fromPb(NULL_FIELD).hashCode()); diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/SerializationTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/SerializationTest.java index 30b1b9e067ec..8e12e3a6839d 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/SerializationTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/SerializationTest.java @@ -68,7 +68,7 @@ public class SerializationTest extends BaseSerializationTest { .encoding(StandardCharsets.ISO_8859_1) .fieldDelimiter(",") .quote("\"") - .skipLeadingRows(42) + .skipLeadingRows(42L) .build(); private static final Field FIELD_SCHEMA1 = Field.builder("StringField", Field.Type.string()) diff --git a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java index dde170f87859..5573b36d4cbc 100644 --- a/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java +++ b/gcloud-java-bigquery/src/test/java/com/google/cloud/bigquery/it/ITBigQueryTest.java @@ -16,6 +16,7 @@ package com.google.cloud.bigquery.it; +import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -68,6 +69,7 @@ import com.google.cloud.storage.testing.RemoteStorageHelper; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.io.BaseEncoding; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -88,6 +90,8 @@ public class ITBigQueryTest { + private static final byte[] BYTES = {0xD, 0xE, 0xA, 0xD}; + private static final String BYTES_BASE64 = BaseEncoding.base64().encode(BYTES); private static final Logger LOG = Logger.getLogger(ITBigQueryTest.class.getName()); private static final String DATASET = RemoteBigQueryHelper.generateDatasetName(); private static final String DESCRIPTION = "Test dataset"; @@ -112,14 +116,19 @@ public class ITBigQueryTest { .mode(Field.Mode.NULLABLE) .description("BooleanDescription") .build(); + private static final Field BYTES_FIELD_SCHEMA = + Field.builder("BytesField", Field.Type.bytes()) + .mode(Field.Mode.NULLABLE) + .description("BytesDescription") + .build(); private static final Field RECORD_FIELD_SCHEMA = Field.builder("RecordField", Field.Type.record(TIMESTAMP_FIELD_SCHEMA, - STRING_FIELD_SCHEMA, INTEGER_FIELD_SCHEMA, BOOLEAN_FIELD_SCHEMA)) + STRING_FIELD_SCHEMA, INTEGER_FIELD_SCHEMA, BOOLEAN_FIELD_SCHEMA, BYTES_FIELD_SCHEMA)) .mode(Field.Mode.REQUIRED) .description("RecordDescription") .build(); private static final Schema TABLE_SCHEMA = Schema.of(TIMESTAMP_FIELD_SCHEMA, STRING_FIELD_SCHEMA, - INTEGER_FIELD_SCHEMA, BOOLEAN_FIELD_SCHEMA, RECORD_FIELD_SCHEMA); + INTEGER_FIELD_SCHEMA, BOOLEAN_FIELD_SCHEMA, BYTES_FIELD_SCHEMA, RECORD_FIELD_SCHEMA); private static final Schema SIMPLE_SCHEMA = Schema.of(STRING_FIELD_SCHEMA); private static final Schema QUERY_RESULT_SCHEMA = Schema.builder() .addField(Field.builder("TimestampField", Field.Type.timestamp()) @@ -143,11 +152,13 @@ public class ITBigQueryTest { + "\"StringField\": \"stringValue\"," + "\"IntegerField\": [\"0\", \"1\"]," + "\"BooleanField\": \"false\"," + + "\"BytesField\": \"" + BYTES_BASE64 + "\"," + "\"RecordField\": {" + "\"TimestampField\": \"1969-07-20 20:18:04 UTC\"," + "\"StringField\": null," + "\"IntegerField\": [\"1\",\"0\"]," - + "\"BooleanField\": \"true\"" + + "\"BooleanField\": \"true\"," + + "\"BytesField\": \"" + BYTES_BASE64 + "\"" + "}" + "}\n" + "{" @@ -155,11 +166,13 @@ public class ITBigQueryTest { + "\"StringField\": \"stringValue\"," + "\"IntegerField\": [\"0\", \"1\"]," + "\"BooleanField\": \"false\"," + + "\"BytesField\": \"" + BYTES_BASE64 + "\"," + "\"RecordField\": {" + "\"TimestampField\": \"1969-07-20 20:18:04 UTC\"," + "\"StringField\": null," + "\"IntegerField\": [\"1\",\"0\"]," - + "\"BooleanField\": \"true\"" + + "\"BooleanField\": \"true\"," + + "\"BytesField\": \"" + BYTES_BASE64 + "\"" + "}" + "}"; @@ -510,30 +523,36 @@ public void testDeleteNonExistingTable() { } @Test - public void testInsertAll() { + public void testInsertAll() throws IOException { String tableName = "test_insert_all_table"; StandardTableDefinition tableDefinition = StandardTableDefinition.of(TABLE_SCHEMA); TableInfo tableInfo = TableInfo.of(TableId.of(DATASET, tableName), tableDefinition); assertNotNull(bigquery.create(tableInfo)); + ImmutableMap.Builder builder1 = ImmutableMap.builder(); + builder1.put("TimestampField", "2014-08-19 07:41:35.220 -05:00"); + builder1.put("StringField", "stringValue"); + builder1.put("IntegerField", ImmutableList.of(0, 1)); + builder1.put("BooleanField", false); + builder1.put("BytesField", BYTES_BASE64); + builder1.put("RecordField", ImmutableMap.of( + "TimestampField", "1969-07-20 20:18:04 UTC", + "IntegerField", ImmutableList.of(1, 0), + "BooleanField", true, + "BytesField", BYTES_BASE64)); + ImmutableMap.Builder builder2 = ImmutableMap.builder(); + builder2.put("TimestampField", "2014-08-19 07:41:35.220 -05:00"); + builder2.put("StringField", "stringValue"); + builder2.put("IntegerField", ImmutableList.of(0, 1)); + builder2.put("BooleanField", false); + builder2.put("BytesField", BYTES_BASE64); + builder2.put("RecordField", ImmutableMap.of( + "TimestampField", "1969-07-20 20:18:04 UTC", + "IntegerField", ImmutableList.of(1, 0), + "BooleanField", true, + "BytesField", BYTES_BASE64)); InsertAllRequest request = InsertAllRequest.builder(tableInfo.tableId()) - .addRow(ImmutableMap.of( - "TimestampField", "2014-08-19 07:41:35.220 -05:00", - "StringField", "stringValue", - "IntegerField", ImmutableList.of(0, 1), - "BooleanField", false, - "RecordField", ImmutableMap.of( - "TimestampField", "1969-07-20 20:18:04 UTC", - "IntegerField", ImmutableList.of(1, 0), - "BooleanField", true))) - .addRow(ImmutableMap.of( - "TimestampField", "2014-08-19 07:41:35.220 -05:00", - "StringField", "stringValue", - "IntegerField", ImmutableList.of(0, 1), - "BooleanField", false, - "RecordField", ImmutableMap.of( - "TimestampField", "1969-07-20 20:18:04 UTC", - "IntegerField", ImmutableList.of(1, 0), - "BooleanField", true))) + .addRow(builder1.build()) + .addRow(builder2.build()) .build(); InsertAllResponse response = bigquery.insertAll(request); assertFalse(response.hasErrors()); @@ -547,25 +566,31 @@ public void testInsertAllWithSuffix() throws InterruptedException { StandardTableDefinition tableDefinition = StandardTableDefinition.of(TABLE_SCHEMA); TableInfo tableInfo = TableInfo.of(TableId.of(DATASET, tableName), tableDefinition); assertNotNull(bigquery.create(tableInfo)); + ImmutableMap.Builder builder1 = ImmutableMap.builder(); + builder1.put("TimestampField", "2014-08-19 07:41:35.220 -05:00"); + builder1.put("StringField", "stringValue"); + builder1.put("IntegerField", ImmutableList.of(0, 1)); + builder1.put("BooleanField", false); + builder1.put("BytesField", BYTES_BASE64); + builder1.put("RecordField", ImmutableMap.of( + "TimestampField", "1969-07-20 20:18:04 UTC", + "IntegerField", ImmutableList.of(1, 0), + "BooleanField", true, + "BytesField", BYTES_BASE64)); + ImmutableMap.Builder builder2 = ImmutableMap.builder(); + builder2.put("TimestampField", "2014-08-19 07:41:35.220 -05:00"); + builder2.put("StringField", "stringValue"); + builder2.put("IntegerField", ImmutableList.of(0, 1)); + builder2.put("BooleanField", false); + builder2.put("BytesField", BYTES_BASE64); + builder2.put("RecordField", ImmutableMap.of( + "TimestampField", "1969-07-20 20:18:04 UTC", + "IntegerField", ImmutableList.of(1, 0), + "BooleanField", true, + "BytesField", BYTES_BASE64)); InsertAllRequest request = InsertAllRequest.builder(tableInfo.tableId()) - .addRow(ImmutableMap.of( - "TimestampField", "2014-08-19 07:41:35.220 -05:00", - "StringField", "stringValue", - "IntegerField", ImmutableList.of(0, 1), - "BooleanField", false, - "RecordField", ImmutableMap.of( - "TimestampField", "1969-07-20 20:18:04 UTC", - "IntegerField", ImmutableList.of(1, 0), - "BooleanField", true))) - .addRow(ImmutableMap.of( - "TimestampField", "2014-08-19 07:41:35.220 -05:00", - "StringField", "stringValue", - "IntegerField", ImmutableList.of(0, 1), - "BooleanField", false, - "RecordField", ImmutableMap.of( - "TimestampField", "1969-07-20 20:18:04 UTC", - "IntegerField", ImmutableList.of(1, 0), - "BooleanField", true))) + .addRow(builder1.build()) + .addRow(builder2.build()) .templateSuffix("_suffix") .build(); InsertAllResponse response = bigquery.insertAll(request); @@ -588,30 +613,38 @@ public void testInsertAllWithErrors() { StandardTableDefinition tableDefinition = StandardTableDefinition.of(TABLE_SCHEMA); TableInfo tableInfo = TableInfo.of(TableId.of(DATASET, tableName), tableDefinition); assertNotNull(bigquery.create(tableInfo)); + ImmutableMap.Builder builder1 = ImmutableMap.builder(); + builder1.put("TimestampField", "2014-08-19 07:41:35.220 -05:00"); + builder1.put("StringField", "stringValue"); + builder1.put("IntegerField", ImmutableList.of(0, 1)); + builder1.put("BooleanField", false); + builder1.put("BytesField", BYTES_BASE64); + builder1.put("RecordField", ImmutableMap.of( + "TimestampField", "1969-07-20 20:18:04 UTC", + "IntegerField", ImmutableList.of(1, 0), + "BooleanField", true, + "BytesField", BYTES_BASE64)); + ImmutableMap.Builder builder2 = ImmutableMap.builder(); + builder2.put("TimestampField", "invalidDate"); + builder2.put("StringField", "stringValue"); + builder2.put("IntegerField", ImmutableList.of(0, 1)); + builder2.put("BooleanField", false); + builder2.put("BytesField", BYTES_BASE64); + builder2.put("RecordField", ImmutableMap.of( + "TimestampField", "1969-07-20 20:18:04 UTC", + "IntegerField", ImmutableList.of(1, 0), + "BooleanField", true, + "BytesField", BYTES_BASE64)); + ImmutableMap.Builder builder3 = ImmutableMap.builder(); + builder3.put("TimestampField", "2014-08-19 07:41:35.220 -05:00"); + builder3.put("StringField", "stringValue"); + builder3.put("IntegerField", ImmutableList.of(0, 1)); + builder3.put("BooleanField", false); + builder3.put("BytesField", BYTES_BASE64); InsertAllRequest request = InsertAllRequest.builder(tableInfo.tableId()) - .addRow(ImmutableMap.of( - "TimestampField", "2014-08-19 07:41:35.220 -05:00", - "StringField", "stringValue", - "IntegerField", ImmutableList.of(0, 1), - "BooleanField", false, - "RecordField", ImmutableMap.of( - "TimestampField", "1969-07-20 20:18:04 UTC", - "IntegerField", ImmutableList.of(1, 0), - "BooleanField", true))) - .addRow(ImmutableMap.of( - "TimestampField", "invalidDate", - "StringField", "stringValue", - "IntegerField", ImmutableList.of(0, 1), - "BooleanField", false, - "RecordField", ImmutableMap.of( - "TimestampField", "1969-07-20 20:18:04 UTC", - "IntegerField", ImmutableList.of(1, 0), - "BooleanField", true))) - .addRow(ImmutableMap.of( - "TimestampField", "1969-07-20 20:18:04 UTC", - "StringField", "stringValue", - "IntegerField", ImmutableList.of(0, 1), - "BooleanField", false)) + .addRow(builder1.build()) + .addRow(builder2.build()) + .addRow(builder3.build()) .skipInvalidRows(true) .build(); InsertAllResponse response = bigquery.insertAll(request); @@ -631,17 +664,20 @@ public void testListAllTableData() { FieldValue stringCell = row.get(1); FieldValue integerCell = row.get(2); FieldValue booleanCell = row.get(3); - FieldValue recordCell = row.get(4); + FieldValue bytesCell = row.get(4); + FieldValue recordCell = row.get(5); assertEquals(FieldValue.Attribute.PRIMITIVE, timestampCell.attribute()); assertEquals(FieldValue.Attribute.PRIMITIVE, stringCell.attribute()); assertEquals(FieldValue.Attribute.REPEATED, integerCell.attribute()); assertEquals(FieldValue.Attribute.PRIMITIVE, booleanCell.attribute()); + assertEquals(FieldValue.Attribute.PRIMITIVE, bytesCell.attribute()); assertEquals(FieldValue.Attribute.RECORD, recordCell.attribute()); assertEquals(1408452095220000L, timestampCell.timestampValue()); assertEquals("stringValue", stringCell.stringValue()); assertEquals(0, integerCell.repeatedValue().get(0).longValue()); assertEquals(1, integerCell.repeatedValue().get(1).longValue()); assertEquals(false, booleanCell.booleanValue()); + assertArrayEquals(BYTES, bytesCell.bytesValue()); assertEquals(-14182916000000L, recordCell.recordValue().get(0).timestampValue()); assertTrue(recordCell.recordValue().get(1).isNull()); assertEquals(1, recordCell.recordValue().get(2).repeatedValue().get(0).longValue()); @@ -920,17 +956,20 @@ public void testInsertFromFile() throws InterruptedException { FieldValue stringCell = row.get(1); FieldValue integerCell = row.get(2); FieldValue booleanCell = row.get(3); - FieldValue recordCell = row.get(4); + FieldValue bytesCell = row.get(4); + FieldValue recordCell = row.get(5); assertEquals(FieldValue.Attribute.PRIMITIVE, timestampCell.attribute()); assertEquals(FieldValue.Attribute.PRIMITIVE, stringCell.attribute()); assertEquals(FieldValue.Attribute.REPEATED, integerCell.attribute()); assertEquals(FieldValue.Attribute.PRIMITIVE, booleanCell.attribute()); + assertEquals(FieldValue.Attribute.PRIMITIVE, bytesCell.attribute()); assertEquals(FieldValue.Attribute.RECORD, recordCell.attribute()); assertEquals(1408452095220000L, timestampCell.timestampValue()); assertEquals("stringValue", stringCell.stringValue()); assertEquals(0, integerCell.repeatedValue().get(0).longValue()); assertEquals(1, integerCell.repeatedValue().get(1).longValue()); assertEquals(false, booleanCell.booleanValue()); + assertArrayEquals(BYTES, bytesCell.bytesValue()); assertEquals(-14182916000000L, recordCell.recordValue().get(0).timestampValue()); assertTrue(recordCell.recordValue().get(1).isNull()); assertEquals(1, recordCell.recordValue().get(2).repeatedValue().get(0).longValue()); diff --git a/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java b/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java index 156e475a5ac9..3ac1335cca7a 100644 --- a/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java +++ b/gcloud-java-examples/src/main/java/com/google/cloud/examples/bigquery/BigQueryExample.java @@ -92,10 +92,10 @@ * operations that apply to more than one entity (`list`, `create`, `info` and `delete`) the third * parameter specifies the entity. {@code } indicates that only primitive types are * supported by the {@code create table} and {@code create external-table} operations - * ({@code string}, {@code float}, {@code integer}, {@code timestamp}, {@code boolean}). - * {@code }, {@code } and {@code } parameters are URIs to - * Google Cloud Storage blobs, in the form {@code gs://bucket/path}. See each action's run method - * for the specific BigQuery interaction. + * ({@code string}, {@code float}, {@code integer}, {@code timestamp}, {@code boolean}, + * {@code bytes}). {@code }, {@code } and {@code } + * parameters are URIs to Google Cloud Storage blobs, in the form {@code gs://bucket/path}. + * See each action's run method for the specific BigQuery interaction. */ public class BigQueryExample { @@ -426,6 +426,9 @@ static Schema parseSchema(String[] args, int start, int end) { case "boolean": fieldType = Field.Type.bool(); break; + case "bytes": + fieldType = Field.Type.bytes(); + break; default: throw new IllegalArgumentException("Unrecognized field type '" + typeString + "'."); } From cb575508b59b0ffa8f4c133e8a0337ca411e179d Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 10 Jun 2016 16:17:16 +0200 Subject: [PATCH 372/375] Release 0.2.3 --- gcloud-java-bigquery/pom.xml | 2 +- gcloud-java-compute/pom.xml | 2 +- gcloud-java-contrib/pom.xml | 2 +- gcloud-java-core/pom.xml | 2 +- gcloud-java-datastore/pom.xml | 2 +- gcloud-java-dns/pom.xml | 2 +- gcloud-java-examples/pom.xml | 2 +- gcloud-java-resourcemanager/pom.xml | 2 +- gcloud-java-storage/pom.xml | 2 +- gcloud-java/pom.xml | 2 +- pom.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/gcloud-java-bigquery/pom.xml b/gcloud-java-bigquery/pom.xml index 660dd93916df..fd0f308a10d6 100644 --- a/gcloud-java-bigquery/pom.xml +++ b/gcloud-java-bigquery/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.3-SNAPSHOT + 0.2.3 gcloud-java-bigquery diff --git a/gcloud-java-compute/pom.xml b/gcloud-java-compute/pom.xml index 57de0db7627f..a7e40fb9107f 100644 --- a/gcloud-java-compute/pom.xml +++ b/gcloud-java-compute/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.3-SNAPSHOT + 0.2.3 gcloud-java-compute diff --git a/gcloud-java-contrib/pom.xml b/gcloud-java-contrib/pom.xml index 341750b29225..e5ba21c09498 100644 --- a/gcloud-java-contrib/pom.xml +++ b/gcloud-java-contrib/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.3-SNAPSHOT + 0.2.3 gcloud-java-contrib diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml index 8ebc30a629b9..2a41f628b13a 100644 --- a/gcloud-java-core/pom.xml +++ b/gcloud-java-core/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.3-SNAPSHOT + 0.2.3 gcloud-java-core diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index bcbd50334e2f..32cd19b4c0cc 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.3-SNAPSHOT + 0.2.3 gcloud-java-datastore diff --git a/gcloud-java-dns/pom.xml b/gcloud-java-dns/pom.xml index 6a18f5c69857..bbbd96ecd34c 100644 --- a/gcloud-java-dns/pom.xml +++ b/gcloud-java-dns/pom.xml @@ -13,7 +13,7 @@ com.google.cloud gcloud-java-pom - 0.2.3-SNAPSHOT + 0.2.3 gcloud-java-dns diff --git a/gcloud-java-examples/pom.xml b/gcloud-java-examples/pom.xml index ec22aa6b4e0d..4630352ebbce 100644 --- a/gcloud-java-examples/pom.xml +++ b/gcloud-java-examples/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.3-SNAPSHOT + 0.2.3 gcloud-java-examples diff --git a/gcloud-java-resourcemanager/pom.xml b/gcloud-java-resourcemanager/pom.xml index 64cecd4385ff..1eed94ec17bb 100644 --- a/gcloud-java-resourcemanager/pom.xml +++ b/gcloud-java-resourcemanager/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.3-SNAPSHOT + 0.2.3 gcloud-java-resourcemanager diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml index 996ced995ce3..83f4a4fa15d9 100644 --- a/gcloud-java-storage/pom.xml +++ b/gcloud-java-storage/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.3-SNAPSHOT + 0.2.3 gcloud-java-storage diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml index ed6a7115af6e..4b7ce9c91817 100644 --- a/gcloud-java/pom.xml +++ b/gcloud-java/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.3-SNAPSHOT + 0.2.3 diff --git a/pom.xml b/pom.xml index 862e3c4c20f7..574abd6312dc 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud gcloud-java-pom pom - 0.2.3-SNAPSHOT + 0.2.3 GCloud Java https://github.com/GoogleCloudPlatform/gcloud-java From adb2f6540b50d4e60b00a2168f27ac28f0a3be5b Mon Sep 17 00:00:00 2001 From: travis-ci Date: Fri, 10 Jun 2016 15:23:17 +0000 Subject: [PATCH 373/375] Updating version in README files. [ci skip] --- README.md | 6 +++--- gcloud-java-bigquery/README.md | 6 +++--- gcloud-java-compute/README.md | 6 +++--- gcloud-java-contrib/README.md | 6 +++--- gcloud-java-core/README.md | 6 +++--- gcloud-java-datastore/README.md | 6 +++--- gcloud-java-dns/README.md | 6 +++--- gcloud-java-examples/README.md | 6 +++--- gcloud-java-resourcemanager/README.md | 6 +++--- gcloud-java-storage/README.md | 6 +++--- gcloud-java/README.md | 6 +++--- 11 files changed, 33 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index f851112f415a..b6a00536f567 100644 --- a/README.md +++ b/README.md @@ -34,16 +34,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java - 0.2.2 + 0.2.3 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java:0.2.2' +compile 'com.google.cloud:gcloud-java:0.2.3' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java" % "0.2.2" +libraryDependencies += "com.google.cloud" % "gcloud-java" % "0.2.3" ``` Example Applications diff --git a/gcloud-java-bigquery/README.md b/gcloud-java-bigquery/README.md index 682221240717..90f49bcf6b4a 100644 --- a/gcloud-java-bigquery/README.md +++ b/gcloud-java-bigquery/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-bigquery - 0.2.2 + 0.2.3 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-bigquery:0.2.2' +compile 'com.google.cloud:gcloud-java-bigquery:0.2.3' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-bigquery" % "0.2.2" +libraryDependencies += "com.google.cloud" % "gcloud-java-bigquery" % "0.2.3" ``` Example Application diff --git a/gcloud-java-compute/README.md b/gcloud-java-compute/README.md index 19c0d56b5b41..0b16cc11b366 100644 --- a/gcloud-java-compute/README.md +++ b/gcloud-java-compute/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-compute - 0.2.2 + 0.2.3 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-compute:0.2.2' +compile 'com.google.cloud:gcloud-java-compute:0.2.3' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-compute" % "0.2.2" +libraryDependencies += "com.google.cloud" % "gcloud-java-compute" % "0.2.3" ``` Example Application diff --git a/gcloud-java-contrib/README.md b/gcloud-java-contrib/README.md index 42801649b277..a70977a1530c 100644 --- a/gcloud-java-contrib/README.md +++ b/gcloud-java-contrib/README.md @@ -16,16 +16,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-contrib - 0.2.2 + 0.2.3 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-contrib:0.2.2' +compile 'com.google.cloud:gcloud-java-contrib:0.2.3' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-contrib" % "0.2.2" +libraryDependencies += "com.google.cloud" % "gcloud-java-contrib" % "0.2.3" ``` Java Versions diff --git a/gcloud-java-core/README.md b/gcloud-java-core/README.md index b9d33a72437d..abd95a563cfb 100644 --- a/gcloud-java-core/README.md +++ b/gcloud-java-core/README.md @@ -19,16 +19,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-core - 0.2.2 + 0.2.3 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-core:0.2.2' +compile 'com.google.cloud:gcloud-java-core:0.2.3' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-core" % "0.2.2" +libraryDependencies += "com.google.cloud" % "gcloud-java-core" % "0.2.3" ``` Troubleshooting diff --git a/gcloud-java-datastore/README.md b/gcloud-java-datastore/README.md index e033a5298584..e0384969974f 100644 --- a/gcloud-java-datastore/README.md +++ b/gcloud-java-datastore/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-datastore - 0.2.2 + 0.2.3 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-datastore:0.2.2' +compile 'com.google.cloud:gcloud-java-datastore:0.2.3' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-datastore" % "0.2.2" +libraryDependencies += "com.google.cloud" % "gcloud-java-datastore" % "0.2.3" ``` Example Application diff --git a/gcloud-java-dns/README.md b/gcloud-java-dns/README.md index 161617127ef6..8ce767875935 100644 --- a/gcloud-java-dns/README.md +++ b/gcloud-java-dns/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-dns - 0.2.2 + 0.2.3 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-dns:0.2.2' +compile 'com.google.cloud:gcloud-java-dns:0.2.3' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-dns" % "0.2.2" +libraryDependencies += "com.google.cloud" % "gcloud-java-dns" % "0.2.3" ``` Example Application diff --git a/gcloud-java-examples/README.md b/gcloud-java-examples/README.md index b51af6c09fff..588236d8d7fe 100644 --- a/gcloud-java-examples/README.md +++ b/gcloud-java-examples/README.md @@ -19,16 +19,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-examples - 0.2.2 + 0.2.3 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-examples:0.2.2' +compile 'com.google.cloud:gcloud-java-examples:0.2.3' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-examples" % "0.2.2" +libraryDependencies += "com.google.cloud" % "gcloud-java-examples" % "0.2.3" ``` To run examples from your command line: diff --git a/gcloud-java-resourcemanager/README.md b/gcloud-java-resourcemanager/README.md index 519c0e92a0ac..e9a5c7d2dd79 100644 --- a/gcloud-java-resourcemanager/README.md +++ b/gcloud-java-resourcemanager/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-resourcemanager - 0.2.2 + 0.2.3 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-resourcemanager:0.2.2' +compile 'com.google.cloud:gcloud-java-resourcemanager:0.2.3' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-resourcemanager" % "0.2.2" +libraryDependencies += "com.google.cloud" % "gcloud-java-resourcemanager" % "0.2.3" ``` Example Application diff --git a/gcloud-java-storage/README.md b/gcloud-java-storage/README.md index e5dd12d407b6..d8940ae7ce41 100644 --- a/gcloud-java-storage/README.md +++ b/gcloud-java-storage/README.md @@ -22,16 +22,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java-storage - 0.2.2 + 0.2.3 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java-storage:0.2.2' +compile 'com.google.cloud:gcloud-java-storage:0.2.3' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java-storage" % "0.2.2" +libraryDependencies += "com.google.cloud" % "gcloud-java-storage" % "0.2.3" ``` Example Application diff --git a/gcloud-java/README.md b/gcloud-java/README.md index 87c1404ce001..cf2a42f0ccb2 100644 --- a/gcloud-java/README.md +++ b/gcloud-java/README.md @@ -27,16 +27,16 @@ If you are using Maven, add this to your pom.xml file com.google.cloud gcloud-java - 0.2.2 + 0.2.3 ``` If you are using Gradle, add this to your dependencies ```Groovy -compile 'com.google.cloud:gcloud-java:0.2.2' +compile 'com.google.cloud:gcloud-java:0.2.3' ``` If you are using SBT, add this to your dependencies ```Scala -libraryDependencies += "com.google.cloud" % "gcloud-java" % "0.2.2" +libraryDependencies += "com.google.cloud" % "gcloud-java" % "0.2.3" ``` Troubleshooting From 45e2751f5572ed2876eebd61fed9c85ba5c5d1f0 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Fri, 10 Jun 2016 18:14:06 +0200 Subject: [PATCH 374/375] Update version to 0.2.4-SNAPSHOT --- gcloud-java-bigquery/pom.xml | 2 +- gcloud-java-compute/pom.xml | 2 +- gcloud-java-contrib/pom.xml | 2 +- gcloud-java-core/pom.xml | 2 +- gcloud-java-datastore/pom.xml | 2 +- gcloud-java-dns/pom.xml | 2 +- gcloud-java-examples/pom.xml | 2 +- gcloud-java-resourcemanager/pom.xml | 2 +- gcloud-java-storage/pom.xml | 2 +- gcloud-java/pom.xml | 2 +- pom.xml | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/gcloud-java-bigquery/pom.xml b/gcloud-java-bigquery/pom.xml index fd0f308a10d6..1682bd7080bd 100644 --- a/gcloud-java-bigquery/pom.xml +++ b/gcloud-java-bigquery/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.3 + 0.2.4-SNAPSHOT gcloud-java-bigquery diff --git a/gcloud-java-compute/pom.xml b/gcloud-java-compute/pom.xml index a7e40fb9107f..99a17fd573db 100644 --- a/gcloud-java-compute/pom.xml +++ b/gcloud-java-compute/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.3 + 0.2.4-SNAPSHOT gcloud-java-compute diff --git a/gcloud-java-contrib/pom.xml b/gcloud-java-contrib/pom.xml index e5ba21c09498..10f649fd7359 100644 --- a/gcloud-java-contrib/pom.xml +++ b/gcloud-java-contrib/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.3 + 0.2.4-SNAPSHOT gcloud-java-contrib diff --git a/gcloud-java-core/pom.xml b/gcloud-java-core/pom.xml index 2a41f628b13a..927256b57778 100644 --- a/gcloud-java-core/pom.xml +++ b/gcloud-java-core/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.3 + 0.2.4-SNAPSHOT gcloud-java-core diff --git a/gcloud-java-datastore/pom.xml b/gcloud-java-datastore/pom.xml index 32cd19b4c0cc..099a39d4756c 100644 --- a/gcloud-java-datastore/pom.xml +++ b/gcloud-java-datastore/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.3 + 0.2.4-SNAPSHOT gcloud-java-datastore diff --git a/gcloud-java-dns/pom.xml b/gcloud-java-dns/pom.xml index bbbd96ecd34c..3e157eaaeec2 100644 --- a/gcloud-java-dns/pom.xml +++ b/gcloud-java-dns/pom.xml @@ -13,7 +13,7 @@ com.google.cloud gcloud-java-pom - 0.2.3 + 0.2.4-SNAPSHOT gcloud-java-dns diff --git a/gcloud-java-examples/pom.xml b/gcloud-java-examples/pom.xml index 4630352ebbce..87ce1224fc16 100644 --- a/gcloud-java-examples/pom.xml +++ b/gcloud-java-examples/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.3 + 0.2.4-SNAPSHOT gcloud-java-examples diff --git a/gcloud-java-resourcemanager/pom.xml b/gcloud-java-resourcemanager/pom.xml index 1eed94ec17bb..5829c9234dfd 100644 --- a/gcloud-java-resourcemanager/pom.xml +++ b/gcloud-java-resourcemanager/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.3 + 0.2.4-SNAPSHOT gcloud-java-resourcemanager diff --git a/gcloud-java-storage/pom.xml b/gcloud-java-storage/pom.xml index 83f4a4fa15d9..afe6d0b02533 100644 --- a/gcloud-java-storage/pom.xml +++ b/gcloud-java-storage/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.3 + 0.2.4-SNAPSHOT gcloud-java-storage diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml index 4b7ce9c91817..ec9c81aca11c 100644 --- a/gcloud-java/pom.xml +++ b/gcloud-java/pom.xml @@ -11,7 +11,7 @@ com.google.cloud gcloud-java-pom - 0.2.3 + 0.2.4-SNAPSHOT diff --git a/pom.xml b/pom.xml index 574abd6312dc..1acb7c33894c 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.google.cloud gcloud-java-pom pom - 0.2.3 + 0.2.4-SNAPSHOT GCloud Java https://github.com/GoogleCloudPlatform/gcloud-java From 91d320a4631684e4532df242d284569f296c19d1 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 13 Jun 2016 11:24:04 +0200 Subject: [PATCH 375/375] Update logging module version and dependencies --- gcloud-java-logging/pom.xml | 16 ++++++++-------- pom.xml | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/gcloud-java-logging/pom.xml b/gcloud-java-logging/pom.xml index 02b004b681d7..75473a775c23 100644 --- a/gcloud-java-logging/pom.xml +++ b/gcloud-java-logging/pom.xml @@ -1,26 +1,26 @@ 4.0.0 + gcloud-java-logging + jar GCloud Java Logging + https://github.com/GoogleCloudPlatform/gcloud-java/tree/master/gcloud-java-logging Java idiomatic client for Google Cloud Logging. - com.google.gcloud - gcloud-java-logging - com.google.gcloud + com.google.cloud gcloud-java-pom - 0.1.4 + 0.2.4-SNAPSHOT - jar gcloud-java-logging - com.google.api - gax - 0.0.13 + ${project.groupId} + gcloud-java-core + ${project.version} com.google.api.grpc diff --git a/pom.xml b/pom.xml index 62dead9d2f78..da8c9e76887b 100644 --- a/pom.xml +++ b/pom.xml @@ -101,8 +101,8 @@ gcloud-java-datastore gcloud-java-dns gcloud-java-examples - gcloud-java-pubsub gcloud-java-logging + gcloud-java-pubsub gcloud-java-resourcemanager gcloud-java-storage