diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkId.java new file mode 100644 index 000000000000..09bf05fb6b9c --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/NetworkId.java @@ -0,0 +1,137 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects.ToStringHelper; + +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Identity for a Google Compute Engine network. + */ +public final class NetworkId extends ResourceId { + + private static final String REGEX = ResourceId.REGEX + "global/networks/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); + private static final long serialVersionUID = 2386765228138819506L; + + private final String network; + + NetworkId(String project, String network) { + super(project); + this.network = checkNotNull(network); + } + + private NetworkId(NetworkId networkId) { + super(networkId.project()); + this.network = checkNotNull(networkId.network()); + } + + /** + * Returns the name of the network. The network name must be 1-63 characters long and comply with + * RFC1035. Specifically, the name must match the regular expression + * {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a lowercase letter, + * and all following characters must be a dash, lowercase letter, or digit, except the last + * character, which cannot be a dash. + * + * @see RFC1035 + */ + public String network() { + return network; + } + + @Override + public String selfLink() { + return super.selfLink() + "/global/networks/" + network; + } + + @Override + ToStringHelper toStringHelper() { + return super.toStringHelper().add("network", network); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), network); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof NetworkId)) { + return false; + } + NetworkId other = (NetworkId) obj; + return baseEquals(other) && Objects.equals(network, other.network); + } + + @Override + NetworkId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return NetworkId.of(projectId, network); + } + + /** + * Returns a new network identity given project and network names. The network name must be 1-63 + * characters long and comply with RFC1035. Specifically, the name must match the regular + * expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a + * lowercase letter, and all following characters must be a dash, lowercase letter, or digit, + * except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public static NetworkId of(String project, String network) { + return new NetworkId(project, network); + } + + /** + * Returns a new network identity given network name. The network name must be 1-63 characters + * long and comply with RFC1035. Specifically, the name must match the regular expression + * {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a lowercase letter, + * and all following characters must be a dash, lowercase letter, or digit, except the last + * character, which cannot be a dash. + * + * @see RFC1035 + */ + public static NetworkId of(String network) { + return NetworkId.of(null, network); + } + + /** + * Returns {@code true} if the provided string matches the expected format of a network URL. + * Returns {@code false} otherwise. + */ + static boolean matchesUrl(String url) { + return PATTERN.matcher(url).matches(); + } + + static NetworkId fromUrl(String url) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { + throw new IllegalArgumentException(url + " is not a valid network URL"); + } + return NetworkId.of(matcher.group(1), matcher.group(2)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkId.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkId.java new file mode 100644 index 000000000000..7ed56f4ba3cf --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkId.java @@ -0,0 +1,179 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; + +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Identity for a Google Compute Engine subnetwork. + */ +public final class SubnetworkId extends ResourceId { + + static final Function FROM_URL_FUNCTION = + new Function() { + @Override + public SubnetworkId apply(String pb) { + return SubnetworkId.fromUrl(pb); + } + }; + static final Function TO_URL_FUNCTION = + new Function() { + @Override + public String apply(SubnetworkId zoneId) { + return zoneId.selfLink(); + } + }; + + private static final String REGEX = ResourceId.REGEX + "regions/([^/]+)/subnetworks/([^/]+)"; + private static final Pattern PATTERN = Pattern.compile(REGEX); + private static final long serialVersionUID = -5451054513760540282L; + + private final String region; + private final String subnetwork; + + private SubnetworkId(String project, String region, String subnetwork) { + super(project); + this.region = checkNotNull(region); + this.subnetwork = checkNotNull(subnetwork); + } + + /** + * Returns the name of the region this subnetwork belongs to. + */ + public String region() { + return region; + } + + /** + * Returns the identity of the region this subnetwork belongs to. + */ + public RegionId regionId() { + return RegionId.of(project(), region); + } + + /** + * Returns the name of the subnetwork. The name must be 1-63 characters long and comply with + * RFC1035. Specifically, the name must match the regular expression + * {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a lowercase letter, + * and all following characters must be a dash, lowercase letter, or digit, except the last + * character, which cannot be a dash. + * + * @see RFC1035 + */ + public String subnetwork() { + return subnetwork; + } + + @Override + public String selfLink() { + return super.selfLink() + "/regions/" + region + "/subnetworks/" + subnetwork; + } + + @Override + MoreObjects.ToStringHelper toStringHelper() { + return MoreObjects.toStringHelper(this).add("region", region).add("subnetwork", subnetwork); + } + + @Override + public int hashCode() { + return Objects.hash(baseHashCode(), region, subnetwork); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + if (!(obj instanceof SubnetworkId)) { + return false; + } + SubnetworkId other = (SubnetworkId) obj; + return baseEquals(other) + && Objects.equals(region, other.region) + && Objects.equals(subnetwork, other.subnetwork); + } + + @Override + SubnetworkId setProjectId(String projectId) { + if (project() != null) { + return this; + } + return SubnetworkId.of(projectId, region(), subnetwork); + } + + /** + * Returns a subnetwork identity given the region identity and the subnetwork name. The subnetwork + * name must be 1-63 characters long and comply with RFC1035. Specifically, the name must match + * the regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must + * be a lowercase letter, and all following characters must be a dash, lowercase letter, or digit, + * except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public static SubnetworkId of(RegionId regionId, String subnetwork) { + return new SubnetworkId(regionId.project(), regionId.region(), subnetwork); + } + + /** + * Returns a subnetwork identity given the region and subnetwork names. The subnetwork name must + * be 1-63 characters long and comply with RFC1035. Specifically, the name must match the regular + * expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a + * lowercase letter, and all following characters must be a dash, lowercase letter, or digit, + * except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public static SubnetworkId of(String region, String subnetwork) { + return new SubnetworkId(null, region, subnetwork); + } + + /** + * Returns a subnetwork identity given project, region and subnetwork names. The subnetwork name + * must be 1-63 characters long and comply with RFC1035. Specifically, the name must match the + * regular expression {@code [a-z]([-a-z0-9]*[a-z0-9])?} which means the first character must be a + * lowercase letter, and all following characters must be a dash, lowercase letter, or digit, + * except the last character, which cannot be a dash. + * + * @see RFC1035 + */ + public static SubnetworkId of(String project, String region, String subnetwork) { + return new SubnetworkId(project, region, subnetwork); + } + + /** + * Returns {@code true} if the provided string matches the expected format of a subnetwork URL. + * Returns {@code false} otherwise. + */ + static boolean matchesUrl(String url) { + return PATTERN.matcher(url).matches(); + } + + static SubnetworkId fromUrl(String url) { + Matcher matcher = PATTERN.matcher(url); + if (!matcher.matches()) { + throw new IllegalArgumentException(url + " is not a valid subnetwork URL"); + } + return SubnetworkId.of(matcher.group(1), matcher.group(2), matcher.group(3)); + } +} diff --git a/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkInfo.java b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkInfo.java new file mode 100644 index 000000000000..05eb0c95fc03 --- /dev/null +++ b/gcloud-java-compute/src/main/java/com/google/gcloud/compute/SubnetworkInfo.java @@ -0,0 +1,347 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.api.services.compute.model.Subnetwork; +import com.google.common.base.Function; +import com.google.common.base.MoreObjects; + +import org.joda.time.format.DateTimeFormatter; +import org.joda.time.format.ISODateTimeFormat; + +import java.io.Serializable; +import java.math.BigInteger; +import java.util.Objects; + +/** + * A Google Compute Engine subnetwork. Compute Engine subnetworks allow you to segment your Compute + * Engine network IP space into subnetworks. Subnetworks for a Compute Engine network can be + * automatically allocated, or you can create a custom topology. + * + * @see Subnetworks + */ +public class SubnetworkInfo implements Serializable { + + static final Function FROM_PB_FUNCTION = + new Function() { + @Override + public SubnetworkInfo apply(Subnetwork pb) { + return SubnetworkInfo.fromPb(pb); + } + }; + static final Function TO_PB_FUNCTION = + new Function() { + @Override + public Subnetwork apply(SubnetworkInfo subnetwork) { + return subnetwork.toPb(); + } + }; + + private static final long serialVersionUID = 7491176262675441579L; + private static final DateTimeFormatter TIMESTAMP_FORMATTER = ISODateTimeFormat.dateTime(); + + private final String id; + private final SubnetworkId subnetworkId; + private final Long creationTimestamp; + private final String description; + private final String gatewayAddress; + private final NetworkId network; + private final String ipRange; + + /** + * A builder for {@code SubnetworkInfo} objects. + */ + public static abstract class Builder { + + abstract Builder id(String id); + + abstract Builder creationTimestamp(Long creationTimestamp); + + /** + * Sets the identity of the subnework. + */ + public abstract Builder subnetworkId(SubnetworkId subnetworkId); + + /** + * Sets an optional textual description of the subnetwork. + */ + abstract public Builder description(String description); + + abstract Builder gatewayAddress(String gatewayAddress); + + /** + * Sets the identity of the network to which this subnetwork belongs. Only networks that are in + * subnet mode can have subnetworks. + */ + abstract public Builder network(NetworkId network); + + /** + * Sets the range of internal IPv4 addresses that are owned by this subnetwork. This range must + * be a CIDR specification, for example: {@code 192.168.0.0/16}. Ranges must be unique and + * non-overlapping within a network. + * + * @see CIDR + */ + abstract public Builder ipRange(String ipRange); + + /** + * Creates a {@code SubnetworkInfo} object. + */ + abstract public SubnetworkInfo build(); + } + + static final class BuilderImpl extends Builder { + + private String id; + private SubnetworkId subnetworkId; + private Long creationTimestamp; + private String description; + private String gatewayAddress; + private NetworkId network; + private String ipRange; + + BuilderImpl(SubnetworkId subnetworkId, NetworkId network, String ipRange) { + this.subnetworkId = checkNotNull(subnetworkId); + this.network = checkNotNull(network); + this.ipRange = checkNotNull(ipRange); + } + + BuilderImpl(SubnetworkInfo subnetworkInfo) { + this.id = subnetworkInfo.id; + this.creationTimestamp = subnetworkInfo.creationTimestamp; + this.subnetworkId = subnetworkInfo.subnetworkId; + this.description = subnetworkInfo.description; + this.gatewayAddress = subnetworkInfo.gatewayAddress; + this.network = subnetworkInfo.network; + this.ipRange = subnetworkInfo.ipRange; + } + + BuilderImpl(Subnetwork subnetworkPb) { + if (subnetworkPb.getId() != null) { + this.id = subnetworkPb.getId().toString(); + } + if (subnetworkPb.getCreationTimestamp() != null) { + this.creationTimestamp = + TIMESTAMP_FORMATTER.parseMillis(subnetworkPb.getCreationTimestamp()); + } + this.subnetworkId = SubnetworkId.fromUrl(subnetworkPb.getSelfLink()); + this.description = subnetworkPb.getDescription(); + this.gatewayAddress = subnetworkPb.getGatewayAddress(); + if (subnetworkPb.getNetwork() != null) { + this.network = NetworkId.fromUrl(subnetworkPb.getNetwork()); + } + this.ipRange = subnetworkPb.getIpCidrRange(); + } + + @Override + BuilderImpl id(String id) { + this.id = id; + return this; + } + + @Override + BuilderImpl creationTimestamp(Long creationTimestamp) { + this.creationTimestamp = creationTimestamp; + return this; + } + + @Override + public BuilderImpl subnetworkId(SubnetworkId subnetworkId) { + this.subnetworkId = checkNotNull(subnetworkId); + return this; + } + + @Override + public BuilderImpl description(String description) { + this.description = description; + return this; + } + + @Override + BuilderImpl gatewayAddress(String gatewayAddress) { + this.gatewayAddress = gatewayAddress; + return this; + } + + @Override + public BuilderImpl network(NetworkId network) { + this.network = checkNotNull(network); + return this; + } + + @Override + public BuilderImpl ipRange(String ipRange) { + this.ipRange = checkNotNull(ipRange); + return this; + } + + @Override + public SubnetworkInfo build() { + return new SubnetworkInfo(this); + } + } + + SubnetworkInfo(BuilderImpl builder) { + this.id = builder.id; + this.creationTimestamp = builder.creationTimestamp; + this.subnetworkId = checkNotNull(builder.subnetworkId); + this.description = builder.description; + this.gatewayAddress = builder.gatewayAddress; + this.network = builder.network; + this.ipRange = builder.ipRange; + } + + /** + * Returns the unique identifier for the subnetwork; defined by the service. + */ + public String id() { + return id; + } + + /** + * Returns the creation timestamp in milliseconds since epoch. + */ + public Long creationTimestamp() { + return creationTimestamp; + } + + /** + * Returns the subnetwork identity. + */ + public SubnetworkId subnetworkId() { + return subnetworkId; + } + + /** + * Returns a textual description of the subnetwork. + */ + public String description() { + return description; + } + + /** + * Returns the gateway IPv4 address for this subnetwork, selected by the service. + */ + public String gatewayAddress() { + return gatewayAddress; + } + + /** + * Returns the identity of the network to which this subnetwork belongs. Only networks that are in + * subnet mode can have subnetworks. + */ + public NetworkId network() { + return network; + } + + /** + * Returns the range of internal IPv4 addresses that are owned by this subnetwork. This range is a + * CIDR specification, for example: {@code 192.168.0.0/16}. Ranges must be unique and + * non-overlapping within a network. + * + * @see CIDR + */ + public String ipRange() { + return ipRange; + } + + /** + * Returns a builder for the current subnetwork. + */ + public Builder toBuilder() { + return new BuilderImpl(this); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id) + .add("creationTimestamp", creationTimestamp) + .add("subnetworkId", subnetworkId) + .add("description", description) + .add("gatewayAddress", gatewayAddress) + .add("network", network) + .add("ipRange", ipRange) + .toString(); + } + + @Override + public int hashCode() { + return Objects.hash(id, creationTimestamp, subnetworkId, description, gatewayAddress, network, + ipRange); + } + + @Override + public boolean equals(Object obj) { + return obj != null + && obj.getClass().equals(SubnetworkInfo.class) + && Objects.equals(toPb(), ((SubnetworkInfo) obj).toPb()); + } + + SubnetworkInfo setProjectId(String projectId) { + return toBuilder() + .subnetworkId(subnetworkId.setProjectId(projectId)) + .network(network.setProjectId(projectId)) + .build(); + } + + Subnetwork toPb() { + Subnetwork subnetworkPb = new Subnetwork(); + if (id != null) { + subnetworkPb.setId(new BigInteger(id)); + } + if (creationTimestamp != null) { + subnetworkPb.setCreationTimestamp(TIMESTAMP_FORMATTER.print(creationTimestamp)); + } + subnetworkPb.setName(subnetworkId.subnetwork()); + subnetworkPb.setDescription(description); + subnetworkPb.setSelfLink(subnetworkId.selfLink()); + subnetworkPb.setGatewayAddress(gatewayAddress); + subnetworkPb.setNetwork(network.selfLink()); + subnetworkPb.setIpCidrRange(ipRange); + return subnetworkPb; + } + + /** + * Returns a builder for a {@code SubnetworkInfo} object given the identity of the subnetwork, the + * identity of the network this subnetwork belongs to and the range of IPv4 addresses owned by + * this subnetwork. {@code ipRange} must be a CIDR specification, for example: + * {@code 192.168.0.0/16}. + * + * @see CIDR + */ + public static Builder builder(SubnetworkId subnetworkId, NetworkId network, String ipRange) { + return new BuilderImpl(subnetworkId, network, ipRange); + } + + /** + * Returns a {@code SubnetworkInfo} object given the identity of the subnetwork, the identity of + * the network this subnetwork belongs to and the range of IPv4 addresses owned by this + * subnetwork. {@code ipRange} must be a CIDR specification, for example: {@code 192.168.0.0/16}. + * + * @see CIDR + */ + public static SubnetworkInfo of(SubnetworkId subnetworkId, NetworkId network, String ipRange) { + return builder(subnetworkId, network, ipRange).build(); + } + + static SubnetworkInfo fromPb(Subnetwork subnetworkPb) { + return new BuilderImpl(subnetworkPb).build(); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkIdTest.java new file mode 100644 index 000000000000..08b012d25d62 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/NetworkIdTest.java @@ -0,0 +1,79 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class NetworkIdTest { + + private static final String PROJECT = "project"; + private static final String NETWORK = "network"; + private static final String URL = + "https://www.googleapis.com/compute/v1/projects/project/global/networks/network"; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testOf() { + NetworkId networkId = NetworkId.of(PROJECT, NETWORK); + assertEquals(PROJECT, networkId.project()); + assertEquals(NETWORK, networkId.network()); + assertEquals(URL, networkId.selfLink()); + networkId = NetworkId.of(NETWORK); + assertNull(networkId.project()); + assertEquals(NETWORK, networkId.network()); + } + + @Test + public void testToAndFromUrl() { + NetworkId networkId = NetworkId.of(PROJECT, NETWORK); + compareNetworkId(networkId, NetworkId.fromUrl(networkId.selfLink())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid network URL"); + NetworkId.fromUrl("notMatchingUrl"); + } + + @Test + public void testSetProjectId() { + NetworkId networkId = NetworkId.of(PROJECT, NETWORK); + assertSame(networkId, networkId.setProjectId(PROJECT)); + compareNetworkId(networkId, NetworkId.of(NETWORK).setProjectId(PROJECT)); + } + + @Test + public void testMatchesUrl() { + assertTrue(NetworkId.matchesUrl(NetworkId.of(PROJECT, NETWORK).selfLink())); + assertFalse(NetworkId.matchesUrl("notMatchingUrl")); + } + + private void compareNetworkId(NetworkId expected, NetworkId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.network(), expected.network()); + assertEquals(expected.selfLink(), expected.selfLink()); + assertEquals(expected.hashCode(), expected.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java index bec8844ae111..5f06d252af34 100644 --- a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SerializationTest.java @@ -156,6 +156,11 @@ public class SerializationTest { private static final DiskInfo DISK_INFO = DiskInfo.of(DISK_ID, STANDARD_DISK_CONFIGURATION); private static final Disk DISK = new Disk.Builder(COMPUTE, DISK_ID, STANDARD_DISK_CONFIGURATION).build(); + private static final SubnetworkId SUBNETWORK_ID = + SubnetworkId.of("project", "region", "subnetwork"); + private static final NetworkId NETWORK_ID = NetworkId.of("project", "network"); + private static final SubnetworkInfo SUBNETWORK_INFO = + SubnetworkInfo.of(SUBNETWORK_ID, NETWORK_ID, "192.168.0.0/16"); private static final Compute.DiskTypeOption DISK_TYPE_OPTION = Compute.DiskTypeOption.fields(); private static final Compute.DiskTypeFilter DISK_TYPE_FILTER = @@ -241,11 +246,12 @@ public void testModelAndRequests() throws Exception { ADDRESS_INFO, ADDRESS, DISK_ID, SNAPSHOT_ID, SNAPSHOT_INFO, SNAPSHOT, IMAGE_ID, DISK_IMAGE_CONFIGURATION, STORAGE_IMAGE_CONFIGURATION, IMAGE_INFO, IMAGE, STANDARD_DISK_CONFIGURATION, IMAGE_DISK_CONFIGURATION, SNAPSHOT_DISK_CONFIGURATION, - DISK_INFO, DISK, DISK_TYPE_OPTION, DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, - DISK_TYPE_AGGREGATED_LIST_OPTION, MACHINE_TYPE_OPTION, MACHINE_TYPE_FILTER, - MACHINE_TYPE_LIST_OPTION, MACHINE_TYPE_AGGREGATED_LIST_OPTION, REGION_OPTION, REGION_FILTER, - REGION_LIST_OPTION, ZONE_OPTION, ZONE_FILTER, ZONE_LIST_OPTION, LICENSE_OPTION, - OPERATION_OPTION, OPERATION_FILTER, OPERATION_LIST_OPTION, ADDRESS_OPTION, ADDRESS_FILTER, + DISK_INFO, DISK, SUBNETWORK_ID, NETWORK_ID, SUBNETWORK_INFO, DISK_TYPE_OPTION, + DISK_TYPE_FILTER, DISK_TYPE_LIST_OPTION, DISK_TYPE_AGGREGATED_LIST_OPTION, + MACHINE_TYPE_OPTION, MACHINE_TYPE_FILTER, MACHINE_TYPE_LIST_OPTION, + MACHINE_TYPE_AGGREGATED_LIST_OPTION, REGION_OPTION, REGION_FILTER, REGION_LIST_OPTION, + ZONE_OPTION, ZONE_FILTER, ZONE_LIST_OPTION, LICENSE_OPTION, OPERATION_OPTION, + OPERATION_FILTER, OPERATION_LIST_OPTION, ADDRESS_OPTION, ADDRESS_FILTER, ADDRESS_LIST_OPTION, ADDRESS_AGGREGATED_LIST_OPTION, SNAPSHOT_OPTION, SNAPSHOT_FILTER, SNAPSHOT_LIST_OPTION, IMAGE_OPTION, IMAGE_FILTER, IMAGE_LIST_OPTION, DISK_OPTION, DISK_FILTER, DISK_LIST_OPTION, DISK_AGGREGATED_LIST_OPTION}; diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkIdTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkIdTest.java new file mode 100644 index 000000000000..25e428c9009b --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkIdTest.java @@ -0,0 +1,87 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +public class SubnetworkIdTest { + + private static final String PROJECT = "project"; + private static final String REGION = "region"; + private static final String NAME = "subnet"; + private static final String URL = + "https://www.googleapis.com/compute/v1/projects/project/regions/region/subnetworks/subnet"; + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void testOf() { + SubnetworkId subnetworkId = SubnetworkId.of(PROJECT, REGION, NAME); + assertEquals(PROJECT, subnetworkId.project()); + assertEquals(REGION, subnetworkId.region()); + assertEquals(NAME, subnetworkId.subnetwork()); + assertEquals(URL, subnetworkId.selfLink()); + subnetworkId = SubnetworkId.of(REGION, NAME); + assertNull(subnetworkId.project()); + assertEquals(REGION, subnetworkId.region()); + assertEquals(NAME, subnetworkId.subnetwork()); + subnetworkId = SubnetworkId.of(RegionId.of(PROJECT, REGION), NAME); + assertEquals(PROJECT, subnetworkId.project()); + assertEquals(REGION, subnetworkId.region()); + assertEquals(NAME, subnetworkId.subnetwork()); + } + + @Test + public void testToAndFromUrl() { + SubnetworkId subnetworkId = SubnetworkId.of(PROJECT, REGION, NAME); + compareSubnetworkId(subnetworkId, SubnetworkId.fromUrl(subnetworkId.selfLink())); + thrown.expect(IllegalArgumentException.class); + thrown.expectMessage("notMatchingUrl is not a valid subnetwork URL"); + SubnetworkId.fromUrl("notMatchingUrl"); + } + + @Test + public void testSetProjectId() { + SubnetworkId subnetworkId = SubnetworkId.of(PROJECT, REGION, NAME); + assertSame(subnetworkId, subnetworkId.setProjectId(PROJECT)); + compareSubnetworkId(subnetworkId, SubnetworkId.of(REGION, NAME).setProjectId(PROJECT)); + } + + @Test + public void testMatchesUrl() { + assertTrue(SubnetworkId.matchesUrl(SubnetworkId.of(PROJECT, REGION, NAME).selfLink())); + assertFalse(SubnetworkId.matchesUrl("notMatchingUrl")); + } + + private void compareSubnetworkId(SubnetworkId expected, SubnetworkId value) { + assertEquals(expected, value); + assertEquals(expected.project(), expected.project()); + assertEquals(expected.region(), expected.region()); + assertEquals(expected.subnetwork(), expected.subnetwork()); + assertEquals(expected.selfLink(), expected.selfLink()); + assertEquals(expected.hashCode(), expected.hashCode()); + } +} diff --git a/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkInfoTest.java b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkInfoTest.java new file mode 100644 index 000000000000..64d2e92852c9 --- /dev/null +++ b/gcloud-java-compute/src/test/java/com/google/gcloud/compute/SubnetworkInfoTest.java @@ -0,0 +1,108 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.compute; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Test; + +public class SubnetworkInfoTest { + + private static final String ID = "42"; + private static final Long CREATION_TIMESTAMP = 1453293540000L; + private static final String DESCRIPTION = "description"; + private static final SubnetworkId SUBNETWORK_ID = + SubnetworkId.of("project", "region", "subnetwork"); + private static final String GATEWAY_ADDRESS = "192.168.1.1"; + private static final NetworkId NETWORK_ID = NetworkId.of("project", "network"); + private static final String IP_CIDR_RANGE = "192.168.0.0/16"; + private static final SubnetworkInfo SUBNETWORK_INFO = + SubnetworkInfo.builder(SUBNETWORK_ID, NETWORK_ID, IP_CIDR_RANGE) + .id(ID) + .creationTimestamp(CREATION_TIMESTAMP) + .description(DESCRIPTION) + .gatewayAddress(GATEWAY_ADDRESS) + .build(); + + @Test + public void testToBuilder() { + compareSubnetworkInfo(SUBNETWORK_INFO, SUBNETWORK_INFO.toBuilder().build()); + SubnetworkInfo subnetworkInfo = + SUBNETWORK_INFO.toBuilder().description("newDescription").build(); + assertEquals("newDescription", subnetworkInfo.description()); + subnetworkInfo = subnetworkInfo.toBuilder().description("description").build(); + compareSubnetworkInfo(SUBNETWORK_INFO, subnetworkInfo); + } + + @Test + public void testToBuilderIncomplete() { + SubnetworkInfo subnetworkInfo = SubnetworkInfo.of(SUBNETWORK_ID, NETWORK_ID, IP_CIDR_RANGE); + assertEquals(subnetworkInfo, subnetworkInfo.toBuilder().build()); + } + + @Test + public void testBuilder() { + assertEquals(ID, SUBNETWORK_INFO.id()); + assertEquals(SUBNETWORK_ID, SUBNETWORK_INFO.subnetworkId()); + assertEquals(CREATION_TIMESTAMP, SUBNETWORK_INFO.creationTimestamp()); + assertEquals(DESCRIPTION, SUBNETWORK_INFO.description()); + assertEquals(GATEWAY_ADDRESS, SUBNETWORK_INFO.gatewayAddress()); + assertEquals(NETWORK_ID, SUBNETWORK_INFO.network()); + assertEquals(IP_CIDR_RANGE, SUBNETWORK_INFO.ipRange()); + } + + @Test + public void testOf() { + SubnetworkInfo subnetworkInfo = SubnetworkInfo.of(SUBNETWORK_ID, NETWORK_ID, IP_CIDR_RANGE); + assertNull(subnetworkInfo.id()); + assertEquals(SUBNETWORK_ID, subnetworkInfo.subnetworkId()); + assertNull(subnetworkInfo.creationTimestamp()); + assertNull(subnetworkInfo.description()); + assertNull(subnetworkInfo.gatewayAddress()); + assertEquals(NETWORK_ID, subnetworkInfo.network()); + assertEquals(IP_CIDR_RANGE, subnetworkInfo.ipRange()); + } + + @Test + public void testToAndFromPb() { + compareSubnetworkInfo(SUBNETWORK_INFO, SubnetworkInfo.fromPb(SUBNETWORK_INFO.toPb())); + SubnetworkInfo subnetworkInfo = SubnetworkInfo.of(SUBNETWORK_ID, NETWORK_ID, IP_CIDR_RANGE); + compareSubnetworkInfo(subnetworkInfo, SubnetworkInfo.fromPb(subnetworkInfo.toPb())); + } + + @Test + public void testSetProjectId() { + SubnetworkInfo subnetworkInfo = SUBNETWORK_INFO.toBuilder() + .subnetworkId(SubnetworkId.of("region", "subnetwork")) + .network(NetworkId.of("network")) + .build(); + compareSubnetworkInfo(SUBNETWORK_INFO, subnetworkInfo.setProjectId("project")); + } + + public void compareSubnetworkInfo(SubnetworkInfo expected, SubnetworkInfo value) { + assertEquals(expected, value); + assertEquals(expected.id(), value.id()); + assertEquals(expected.subnetworkId(), value.subnetworkId()); + assertEquals(expected.creationTimestamp(), value.creationTimestamp()); + assertEquals(expected.description(), value.description()); + assertEquals(expected.gatewayAddress(), value.gatewayAddress()); + assertEquals(expected.network(), value.network()); + assertEquals(expected.ipRange(), value.ipRange()); + assertEquals(expected.hashCode(), value.hashCode()); + } +}