/** * Licensed to jclouds, Inc. (jclouds) under one or more * contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. jclouds licenses this file * to you 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 WATCANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.jclouds.ultradns.ws.features; import static com.google.common.base.Predicates.equalTo; import static com.google.common.base.Predicates.not; import static com.google.common.collect.Iterables.filter; import static com.google.common.collect.Iterables.isEmpty; import static com.google.common.collect.Sets.newLinkedHashSet; import static java.util.logging.Logger.getAnonymousLogger; import static org.jclouds.ultradns.ws.domain.DirectionalPool.RecordType.IPV4; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertNull; import static org.testng.Assert.assertTrue; import java.util.EnumSet; import java.util.Set; import org.jclouds.rest.ResourceNotFoundException; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.DirectionalGroupOverlapException; import org.jclouds.ultradns.ws.UltraDNSWSExceptions.ResourceAlreadyExistsException; import org.jclouds.ultradns.ws.domain.DirectionalGroup; import org.jclouds.ultradns.ws.domain.DirectionalPool; import org.jclouds.ultradns.ws.domain.DirectionalPool.RecordType; import org.jclouds.ultradns.ws.domain.DirectionalPool.TieBreak; import org.jclouds.ultradns.ws.domain.DirectionalPool.Type; import org.jclouds.ultradns.ws.domain.DirectionalPoolRecord; import org.jclouds.ultradns.ws.domain.DirectionalPoolRecordDetail; import org.jclouds.ultradns.ws.domain.IdAndName; import org.jclouds.ultradns.ws.domain.Zone; import org.jclouds.ultradns.ws.internal.BaseDirectionalApiLiveTest; import org.testng.annotations.Test; import com.google.common.base.Optional; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Multimap; /** * @author Adrian Cole */ @Test(groups = "live", singleThreaded = true, testName = "DirectionalPoolApiLiveTest") public class DirectionalPoolApiLiveTest extends BaseDirectionalApiLiveTest { @Test public void testListDirectionalPools() { for (Zone zone : api.getZoneApi().listByAccount(account.getId())) { for (DirectionalPool pool : api(zone.getName()).list()) { checkDirectional(pool); } } } private void checkDirectional(DirectionalPool pool) { assertNotNull(pool.getZoneId(), "ZoneId cannot be null " + pool); assertNotNull(pool.getId(), "Id cannot be null " + pool); assertNotNull(pool.getDName(), "DName cannot be null " + pool); assertNotNull(pool.getName(), "Name cannot be null " + pool); assertNotNull(pool.getType(), "Type cannot be null " + pool); assertNotNull(pool.getTieBreak(), "TieBreak cannot be null " + pool); } Set<IdAndName> allDirectionalGroups = newLinkedHashSet(); @Test public void testListDirectionalRecords() { for (Zone zone : api.getZoneApi().listByAccount(account.getId())) { for (DirectionalPool pool : api(zone.getName()).list()) { for (RecordType type : EnumSet.allOf(RecordType.class)) { for (DirectionalPoolRecordDetail rr : api(zone.getName()) .listRecordsByDNameAndType(pool.getDName(), type.getCode())) { checkDirectionalRecordDetail(rr); Iterable<IdAndName> groups = Optional.presentInstances(ImmutableSet.of(rr.getGroup(), rr.getGeolocationGroup(), rr.getGeolocationGroup())); assertFalse(isEmpty(groups), "No groups " + rr); for (IdAndName group : groups) { allDirectionalGroups.add(group); assertNotNull(group.getId(), "Id cannot be null " + group); assertNotNull(group.getName(), "Name cannot be null " + group); } assertEquals(rr.getZoneName(), zone.getName()); assertEquals(rr.getName(), pool.getDName()); switch (pool.getType()) { case GEOLOCATION: assertNotNull(rr.getGeolocationGroup().or(rr.getGroup()).orNull(), "GeolocationGroup or Group must be present " + rr); assertNull(rr.getSourceIpGroup().orNull(), "SourceIpGroup must be absent " + rr); break; case SOURCEIP: assertNotNull(rr.getSourceIpGroup().orNull(), "SourceIpGroup must be present " + rr); assertNull(rr.getGeolocationGroup().orNull(), "GeolocationGroup must be absent " + rr); break; case MIXED: assertNotNull(rr.getGeolocationGroup().or(rr.getSourceIpGroup()).or(rr.getGroup()).orNull(), "GeolocationGroup, SourceIpGroup or Group must be present " + rr); break; } } } } } } static void checkDirectionalRecord(DirectionalPoolRecord rr) { assertNotNull(rr.getType(), "Type cannot be null " + rr); assertNotNull(rr.getTTL(), "TTL cannot be null " + rr); assertNotNull(rr.getRData(), "InfoValues cannot be null " + rr); } static DirectionalPoolRecordDetail checkDirectionalRecordDetail(DirectionalPoolRecordDetail rr) { assertNotNull(rr.getZoneName(), "ZoneName cannot be null " + rr); assertNotNull(rr.getName(), "DName cannot be null " + rr); assertNotNull(rr.getId(), "Id cannot be null " + rr); assertNotNull(rr.getZoneName(), "ZoneName cannot be null " + rr); checkDirectionalRecord(rr.getRecord()); return rr; } @Test(expectedExceptions = ResourceNotFoundException.class, expectedExceptionsMessageRegExp = "Parent Zone does not exist in the system.") public void testListDirectionalsWhenZoneIdNotFound() { api("AAAAAAAAAAAAAAAA").list(); } @Test public void testDeleteWhenNotFound() { api(zoneName).delete("06063D9C54C5AE09"); } @Test public void testDeleteRecordWhenNotFound() { api(zoneName).deleteRecord("06063D9C54C5AE09"); } @Test(expectedExceptions = ResourceNotFoundException.class, expectedExceptionsMessageRegExp = "Directional Pool Record does not exist in the system") public void testUpdateRecordWhenNotFound() { api(zoneName).updateRecord("06063D9C54C5AE09", cnameRecordCanary); } @Test public void testCreateCNAMEPool() { cnamePoolId = api(zoneName).createForDNameAndType("Geo pool", dname, IPV4.getCode()); getAnonymousLogger().info("created Geo pool: " + cnamePoolId); Optional<DirectionalPool> ipv4Pool = getPoolById(cnamePoolId); assertTrue(ipv4Pool.isPresent()); assertEquals(ipv4Pool.get().getZoneId(), zoneId); assertEquals(ipv4Pool.get().getName().get(), "Geo pool"); assertEquals(ipv4Pool.get().getDName(), dname); assertEquals(ipv4Pool.get().getType(), Type.GEOLOCATION); assertEquals(ipv4Pool.get().getTieBreak(), TieBreak.GEOLOCATION); } @Test(dependsOnMethods = "testCreateCNAMEPool", expectedExceptions = ResourceAlreadyExistsException.class) public void testDuplicateCreateCNAMEPool() { api(zoneName).createForDNameAndType("Geo pool", dname, IPV4.getCode()); } @Test(dependsOnMethods = "testDuplicateCreateCNAMEPool") public void addCNAMERecordsToPool() { cnameEU = api(zoneName).addRecordIntoNewGroup(cnamePoolId, cnameRecordEU, eu); getAnonymousLogger().info("created CNAME record in ipv4 pool: " + cnameEU); checkRecordConsistent(dname, cnameEU, cnameRecordEU, eu); cnameUS = api(zoneName).addRecordIntoNewGroup(cnamePoolId, cnameRecordUS, us); getAnonymousLogger().info("created CNAME record in ipv4 pool: " + cnameUS); checkRecordConsistent(dname, cnameUS, cnameRecordUS, us); cnameCanary = api(zoneName).addRecordIntoNewGroup(cnamePoolId, cnameRecordCanary, nebraska); getAnonymousLogger().info("created CNAME record in ipv4 pool: " + cnameCanary); checkRecordConsistent(dname, cnameCanary, cnameRecordCanary, nebraska); } @Test(dependsOnMethods = "addCNAMERecordsToPool", expectedExceptions = ResourceAlreadyExistsException.class) public void testDuplicateAddCNAMERecordsToPool() { api(zoneName).addRecordIntoNewGroup(cnamePoolId, cnameRecordEU, eu); } @Test(dependsOnMethods = "testDuplicateAddCNAMERecordsToPool") public void testUpdateRecordTTL() { cnameRecordCanary = cnameRecordCanary.toBuilder().ttl(180).build(); api(zoneName).updateRecord(cnameCanary, cnameRecordCanary); getAnonymousLogger().info("updated CNAME record TTL in ipv4 pool: " + cnameCanary); checkRecordConsistent(dname, cnameCanary, cnameRecordCanary, nebraska); } @Test(dependsOnMethods = "testUpdateRecordTTL", expectedExceptions = DirectionalGroupOverlapException.class) public void testUpdateGroupWithOverlappingTerritories() { DirectionalGroup withUtah = nebraska.toBuilder().mapRegionToTerritory(REGION_US, "Utah").build(); checkGroupByDNameAndIdContainsTerritory(dname, cnameUS, "Utah"); try { api(zoneName).updateRecordAndGroup(cnameCanary, cnameRecordCanary, withUtah); } finally { checkRecordConsistent(dname, cnameCanary, cnameRecordCanary, nebraska); } } @Test(dependsOnMethods = "testUpdateGroupWithOverlappingTerritories") public void testUpdateGroupWithLessTerritories() { Multimap<String, String> minusUtah = ImmutableMultimap.<String, String>builder() .putAll("United States (US)", filter(us.get(REGION_US), not(equalTo("Utah")))) .build(); api(zoneName).updateRecordAndGroup(cnameUS, cnameRecordUS, us.toBuilder() .regionToTerritories(minusUtah) .build()); checkGroupByDNameAndIdDoesntContainTerritory(dname, cnameUS, "Utah"); } @Test(dependsOnMethods = "testUpdateGroupWithLessTerritories") public void testUpdateGroupWithMoreTerritories() { DirectionalGroup withUtah = nebraska.toBuilder().mapRegionToTerritory(REGION_US, "Utah").build(); api(zoneName).updateRecordAndGroup(cnameCanary, cnameRecordCanary, withUtah); getAnonymousLogger().info("update CNAME record in ipv4 pool: " + cnameCanary); checkRecordConsistent(dname, cnameCanary, cnameRecordCanary, withUtah); checkGroupByDNameAndIdContainsTerritory(dname, cnameCanary, "Nebraska"); checkGroupByDNameAndIdContainsTerritory(dname, cnameCanary, "Utah"); } @Test(dependsOnMethods = "testUpdateGroupWithMoreTerritories") public void testAddRecordIntoGeoGroup() { String geoGroupId = getRecordByDNameAndId(dname, cnameCanary).get().getGeolocationGroup().get().getId(); cname2Canary = api(zoneName).addRecordIntoExistingGroup(cnamePoolId, cname2RecordCanary, geoGroupId); getAnonymousLogger().info("created CNAME record in ipv4 pool: " + cname2Canary); DirectionalPoolRecordDetail detail = checkRecordConsistentInNonConfiguredGroup(dname, cname2Canary, cname2RecordCanary); assertEquals(detail.getGroup().get().getId(), geoGroupId); } @Test(dependsOnMethods = "testAddRecordIntoGeoGroup") public void testDeleteRecord() { api(zoneName).deleteRecord(cnameEU); assertFalse(getRecordByDNameAndId(dname, cnameEU).isPresent()); assertTrue(getRecordByDNameAndId(dname, cnameUS).isPresent()); } @Test public void addRecordsWithUnconfiguredGroupToPool() { aPoolId = api(zoneName).createForDNameAndType("Geo pool", "a-" + dname, IPV4.getCode()); getAnonymousLogger().info("created Geo pool: " + aPoolId); a1Prod = api(zoneName).addFirstRecordInNonConfiguredGroup(aPoolId, a1RecordProd); getAnonymousLogger().info("created A record in ipv4 pool: " + a1Prod); checkRecordConsistentInNonConfiguredGroup("a-" + dname, a1Prod, a1RecordProd); checkGroupByDNameAndIdContainsTerritory("a-" + dname, a1Prod, "Nebraska"); a1Canary = api(zoneName).addRecordIntoNewGroup(aPoolId, a1RecordCanary, nebraska); getAnonymousLogger().info("created A record in ipv4 pool: " + a1Canary); checkRecordConsistent("a-" + dname, a1Canary, a1RecordCanary, nebraska); checkGroupByDNameAndIdContainsTerritory("a-" + dname, a1Canary, "Nebraska"); checkGroupByDNameAndIdDoesntContainTerritory("a-" + dname, a1Prod, "Nebraska"); } @Test(dependsOnMethods = "addRecordsWithUnconfiguredGroupToPool", expectedExceptions = ResourceAlreadyExistsException.class) public void addDuplicateFirstRecordInNonConfiguredGroup() { api(zoneName).addFirstRecordInNonConfiguredGroup(aPoolId, a1RecordProd); } @Test(dependsOnMethods = "addRecordsWithUnconfiguredGroupToPool", expectedExceptions = ResourceAlreadyExistsException.class) public void addDuplicateRecordIntoNewGroup() { api(zoneName).addRecordIntoNewGroup(aPoolId, a1RecordCanary, nebraska); } @Test(dependsOnMethods = { "addDuplicateFirstRecordInNonConfiguredGroup", "addRecordsWithUnconfiguredGroupToPool" }) public void testRemovingAddsTerritoriesBackIntoNonConfiguredGroup() { api(zoneName).deleteRecord(a1Canary); assertFalse(getRecordByDNameAndId("a-" + dname, a1Canary).isPresent()); checkGroupByDNameAndIdContainsTerritory("a-" + dname, a1Prod, "Nebraska"); } @Test(dependsOnMethods = { "testDeleteRecord", "testRemovingAddsTerritoriesBackIntoNonConfiguredGroup" }) public void testDeletePool() { api(zoneName).delete(cnamePoolId); assertFalse(getPoolById(cnamePoolId).isPresent()); api(zoneName).delete(aPoolId); assertFalse(getPoolById(aPoolId).isPresent()); } private DirectionalPoolRecordDetail checkRecordConsistent(String dname, String recordId, DirectionalPoolRecord record, DirectionalGroup group) { DirectionalPoolRecordDetail recordDetail = getRecordByDNameAndId(dname, recordId).get(); checkDirectionalRecordDetail(recordDetail); IdAndName rGroup = recordDetail.getGeolocationGroup().get(); assertEquals(rGroup.getName(), group.getName()); // TODO: look up each key with all and do a comparison if (!group.containsValue("all")) assertEquals(groupApi().get(rGroup.getId()), group); assertFalse(recordDetail.getGroup().isPresent()); assertFalse(recordDetail.getSourceIpGroup().isPresent()); assertEquals(recordDetail.getName(), dname); assertEquals(recordDetail.getZoneName(), zoneName); assertEquals(recordDetail.getRecord(), record); return recordDetail; } private DirectionalPoolRecordDetail checkRecordConsistentInNonConfiguredGroup(String dname, String recordId, DirectionalPoolRecord record) { DirectionalPoolRecordDetail recordDetail = getRecordByDNameAndId(dname, recordId).get(); checkDirectionalRecordDetail(recordDetail); IdAndName rGroup = recordDetail.getGroup().get(); assertEquals(rGroup.getName(), "All Non-Configured Regions"); DirectionalGroup allNonConfigured = groupApi().get(rGroup.getId()); assertEquals(allNonConfigured.getName(), "All Non-Configured Regions"); assertEquals(allNonConfigured.size(), 323); assertFalse(recordDetail.getGeolocationGroup().isPresent()); assertFalse(recordDetail.getSourceIpGroup().isPresent()); assertEquals(recordDetail.getZoneName(), zoneName); assertEquals(recordDetail.getRecord(), record); return recordDetail; } private DirectionalPoolApi api(String zoneName) { return api.getDirectionalPoolApiForZone(zoneName); } private DirectionalGroupApi groupApi() { return api.getDirectionalGroupApiForAccount(account.getId()); } }