diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java new file mode 100644 index 000000000000..d27e134ad908 --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java @@ -0,0 +1,324 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.dns; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.base.MoreObjects; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + +import org.joda.time.DateTime; +import org.joda.time.format.ISODateTimeFormat; + +import java.io.Serializable; +import java.math.BigInteger; +import java.util.LinkedList; +import java.util.List; +import java.util.Objects; + +/** + * A {@code ManagedZone} represents a DNS zone hosted by the Google Cloud DNS service. A zone is a + * subtree of the DNS namespace under one administrative responsibility. See Google Cloud DNS documentation for + * more information. + */ +public class ManagedZoneInfo implements Serializable { + + private static final long serialVersionUID = 201601191647L; + private final String name; + private final BigInteger id; + private final Long creationTimeMillis; + private final String dnsName; + private final String description; + private final String nameServerSet; + private final List nameServers; + + /** + * A builder for {@code ManagedZoneInfo}. + */ + public static class Builder { + private String name; + private BigInteger id; + private Long creationTimeMillis; + private String dnsName; + private String description; + private String nameServerSet; + private List nameServers = new LinkedList<>(); + + /** + * Returns an empty builder for {@code ManagedZoneInfo}. We use it internally in {@code + * toPb()}. + */ + private Builder() { + } + + private Builder(BigInteger id) { + this.id = checkNotNull(id); + } + + private Builder(String name) { + this.name = checkNotNull(name); + } + + private Builder(String name, BigInteger id) { + this.name = checkNotNull(name); + this.id = checkNotNull(id); + } + + /** + * Creates a builder from an existing ManagedZoneInfo object. + */ + Builder(ManagedZoneInfo info) { + this.name = info.name; + this.id = info.id; + this.creationTimeMillis = info.creationTimeMillis; + this.dnsName = info.dnsName; + this.description = info.description; + this.nameServerSet = info.nameServerSet; + this.nameServers.addAll(info.nameServers); + } + + /** + * Sets a mandatory user-provided name for the zone. It must be unique within the project. + */ + public Builder name(String name) { + this.name = checkNotNull(name); + return this; + } + + /** + * Sets an id for the managed zone which is assigned to the managed zone by the server. + */ + Builder id(BigInteger id) { + this.id = id; + return this; + } + + /** + * Sets the time when this managed zone was created. + */ + Builder creationTimeMillis(long creationTimeMillis) { + this.creationTimeMillis = creationTimeMillis; + return this; + } + + /** + * Sets a mandatory DNS name of this managed zone, for instance "example.com.". + */ + public Builder dnsName(String dnsName) { + this.dnsName = checkNotNull(dnsName); + return this; + } + + /** + * Sets a mandatory description for this managed zone. The value is a string of at most 1024 + * characters which has no effect on the managed zone's function. + */ + public Builder description(String description) { + this.description = checkNotNull(description); + return this; + } + + /** + * Optionally specifies the NameServerSet for this managed zone. A NameServerSet is a set of DNS + * name servers that all host the same ManagedZones. Most users will not need to specify this + * value. + */ + public Builder nameServerSet(String nameServerSet) { + // todo(mderka) add more to the doc when questions are answered by the service owner + this.nameServerSet = checkNotNull(nameServerSet); + return this; + } + + /** + * Sets a list of servers that hold the information about the managed zone. This information is + * provided by Google Cloud DNS and is read only. + */ + Builder nameServers(List nameServers) { + checkNotNull(nameServers); + this.nameServers = Lists.newLinkedList(nameServers); + return this; + } + + /** + * Builds the instance of {@code ManagedZoneInfo} based on the information set by this builder. + */ + public ManagedZoneInfo build() { + return new ManagedZoneInfo(this); + } + } + + private ManagedZoneInfo(Builder builder) { + this.name = builder.name; + this.id = builder.id; + this.creationTimeMillis = builder.creationTimeMillis; + this.dnsName = builder.dnsName; + this.description = builder.description; + this.nameServerSet = builder.nameServerSet; + this.nameServers = ImmutableList.copyOf(builder.nameServers); + } + + /** + * Returns a builder for {@code ManagedZoneInfo} with an assigned {@code name}. + */ + public static Builder builder(String name) { + return new Builder(name); + } + + /** + * Returns a builder for {@code ManagedZoneInfo} with an assigned {@code id}. + */ + public static Builder builder(BigInteger id) { + return new Builder(id); + } + + /** + * Returns a builder for {@code ManagedZoneInfo} with an assigned {@code name} and {@code id}. + */ + public static Builder builder(String name, BigInteger id) { + return new Builder(name, id); + } + + /** + * Returns the user-defined name of the managed zone. + */ + public String name() { + return name; + } + + /** + * Returns the read-only managed zone id assigned by the server. + */ + public BigInteger id() { + return id; + } + + /** + * Returns the time when this time that this managed zone was created on the server. + */ + public Long creationTimeMillis() { + return creationTimeMillis; + } + + /** + * Returns the DNS name of this managed zone, for instance "example.com.". + */ + public String dnsName() { + return dnsName; + } + + /** + * Returns the description of this managed zone. + */ + public String description() { + return description; + } + + /** + * Returns the optionally specified set of DNS name servers that all host this managed zone. + */ + public String nameServerSet() { + // todo(mderka) update this doc after finding out more about this from the service owners + return nameServerSet; + } + + /** + * The nameservers that the managed zone should be delegated to. This is defined by the Google DNS + * cloud. + */ + public List nameServers() { + return nameServers; + } + + /** + * Returns a builder for {@code ManagedZoneInfo} prepopulated with the metadata of this managed + * zone. + */ + public Builder toBuilder() { + return new Builder(this); + } + + com.google.api.services.dns.model.ManagedZone toPb() { + com.google.api.services.dns.model.ManagedZone pb = + new com.google.api.services.dns.model.ManagedZone(); + pb.setDescription(this.description()); + pb.setDnsName(this.dnsName()); + if (this.id() != null) { + pb.setId(this.id()); + } + pb.setName(this.name()); + pb.setNameServers(this.nameServers()); + pb.setNameServerSet(this.nameServerSet()); + if (this.creationTimeMillis() != null) { + pb.setCreationTime(ISODateTimeFormat.dateTime() + .withZoneUTC() + .print(this.creationTimeMillis())); + } + return pb; + } + + static ManagedZoneInfo fromPb(com.google.api.services.dns.model.ManagedZone pb) { + Builder b = new Builder(); + if (pb.getDescription() != null) { + b.description(pb.getDescription()); + } + if (pb.getDnsName() != null) { + b.dnsName(pb.getDnsName()); + } + if (pb.getId() != null) { + b.id(pb.getId()); + } + if (pb.getName() != null) { + b.name(pb.getName()); + } + if (pb.getNameServers() != null) { + b.nameServers(pb.getNameServers()); + } + if (pb.getNameServerSet() != null) { + b.nameServerSet(pb.getNameServerSet()); + } + if (pb.getCreationTime() != null) { + b.creationTimeMillis(DateTime.parse(pb.getCreationTime()).getMillis()); + } + return b.build(); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof ManagedZoneInfo && Objects.equals(toPb(), ((ManagedZoneInfo) obj).toPb()); + } + + @Override + public int hashCode() { + return Objects.hash(name, id, creationTimeMillis, dnsName, + description, nameServerSet, nameServers); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("name", name()) + .add("id", id()) + .add("description", description()) + .add("dnsName", dnsName()) + .add("nameServerSet", nameServerSet()) + .add("nameServers", nameServers()) + .add("creationTimeMillis", creationTimeMillis()) + .toString(); + } +} diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java index 43ced20cf207..412aa2ce08ad 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java @@ -72,16 +72,16 @@ public void testValidTtl() { @Test public void testEqualsAndNotEquals() { DnsRecord clone = record.toBuilder().build(); - assertEquals(clone, record); + assertEquals(record, clone); clone = record.toBuilder().addRecord("another record").build(); - assertNotEquals(clone, record); + assertNotEquals(record, clone); String differentName = "totally different name"; clone = record.toBuilder().name(differentName).build(); - assertNotEquals(clone, record); + assertNotEquals(record, clone); clone = record.toBuilder().ttl(record.ttl() + 1).build(); - assertNotEquals(clone, record); + assertNotEquals(record, clone); clone = record.toBuilder().type(DnsRecord.Type.TXT).build(); - assertNotEquals(clone, record); + assertNotEquals(record, clone); } @Test diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ManagedZoneInfoTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ManagedZoneInfoTest.java new file mode 100644 index 000000000000..936164c81723 --- /dev/null +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/ManagedZoneInfoTest.java @@ -0,0 +1,183 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.gcloud.dns; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; + +import org.junit.Test; + +import java.math.BigInteger; +import java.util.LinkedList; +import java.util.List; + +public class ManagedZoneInfoTest { + + private static final String NAME = "mz-example.com"; + private static final BigInteger ID = BigInteger.valueOf(123L); + private static final Long CREATION_TIME_MILLIS = 1123468321321L; + private static final String DNS_NAME = "example.com."; + private static final String DESCRIPTION = "description for the zone"; + private static final String NAME_SERVER_SET = "some set"; + private static final String NS1 = "name server 1"; + private static final String NS2 = "name server 2"; + private static final String NS3 = "name server 3"; + private static final List NAME_SERVERS = ImmutableList.of(NS1, NS2, NS3); + private static final ManagedZoneInfo INFO = ManagedZoneInfo.builder(NAME, ID) + .creationTimeMillis(CREATION_TIME_MILLIS) + .dnsName(DNS_NAME) + .description(DESCRIPTION) + .nameServerSet(NAME_SERVER_SET) + .nameServers(NAME_SERVERS) + .build(); + + @Test + public void testDefaultBuilders() { + ManagedZoneInfo withName = ManagedZoneInfo.builder(NAME).build(); + assertTrue(withName.nameServers().isEmpty()); + assertEquals(NAME, withName.name()); + assertNull(withName.id()); + assertNull(withName.creationTimeMillis()); + assertNull(withName.nameServerSet()); + assertNull(withName.description()); + assertNull(withName.dnsName()); + ManagedZoneInfo withId = ManagedZoneInfo.builder(ID).build(); + assertTrue(withId.nameServers().isEmpty()); + assertEquals(ID, withId.id()); + assertNull(withId.name()); + assertNull(withId.creationTimeMillis()); + assertNull(withId.nameServerSet()); + assertNull(withId.description()); + assertNull(withId.dnsName()); + ManagedZoneInfo withBoth = ManagedZoneInfo.builder(NAME, ID).build(); + assertTrue(withBoth.nameServers().isEmpty()); + assertEquals(ID, withBoth.id()); + assertEquals(NAME, withBoth.name()); + assertNull(withBoth.creationTimeMillis()); + assertNull(withBoth.nameServerSet()); + assertNull(withBoth.description()); + assertNull(withBoth.dnsName()); + } + + @Test + public void testBuilder() { + assertEquals(3, INFO.nameServers().size()); + assertEquals(NS1, INFO.nameServers().get(0)); + assertEquals(NS2, INFO.nameServers().get(1)); + assertEquals(NS3, INFO.nameServers().get(2)); + assertEquals(NAME, INFO.name()); + assertEquals(ID, INFO.id()); + assertEquals(CREATION_TIME_MILLIS, INFO.creationTimeMillis()); + assertEquals(NAME_SERVER_SET, INFO.nameServerSet()); + assertEquals(DESCRIPTION, INFO.description()); + assertEquals(DNS_NAME, INFO.dnsName()); + } + + @Test + public void testEqualsAndNotEquals() { + ManagedZoneInfo clone = INFO.toBuilder().build(); + assertEquals(INFO, clone); + List moreServers = Lists.newLinkedList(NAME_SERVERS); + moreServers.add(NS1); + clone = INFO.toBuilder().nameServers(moreServers).build(); + assertNotEquals(INFO, clone); + String differentName = "totally different name"; + clone = INFO.toBuilder().name(differentName).build(); + assertNotEquals(INFO, clone); + clone = INFO.toBuilder().creationTimeMillis(INFO.creationTimeMillis() + 1).build(); + assertNotEquals(INFO, clone); + clone = INFO.toBuilder().description(INFO.description() + "aaaa").build(); + assertNotEquals(INFO, clone); + clone = INFO.toBuilder().dnsName(differentName).build(); + assertNotEquals(INFO, clone); + clone = INFO.toBuilder().id(INFO.id().add(BigInteger.ONE)).build(); + assertNotEquals(INFO, clone); + clone = INFO.toBuilder().nameServerSet(INFO.nameServerSet() + "salt").build(); + assertNotEquals(INFO, clone); + } + + @Test + public void testSameHashCodeOnEquals() { + int hash = INFO.hashCode(); + ManagedZoneInfo clone = INFO.toBuilder().build(); + assertEquals(clone.hashCode(), hash); + } + + @Test + public void testToBuilder() { + assertEquals(INFO, INFO.toBuilder().build()); + ManagedZoneInfo partial = ManagedZoneInfo.builder(NAME).build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ManagedZoneInfo.builder(ID).build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ManagedZoneInfo.builder(NAME).description(DESCRIPTION).build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ManagedZoneInfo.builder(NAME).dnsName(DNS_NAME).build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ManagedZoneInfo.builder(NAME).creationTimeMillis(CREATION_TIME_MILLIS).build(); + assertEquals(partial, partial.toBuilder().build()); + List nameServers = new LinkedList<>(); + nameServers.add(NS1); + partial = ManagedZoneInfo.builder(NAME).nameServers(nameServers).build(); + assertEquals(partial, partial.toBuilder().build()); + partial = ManagedZoneInfo.builder(NAME).nameServerSet(NAME_SERVER_SET).build(); + assertEquals(partial, partial.toBuilder().build()); + } + + @Test + public void testToAndFromPb() { + assertEquals(INFO, ManagedZoneInfo.fromPb(INFO.toPb())); + ManagedZoneInfo partial = ManagedZoneInfo.builder(NAME).build(); + assertEquals(partial, ManagedZoneInfo.fromPb(partial.toPb())); + partial = ManagedZoneInfo.builder(ID).build(); + assertEquals(partial, ManagedZoneInfo.fromPb(partial.toPb())); + partial = ManagedZoneInfo.builder(NAME).description(DESCRIPTION).build(); + assertEquals(partial, ManagedZoneInfo.fromPb(partial.toPb())); + partial = ManagedZoneInfo.builder(NAME).dnsName(DNS_NAME).build(); + assertEquals(partial, ManagedZoneInfo.fromPb(partial.toPb())); + partial = ManagedZoneInfo.builder(NAME).creationTimeMillis(CREATION_TIME_MILLIS).build(); + assertEquals(partial, ManagedZoneInfo.fromPb(partial.toPb())); + List nameServers = new LinkedList<>(); + nameServers.add(NS1); + partial = ManagedZoneInfo.builder(NAME).nameServers(nameServers).build(); + assertEquals(partial, ManagedZoneInfo.fromPb(partial.toPb())); + partial = ManagedZoneInfo.builder(NAME).nameServerSet(NAME_SERVER_SET).build(); + assertEquals(partial, ManagedZoneInfo.fromPb(partial.toPb())); + } + + @Test + public void testEmptyNameServers() { + ManagedZoneInfo clone = INFO.toBuilder().nameServers(new LinkedList()).build(); + assertTrue(clone.nameServers().isEmpty()); + clone.toPb(); // test that this is allowed + } + + @Test + public void testDateParsing() { + com.google.api.services.dns.model.ManagedZone pb = INFO.toPb(); + pb.setCreationTime("2016-01-19T18:00:12.854Z"); // a real value obtained from Google Cloud DNS + ManagedZoneInfo mz = ManagedZoneInfo.fromPb(pb); // parses the string timestamp to millis + com.google.api.services.dns.model.ManagedZone pbClone = mz.toPb(); // converts it back to string + assertEquals(pb, pbClone); + assertEquals(pb.getCreationTime(), pbClone.getCreationTime()); + } +}