From 2bf4925cb3fa8fa782b78de164e3a841bf5fdf4f Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Fri, 15 Jan 2016 17:54:12 -0800 Subject: [PATCH 1/8] Initial project for Google Cloud DNS in gcloud-java --- gcloud-java-dns/pom.xml | 54 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 gcloud-java-dns/pom.xml diff --git a/gcloud-java-dns/pom.xml b/gcloud-java-dns/pom.xml new file mode 100644 index 000000000000..55d720bc0a36 --- /dev/null +++ b/gcloud-java-dns/pom.xml @@ -0,0 +1,54 @@ + + + 4.0.0 + com.google.gcloud + gcloud-java-dns + jar + GCloud Java DNS + + Java idiomatic client for Google Cloud DNS. + + + com.google.gcloud + gcloud-java-pom + 0.1.3-SNAPSHOT + + + gcloud-java-dns + + + + ${project.groupId} + gcloud-java-core + ${project.version} + + + com.google.apis + google-api-services-dns + v1-rev7-1.21.0 + compile + + + com.google.guava + guava-jdk5 + + + com.google.api-client + google-api-client + + + + + junit + junit + 4.12 + test + + + org.easymock + easymock + 3.3 + test + + + From fe4e137fce65882465ca0e092761e080f366fece Mon Sep 17 00:00:00 2001 From: Martin Derka Date: Fri, 15 Jan 2016 17:56:24 -0800 Subject: [PATCH 2/8] Added DnsRecord as a part of the basic data model. ManagedZoneInfo is to be completed and it is included only as it is required as a builder parameter. This class will change in the near future. --- .../java/com/google/gcloud/dns/DnsRecord.java | 254 ++++++++++++++++++ .../google/gcloud/dns/ManagedZoneInfo.java | 44 +++ .../com/google/gcloud/dns/DnsRecordTest.java | 94 +++++++ 3 files changed, 392 insertions(+) create mode 100644 gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java create mode 100644 gcloud-java-dns/src/main/java/com/google/gcloud/dns/ManagedZoneInfo.java create mode 100644 gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java new file mode 100644 index 000000000000..8abf335969f8 --- /dev/null +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/DnsRecord.java @@ -0,0 +1,254 @@ +/* + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.gcloud.dns; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.collect.ImmutableList; + +import java.util.LinkedList; +import java.util.List; + +/** + * A class that represents Google Cloud DNS record set. + * + *

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

A {@code DnsRecord} is the unit of data that will be returned by the DNS servers upon a DNS * request for a specific domain. The {@code DnsRecord} holds the current state of the DNS records - * that make up a managed zone. You can read the records but you do not modify them directly. + * that make up a managed zone. You can read the records but you cannot modify them directly. * Rather, you edit the records in a managed zone by creating a ChangeRequest. * * @see Google Cloud DNS @@ -45,7 +45,7 @@ public class DnsRecord implements Serializable { private final String name; private final List rrdatas; private final Integer ttl; - private final DnsRecordType type; + private final Type type; /** * Enum for the DNS record types supported by Cloud DNS. @@ -56,7 +56,7 @@ public class DnsRecord implements Serializable { * @see Cloud DNS * supported record types */ - public enum DnsRecordType { + public enum Type { /** * Address record, which is used to map host names to their IPv4 address. */ @@ -105,14 +105,19 @@ public enum DnsRecordType { TXT } + /** + * A builder of {@link DnsRecord}. + */ public static class Builder { private List rrdatas = new LinkedList<>(); private String name; private Integer ttl; - private DnsRecordType type; + private Type type; - private Builder() { + private Builder(String name, Type type) { + this.name = checkNotNull(name); + this.type = checkNotNull(type); } /** @@ -177,7 +182,7 @@ public Builder name(String name) { * @param ttl A non-negative number of seconds */ public Builder ttl(int ttl) { - checkArgument(ttl >= 0, "TTL cannot be negative. The supplied value was " + ttl + "."); + checkArgument(ttl >= 0, "TTL cannot be negative. The supplied value was %s.", ttl); this.ttl = ttl; return this; } @@ -185,7 +190,7 @@ public Builder ttl(int ttl) { /** * The identifier of a supported record type, for example, A, AAAA, MX, TXT, and so on. */ - public Builder type(DnsRecordType type) { + public Builder type(Type type) { this.type = checkNotNull(type); return this; } @@ -198,7 +203,7 @@ public DnsRecord build() { } } - DnsRecord(Builder builder) { + private DnsRecord(Builder builder) { this.name = builder.name; this.rrdatas = ImmutableList.copyOf(builder.rrdatas); this.ttl = builder.ttl; @@ -213,14 +218,14 @@ public Builder toBuilder() { } /** - * Creates a builder for {@code DnsRecord} with mandatorily set name and type of the record. + * Creates a {@code DnsRecord} builder for the given {@code name} and {@code type}. */ - public static Builder builder(String name, DnsRecordType type) { - return new Builder().name(name).type(type); + public static Builder builder(String name, Type type) { + return new Builder(name, type); } /** - * Get the mandatory user assigned name of this DNS record. + * Returns the user-assigned name of this DNS record. */ public String name() { return name; @@ -243,7 +248,7 @@ public Integer ttl() { /** * Returns the type of this DNS record. */ - public DnsRecordType type() { + public Type type() { return type; } @@ -259,16 +264,16 @@ public boolean equals(Object obj) { com.google.api.services.dns.model.ResourceRecordSet toPb() { com.google.api.services.dns.model.ResourceRecordSet pb = - new com.google.api.services.dns.model.ResourceRecordSet(); + new com.google.api.services.dns.model.ResourceRecordSet(); pb.setName(this.name()); pb.setRrdatas(this.records()); pb.setTtl(this.ttl()); - pb.setType(this.type() == null ? null : this.type().name()); + pb.setType(this.type().name()); return pb; } static DnsRecord fromPb(com.google.api.services.dns.model.ResourceRecordSet pb) { - Builder b = builder(pb.getName(), DnsRecordType.valueOf(pb.getType())); + Builder b = builder(pb.getName(), Type.valueOf(pb.getType())); if (pb.getRrdatas() != null) { b.records(pb.getRrdatas()); } @@ -281,10 +286,10 @@ static DnsRecord fromPb(com.google.api.services.dns.model.ResourceRecordSet pb) @Override public String toString() { return MoreObjects.toStringHelper(this) - .add("name", name()) - .add("rrdatas", records()) - .add("ttl", ttl()) - .add("type", type()) - .toString(); + .add("name", name()) + .add("rrdatas", records()) + .add("ttl", ttl()) + .add("type", type()) + .toString(); } } diff --git a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java index e5b283a20acc..43ced20cf207 100644 --- a/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java +++ b/gcloud-java-dns/src/test/java/com/google/gcloud/dns/DnsRecordTest.java @@ -26,29 +26,32 @@ public class DnsRecordTest { private static final String NAME = "example.com."; private static final Integer TTL = 3600; - private static final DnsRecord.DnsRecordType TYPE = DnsRecord.DnsRecordType.AAAA; + private static final DnsRecord.Type TYPE = DnsRecord.Type.AAAA; private static final DnsRecord record = DnsRecord.builder(NAME, TYPE) - .ttl(TTL) - .build(); + .ttl(TTL) + .build(); @Test public void testDefaultDnsRecord() { DnsRecord record = DnsRecord.builder(NAME, TYPE).build(); assertEquals(0, record.records().size()); + assertEquals(TYPE, record.type()); + assertEquals(NAME, record.name()); } @Test public void testBuilder() { assertEquals(NAME, record.name()); assertEquals(TTL, record.ttl()); + assertEquals(TYPE, record.type()); assertEquals(0, record.records().size()); // verify that one can add records to the record set String testingRecord = "Testing record"; String anotherTestingRecord = "Another record 123"; DnsRecord anotherRecord = record.toBuilder() - .addRecord(testingRecord) - .addRecord(anotherTestingRecord) - .build(); + .addRecord(testingRecord) + .addRecord(anotherTestingRecord) + .build(); assertEquals(2, anotherRecord.records().size()); assertTrue(anotherRecord.records().contains(testingRecord)); assertTrue(anotherRecord.records().contains(anotherTestingRecord)); @@ -72,12 +75,12 @@ public void testEqualsAndNotEquals() { assertEquals(clone, record); clone = record.toBuilder().addRecord("another record").build(); assertNotEquals(clone, record); - final String differentName = "totally different name"; + String differentName = "totally different name"; clone = record.toBuilder().name(differentName).build(); assertNotEquals(clone, record); clone = record.toBuilder().ttl(record.ttl() + 1).build(); assertNotEquals(clone, record); - clone = record.toBuilder().type(DnsRecord.DnsRecordType.TXT).build(); + clone = record.toBuilder().type(DnsRecord.Type.TXT).build(); assertNotEquals(clone, record); } @@ -109,4 +112,24 @@ public void testToBuilder() { partial = DnsRecord.builder(NAME, TYPE).ttl(15).build(); assertEquals(partial, partial.toBuilder().build()); } -} \ No newline at end of file + + @Test + public void clearRecordSet() { + // make sure that we are starting not empty + DnsRecord clone = record.toBuilder().addRecord("record").addRecord("another").build(); + assertNotEquals(0, clone.records().size()); + clone = clone.toBuilder().clearRecords().build(); + assertEquals(0, clone.records().size()); + clone.toPb(); // verify that pb allows it + } + + @Test + public void removeFromRecordSet() { + String recordString = "record"; + // make sure that we are starting not empty + DnsRecord clone = record.toBuilder().addRecord(recordString).build(); + assertNotEquals(0, clone.records().size()); + clone = clone.toBuilder().removeRecord(recordString).build(); + assertEquals(0, clone.records().size()); + } +}