From c45336b5fcf9e21fecff65aaf40706f0da9c075e Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Wed, 16 Mar 2016 16:45:38 +0100 Subject: [PATCH 01/11] 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 aee1ac36062b18edf7308d34b911ef98c1a7fcde Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Thu, 17 Mar 2016 10:59:05 +0100 Subject: [PATCH 02/11] 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 a59366b82d8b68fdc132909ef30be7980465c79e Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 21 Mar 2016 09:20:53 +0100 Subject: [PATCH 03/11] 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 e5194e5c6ce69460a5cace1a87e5c25ff92866cf Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 21 Mar 2016 12:36:44 +0100 Subject: [PATCH 04/11] 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 26092cd715e964ef781d436a06f11e5382193026 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 21 Mar 2016 12:38:58 +0100 Subject: [PATCH 05/11] 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 645417ed9872e539ab800040a192fbb091d96de9 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 21 Mar 2016 12:42:46 +0100 Subject: [PATCH 06/11] 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 2f7a07fd0800fa44536df007614cb0df2c47a276 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 21 Mar 2016 12:47:21 +0100 Subject: [PATCH 07/11] 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 3e9c62e45fd9f52c1f833018927991f3c92e4caf Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Mon, 21 Mar 2016 19:08:10 +0100 Subject: [PATCH 08/11] 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 e5414000e1a7338f66805366054e08d58dbc60dc Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 22 Mar 2016 11:57:27 +0100 Subject: [PATCH 09/11] 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 61d87e30146080a47a6aa6a33545b35425859567 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 22 Mar 2016 12:24:23 +0100 Subject: [PATCH 10/11] 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 5d172b6a5c32dab9de6ddd8ac27250916b28e3e2 Mon Sep 17 00:00:00 2001 From: Marco Ziccardi Date: Tue, 22 Mar 2016 13:35:03 +0100 Subject: [PATCH 11/11] 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;