diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java index 3ad2094ec2e3..b2cb9fbad371 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/dns/Dns.java @@ -68,7 +68,8 @@ static String selector(ProjectField... fields) { * The fields of a zone. * *

These values can be used to specify the fields to include in a partial response when calling - * {@link Dns#getZone(String, ZoneOption...)}. The name is always returned, even if not specified. + * {@link Dns#getZone(String, ZoneOption...)}. The name is always returned, even if not + * specified. */ enum ZoneField { CREATION_TIME("creationTime"), @@ -103,8 +104,8 @@ static String selector(ZoneField... fields) { * The fields of a DNS record. * *

These values can be used to specify the fields to include in a partial response when calling - * {@link Dns#listDnsRecords(String, DnsRecordListOption...)}. The name is always returned even if - * not selected. + * {@link Dns#listDnsRecords(String, DnsRecordListOption...)}. The name and type are always + * returned even if not selected. */ enum DnsRecordField { DNS_RECORDS("rrdatas"), @@ -125,6 +126,7 @@ String selector() { static String selector(DnsRecordField... fields) { Set fieldStrings = Sets.newHashSetWithExpectedSize(fields.length + 1); fieldStrings.add(NAME.selector()); + fieldStrings.add(TYPE.selector()); for (DnsRecordField field : fields) { fieldStrings.add(field.selector()); } @@ -198,7 +200,7 @@ class DnsRecordListOption extends AbstractOption implements Serializable { */ public static DnsRecordListOption fields(DnsRecordField... fields) { StringBuilder builder = new StringBuilder(); - builder.append("rrsets(").append(DnsRecordField.selector(fields)).append(')'); + builder.append("nextPageToken,rrsets(").append(DnsRecordField.selector(fields)).append(')'); return new DnsRecordListOption(DnsRpc.Option.FIELDS, builder.toString()); } @@ -234,7 +236,7 @@ public static DnsRecordListOption dnsName(String dnsName) { * Dns.DnsRecordListOption#dnsName(String)} must also be present. */ public static DnsRecordListOption type(DnsRecord.Type type) { - return new DnsRecordListOption(DnsRpc.Option.DNS_TYPE, type); + return new DnsRecordListOption(DnsRpc.Option.DNS_TYPE, type.name()); } } @@ -281,7 +283,7 @@ class ZoneListOption extends AbstractOption implements Serializable { */ public static ZoneListOption fields(ZoneField... fields) { StringBuilder builder = new StringBuilder(); - builder.append("managedZones(").append(ZoneField.selector(fields)).append(')'); + builder.append("nextPageToken,managedZones(").append(ZoneField.selector(fields)).append(')'); return new ZoneListOption(DnsRpc.Option.FIELDS, builder.toString()); } @@ -388,7 +390,8 @@ class ChangeRequestListOption extends AbstractOption implements Serializable { */ public static ChangeRequestListOption fields(ChangeRequestField... fields) { StringBuilder builder = new StringBuilder(); - builder.append("changes(").append(ChangeRequestField.selector(fields)).append(')'); + builder.append("nextPageToken,changes(").append(ChangeRequestField.selector(fields)) + .append(')'); return new ChangeRequestListOption(DnsRpc.Option.FIELDS, builder.toString()); } diff --git a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java index 6ed9c7e0f216..1df0a8a2f831 100644 --- a/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java +++ b/gcloud-java-dns/src/main/java/com/google/gcloud/spi/DefaultDnsRpc.java @@ -162,7 +162,9 @@ public Change getChangeRequest(String zoneName, String changeRequestId, Map zones = DNS.listZones(); + Iterator zoneIterator = zones.iterateAll(); + while (zoneIterator.hasNext()) { + Zone zone = zoneIterator.next(); + List toDelete = new LinkedList<>(); + if (zone.name().startsWith(PREFIX)) { + Iterator dnsRecordIterator = zone.listDnsRecords().iterateAll(); + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + if (!ImmutableList.of(DnsRecord.Type.NS, DnsRecord.Type.SOA).contains(record.type())) { + toDelete.add(record); + } + } + if (!toDelete.isEmpty()) { + ChangeRequest deletion = + zone.applyChangeRequest(ChangeRequest.builder().deletions(toDelete).build()); + waitUntilComplete(zone.name(), deletion.id()); + } + zone.delete(); + } + } + } + + private static List filter(Iterator iterator) { + List result = new LinkedList<>(); + while (iterator.hasNext()) { + Zone zone = iterator.next(); + if (zone.name().startsWith(PREFIX)) { + result.add(zone); + } + } + return result; + } + + @BeforeClass + public static void before() { + clear(); + } + + @AfterClass + public static void after() { + clear(); + } + + private static void assertEqChangesIgnoreStatus(ChangeRequest expected, ChangeRequest actual) { + assertEquals(expected.additions(), actual.additions()); + assertEquals(expected.deletions(), actual.deletions()); + assertEquals(expected.id(), actual.id()); + assertEquals(expected.startTimeMillis(), actual.startTimeMillis()); + } + + private static void waitUntilComplete(String zoneName, String changeId) { + while (true) { + ChangeRequest changeRequest = DNS.getChangeRequest(zoneName, changeId, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); + if (ChangeRequest.Status.DONE.equals(changeRequest.status())) { + return; + } + try { + Thread.sleep(500); + } catch (InterruptedException e) { + fail("Thread was interrupted while waiting for change processing."); + } + } + } + + @Rule + public Timeout globalTimeout = Timeout.seconds(300); + + @Test + public void testCreateValidZone() { + try { + Zone created = DNS.create(ZONE1); + assertEquals(ZONE1.description(), created.description()); + assertEquals(ZONE1.dnsName(), created.dnsName()); + assertEquals(ZONE1.name(), created.name()); + assertNotNull(created.creationTimeMillis()); + assertNotNull(created.nameServers()); + assertNull(created.nameServerSet()); + assertNotNull(created.id()); + Zone retrieved = DNS.getZone(ZONE1.name()); + assertEquals(created, retrieved); + created = DNS.create(ZONE_EMPTY_DESCRIPTION); + assertEquals(ZONE_EMPTY_DESCRIPTION.description(), created.description()); + assertEquals(ZONE_EMPTY_DESCRIPTION.dnsName(), created.dnsName()); + assertEquals(ZONE_EMPTY_DESCRIPTION.name(), created.name()); + assertNotNull(created.creationTimeMillis()); + assertNotNull(created.nameServers()); + assertNull(created.nameServerSet()); + assertNotNull(created.id()); + retrieved = DNS.getZone(ZONE_EMPTY_DESCRIPTION.name()); + assertEquals(created, retrieved); + } finally { + DNS.delete(ZONE1.name()); + DNS.delete(ZONE_EMPTY_DESCRIPTION.name()); + } + } + + @Test + public void testCreateZoneWithErrors() { + try { + try { + DNS.create(ZONE_MISSING_DNS_NAME); + fail("Zone is missing DNS name. The service returns an error."); + } catch (DnsException ex) { + // expected + // todo(mderka) test non-retryable when implemented within #593 + } + try { + DNS.create(ZONE_MISSING_DESCRIPTION); + fail("Zone is missing description name. The service returns an error."); + } catch (DnsException ex) { + // expected + // todo(mderka) test non-retryable when implemented within #593 + } + try { + DNS.create(ZONE_NAME_ERROR); + fail("Zone name is missing a period. The service returns an error."); + } catch (DnsException ex) { + // expected + // todo(mderka) test non-retryable when implemented within #593 + } + try { + DNS.create(ZONE_DNS_NO_PERIOD); + fail("Zone name is missing a period. The service returns an error."); + } catch (DnsException ex) { + // expected + // todo(mderka) test non-retryable when implemented within #593 + } + } finally { + DNS.delete(ZONE_MISSING_DNS_NAME.name()); + DNS.delete(ZONE_MISSING_DESCRIPTION.name()); + DNS.delete(ZONE_NAME_ERROR.name()); + DNS.delete(ZONE_DNS_NO_PERIOD.name()); + } + } + + @Test + public void testCreateZoneWithOptions() { + try { + Zone created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.CREATION_TIME)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNotNull(created.creationTimeMillis()); + assertNull(created.description()); + assertNull(created.dnsName()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created.delete(); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.DESCRIPTION)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertEquals(ZONE1.description(), created.description()); + assertNull(created.dnsName()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created.delete(); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.DNS_NAME)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertEquals(ZONE1.dnsName(), created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created.delete(); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created.delete(); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVER_SET)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); // we did not set it + assertNull(created.id()); + created.delete(); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVERS)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertFalse(created.nameServers().isEmpty()); + assertNull(created.nameServerSet()); + assertNull(created.id()); + created.delete(); + created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertNotNull(created.nameServers()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNotNull(created.id()); + created.delete(); + // combination of multiple things + created = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID, + Dns.ZoneField.NAME_SERVERS, Dns.ZoneField.NAME_SERVER_SET, Dns.ZoneField.DESCRIPTION)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertEquals(ZONE1.description(), created.description()); + assertFalse(created.nameServers().isEmpty()); + assertNull(created.nameServerSet()); // we did not set it + assertNotNull(created.id()); + } finally { + DNS.delete(ZONE1.name()); + } + } + + @Test + public void testGetZone() { + try { + DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); + Zone created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.CREATION_TIME)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNotNull(created.creationTimeMillis()); + assertNull(created.description()); + assertNull(created.dnsName()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.DESCRIPTION)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertEquals(ZONE1.description(), created.description()); + assertNull(created.dnsName()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.DNS_NAME)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertEquals(ZONE1.dnsName(), created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.NAME)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); + assertNull(created.id()); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVER_SET)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNull(created.nameServerSet()); // we did not set it + assertNull(created.id()); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.NAME_SERVERS)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertFalse(created.nameServers().isEmpty()); + assertNull(created.nameServerSet()); + assertNull(created.id()); + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertNull(created.description()); + assertNotNull(created.nameServers()); + assertTrue(created.nameServers().isEmpty()); // never returns null + assertNotNull(created.id()); + // combination of multiple things + created = DNS.getZone(ZONE1.name(), Dns.ZoneOption.fields(Dns.ZoneField.ZONE_ID, + Dns.ZoneField.NAME_SERVERS, Dns.ZoneField.NAME_SERVER_SET, Dns.ZoneField.DESCRIPTION)); + assertEquals(ZONE1.name(), created.name()); // always returned + assertNull(created.creationTimeMillis()); + assertNull(created.dnsName()); + assertEquals(ZONE1.description(), created.description()); + assertFalse(created.nameServers().isEmpty()); + assertNull(created.nameServerSet()); // we did not set it + assertNotNull(created.id()); + } finally { + DNS.delete(ZONE1.name()); + } + } + + @Test + public void testListZones() { + try { + List zones = filter(DNS.listZones().iterateAll()); + assertEquals(0, zones.size()); + // some zones exists + Zone created = DNS.create(ZONE1); + zones = filter(DNS.listZones().iterateAll()); + assertEquals(created, zones.get(0)); + assertEquals(1, zones.size()); + created = DNS.create(ZONE_EMPTY_DESCRIPTION); + zones = filter(DNS.listZones().iterateAll()); + assertEquals(2, zones.size()); + assertTrue(zones.contains(created)); + // error in options + try { + DNS.listZones(Dns.ZoneListOption.pageSize(0)); + fail(); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test not-retryable + } + try { + DNS.listZones(Dns.ZoneListOption.pageSize(-1)); + fail(); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test not-retryable + } + // ok size + zones = filter(DNS.listZones(Dns.ZoneListOption.pageSize(1000)).iterateAll()); + assertEquals(2, zones.size()); // we still have only 2 zones + // dns name problems + try { + DNS.listZones(Dns.ZoneListOption.dnsName("aaaaa")); + fail(); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test not-retryable + } + // ok name + zones = filter(DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName())).iterateAll()); + assertEquals(1, zones.size()); + // field options + Iterator zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(Dns.ZoneField.ZONE_ID)).iterateAll(); + Zone zone = zoneIterator.next(); + assertNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNull(zone.dnsName()); + assertNull(zone.description()); + assertNull(zone.nameServerSet()); + assertTrue(zone.nameServers().isEmpty()); + assertNotNull(zone.id()); + assertFalse(zoneIterator.hasNext()); + zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(Dns.ZoneField.CREATION_TIME)).iterateAll(); + zone = zoneIterator.next(); + assertNotNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNull(zone.dnsName()); + assertNull(zone.description()); + assertNull(zone.nameServerSet()); + assertTrue(zone.nameServers().isEmpty()); + assertNull(zone.id()); + assertFalse(zoneIterator.hasNext()); + zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(Dns.ZoneField.DNS_NAME)).iterateAll(); + zone = zoneIterator.next(); + assertNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNotNull(zone.dnsName()); + assertNull(zone.description()); + assertNull(zone.nameServerSet()); + assertTrue(zone.nameServers().isEmpty()); + assertNull(zone.id()); + assertFalse(zoneIterator.hasNext()); + zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(Dns.ZoneField.DESCRIPTION)).iterateAll(); + zone = zoneIterator.next(); + assertNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNull(zone.dnsName()); + assertNotNull(zone.description()); + assertNull(zone.nameServerSet()); + assertTrue(zone.nameServers().isEmpty()); + assertNull(zone.id()); + assertFalse(zoneIterator.hasNext()); + zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(Dns.ZoneField.NAME_SERVERS)).iterateAll(); + zone = zoneIterator.next(); + assertNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNull(zone.dnsName()); + assertNull(zone.description()); + assertNull(zone.nameServerSet()); + assertTrue(!zone.nameServers().isEmpty()); + assertNull(zone.id()); + assertFalse(zoneIterator.hasNext()); + zoneIterator = DNS.listZones(Dns.ZoneListOption.dnsName(ZONE1.dnsName()), + Dns.ZoneListOption.fields(Dns.ZoneField.NAME_SERVER_SET)).iterateAll(); + zone = zoneIterator.next(); + assertNull(zone.creationTimeMillis()); + assertNotNull(zone.name()); + assertNull(zone.dnsName()); + assertNull(zone.description()); + assertNull(zone.nameServerSet()); // we cannot set it using gcloud java + assertTrue(zone.nameServers().isEmpty()); + assertNull(zone.id()); + assertFalse(zoneIterator.hasNext()); + // several combined + zones = filter(DNS.listZones(Dns.ZoneListOption.fields(Dns.ZoneField.ZONE_ID, + Dns.ZoneField.DESCRIPTION), + Dns.ZoneListOption.pageSize(1)).iterateAll()); + assertEquals(2, zones.size()); + for (Zone current : zones) { + assertNull(current.creationTimeMillis()); + assertNotNull(current.name()); + assertNull(current.dnsName()); + assertNotNull(current.description()); + assertNull(current.nameServerSet()); + assertTrue(zone.nameServers().isEmpty()); + assertNotNull(current.id()); + } + } finally { + DNS.delete(ZONE1.name()); + DNS.delete(ZONE_EMPTY_DESCRIPTION.name()); + } + } + + @Test + public void testDeleteZone() { + try { + Zone created = DNS.create(ZONE1); + assertEquals(created, DNS.getZone(ZONE1.name())); + DNS.delete(ZONE1.name()); + assertNull(DNS.getZone(ZONE1.name())); + } finally { + DNS.delete(ZONE1.name()); + } + } + + @Test + public void testCreateChange() { + try { + DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); + ChangeRequest created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); + assertEquals(CHANGE_ADD_ZONE1.additions(), created.additions()); + assertNotNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertEquals("1", created.id()); + assertTrue(ImmutableList.of(ChangeRequest.Status.PENDING, ChangeRequest.Status.DONE) + .contains(created.status())); + assertEqChangesIgnoreStatus(created, DNS.getChangeRequest(ZONE1.name(), "1")); + waitUntilComplete(ZONE1.name(), "1"); + DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + waitUntilComplete(ZONE1.name(), "2"); + // with options + created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); + assertTrue(created.additions().isEmpty()); + assertNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertEquals("3", created.id()); + assertNull(created.status()); + waitUntilComplete(ZONE1.name(), "3"); + DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + waitUntilComplete(ZONE1.name(), "4"); + created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); + assertTrue(created.additions().isEmpty()); + assertNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertEquals("5", created.id()); + assertNotNull(created.status()); + waitUntilComplete(ZONE1.name(), "5"); + DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + waitUntilComplete(ZONE1.name(), "6"); + created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); + assertTrue(created.additions().isEmpty()); + assertNotNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertEquals("7", created.id()); + assertNull(created.status()); + waitUntilComplete(ZONE1.name(), "7"); + DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + waitUntilComplete(ZONE1.name(), "8"); + created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); + assertEquals(CHANGE_ADD_ZONE1.additions(), created.additions()); + assertNull(created.startTimeMillis()); + assertTrue(created.deletions().isEmpty()); + assertEquals("9", created.id()); + assertNull(created.status()); + // finishes with delete otherwise we cannot delete the zone + waitUntilComplete(ZONE1.name(), "9"); + created = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); + waitUntilComplete(ZONE1.name(), "10"); + assertEquals(CHANGE_DELETE_ZONE1.deletions(), created.deletions()); + assertNull(created.startTimeMillis()); + assertTrue(created.additions().isEmpty()); + assertEquals("10", created.id()); + assertNull(created.status()); + waitUntilComplete(ZONE1.name(), "10"); + } finally { + clear(); + } + } + + @Test + public void testListChanges() { + try { + // no such zone exists + try { + DNS.listChangeRequests(ZONE1.name()); + fail(); + } catch (DnsException ex) { + // expected + assertEquals(404, ex.code()); + // todo(mderka) test retry functionality + } + // zone exists but has no changes + DNS.create(ZONE1); + ImmutableList changes = ImmutableList.copyOf( + DNS.listChangeRequests(ZONE1.name()).iterateAll()); + assertEquals(1, changes.size()); // default change creating SOA and NS + // zone has changes + ChangeRequest change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); + waitUntilComplete(ZONE1.name(), change.id()); + change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + waitUntilComplete(ZONE1.name(), change.id()); + change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); + waitUntilComplete(ZONE1.name(), change.id()); + change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_DELETE_ZONE1); + waitUntilComplete(ZONE1.name(), change.id()); + changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name()).iterateAll()); + assertEquals(5, changes.size()); + // error in options + try { + DNS.listChangeRequests(ZONE1.name(), Dns.ChangeRequestListOption.pageSize(0)); + fail(); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test retry functionality + } + try { + DNS.listChangeRequests(ZONE1.name(), Dns.ChangeRequestListOption.pageSize(-1)); + fail(); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test retry functionality + } + // sorting order + ImmutableList ascending = ImmutableList.copyOf(DNS.listChangeRequests( + ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING)).iterateAll()); + ImmutableList descending = ImmutableList.copyOf(DNS.listChangeRequests( + ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.DESCENDING)).iterateAll()); + int size = 5; + assertEquals(size, descending.size()); + assertEquals(size, ascending.size()); + for (int i = 0; i < size; i++) { + assertEquals(descending.get(i), ascending.get(size - i - 1)); + } + // field options + changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.ADDITIONS)).iterateAll()); + change = changes.get(1); + assertEquals(CHANGE_ADD_ZONE1.additions(), change.additions()); + assertTrue(change.deletions().isEmpty()); + assertEquals("1", change.id()); + assertNull(change.startTimeMillis()); + assertNull(change.status()); + changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.DELETIONS)).iterateAll()); + change = changes.get(2); + assertTrue(change.additions().isEmpty()); + assertNotNull(change.deletions()); + assertEquals("2", change.id()); + assertNull(change.startTimeMillis()); + assertNull(change.status()); + changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.ID)).iterateAll()); + change = changes.get(1); + assertTrue(change.additions().isEmpty()); + assertTrue(change.deletions().isEmpty()); + assertEquals("1", change.id()); + assertNull(change.startTimeMillis()); + assertNull(change.status()); + changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.START_TIME)).iterateAll()); + change = changes.get(1); + assertTrue(change.additions().isEmpty()); + assertTrue(change.deletions().isEmpty()); + assertEquals("1", change.id()); + assertNotNull(change.startTimeMillis()); + assertNull(change.status()); + changes = ImmutableList.copyOf(DNS.listChangeRequests(ZONE1.name(), + Dns.ChangeRequestListOption.sortOrder(Dns.SortingOrder.ASCENDING), + Dns.ChangeRequestListOption.fields(Dns.ChangeRequestField.STATUS)).iterateAll()); + change = changes.get(1); + assertTrue(change.additions().isEmpty()); + assertTrue(change.deletions().isEmpty()); + assertEquals("1", change.id()); + assertNull(change.startTimeMillis()); + assertEquals(ChangeRequest.Status.DONE, change.status()); + } finally { + clear(); + } + } + + @Test + public void testGetChange() { + try { + Zone zone = DNS.create(ZONE1, Dns.ZoneOption.fields(Dns.ZoneField.NAME)); + ChangeRequest created = zone.applyChangeRequest(CHANGE_ADD_ZONE1); + ChangeRequest retrieved = DNS.getChangeRequest(zone.name(), created.id()); + assertEqChangesIgnoreStatus(created, retrieved); + zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + // with options + created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); + retrieved = DNS.getChangeRequest(zone.name(), created.id(), + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ID)); + assertEqChangesIgnoreStatus(created, retrieved); + zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); + retrieved = DNS.getChangeRequest(zone.name(), created.id(), + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.STATUS)); + assertEqChangesIgnoreStatus(created, retrieved); + zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); + retrieved = DNS.getChangeRequest(zone.name(), created.id(), + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.START_TIME)); + assertEqChangesIgnoreStatus(created, retrieved); + zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + created = zone.applyChangeRequest(CHANGE_ADD_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); + retrieved = DNS.getChangeRequest(zone.name(), created.id(), + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.ADDITIONS)); + assertEqChangesIgnoreStatus(created, retrieved); + // finishes with delete otherwise we cannot delete the zone + created = zone.applyChangeRequest(CHANGE_DELETE_ZONE1, + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); + retrieved = DNS.getChangeRequest(zone.name(), created.id(), + Dns.ChangeRequestOption.fields(Dns.ChangeRequestField.DELETIONS)); + assertEqChangesIgnoreStatus(created, retrieved); + } finally { + clear(); + } + } + + @Test + public void testGetProject() { + // fetches all fields + ProjectInfo project = DNS.getProject(); + assertNotNull(project.quota()); + // options + project = DNS.getProject(Dns.ProjectOption.fields(Dns.ProjectField.QUOTA)); + assertNotNull(project.quota()); + project = DNS.getProject(Dns.ProjectOption.fields(Dns.ProjectField.PROJECT_ID)); + assertNull(project.quota()); + project = DNS.getProject(Dns.ProjectOption.fields(Dns.ProjectField.PROJECT_NUMBER)); + assertNull(project.quota()); + project = DNS.getProject(Dns.ProjectOption.fields(Dns.ProjectField.PROJECT_NUMBER, + Dns.ProjectField.QUOTA, Dns.ProjectField.PROJECT_ID)); + assertNotNull(project.quota()); + } + + @Test + public void testListDnsRecords() { + try { + Zone zone = DNS.create(ZONE1); + ImmutableList dnsRecords = ImmutableList.copyOf( + DNS.listDnsRecords(zone.name()).iterateAll()); + assertEquals(2, dnsRecords.size()); + ImmutableList defaultRecords = + ImmutableList.of(DnsRecord.Type.NS, DnsRecord.Type.SOA); + for (DnsRecord record : dnsRecords) { + assertTrue(defaultRecords.contains(record.type())); + } + // field options + Iterator dnsRecordIterator = DNS.listDnsRecords(zone.name(), + Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TTL)).iterateAll(); + int counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertEquals(dnsRecords.get(counter).ttl(), record.ttl()); + assertEquals(dnsRecords.get(counter).name(), record.name()); + assertEquals(dnsRecords.get(counter).type(), record.type()); + assertTrue(record.records().isEmpty()); + counter++; + } + assertEquals(2, counter); + dnsRecordIterator = DNS.listDnsRecords(zone.name(), + Dns.DnsRecordListOption.fields(Dns.DnsRecordField.NAME)).iterateAll(); + counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertEquals(dnsRecords.get(counter).name(), record.name()); + assertEquals(dnsRecords.get(counter).type(), record.type()); + assertTrue(record.records().isEmpty()); + assertNull(record.ttl()); + counter++; + } + assertEquals(2, counter); + dnsRecordIterator = DNS.listDnsRecords(zone.name(), + Dns.DnsRecordListOption.fields(Dns.DnsRecordField.DNS_RECORDS)).iterateAll(); + counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertEquals(dnsRecords.get(counter).records(), record.records()); + assertEquals(dnsRecords.get(counter).name(), record.name()); + assertEquals(dnsRecords.get(counter).type(), record.type()); + assertNull(record.ttl()); + counter++; + } + assertEquals(2, counter); + dnsRecordIterator = DNS.listDnsRecords(zone.name(), + Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TYPE), + Dns.DnsRecordListOption.pageSize(1)).iterateAll(); // also test paging + counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertEquals(dnsRecords.get(counter).type(), record.type()); + assertEquals(dnsRecords.get(counter).name(), record.name()); + assertTrue(record.records().isEmpty()); + assertNull(record.ttl()); + counter++; + } + assertEquals(2, counter); + // test page size + Page dnsRecordPage = DNS.listDnsRecords(zone.name(), + Dns.DnsRecordListOption.fields(Dns.DnsRecordField.TYPE), + Dns.DnsRecordListOption.pageSize(1)); + assertEquals(1, ImmutableList.copyOf(dnsRecordPage.values().iterator()).size()); + // test name filter + ChangeRequest change = DNS.applyChangeRequest(ZONE1.name(), CHANGE_ADD_ZONE1); + waitUntilComplete(ZONE1.name(), change.id()); + dnsRecordIterator = DNS.listDnsRecords(ZONE1.name(), + Dns.DnsRecordListOption.dnsName(A_RECORD_ZONE1.name())).iterateAll(); + counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertTrue(ImmutableList.of(A_RECORD_ZONE1.type(), AAAA_RECORD_ZONE1.type()) + .contains(record.type())); + counter++; + } + assertEquals(2, counter); + // test type filter + waitUntilComplete(ZONE1.name(), change.id()); + dnsRecordIterator = DNS.listDnsRecords(ZONE1.name(), + Dns.DnsRecordListOption.dnsName(A_RECORD_ZONE1.name()), + Dns.DnsRecordListOption.type(A_RECORD_ZONE1.type())) + .iterateAll(); + counter = 0; + while (dnsRecordIterator.hasNext()) { + DnsRecord record = dnsRecordIterator.next(); + assertEquals(A_RECORD_ZONE1, record); + counter++; + } + assertEquals(1, counter); + change = zone.applyChangeRequest(CHANGE_DELETE_ZONE1); + // check wrong arguments + try { + // name is not set + DNS.listDnsRecords(ZONE1.name(), Dns.DnsRecordListOption.type(A_RECORD_ZONE1.type())); + fail(); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test retry functionality when available + } + try { + DNS.listDnsRecords(ZONE1.name(), Dns.DnsRecordListOption.pageSize(0)); + fail(); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test retry functionality when available + } + try { + DNS.listDnsRecords(ZONE1.name(), Dns.DnsRecordListOption.pageSize(-1)); + fail(); + } catch (DnsException ex) { + // expected + assertEquals(400, ex.code()); + // todo(mderka) test retry functionality when available + } + waitUntilComplete(ZONE1.name(), change.id()); + } finally { + clear(); + } + } +}