Skip to content

Commit fe4e137

Browse files
committed
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.
1 parent 2bf4925 commit fe4e137

File tree

3 files changed

+392
-0
lines changed

3 files changed

+392
-0
lines changed
Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
/*
2+
* Copyright 2016 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.google.gcloud.dns;
17+
18+
import static com.google.common.base.Preconditions.checkNotNull;
19+
20+
import com.google.common.collect.ImmutableList;
21+
22+
import java.util.LinkedList;
23+
import java.util.List;
24+
25+
/**
26+
* A class that represents Google Cloud DNS record set.
27+
*
28+
* <p>
29+
* A unit of data that will be returned by the DNS servers.
30+
*
31+
* @see <a href="https://cloud.google.com/dns/api/v1/resourceRecordSets">Google
32+
* Cloud DNS documentation</a>
33+
*/
34+
public class DnsRecord {
35+
36+
private String name;
37+
private List<String> rrdatas = new LinkedList<>();
38+
private Integer ttl = 86400; // the default ttl of 24 hours
39+
private DnsRecordType type;
40+
private String parentName;
41+
private Long parentId;
42+
43+
/**
44+
* A private constructor. Obtain an instance using {@link DnsRecord#Builder}.
45+
*/
46+
private DnsRecord() {
47+
}
48+
49+
DnsRecord(Builder builder) {
50+
this.name = builder.name;
51+
this.rrdatas = ImmutableList.copyOf(builder.rrdatas);
52+
this.ttl = builder.ttl;
53+
this.type = builder.type;
54+
this.parentName = builder.parentName;
55+
this.parentId = builder.parentId;
56+
}
57+
58+
/**
59+
* Enum for the DNS record types supported by Cloud DNS.
60+
*
61+
* <p>
62+
* Google Cloud DNS currently supports records of type A, AAAA, CNAME, MX
63+
* NAPTR, NS, PTR, SOA, SPF, SRV, TXT.
64+
*
65+
* @see
66+
* <a href="https://cloud.google.com/dns/what-is-cloud-dns#supported_record_types">Cloud
67+
* DNS supported record types</a>
68+
*/
69+
public enum DnsRecordType {
70+
A("A"),
71+
AAAA("AAAA"),
72+
CNAME("CNAME"),
73+
MX("MX"),
74+
NAPTR("NAPTR"),
75+
NS("NS"),
76+
PTR("PTR"),
77+
SOA("SOA"),
78+
SPF("SPF"),
79+
SRV("SRV"),
80+
TXT("TXT");
81+
82+
private final String type;
83+
84+
private DnsRecordType(String type) {
85+
this.type = type;
86+
}
87+
}
88+
89+
public static class Builder {
90+
91+
private List<String> rrdatas = new LinkedList<>();
92+
private String name;
93+
private Integer ttl = 86400; // default ttl of 24 hours
94+
private DnsRecordType type;
95+
private String parentName;
96+
private Long parentId;
97+
98+
private Builder() {
99+
}
100+
101+
/**
102+
* Creates a builder and pre-populates attributes with the values from the
103+
* provided DnsRecord instance.
104+
*/
105+
public Builder(DnsRecord record) {
106+
this.name = record.name;
107+
this.ttl = record.ttl;
108+
this.type = record.type;
109+
this.parentId = record.parentId;
110+
this.parentName = record.parentName;
111+
this.rrdatas.addAll(record.rrdatas);
112+
}
113+
114+
/**
115+
* Adds a record to the record set.
116+
*
117+
* <p>
118+
* The records should be as defined in RFC 1035 (section 5) and RFC 1034
119+
* (section 3.6.1). Examples of records are available in
120+
* <a href="https://cloud.google.com/dns/what-is-cloud-dns#supported_record_types">Cloud
121+
* DNS documentation</a>.
122+
*/
123+
public Builder add(String record) {
124+
this.rrdatas.add(checkNotNull(record));
125+
return this;
126+
}
127+
128+
/**
129+
* Sets name for this DNS record set. For example, www.example.com.
130+
*/
131+
public Builder name(String name) {
132+
this.name = checkNotNull(name);
133+
return this;
134+
}
135+
136+
/**
137+
* Sets the number of seconds that this record can be cached by resolvers.
138+
* This number must be non-negative.
139+
*
140+
* @param ttl A non-negative number of seconds
141+
*/
142+
public Builder ttl(int ttl) {
143+
// change only if
144+
if (ttl < 0) {
145+
throw new IllegalArgumentException(
146+
"TTL cannot be negative. The supplied value was " + ttl + "."
147+
);
148+
}
149+
this.ttl = ttl;
150+
return this;
151+
}
152+
153+
/**
154+
* The identifier of a supported record type, for example, A, AAAA, MX, TXT,
155+
* and so on.
156+
*/
157+
public Builder type(DnsRecordType type) {
158+
this.type = checkNotNull(type);
159+
return this;
160+
}
161+
162+
/**
163+
* Builds the DNS record.
164+
*/
165+
public DnsRecord build() {
166+
return new DnsRecord(this);
167+
}
168+
169+
/**
170+
* Sets references to the managed zone that this DNS record belongs to.
171+
*/
172+
public Builder managedZone(ManagedZoneInfo parent) {
173+
checkNotNull(parent);
174+
this.parentId = parent.id();
175+
this.parentName = parent.name();
176+
return this;
177+
}
178+
}
179+
180+
/**
181+
* Creates a builder pre-populated with the attribute values of this instance.
182+
*/
183+
public Builder toBuilder() {
184+
return new Builder(this);
185+
}
186+
187+
/**
188+
* Creates an empty builder
189+
*/
190+
public static Builder builder() {
191+
return new Builder();
192+
}
193+
194+
/**
195+
* Get user assigned name of this DNS record.
196+
*
197+
* TODO: is this field mandatory?
198+
*/
199+
public String name() {
200+
return name;
201+
}
202+
203+
/**
204+
* Returns a list of DNS record stored in this record set.
205+
*/
206+
public List<String> rrdatas() {
207+
return rrdatas;
208+
}
209+
210+
/**
211+
* Returns the number of seconds that this ResourceRecordSet can be cached by
212+
* resolvers.
213+
*
214+
* <p>
215+
* This number is provided by the user. If this values is not set, we use
216+
* default of 86400.
217+
*/
218+
public Integer ttl() {
219+
return ttl;
220+
}
221+
222+
/**
223+
* Returns the type of this DNS record.
224+
*/
225+
public DnsRecordType type() {
226+
return type;
227+
}
228+
229+
/**
230+
* Returns name of the managed zone that this record belongs to.
231+
*
232+
* <p>
233+
* The name of the managed zone is provided by the user when the managed zone
234+
* is created. It is unique within a project. If this DNS record is not
235+
* associated with a managed zone, this returns null.
236+
*/
237+
public String parentName() {
238+
return parentName;
239+
}
240+
241+
/**
242+
* Returns name of the managed zone that this record belongs to.
243+
*
244+
* <p>
245+
* The id of the managed zone is determined by the server when the managed
246+
* zone is created. It is a read only value. If this DNS record is not
247+
* associated with a managed zone, or if the id of the managed zone was not
248+
* loaded from the cloud service, this returns null.
249+
*/
250+
public Long parentId() {
251+
return parentId;
252+
}
253+
254+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright 2016 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.google.gcloud.dns;
17+
18+
/**
19+
* TODO: Implement.
20+
* TODO: Add documentation.
21+
*/
22+
public class ManagedZoneInfo {
23+
24+
private final String name;
25+
private final Long id;
26+
27+
public String name() {
28+
throw new UnsupportedOperationException("Not implemented yet.");
29+
// TODO: Implement
30+
}
31+
32+
public Long id() {
33+
return id;
34+
// TODO: Implement
35+
}
36+
37+
private ManagedZoneInfo() {
38+
name = null;
39+
id = null;
40+
throw new UnsupportedOperationException("Not implemented yet");
41+
// TODO: Implement
42+
}
43+
44+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/*
2+
* Copyright 2016 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.google.gcloud.dns;
17+
18+
import org.easymock.EasyMock;
19+
20+
import org.junit.Test;
21+
import org.junit.Before;
22+
23+
import static org.junit.Assert.*;
24+
25+
public class DnsRecordTest {
26+
27+
private static final String NAME = "example.com.";
28+
private static final Integer TTL = 3600;
29+
private static final DnsRecord.DnsRecordType TYPE = DnsRecord.DnsRecordType.AAAA;
30+
private static final ManagedZoneInfo MANAGED_ZONE_INFO_MOCK
31+
= EasyMock.createMock(ManagedZoneInfo.class);
32+
private static final Long PARENT_ID = 12L;
33+
private static final String PARENT_NAME = "name";
34+
static {
35+
EasyMock.expect(MANAGED_ZONE_INFO_MOCK.id()).andReturn(PARENT_ID);
36+
EasyMock.expect(MANAGED_ZONE_INFO_MOCK.name()).andReturn(PARENT_NAME);
37+
EasyMock.replay(MANAGED_ZONE_INFO_MOCK);
38+
}
39+
private static final DnsRecord RECORD = DnsRecord.builder()
40+
.name(NAME)
41+
.ttl(TTL)
42+
.managedZone(MANAGED_ZONE_INFO_MOCK)
43+
.build();
44+
private static final Integer DEFAULT_TTL = 86400;
45+
46+
@Test
47+
public void testDefaultDnsRecord() {
48+
DnsRecord record = DnsRecord.builder().build();
49+
assertEquals(DEFAULT_TTL, record.ttl());
50+
assertEquals(0, record.rrdatas().size());
51+
}
52+
53+
@Test
54+
public void testBuilder() {
55+
56+
assertEquals(NAME, RECORD.name());
57+
assertEquals(TTL, RECORD.ttl());
58+
59+
assertEquals(PARENT_ID, RECORD.parentId()); // this was never assigned
60+
assertEquals(PARENT_NAME, RECORD.parentName());
61+
assertEquals(0, RECORD.rrdatas().size());
62+
// verify that one can add records to the record set
63+
String testingRecord = "Testing record";
64+
String anotherTestingRecord = "Another record 123";
65+
DnsRecord anotherRecord = RECORD.toBuilder()
66+
.add(testingRecord)
67+
.add(anotherTestingRecord)
68+
.build();
69+
assertEquals(2, anotherRecord.rrdatas().size());
70+
assertTrue(anotherRecord.rrdatas().contains(testingRecord));
71+
assertTrue(anotherRecord.rrdatas().contains(anotherTestingRecord));
72+
}
73+
74+
@Test
75+
public void testValidTtl() {
76+
try {
77+
DnsRecord.builder().ttl(-1);
78+
fail("A negative value is not acceptable for ttl.");
79+
} catch (IllegalArgumentException e) {
80+
// ok
81+
}
82+
try {
83+
DnsRecord.builder().ttl(0);
84+
} catch (IllegalArgumentException e) {
85+
fail("0 is a valid value.");
86+
}
87+
try {
88+
DnsRecord.builder().ttl(Integer.MAX_VALUE);
89+
} catch (Exception e) {
90+
fail("Large numbers should be ok too.");
91+
}
92+
}
93+
94+
}

0 commit comments

Comments
 (0)