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 + + + 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."); + } + } + +} diff --git a/gcloud-java/pom.xml b/gcloud-java/pom.xml index 68dcdd661b6d..6e31d339fbe5 100644 --- a/gcloud-java/pom.xml +++ b/gcloud-java/pom.xml @@ -39,5 +39,10 @@ gcloud-java-storage ${project.version} + + ${project.groupId} + gcloud-java-dns + ${project.version} +